From bef8d5939d30100e293ef7f63a6fb2a56652da45 Mon Sep 17 00:00:00 2001 From: jlightner Date: Fri, 3 Apr 2026 08:52:06 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Replaced=20compact=20creator=20header?= =?UTF-8?q?=20with=20full=20hero=20section:=2096px=20avat=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "frontend/src/pages/CreatorDetail.tsx" - "frontend/src/App.css" GSD-Task: S01/T02 --- .gsd/milestones/M017/slices/S01/S01-PLAN.md | 2 +- .../M017/slices/S01/tasks/T01-VERIFY.json | 24 ++++++ .../M017/slices/S01/tasks/T02-SUMMARY.md | 77 +++++++++++++++++++ frontend/src/App.css | 57 ++++++++++---- frontend/src/pages/CreatorDetail.tsx | 67 ++++++++-------- 5 files changed, 182 insertions(+), 45 deletions(-) create mode 100644 .gsd/milestones/M017/slices/S01/tasks/T01-VERIFY.json create mode 100644 .gsd/milestones/M017/slices/S01/tasks/T02-SUMMARY.md diff --git a/.gsd/milestones/M017/slices/S01/S01-PLAN.md b/.gsd/milestones/M017/slices/S01/S01-PLAN.md index ef7195f..2305004 100644 --- a/.gsd/milestones/M017/slices/S01/S01-PLAN.md +++ b/.gsd/milestones/M017/slices/S01/S01-PLAN.md @@ -53,7 +53,7 @@ - Estimate: 25m - Files: frontend/src/api/public-client.ts, frontend/src/pages/CreatorDetail.tsx - Verify: cd frontend && npx tsc --noEmit -- [ ] **T02: Build hero section with large avatar, bio text, and genre pills** — Replace the compact `creator-detail__header` with a full hero section. Large avatar, prominent name, bio paragraph, and genre pills. Use existing `CreatorAvatar` component (supports `imageUrl` prop and arbitrary `size`), existing `.pill` class for genres, and CSS custom properties for theming. +- [x] **T02: Replaced compact creator header with full hero section: 96px avatar, 2rem name, bio paragraph, genre pills, separated stats bar** — Replace the compact `creator-detail__header` with a full hero section. Large avatar, prominent name, bio paragraph, and genre pills. Use existing `CreatorAvatar` component (supports `imageUrl` prop and arbitrary `size`), existing `.pill` class for genres, and CSS custom properties for theming. ## Steps diff --git a/.gsd/milestones/M017/slices/S01/tasks/T01-VERIFY.json b/.gsd/milestones/M017/slices/S01/tasks/T01-VERIFY.json new file mode 100644 index 0000000..8782954 --- /dev/null +++ b/.gsd/milestones/M017/slices/S01/tasks/T01-VERIFY.json @@ -0,0 +1,24 @@ +{ + "schemaVersion": 1, + "taskId": "T01", + "unitId": "M017/S01/T01", + "timestamp": 1775206212614, + "passed": false, + "discoverySource": "task-plan", + "checks": [ + { + "command": "cd frontend", + "exitCode": 0, + "durationMs": 5, + "verdict": "pass" + }, + { + "command": "npx tsc --noEmit", + "exitCode": 1, + "durationMs": 817, + "verdict": "fail" + } + ], + "retryAttempt": 1, + "maxRetries": 2 +} diff --git a/.gsd/milestones/M017/slices/S01/tasks/T02-SUMMARY.md b/.gsd/milestones/M017/slices/S01/tasks/T02-SUMMARY.md new file mode 100644 index 0000000..1b4c41e --- /dev/null +++ b/.gsd/milestones/M017/slices/S01/tasks/T02-SUMMARY.md @@ -0,0 +1,77 @@ +--- +id: T02 +parent: S01 +milestone: M017 +provides: [] +requires: [] +affects: [] +key_files: ["frontend/src/pages/CreatorDetail.tsx", "frontend/src/App.css"] +key_decisions: ["Separated stats bar from hero into its own div below the hero border"] +patterns_established: [] +drill_down_paths: [] +observability_surfaces: [] +duration: "" +verification_result: "npx tsc --noEmit passed with zero errors. npm run build produced clean production build (58 modules, zero warnings)." +completed_at: 2026-04-03T08:52:03.434Z +blocker_discovered: false +--- + +# T02: Replaced compact creator header with full hero section: 96px avatar, 2rem name, bio paragraph, genre pills, separated stats bar + +> Replaced compact creator header with full hero section: 96px avatar, 2rem name, bio paragraph, genre pills, separated stats bar + +## What Happened +--- +id: T02 +parent: S01 +milestone: M017 +key_files: + - frontend/src/pages/CreatorDetail.tsx + - frontend/src/App.css +key_decisions: + - Separated stats bar from hero into its own div below the hero border +duration: "" +verification_result: passed +completed_at: 2026-04-03T08:52:03.434Z +blocker_discovered: false +--- + +# T02: Replaced compact creator header with full hero section: 96px avatar, 2rem name, bio paragraph, genre pills, separated stats bar + +**Replaced compact creator header with full hero section: 96px avatar, 2rem name, bio paragraph, genre pills, separated stats bar** + +## What Happened + +Replaced the old creator-detail__header block with a new creator-hero layout featuring a 96px CreatorAvatar (using avatar_url), prominent 2rem name, conditional bio paragraph, and genre pills. Stats moved to a separate stats-bar div below the hero border. Updated CSS with flex layout, responsive mobile stacking at 768px, and removed old unused rules. Fixed unused CreatorTechniqueItem import from T01 that caused tsc -b to fail. + +## Verification + +npx tsc --noEmit passed with zero errors. npm run build produced clean production build (58 modules, zero warnings). + +## Verification Evidence + +| # | Command | Exit Code | Verdict | Duration | +|---|---------|-----------|---------|----------| +| 1 | `npx tsc --noEmit` | 0 | ✅ pass | 1500ms | +| 2 | `npm run build` | 0 | ✅ pass | 3500ms | + + +## Deviations + +Removed unused CreatorTechniqueItem import from T01 that caused tsc -b (used by npm run build) to fail with TS6133. + +## Known Issues + +None. + +## Files Created/Modified + +- `frontend/src/pages/CreatorDetail.tsx` +- `frontend/src/App.css` + + +## Deviations +Removed unused CreatorTechniqueItem import from T01 that caused tsc -b (used by npm run build) to fail with TS6133. + +## Known Issues +None. diff --git a/frontend/src/App.css b/frontend/src/App.css index c5904d0..1d95c39 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -2659,32 +2659,51 @@ a.app-footer__repo:hover { max-width: 64rem; } -.creator-detail__header { +/* Creator Hero */ +.creator-hero { + display: flex; + align-items: flex-start; + gap: 1.5rem; margin-bottom: 1.5rem; + padding-bottom: 1.5rem; + border-bottom: 1px solid var(--color-border); } -.creator-detail__name { +.creator-hero__info { display: flex; - align-items: center; - gap: 0.75rem; - font-size: 1.75rem; + flex-direction: column; + gap: 0.5rem; + min-width: 0; +} + +.creator-hero__name { + font-size: 2rem; font-weight: 800; letter-spacing: -0.02em; - margin-bottom: 0.5rem; line-height: 1.2; + margin: 0; } -.creator-detail__meta { +.creator-hero__bio { + color: var(--color-text-secondary); + font-size: 1rem; + line-height: 1.6; + max-width: 48rem; + margin: 0; +} + +.creator-hero__genres { + display: flex; + flex-wrap: wrap; + gap: 0.375rem; +} + +.creator-detail__stats-bar { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; -} - -.creator-detail__genres { - display: inline-flex; - gap: 0.25rem; - flex-wrap: wrap; + margin-bottom: 0.5rem; } .creator-detail__stats { @@ -3164,10 +3183,20 @@ a.app-footer__repo:hover { .creators-browse__title, .topics-browse__title, - .creator-detail__name { + .creator-hero__name { font-size: 1.375rem; } + .creator-hero { + flex-direction: column; + align-items: center; + text-align: center; + } + + .creator-hero__genres { + justify-content: center; + } + .topics-grid { grid-template-columns: 1fr; } diff --git a/frontend/src/pages/CreatorDetail.tsx b/frontend/src/pages/CreatorDetail.tsx index 8344d21..6388d8e 100644 --- a/frontend/src/pages/CreatorDetail.tsx +++ b/frontend/src/pages/CreatorDetail.tsx @@ -10,7 +10,6 @@ import { Link, useParams } from "react-router-dom"; import { fetchCreator, type CreatorDetailResponse, - type CreatorTechniqueItem, } from "../api/public-client"; import CreatorAvatar from "../components/CreatorAvatar"; import SortDropdown from "../components/SortDropdown"; @@ -110,39 +109,47 @@ export default function CreatorDetail() { ← Creators - {/* Header */} -
-

{creator.name}

-
- {creator.genres && creator.genres.length > 0 && ( - - {creator.genres.map((g) => ( - - {g} - - ))} - + {/* Hero */} +
+ +
+

{creator.name}

+ {creator.bio && ( +

{creator.bio}

+ )} + {creator.genres && creator.genres.length > 0 && ( +
+ {creator.genres.map((g) => ( + {g} + ))} +
)} - - {creator.video_count} video{creator.video_count !== 1 ? "s" : ""} - {Object.keys(creator.genre_breakdown).length > 0 && ( - <> - · - - {Object.entries(creator.genre_breakdown) - .sort(([, a], [, b]) => b - a) - .map(([cat, count]) => ( - - {cat}: {count} - - ))} - - - )} -
+ {/* Stats */} +
+ + {creator.video_count} video{creator.video_count !== 1 ? "s" : ""} + + {Object.keys(creator.genre_breakdown).length > 0 && ( + + {Object.entries(creator.genre_breakdown) + .sort(([, a], [, b]) => b - a) + .map(([cat, count]) => ( + + {cat}: {count} + + ))} + + )} +
+ {/* Technique pages */}