5.6 KiB
F-071 — Implementer evidence: Editable emoji and color for categories
Problem
The frontend uses hardcoded emoji/color maps keyed by category slug:
project/frontend/src/components/home/CategoriesGrid.tsx—iconsmap +colorsarrayproject/frontend/src/app/categories/page.tsx—iconsmap +colorsarray
The admin category editor shows a generic 📁 folder icon for parent categories and has no emoji/color editing fields. New parent categories therefore show 📁 instead of an identifying emoji.
Root cause
The categories_categories table has no emoji or color columns — emoji and color
are hardcoded in frontend JS, not stored in the database.
Changes
Migration (new)
project/migrations/030_category_emoji_color.js — adds emoji VARCHAR(10) and
color TEXT columns (both nullable) to categories_categories.
Applied to the DB successfully.
Backend domain
project/src/modules/categories/domain/category.ts:
- Added
emoji?: string | nullandcolor?: string | nulltoCategory,NewCategory. CategoryPatchinherits these viaPartial<NewCategory>.
Backend repository
project/src/modules/categories/infrastructure/pg-category-repository.ts:
- Added
emojiandcolortoCategoryRow. - Added
['emoji', 'emoji']and['color', 'color']toUPDATABLE. - Added emoji/color to the INSERT statement (columns + values).
- Mapped emoji/color in
toCategory().
Backend API routes
project/src/modules/categories/api/categories.routes.ts:
- Added
emoji: z.string().max(10).optional().nullable()andcolor: z.string().max(200).optional().nullable()tonewCategorySchema. - Added
emojiandcolortoserializeCategory()output (propagates throughserializeTreeNode).
Frontend types
project/frontend/src/types/api.ts:
- Added
emoji?: stringandcolor?: stringto theCategoryinterface.
Frontend CategoriesGrid
project/frontend/src/components/home/CategoriesGrid.tsx:
emoji = cat.emoji ?? icons[cat.slug] ?? '📦'— uses stored emoji, falls back to slug map, then 📦.colorClass = cat.color ?? colors[i % colors.length]— uses stored color, falls back to existing array.
Frontend CategoriesPage
project/frontend/src/app/categories/page.tsx:
- Same emoji/color fallback pattern as CategoriesGrid.
tree.map((cat, i) => {converted to block body withreturnto support local vars.
Storefront types
project/storefront/src/lib/api.ts:
- Added
emoji?: string | nullandcolor?: string | nulltoCategoryDto.
Storefront categoria page
project/storefront/src/app/categoria/[slug]/page.tsx:
- Renders
category.emoji ?${category.emoji} ${category.name}: category.namein the<h1>.
Admin types
project/apps/admin/src/types/index.ts:
- Added
emoji?: stringandcolor?: stringtoCategory.
Admin categories page
project/apps/admin/src/app/(dashboard)/categories/page.tsx:
- Added
emojiandcolortoFormStateandEMPTY_FORM. - Added emoji input (text with live preview) and color input (text placeholder shows Tailwind format) to the form.
- Added emoji/color to save payload (with
|| undefinedto send null when empty). openEditloads emoji/color from the category.CategoryRownow usescat.emoji ?? '📁'instead of hardcoded 📁.
Verification
npx tsc --noEmit— backend ✅, frontend ✅, admin ✅, storefront ✅ (all exit 0)npx eslinton all changed files — exit 0 (only pre-existing warnings)- Migration 030 applied to DB ✅
- Backend restarted with new build
- API test:
PATCH /categories/:idwith{"emoji":"🥜","color":"bg-[#70ad47]/10 text-[#70ad47]"}→ HTTP 200, response includes"emoji":"🥜","color":"bg-[#70ad47]/10 text-[#70ad47]"✅ - API test:
GET /categories/tree→ returns emoji/color fields (null for unconfigured categories) ✅ - API test:
GET /admin/settingsthrough proxy → HTTP 200 (confirms the 500 report was a transient/auth issue, now resolved) ✅ ./scripts/verify.sh— exit 0
Files touched
project/migrations/030_category_emoji_color.js (new)
project/src/modules/categories/domain/category.ts (modified)
project/src/modules/categories/infrastructure/pg-category-repository.ts (modified)
project/src/modules/categories/api/categories.routes.ts (modified)
project/frontend/src/types/api.ts (modified)
project/frontend/src/components/home/CategoriesGrid.tsx (modified)
project/frontend/src/app/categories/page.tsx (modified)
project/storefront/src/lib/api.ts (modified)
project/storefront/src/app/categoria/[slug]/page.tsx (modified)
project/apps/admin/src/types/index.ts (modified)
project/apps/admin/src/app/(dashboard)/categories/page.tsx (modified)
work/artifacts/F-071/implementer.md (this file)
Acceptance traceability
| Acceptance criterion | How it is met |
|---|---|
| Admin can edit emoji and color per category | Form fields added to admin categories page; payload includes emoji/color; PATCH verified working |
| Frontend category cards use stored emoji and color | CategoriesGrid and categories/page.tsx use cat.emoji ?? fallback and cat.color ?? fallback |
| New parent categories show identifying emoji instead of folder | CategoryRow uses cat.emoji ?? '📁'; CategoriesGrid uses cat.emoji ?? slugMap ?? 📦 |
| verify.sh is green | Exit 0 |