From 47014f5a3f90ef299edb28a33e7fe7b711d5b134 Mon Sep 17 00:00:00 2001 From: jlightner Date: Fri, 3 Apr 2026 09:10:14 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Featured=20technique=20card=20with=20gr?= =?UTF-8?q?adient=20border=20and=20enriched=20recent-=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "frontend/src/api/public-client.ts" - "frontend/src/pages/CreatorDetail.tsx" - "frontend/src/App.css" GSD-Task: S03/T02 --- .gsd/milestones/M017/slices/S03/S03-PLAN.md | 2 +- .../M017/slices/S03/tasks/T01-VERIFY.json | 16 ++++ .../M017/slices/S03/tasks/T02-SUMMARY.md | 82 +++++++++++++++++ frontend/src/App.css | 54 ++++++++++++ frontend/src/api/public-client.ts | 3 + frontend/src/pages/CreatorDetail.tsx | 87 +++++++++++++++---- 6 files changed, 225 insertions(+), 19 deletions(-) create mode 100644 .gsd/milestones/M017/slices/S03/tasks/T01-VERIFY.json create mode 100644 .gsd/milestones/M017/slices/S03/tasks/T02-SUMMARY.md diff --git a/.gsd/milestones/M017/slices/S03/S03-PLAN.md b/.gsd/milestones/M017/slices/S03/S03-PLAN.md index 70cf5ad..1aaa221 100644 --- a/.gsd/milestones/M017/slices/S03/S03-PLAN.md +++ b/.gsd/milestones/M017/slices/S03/S03-PLAN.md @@ -29,7 +29,7 @@ - Estimate: 20m - Files: backend/schemas.py, backend/routers/creators.py - Verify: cd backend && python -c "from schemas import CreatorTechniqueItem; fields = list(CreatorTechniqueItem.model_fields.keys()); assert 'summary' in fields and 'topic_tags' in fields and 'key_moment_count' in fields; print('OK')" -- [ ] **T02: Add featured technique card and restyle grid to recent-card pattern** — Update the frontend to consume the enriched technique fields: render the first technique as a featured card with gradient border, and restyle remaining cards to match the recent-card pattern. +- [x] **T02: Featured technique card with gradient border and enriched recent-card grid rendered on creator detail page** — Update the frontend to consume the enriched technique fields: render the first technique as a featured card with gradient border, and restyle remaining cards to match the recent-card pattern. ## Steps diff --git a/.gsd/milestones/M017/slices/S03/tasks/T01-VERIFY.json b/.gsd/milestones/M017/slices/S03/tasks/T01-VERIFY.json new file mode 100644 index 0000000..47df1ea --- /dev/null +++ b/.gsd/milestones/M017/slices/S03/tasks/T01-VERIFY.json @@ -0,0 +1,16 @@ +{ + "schemaVersion": 1, + "taskId": "T01", + "unitId": "M017/S03/T01", + "timestamp": 1775207254785, + "passed": true, + "discoverySource": "task-plan", + "checks": [ + { + "command": "cd backend", + "exitCode": 0, + "durationMs": 4, + "verdict": "pass" + } + ] +} diff --git a/.gsd/milestones/M017/slices/S03/tasks/T02-SUMMARY.md b/.gsd/milestones/M017/slices/S03/tasks/T02-SUMMARY.md new file mode 100644 index 0000000..f837ea6 --- /dev/null +++ b/.gsd/milestones/M017/slices/S03/tasks/T02-SUMMARY.md @@ -0,0 +1,82 @@ +--- +id: T02 +parent: S03 +milestone: M017 +provides: [] +requires: [] +affects: [] +key_files: ["frontend/src/api/public-client.ts", "frontend/src/pages/CreatorDetail.tsx", "frontend/src/App.css"] +key_decisions: ["Used null-check guard + IIFE for featured technique to satisfy strict TS noUncheckedIndexedAccess"] +patterns_established: [] +drill_down_paths: [] +observability_surfaces: [] +duration: "" +verification_result: "npx tsc --noEmit exits 0. npm run build exits 0. grep confirms creator-featured and recent-card classes in CreatorDetail.tsx. Backend schema check confirms enriched fields present." +completed_at: 2026-04-03T09:10:03.442Z +blocker_discovered: false +--- + +# T02: Featured technique card with gradient border and enriched recent-card grid rendered on creator detail page + +> Featured technique card with gradient border and enriched recent-card grid rendered on creator detail page + +## What Happened +--- +id: T02 +parent: S03 +milestone: M017 +key_files: + - frontend/src/api/public-client.ts + - frontend/src/pages/CreatorDetail.tsx + - frontend/src/App.css +key_decisions: + - Used null-check guard + IIFE for featured technique to satisfy strict TS noUncheckedIndexedAccess +duration: "" +verification_result: passed +completed_at: 2026-04-03T09:10:03.442Z +blocker_discovered: false +--- + +# T02: Featured technique card with gradient border and enriched recent-card grid rendered on creator detail page + +**Featured technique card with gradient border and enriched recent-card grid rendered on creator detail page** + +## What Happened + +Extended CreatorTechniqueItem TypeScript interface with summary, topic_tags, and key_moment_count. Restructured CreatorDetail technique list: first technique renders as a prominent featured card with gradient border-image, summary, category badge, TagList, and moment count. Remaining techniques use the recent-card class pattern with the same enriched fields. Added .creator-featured CSS adapted from .home-featured. + +## Verification + +npx tsc --noEmit exits 0. npm run build exits 0. grep confirms creator-featured and recent-card classes in CreatorDetail.tsx. Backend schema check confirms enriched fields present. + +## Verification Evidence + +| # | Command | Exit Code | Verdict | Duration | +|---|---------|-----------|---------|----------| +| 1 | `cd frontend && npx tsc --noEmit` | 0 | ✅ pass | 3100ms | +| 2 | `cd frontend && npm run build` | 0 | ✅ pass | 3100ms | +| 3 | `grep -q 'creator-featured' frontend/src/pages/CreatorDetail.tsx` | 0 | ✅ pass | 50ms | +| 4 | `grep -q 'recent-card' frontend/src/pages/CreatorDetail.tsx` | 0 | ✅ pass | 50ms | +| 5 | `cd backend && python -c "from schemas import CreatorTechniqueItem; ..."` | 0 | ✅ pass | 500ms | + + +## Deviations + +Added null-check guard before IIFE for featured technique to satisfy Vite's stricter TS build config (noUncheckedIndexedAccess). + +## Known Issues + +None. + +## Files Created/Modified + +- `frontend/src/api/public-client.ts` +- `frontend/src/pages/CreatorDetail.tsx` +- `frontend/src/App.css` + + +## Deviations +Added null-check guard before IIFE for featured technique to satisfy Vite's stricter TS build config (noUncheckedIndexedAccess). + +## Known Issues +None. diff --git a/frontend/src/App.css b/frontend/src/App.css index 6fb5bfb..4d8a3e6 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -2806,6 +2806,60 @@ a.app-footer__repo:hover { line-height: 1.4; } +/* ── Creator Featured Technique ─────────────────────────────────────── */ + +.creator-featured { + display: block; + max-width: 100%; + margin-bottom: 1.25rem; + padding: 1.25rem 1.5rem; + background: var(--color-bg-surface); + border: 1px solid transparent; + border-image: linear-gradient(135deg, #22d3ee, #a855f7) 1; + text-decoration: none; + color: inherit; + position: relative; +} + +.creator-featured__label { + margin-bottom: 0.5rem; +} + +.creator-featured__title { + display: block; + font-size: 1.25rem; + font-weight: 700; + color: var(--color-text); + margin-bottom: 0.5rem; + line-height: 1.3; +} + +.creator-featured:hover .creator-featured__title { + color: var(--color-accent-hover); +} + +.creator-featured__summary { + font-size: 0.875rem; + color: var(--color-text-secondary); + line-height: 1.5; + margin-bottom: 0.75rem; + margin-top: 0; +} + +.creator-featured__meta { + display: flex; + align-items: center; + gap: 0.5rem; + flex-wrap: wrap; + margin-bottom: 0.5rem; +} + +.creator-featured__moments { + font-size: 0.75rem; + color: var(--color-text-tertiary); + white-space: nowrap; +} + /* ══════════════════════════════════════════════════════════════════════════════ TOPICS BROWSE — Card Grid Layout ══════════════════════════════════════════════════════════════════════════════ */ diff --git a/frontend/src/api/public-client.ts b/frontend/src/api/public-client.ts index 30d9c60..723ebc0 100644 --- a/frontend/src/api/public-client.ts +++ b/frontend/src/api/public-client.ts @@ -178,6 +178,9 @@ export interface CreatorTechniqueItem { title: string; slug: string; topic_category: string; + summary: string | null; + topic_tags: string[] | null; + key_moment_count: number; created_at: string; } diff --git a/frontend/src/pages/CreatorDetail.tsx b/frontend/src/pages/CreatorDetail.tsx index b58a978..3da76fc 100644 --- a/frontend/src/pages/CreatorDetail.tsx +++ b/frontend/src/pages/CreatorDetail.tsx @@ -14,6 +14,7 @@ import { import CreatorAvatar from "../components/CreatorAvatar"; import { SocialIcon } from "../components/SocialIcons"; import SortDropdown from "../components/SortDropdown"; +import TagList from "../components/TagList"; import { catSlug } from "../utils/catSlug"; import { useDocumentTitle } from "../hooks/useDocumentTitle"; import { useSortPreference } from "../hooks/useSortPreference"; @@ -184,25 +185,75 @@ export default function CreatorDetail() { {techniques.length === 0 ? (
No techniques yet.
) : ( -
- {techniques.map((t, i) => ( - - - {t.title} - - - - {t.topic_category} + <> + {/* Featured technique — first in sorted order */} + {techniques[0] != null && (() => { + const featured = techniques[0]; + return ( + + + Featured Technique - - - ))} -
+ + {featured.title} + + {featured.summary && ( +

+ {featured.summary} +

+ )} + + + {featured.topic_category} + + {featured.topic_tags && featured.topic_tags.length > 0 && ( + + )} + + + {featured.key_moment_count} moment{featured.key_moment_count !== 1 ? "s" : ""} + + + ); + })()} + + {/* Remaining techniques — recent-card grid */} + {techniques.length > 1 && ( +
+ {techniques.slice(1).map((t, i) => ( + + + {t.title} + + {t.summary && ( + + {t.summary} + + )} + + + {t.topic_category} + + {t.topic_tags && t.topic_tags.length > 0 && ( + + )} + + + {t.key_moment_count} moment{t.key_moment_count !== 1 ? "s" : ""} + + + ))} +
+ )} + )}