9.5 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 18-global-items-public-profiles | 05 | execute | 3 |
|
|
false |
|
|
Purpose: Delivers the client-side experience for PROF-01 (profile edit), PROF-02 (public profile), PROF-03 (setup toggle), PROF-04 (public setup view), PROF-05 (profile lists public setups). Output: useProfile hook, public profile page, ProfileSection component, PublicSetupCard, updated settings and setup views
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/18-global-items-public-profiles/18-CONTEXT.md @.planning/phases/18-global-items-public-profiles/18-RESEARCH.md @.planning/phases/18-global-items-public-profiles/18-03-SUMMARY.md@src/client/routes/settings.tsx @src/client/routes/setups/index.tsx @src/client/hooks/useItems.ts @src/client/lib/api.ts
PUT /api/auth/profile { displayName?, avatarUrl?, bio? } -> updated user (auth required) GET /api/users/:id/profile -> { id, displayName, avatarUrl, bio, setups: [{ id, name, createdAt }] } (no auth) GET /api/setups/:id/public -> { id, name, isPublic, items: [...], totalWeight, totalCost } (no auth, 404 if private) Task 1: Profile hooks and profile edit UI src/client/hooks/useProfile.ts, src/client/components/ProfileSection.tsx, src/client/routes/settings.tsx src/client/routes/settings.tsx, src/client/hooks/useItems.ts, src/client/lib/api.ts **useProfile.ts** hook: Create at `src/client/hooks/useProfile.ts`.-
usePublicProfile(userId: number | null)—useQuerywith key["profiles", userId], fetchesapiGet("/api/users/${userId}/profile"),enabled: userId != null. -
useUpdateProfile()—useMutationcallingapiPut("/api/auth/profile", data). On success, invalidate["profiles"]query key. Return mutation.
ProfileSection.tsx: Create at src/client/components/ProfileSection.tsx. Per D-09.
A form section that contains:
- Display name text input (max 100 chars) with label
- Bio textarea (max 500 chars) with character counter
- Avatar: Show current avatar if set, with a "Change avatar" button that opens the existing ImageUpload component (per D-11, reuse existing image upload + MinIO storage). After upload, set avatarUrl to the returned filename (the route will handle presigned URL generation).
- Save button calling
useUpdateProfile()mutation - Success/error toast feedback (use existing toast pattern if available, otherwise simple inline message)
Pre-populate form with current profile data. On mount, fetch current user profile via an appropriate mechanism (could be from auth context or a dedicated endpoint).
settings.tsx: Read the existing settings page. Add a "Profile" section at the top (before API Keys and other settings). Import and render <ProfileSection />. The section should have a heading "Profile" with a brief description "Your public profile information."
bun run lint 2>&1 | tail -5
<acceptance_criteria>
- grep -q "usePublicProfile" src/client/hooks/useProfile.ts
- grep -q "useUpdateProfile" src/client/hooks/useProfile.ts
- grep -q "ProfileSection" src/client/components/ProfileSection.tsx
- grep -q "ProfileSection" src/client/routes/settings.tsx
</acceptance_criteria>
Profile edit section in settings page with display name, bio, and avatar upload. Hooks handle fetch and mutation. Form saves correctly.
Public profile page (no auth required to view):
- TanStack Router:
createFileRoute("/users/$userId")with params - Fetch profile with
usePublicProfile(Number(userId)) - Layout: Avatar (or placeholder icon), display name (or "User #{id}" fallback), bio text
- Below profile: "Public Setups" heading with grid of PublicSetupCard components
- Empty state if no public setups: "No public setups yet"
- Loading skeleton while fetching
- 404 handling if user not found
PublicSetupCard.tsx: Create at src/client/components/PublicSetupCard.tsx.
A card for setups shown on the public profile:
- Setup name as heading
- Created date formatted
- Links to
/setups/${id}/publicfor the public view (or you can create an inline expandable view) - Light card styling with subtle border/shadow, matching existing setup cards
setups/index.tsx or setup detail: Update the setup list or detail view to include the isPublic toggle per D-14.
- In the setup detail/edit view, add a toggle switch or checkbox labeled "Public" next to the setup name
- When toggled, call the existing setup update mutation with
isPublic: true/false - Show a small icon or badge on the setup list indicating public status (e.g., a globe icon or "Public" chip)
- Default all existing setups to show as private (per D-12)
bun run lint 2>&1 | tail -5
<acceptance_criteria>
- test -f "src/client/routes/users/$userId.tsx"
- grep -q "usePublicProfile" "src/client/routes/users/$userId.tsx"
- test -f src/client/components/PublicSetupCard.tsx
- grep -q "isPublic|public" src/client/routes/setups/index.tsx </acceptance_criteria> Public profile page shows user info and public setups. Setup detail has visibility toggle. Public setups appear on profile. Private setups are hidden from profile.
Steps to verify:
- Start dev server:
bun run dev - Go to Settings — should see a new "Profile" section at top
- Enter a display name and bio, save — should show success
- Upload an avatar image — should display
- Go to Setups, open a setup detail, find the "Public" toggle
- Toggle a setup to public
- Navigate to
/users/{your-user-id}— should see profile with the public setup listed - Open an incognito/private window (no auth)
- Visit the same
/users/{id}URL — should show profile and public setup without login - Toggle the setup back to private — it should disappear from the profile page bun run build 2>&1 | tail -3 User approves profiles and sharing UI: profile edit works, public profile shows correct data, setup toggle works, unauthenticated access functions correctly.
<success_criteria> Profile can be edited in settings. Public profile page works without auth. Setup visibility toggle works. Public setups appear on profile, private ones don't. Avatar upload uses existing image infrastructure. </success_criteria>
After completion, create `.planning/phases/18-global-items-public-profiles/18-05-SUMMARY.md`