diff --git a/backend/app/db/seed.py b/backend/app/db/seed.py index fe93f35..20729cd 100644 --- a/backend/app/db/seed.py +++ b/backend/app/db/seed.py @@ -31,6 +31,10 @@ DEFAULT_INCOME_CATEGORIES = [ ("Freelance", "briefcase", "#1baf7a"), ("Investments", "trending-up", "#4a3aa7"), ("Gifts", "gift", "#e87ba4"), + ("Business Income", "building-2", "#eb6834"), + ("Rental Income", "key", "#eda100"), + ("Benefits", "hand-coins", "#008300"), + ("Item Sales", "tag", "#e34948"), ("Other Income", "plus-circle", "#898781"), ] diff --git a/frontend/package.json b/frontend/package.json index e328f11..5bac112 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "aurum-frontend", "private": true, - "version": "0.23.0", + "version": "0.23.1", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/components/categories/CategoryList.tsx b/frontend/src/components/categories/CategoryList.tsx index d1a5de7..eceac5a 100644 --- a/frontend/src/components/categories/CategoryList.tsx +++ b/frontend/src/components/categories/CategoryList.tsx @@ -1,4 +1,5 @@ import { Pencil, Trash2 } from "lucide-react"; +import { translateCategoryName } from "@/lib/categoryLabels"; import { getCategoryIcon } from "@/lib/icons"; import { useTranslation } from "@/lib/i18n"; import type { Category } from "@/types"; @@ -30,7 +31,7 @@ export function CategoryList({ items, onEdit, onDelete }: CategoryListProps) { - {category.name} + {translateCategoryName(category.name)} {category.is_default && ( {t("category.defaultBadge")} diff --git a/frontend/src/lib/categoryLabels.ts b/frontend/src/lib/categoryLabels.ts index 3b1381d..828163b 100644 --- a/frontend/src/lib/categoryLabels.ts +++ b/frontend/src/lib/categoryLabels.ts @@ -1,10 +1,10 @@ import { t, type TranslationKey } from "@/lib/i18n"; // Maps the exact seeded English category name (backend/app/db/seed.py) to -// its translation key. There's no category-management UI yet, so every -// category currently in the database is one of these — anything that -// doesn't match (a renamed default, or a future custom category) falls -// through unchanged. +// its translation key, so the fixed default set reads in the user's chosen +// language regardless of what the DB literally stores. Categories created +// through the category-management UI (CategoriesPage) aren't in this map — +// their name is whatever the user typed and is shown as-is. const DEFAULT_CATEGORY_KEYS: Record = { "Housing & Utilities": "category.housingUtilities", Groceries: "category.groceries", @@ -18,6 +18,10 @@ const DEFAULT_CATEGORY_KEYS: Record = { Freelance: "category.freelance", Investments: "category.investments", Gifts: "category.gifts", + "Business Income": "category.businessIncome", + "Rental Income": "category.rentalIncome", + Benefits: "category.benefits", + "Item Sales": "category.itemSales", "Other Income": "category.otherIncome", }; diff --git a/frontend/src/lib/i18n.ts b/frontend/src/lib/i18n.ts index 5b1a926..9a5df61 100644 --- a/frontend/src/lib/i18n.ts +++ b/frontend/src/lib/i18n.ts @@ -324,11 +324,10 @@ const ru = { "cashFlow.net": "Баланс", "cashFlow.noData": "Нет данных за выбранный период.", - // Default seeded categories (backend/app/db/seed.py) — there's no - // category-management UI yet, so every category currently in the - // database is one of these; translateCategoryName() matches on the exact - // seeded English name and falls through unchanged for anything else - // (a renamed default, or a future custom category). + // Default seeded categories (backend/app/db/seed.py) — translateCategoryName() + // matches on the exact seeded English name and falls through unchanged + // for anything else (a renamed default, or a custom category added via + // the category-management UI). "category.housingUtilities": "Жильё и коммуналка", "category.groceries": "Продукты", "category.diningOut": "Кафе и рестораны", @@ -341,6 +340,10 @@ const ru = { "category.freelance": "Фриланс", "category.investments": "Инвестиции", "category.gifts": "Подарки", + "category.businessIncome": "Доход от бизнеса", + "category.rentalIncome": "Сдача недвижимости", + "category.benefits": "Пособия и соцвыплаты", + "category.itemSales": "Продажа личных вещей", "category.otherIncome": "Прочий доход", "months.jan": "Янв", @@ -689,6 +692,10 @@ const en: Record = { "category.freelance": "Freelance", "category.investments": "Investments", "category.gifts": "Gifts", + "category.businessIncome": "Business Income", + "category.rentalIncome": "Rental Income", + "category.benefits": "Benefits", + "category.itemSales": "Item Sales", "category.otherIncome": "Other Income", "months.jan": "Jan", diff --git a/frontend/src/lib/icons.tsx b/frontend/src/lib/icons.tsx index d2e6970..75a6942 100644 --- a/frontend/src/lib/icons.tsx +++ b/frontend/src/lib/icons.tsx @@ -11,8 +11,10 @@ import { Gem, Gift, GraduationCap, + HandCoins, HeartPulse, Home, + Key, MoreHorizontal, Package, Plane, @@ -26,6 +28,7 @@ import { Smartphone, Sofa, Sparkles, + Tag, TrendingUp, Truck, Utensils, @@ -71,6 +74,9 @@ const ICON_MAP: Record = { smartphone: Smartphone, sofa: Sofa, sparkles: Sparkles, + tag: Tag, + "hand-coins": HandCoins, + key: Key, truck: Truck, // lucide-react dropped brand/trademarked glyphs (no "Youtube" icon) — a // generic video-camera icon is the closest available stand-in.