feat(06-02): replace EmojiPicker with IconPicker across all category components

- CategoryPicker shows LucideIcon prefix and uses IconPicker for inline create
- CategoryHeader displays LucideIcon in view mode and IconPicker in edit mode
- OnboardingWizard uses IconPicker for category creation step
- CreateThreadModal drops emoji from category select options
- Fixed categoryEmoji -> categoryIcon in routes and useCategories hook

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-15 17:57:56 +01:00
parent 615c8944c4
commit 570bcea5c9
7 changed files with 391 additions and 338 deletions

View File

@@ -98,7 +98,7 @@ function CollectionView() {
// Group items by categoryId
const groupedItems = new Map<
number,
{ items: typeof items; categoryName: string; categoryEmoji: string }
{ items: typeof items; categoryName: string; categoryIcon: string }
>();
for (const item of items) {
@@ -109,7 +109,7 @@ function CollectionView() {
groupedItems.set(item.categoryId, {
items: [item],
categoryName: item.categoryName,
categoryEmoji: item.categoryEmoji,
categoryIcon: item.categoryIcon,
});
}
}
@@ -134,7 +134,7 @@ function CollectionView() {
{Array.from(groupedItems.entries()).map(
([
categoryId,
{ items: categoryItems, categoryName, categoryEmoji },
{ items: categoryItems, categoryName, categoryIcon },
]) => {
const catTotals = categoryTotalsMap.get(categoryId);
return (
@@ -142,7 +142,7 @@ function CollectionView() {
<CategoryHeader
categoryId={categoryId}
name={categoryName}
emoji={categoryEmoji}
icon={categoryIcon}
totalWeight={catTotals?.totalWeight ?? 0}
totalCost={catTotals?.totalCost ?? 0}
itemCount={catTotals?.itemCount ?? categoryItems.length}
@@ -156,7 +156,7 @@ function CollectionView() {
weightGrams={item.weightGrams}
priceCents={item.priceCents}
categoryName={categoryName}
categoryEmoji={categoryEmoji}
categoryIcon={categoryIcon}
imageFilename={item.imageFilename}
/>
))}
@@ -268,7 +268,7 @@ function PlanningView() {
<option value="">All categories</option>
{categories?.map((cat) => (
<option key={cat.id} value={cat.id}>
{cat.emoji} {cat.name}
{cat.name}
</option>
))}
</select>
@@ -356,7 +356,7 @@ function PlanningView() {
createdAt={thread.createdAt}
status={thread.status}
categoryName={thread.categoryName}
categoryEmoji={thread.categoryEmoji}
categoryIcon={thread.categoryIcon}
/>
))}
</div>

View File

@@ -66,7 +66,7 @@ function SetupDetailPage() {
{
items: typeof setup.items;
categoryName: string;
categoryEmoji: string;
categoryIcon: string;
}
>();
@@ -78,7 +78,7 @@ function SetupDetailPage() {
groupedItems.set(item.categoryId, {
items: [item],
categoryName: item.categoryName,
categoryEmoji: item.categoryEmoji,
categoryIcon: item.categoryIcon,
});
}
}
@@ -177,7 +177,7 @@ function SetupDetailPage() {
{Array.from(groupedItems.entries()).map(
([
categoryId,
{ items: categoryItems, categoryName, categoryEmoji },
{ items: categoryItems, categoryName, categoryIcon },
]) => {
const catWeight = categoryItems.reduce(
(sum, item) => sum + (item.weightGrams ?? 0),
@@ -192,7 +192,7 @@ function SetupDetailPage() {
<CategoryHeader
categoryId={categoryId}
name={categoryName}
emoji={categoryEmoji}
icon={categoryIcon}
totalWeight={catWeight}
totalCost={catCost}
itemCount={categoryItems.length}
@@ -206,7 +206,7 @@ function SetupDetailPage() {
weightGrams={item.weightGrams}
priceCents={item.priceCents}
categoryName={categoryName}
categoryEmoji={categoryEmoji}
categoryIcon={categoryIcon}
imageFilename={item.imageFilename}
onRemove={() => removeItem.mutate(item.id)}
/>

View File

@@ -134,7 +134,7 @@ function ThreadDetailPage() {
weightGrams={candidate.weightGrams}
priceCents={candidate.priceCents}
categoryName={candidate.categoryName}
categoryEmoji={candidate.categoryEmoji}
categoryIcon={candidate.categoryIcon}
imageFilename={candidate.imageFilename}
threadId={threadId}
isActive={isActive}