Archive v1.1 artifacts (roadmap, requirements, phases) to milestones/. Evolve PROJECT.md with shipped requirements and new key decisions. Reorganize ROADMAP.md with collapsed milestone groupings. Update retrospective with v1.1 lessons. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
169 lines
7.0 KiB
Markdown
169 lines
7.0 KiB
Markdown
---
|
|
phase: 05-image-handling
|
|
plan: 02
|
|
type: execute
|
|
wave: 2
|
|
depends_on: [05-01]
|
|
files_modified:
|
|
- src/client/components/ItemCard.tsx
|
|
- src/client/components/CandidateCard.tsx
|
|
- src/client/routes/setups/$setupId.tsx
|
|
autonomous: true
|
|
requirements: [IMG-02]
|
|
|
|
must_haves:
|
|
truths:
|
|
- "Item cards always show a 4:3 image area, even when no image exists"
|
|
- "Cards without images show a gray placeholder with the item's category emoji centered"
|
|
- "Cards with images display the image in the 4:3 area"
|
|
- "Candidate cards have the same placeholder treatment as item cards"
|
|
- "Setup item lists show small square thumbnails (~40px) next to item names"
|
|
- "Setup thumbnails show category emoji placeholder when item has no image"
|
|
artifacts:
|
|
- path: "src/client/components/ItemCard.tsx"
|
|
provides: "Always-visible 4:3 image area with placeholder fallback"
|
|
- path: "src/client/components/CandidateCard.tsx"
|
|
provides: "Always-visible 4:3 image area with placeholder fallback"
|
|
- path: "src/client/routes/setups/$setupId.tsx"
|
|
provides: "Small square thumbnails in setup item list"
|
|
key_links:
|
|
- from: "src/client/components/ItemCard.tsx"
|
|
to: "/uploads/{imageFilename}"
|
|
via: "img src attribute"
|
|
pattern: "src=.*uploads"
|
|
- from: "src/client/routes/setups/$setupId.tsx"
|
|
to: "/uploads/{imageFilename}"
|
|
via: "img src for thumbnails"
|
|
pattern: "src=.*uploads"
|
|
---
|
|
|
|
<objective>
|
|
Add image placeholders to all gear cards (items and candidates) so every card has a consistent 4:3 image area, and add small thumbnails to setup item lists.
|
|
|
|
Purpose: Consistent card heights in the grid (no layout shift between cards with/without images) and visual context in setup lists via thumbnails.
|
|
|
|
Output: Updated ItemCard, CandidateCard, and setup detail route with image placeholders and thumbnails.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md
|
|
@/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
@.planning/phases/05-image-handling/05-01-SUMMARY.md
|
|
|
|
@src/client/components/ItemCard.tsx
|
|
@src/client/components/CandidateCard.tsx
|
|
@src/client/routes/setups/$setupId.tsx
|
|
|
|
<interfaces>
|
|
<!-- Key types and contracts the executor needs -->
|
|
|
|
From src/client/components/ItemCard.tsx:
|
|
```typescript
|
|
interface ItemCardProps {
|
|
id: number;
|
|
name: string;
|
|
weightGrams: number | null;
|
|
priceCents: number | null;
|
|
categoryName: string;
|
|
categoryEmoji: string;
|
|
imageFilename: string | null;
|
|
onRemove?: () => void;
|
|
}
|
|
```
|
|
|
|
From src/client/components/CandidateCard.tsx:
|
|
```typescript
|
|
interface CandidateCardProps {
|
|
id: number;
|
|
name: string;
|
|
weightGrams: number | null;
|
|
priceCents: number | null;
|
|
categoryName: string;
|
|
categoryEmoji: string;
|
|
imageFilename: string | null;
|
|
threadId: number;
|
|
isActive: boolean;
|
|
}
|
|
```
|
|
|
|
Setup route renders items via ItemCard with all props including categoryEmoji and imageFilename.
|
|
</interfaces>
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Add always-visible 4:3 image area with placeholders to ItemCard and CandidateCard</name>
|
|
<files>src/client/components/ItemCard.tsx, src/client/components/CandidateCard.tsx</files>
|
|
<action>
|
|
Update both ItemCard and CandidateCard to ALWAYS render the 4:3 image area (currently they conditionally render it only when imageFilename exists).
|
|
|
|
**ItemCard.tsx changes:**
|
|
- Replace the conditional `{imageFilename && (...)}` block with an always-rendered `<div className="aspect-[4/3] bg-gray-50">` container
|
|
- When imageFilename exists: render `<img src={/uploads/${imageFilename}} alt={name} className="w-full h-full object-cover" />` (same as current)
|
|
- When imageFilename is null: render a centered placeholder with the category emoji. Use `<div className="w-full h-full flex flex-col items-center justify-center">` containing a `<span className="text-3xl">{categoryEmoji}</span>`. The gray-50 background provides the subtle placeholder look.
|
|
|
|
**CandidateCard.tsx changes:**
|
|
- Identical treatment: always render the 4:3 area, show image or category emoji placeholder
|
|
- Same structure as ItemCard
|
|
|
|
Both cards already receive categoryEmoji as a prop, so no prop changes needed.
|
|
</action>
|
|
<verify>
|
|
<automated>cd /home/jean-luc-makiola/Development/projects/GearBox && bun run lint 2>&1 | tail -5</automated>
|
|
</verify>
|
|
<done>Every ItemCard and CandidateCard renders a 4:3 image area. Cards with images show the image; cards without show a gray placeholder with the category emoji centered.</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 2: Add small thumbnails to setup item lists</name>
|
|
<files>src/client/routes/setups/$setupId.tsx</files>
|
|
<action>
|
|
The setup detail page currently renders items using ItemCard in a grid. The setup also has a concept of item lists. Add small square thumbnails next to item names in the setup's item display.
|
|
|
|
Since the setup page uses ItemCard components in a grid (which now have the 4:3 area from Task 1), the card-level display is already handled. The additional work here is for any list-style display of setup items.
|
|
|
|
Check the setup detail route for list-view rendering of items. If items are only shown via ItemCard grid, then this task focuses on ensuring the ItemCard placeholder works in the setup context. If there's a separate list view, add thumbnails:
|
|
|
|
**Thumbnail spec (for list views):**
|
|
- Small square image: `w-10 h-10 rounded-lg object-cover flex-shrink-0` (~40px)
|
|
- Placed to the left of the item name in a flex row
|
|
- When imageFilename exists: `<img src={/uploads/${imageFilename}} />`
|
|
- When null: `<div className="w-10 h-10 rounded-lg bg-gray-50 flex items-center justify-center flex-shrink-0"><span className="text-sm">{categoryEmoji}</span></div>`
|
|
|
|
If the setup page only uses ItemCard (no list view), verify the ItemCard changes from Task 1 render correctly in the setup context and note this in the summary.
|
|
</action>
|
|
<verify>
|
|
<automated>cd /home/jean-luc-makiola/Development/projects/GearBox && bun run lint 2>&1 | tail -5</automated>
|
|
</verify>
|
|
<done>Setup item lists show small square thumbnails (or category emoji placeholders) next to item names. If setup only uses ItemCard grid, the placeholder from Task 1 renders correctly in setup context.</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
1. Item cards in the gear collection always show a 4:3 area (no layout jump between cards with/without images)
|
|
2. Cards without images show gray background with category emoji centered
|
|
3. Cards with images show the image with object-cover
|
|
4. Candidate cards have identical placeholder behavior
|
|
5. Setup item display includes image context (thumbnails or card placeholders)
|
|
6. `bun run lint` passes
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- All gear cards have consistent heights due to always-present 4:3 image area
|
|
- Placeholder shows category emoji when no image exists
|
|
- Setup items show image context (thumbnail or card placeholder)
|
|
- No layout shift between cards with and without images
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/05-image-handling/05-02-SUMMARY.md`
|
|
</output>
|