--- phase: 06-category-icons plan: 03 type: execute wave: 2 depends_on: [06-01] files_modified: - src/client/components/ItemCard.tsx - src/client/components/CandidateCard.tsx - src/client/components/ThreadCard.tsx - src/client/components/ItemPicker.tsx - src/client/routes/collection/index.tsx - src/client/routes/setups/$setupId.tsx - src/client/routes/threads/$threadId.tsx - src/client/components/EmojiPicker.tsx - src/client/lib/emojiData.ts autonomous: true requirements: [CAT-02] must_haves: truths: - "Item cards display category Lucide icon in the image placeholder area (not emoji)" - "Item cards display Lucide icon in the category badge/pill (not emoji)" - "Candidate cards display category Lucide icon in placeholder and badge" - "Thread cards display Lucide icon next to category name" - "Collection view category headers use icon prop (not emoji)" - "Setup detail view category headers use icon prop (not emoji)" - "ItemPicker shows Lucide icons next to category names" - "Category filter dropdown in collection view shows Lucide icons" - "Old EmojiPicker.tsx and emojiData.ts files are deleted" - "No remaining emoji references in the codebase" artifacts: - path: "src/client/components/ItemCard.tsx" provides: "Item card with Lucide icon display" contains: "categoryIcon" - path: "src/client/components/ThreadCard.tsx" provides: "Thread card with Lucide icon display" contains: "categoryIcon" key_links: - from: "src/client/components/ItemCard.tsx" to: "src/client/lib/iconData.ts" via: "import LucideIcon" pattern: "LucideIcon" - from: "src/client/routes/collection/index.tsx" to: "src/client/components/CategoryHeader.tsx" via: "icon prop" pattern: "icon=.*categoryIcon" --- Update all display-only components to render Lucide icons instead of emoji, and remove old emoji code. Purpose: Complete the visual migration so every category icon in the app renders as a Lucide icon. Clean up old emoji code to leave zero emoji references. Output: All display components updated, old EmojiPicker and emojiData files deleted. @/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md @/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/06-category-icons/06-CONTEXT.md @.planning/phases/06-category-icons/06-01-SUMMARY.md From src/client/lib/iconData.ts: ```typescript export function LucideIcon({ name, size, className }: { name: string; size?: number; className?: string }): JSX.Element; ``` From services (after Plan 01): ```typescript // All services return: { ...fields, categoryIcon: string } instead of categoryEmoji ``` From src/client/components/CategoryHeader.tsx (after Plan 02): ```typescript interface CategoryHeaderProps { categoryId: number; name: string; icon: string; // was: emoji totalWeight: number; totalCost: number; itemCount: number; } ``` Task 1: Update display components to use categoryIcon with LucideIcon src/client/components/ItemCard.tsx, src/client/components/CandidateCard.tsx, src/client/components/ThreadCard.tsx, src/client/components/ItemPicker.tsx Import `LucideIcon` from `../lib/iconData` in each file. **ItemCard.tsx:** 1. Props: rename `categoryEmoji: string` to `categoryIcon: string`. 2. Image placeholder area (the 4:3 aspect ratio area when no image): Replace `{categoryEmoji}` with ``. Use size 36 (matching the ~32-40px from CONTEXT.md for card placeholder areas). 3. Category badge/pill below the image: Replace `{categoryEmoji} {categoryName}` with ` {categoryName}`. Use size 14 for inline badge context. **CandidateCard.tsx:** Same changes as ItemCard — rename prop `categoryEmoji` to `categoryIcon`, replace emoji text with LucideIcon in placeholder (size 36) and badge (size 14). **ThreadCard.tsx:** 1. Props: rename `categoryEmoji: string` to `categoryIcon: string`. 2. Category display: Replace `{categoryEmoji} {categoryName}` with ` {categoryName}`. **ItemPicker.tsx:** 1. In the grouped items type: rename `categoryEmoji: string` to `categoryIcon: string`. 2. Where items are grouped: change `categoryEmoji: item.categoryEmoji` to `categoryIcon: item.categoryIcon`. 3. In the destructuring: change `categoryEmoji` to `categoryIcon`. 4. Import `LucideIcon` and replace `{categoryEmoji} {categoryName}` with ` {categoryName}`. bun run build 2>&1 | tail -10 - All four components accept `categoryIcon` prop (not `categoryEmoji`) - Icons render as LucideIcon components at appropriate sizes - No emoji text rendering remains in these components - Build succeeds Task 2: Update route files and delete old emoji files src/client/routes/collection/index.tsx, src/client/routes/setups/$setupId.tsx, src/client/routes/threads/$threadId.tsx, src/client/components/EmojiPicker.tsx, src/client/lib/emojiData.ts Import `LucideIcon` from the appropriate relative path in each route file. **src/client/routes/collection/index.tsx:** 1. In the grouped items type: rename `categoryEmoji` to `categoryIcon` everywhere. 2. Where items are grouped into categories: change `categoryEmoji: item.categoryEmoji` to `categoryIcon: item.categoryIcon`. 3. Where CategoryHeader is rendered: change `emoji={categoryEmoji}` to `icon={categoryIcon}`. 4. Where ItemCard is rendered: change `categoryEmoji={categoryEmoji}` to `categoryIcon={categoryIcon}`. 5. Where ThreadCard is rendered (in planning tab): change `categoryEmoji={thread.categoryEmoji}` to `categoryIcon={thread.categoryIcon}`. 6. In the category filter dropdown: replace `{cat.emoji} {cat.name}` with a LucideIcon + name. Use `` before `{cat.name}`. **src/client/routes/setups/$setupId.tsx:** 1. Same pattern — rename `categoryEmoji` to `categoryIcon` in the grouped type, grouping logic, and where CategoryHeader and ItemCard are rendered. 2. CategoryHeader: `emoji=` -> `icon=`. 3. ItemCard: `categoryEmoji=` -> `categoryIcon=`. **src/client/routes/threads/$threadId.tsx:** 1. Where CandidateCard is rendered: change `categoryEmoji={candidate.categoryEmoji}` to `categoryIcon={candidate.categoryIcon}`. **Delete old files:** - Delete `src/client/components/EmojiPicker.tsx` - Delete `src/client/lib/emojiData.ts` **Final verification sweep:** After all changes, grep the entire `src/` directory for any remaining references to: - `emoji` (should find ZERO in component/route files — may still exist in migration files which is fine) - `EmojiPicker` (should find ZERO) - `emojiData` (should find ZERO) - `categoryEmoji` (should find ZERO) Fix any stragglers found. bun run build 2>&1 | tail -5; echo "---"; grep -r "categoryEmoji\|EmojiPicker\|emojiData\|emojiCategories" src/ --include="*.ts" --include="*.tsx" | grep -v node_modules | head -10 || echo "No emoji references found" - Collection route passes `icon` to CategoryHeader and `categoryIcon` to ItemCard/ThreadCard - Setup detail route passes `icon` and `categoryIcon` correctly - Thread detail route passes `categoryIcon` to CandidateCard - Category filter dropdown shows Lucide icons - EmojiPicker.tsx and emojiData.ts are deleted - Zero references to emoji/EmojiPicker/emojiData remain in src/ - Build succeeds - `bun run build` succeeds with zero errors - `grep -r "categoryEmoji\|EmojiPicker\|emojiData" src/ --include="*.ts" --include="*.tsx"` returns nothing - `bun test` passes (no test references broken) - Every category icon in the app renders as a Lucide icon (cards, headers, badges, lists, pickers) - Old EmojiPicker and emojiData files are deleted - Zero emoji references remain in source code - Build and all tests pass After completion, create `.planning/phases/06-category-icons/06-03-SUMMARY.md`