diff --git a/app/Actions/CreateDefaultCategories.php b/app/Actions/CreateDefaultCategories.php index 274e8ed4..0e518678 100644 --- a/app/Actions/CreateDefaultCategories.php +++ b/app/Actions/CreateDefaultCategories.php @@ -26,62 +26,321 @@ class CreateDefaultCategories public static function getDefaultCategories(): array { return [ - ['name' => 'Administrative violations', 'icon' => 'AlertTriangle', 'color' => 'red'], - ['name' => 'Alimony and child support', 'icon' => 'Users', 'color' => 'teal'], - ['name' => 'Association membership fees', 'icon' => 'Users2', 'color' => 'cyan'], - ['name' => 'Bailiffs', 'icon' => 'Scale', 'color' => 'amber'], - ['name' => 'Bills', 'icon' => 'FileText', 'color' => 'red'], - ['name' => 'Cash deposit', 'icon' => 'Banknote', 'color' => 'green'], - ['name' => 'Cash withdrawal', 'icon' => 'Banknote', 'color' => 'emerald'], - ['name' => 'Cashback rewards', 'icon' => 'Gift', 'color' => 'pink'], - ['name' => 'Cheque', 'icon' => 'Receipt', 'color' => 'gray'], - ['name' => 'Cheque deposit', 'icon' => 'Receipt', 'color' => 'green'], - ['name' => 'Children', 'icon' => 'Baby', 'color' => 'yellow'], - ['name' => 'Clothing and shoes', 'icon' => 'ShoppingBag', 'color' => 'pink'], - ['name' => 'Currency exchange', 'icon' => 'Repeat', 'color' => 'green'], - ['name' => 'Debt collection', 'icon' => 'FileText', 'color' => 'orange'], - ['name' => 'Dishonors', 'icon' => 'AlertCircle', 'color' => 'red'], - ['name' => 'Dividends Income', 'icon' => 'TrendingUp', 'color' => 'emerald'], - ['name' => 'Education, health and beauty', 'icon' => 'Heart', 'color' => 'red'], - ['name' => 'Enquiries', 'icon' => 'HelpCircle', 'color' => 'blue'], - ['name' => 'Entertainment', 'icon' => 'Heart', 'color' => 'purple'], - ['name' => 'Financial services and commission', 'icon' => 'Building2', 'color' => 'slate'], - ['name' => 'Food', 'icon' => 'Utensils', 'color' => 'orange'], - ['name' => 'Gambling', 'icon' => 'Dices', 'color' => 'red'], - ['name' => 'Groceries', 'icon' => 'ShoppingBag', 'color' => 'green'], - ['name' => 'Healthcare', 'icon' => 'Heart', 'color' => 'red'], - ['name' => 'Household goods', 'icon' => 'Home', 'color' => 'green'], - ['name' => 'Income from rent', 'icon' => 'Building', 'color' => 'indigo'], - ['name' => 'Insurance', 'icon' => 'Shield', 'color' => 'cyan'], - ['name' => 'Insurance indemnity', 'icon' => 'ShieldCheck', 'color' => 'cyan'], - ['name' => 'Interest received', 'icon' => 'TrendingUp', 'color' => 'emerald'], - ['name' => 'Invoices', 'icon' => 'FileText', 'color' => 'indigo'], - ['name' => 'Leisure activities, traveling', 'icon' => 'Plane', 'color' => 'purple'], - ['name' => 'Loans', 'icon' => 'Landmark', 'color' => 'gray'], - ['name' => 'Online transactions', 'icon' => 'CreditCard', 'color' => 'indigo'], - ['name' => 'Other incoming payments', 'icon' => 'ArrowUpCircle', 'color' => 'green'], - ['name' => 'Other incoming payments from employer', 'icon' => 'Briefcase', 'color' => 'blue'], - ['name' => 'Other outgoing payments', 'icon' => 'ArrowDownCircle', 'color' => 'gray'], - ['name' => 'Pension', 'icon' => 'Wallet', 'color' => 'teal'], - ['name' => 'Personal transfers', 'icon' => 'ArrowLeftRight', 'color' => 'purple'], - ['name' => 'Postal services', 'icon' => 'Mail', 'color' => 'blue'], - ['name' => 'Regular income', 'icon' => 'TrendingUp', 'color' => 'emerald'], - ['name' => 'Restaurants', 'icon' => 'Utensils', 'color' => 'orange'], - ['name' => 'Return debit', 'icon' => 'Undo2', 'color' => 'amber'], - ['name' => 'Returned payments', 'icon' => 'RotateCcw', 'color' => 'orange'], - ['name' => 'Salary', 'icon' => 'Wallet', 'color' => 'green'], - ['name' => 'Savings and investments', 'icon' => 'PiggyBank', 'color' => 'green'], - ['name' => 'Scholarships', 'icon' => 'GraduationCap', 'color' => 'purple'], - ['name' => 'Shopping', 'icon' => 'ShoppingBag', 'color' => 'pink'], - ['name' => 'Social security benefits', 'icon' => 'HandHeart', 'color' => 'cyan'], - ['name' => 'State aid payments', 'icon' => 'Landmark', 'color' => 'blue'], - ['name' => 'Tax return', 'icon' => 'ReceiptText', 'color' => 'green'], - ['name' => 'Taxes and government fees', 'icon' => 'Receipt', 'color' => 'slate'], - ['name' => 'Transportation', 'icon' => 'Car', 'color' => 'blue'], - ['name' => 'Travel', 'icon' => 'Plane', 'color' => 'blue'], - ['name' => 'Utilities', 'icon' => 'Home', 'color' => 'yellow'], - ['name' => 'Utility services', 'icon' => 'Home', 'color' => 'blue'], - ['name' => 'Work on demand', 'icon' => 'Clock', 'color' => 'orange'], + [ + 'name' => 'Food', + 'icon' => 'Utensils', + 'color' => 'red', + ], + [ + 'name' => 'Cafes, restaurants, bars', + 'icon' => 'Wine', + 'color' => 'red', + ], + [ + 'name' => 'Groceries', + 'icon' => 'ShoppingBasket', + 'color' => 'red', + ], + [ + 'name' => 'Tobacco and alcohol', + 'icon' => 'Cigarette', + 'color' => 'red', + ], + [ + 'name' => 'Other groceries', + 'icon' => 'ShoppingBasket', + 'color' => 'red', + ], + [ + 'name' => 'Food delivery', + 'icon' => 'Pizza', + 'color' => 'red', + ], + [ + 'name' => 'Utility services', + 'icon' => 'Home', + 'color' => 'orange', + ], + [ + 'name' => 'Electricity', + 'icon' => 'Bolt', + 'color' => 'orange', + ], + [ + 'name' => 'Natural gas', + 'icon' => 'Flame', + 'color' => 'orange', + ], + [ + 'name' => 'Rent and maintanence', + 'icon' => 'Wrench', + 'color' => 'orange', + ], + [ + 'name' => 'Telephone, internet, TV, computer', + 'icon' => 'Wifi', + 'color' => 'orange', + ], + [ + 'name' => 'Water', + 'icon' => 'Droplets', + 'color' => 'orange', + ], + [ + 'name' => 'Other utility expenses', + 'icon' => 'Receipt', + 'color' => 'orange', + ], + [ + 'name' => 'Household goods', + 'icon' => 'Home', + 'color' => 'orange', + ], + [ + 'name' => 'Transportation', + 'icon' => 'Bus', + 'color' => 'amber', + ], + [ + 'name' => 'Parking', + 'icon' => 'ParkingMeter', + 'color' => 'amber', + ], + [ + 'name' => 'Fuel', + 'icon' => 'Fuel', + 'color' => 'amber', + ], + [ + 'name' => 'Transportation expenses', + 'icon' => 'Ticket', + 'color' => 'amber', + ], + [ + 'name' => 'Vehicle purchase, maintenance', + 'icon' => 'Car', + 'color' => 'amber', + ], + [ + 'name' => 'Clothing and shoes', + 'icon' => 'Shirt', + 'color' => 'pink', + ], + [ + 'name' => 'Leisure activities, traveling', + 'icon' => 'Plane', + 'color' => 'violet', + ], + [ + 'name' => 'Gifts', + 'icon' => 'Gift', + 'color' => 'violet', + ], + [ + 'name' => 'Books, newspapers, magazines', + 'icon' => 'BookOpen', + 'color' => 'violet', + ], + [ + 'name' => 'Accommodation, travel expenses', + 'icon' => 'Hotel', + 'color' => 'violet', + ], + [ + 'name' => 'Sport and sports goods', + 'icon' => 'Dumbbell', + 'color' => 'violet', + ], + [ + 'name' => 'Theatre, music, cinema', + 'icon' => 'Clapperboard', + 'color' => 'violet', + ], + [ + 'name' => 'Hobbies and other leisure time activites', + 'icon' => 'Puzzle', + 'color' => 'violet', + ], + [ + 'name' => 'Education, health and beauty', + 'icon' => 'GraduationCap', + 'color' => 'rose', + ], + [ + 'name' => 'Education and courses', + 'icon' => 'GraduationCap', + 'color' => 'rose', + ], + [ + 'name' => 'Beauty, cosmetics', + 'icon' => 'Sparkles', + 'color' => 'rose', + ], + [ + 'name' => 'Health and pharmaceuticals', + 'icon' => 'HeartPulse', + 'color' => 'rose', + ], + [ + 'name' => 'Online transactions', + 'icon' => 'Globe', + 'color' => 'fuchsia', + ], + [ + 'name' => 'Online services', + 'icon' => 'Server', + 'color' => 'fuchsia', + ], + [ + 'name' => 'Insurance', + 'icon' => 'ShieldCheck', + 'color' => 'yellow', + ], + [ + 'name' => 'Investments', + 'icon' => 'LineChart', + 'color' => 'lime', + ], + [ + 'name' => 'Savings', + 'icon' => 'PiggyBank', + 'color' => 'lime', + ], + [ + 'name' => 'Other investments', + 'icon' => 'TrendingUp', + 'color' => 'lime', + ], + [ + 'name' => 'Financial services and commission', + 'icon' => 'Landmark', + 'color' => 'slate', + ], + [ + 'name' => 'Fines', + 'icon' => 'Gavel', + 'color' => 'slate', + ], + [ + 'name' => 'Mortgage', + 'icon' => 'Building2', + 'color' => 'slate', + ], + [ + 'name' => 'Credit card repayment', + 'icon' => 'CreditCard', + 'color' => 'slate', + ], + [ + 'name' => 'Cash withdrawal', + 'icon' => 'Banknote', + 'color' => 'neutral', + ], + [ + 'name' => 'Gambling', + 'icon' => 'Dice5', + 'color' => 'purple', + ], + [ + 'name' => 'Lottery', + 'icon' => 'TicketPercent', + 'color' => 'purple', + ], + [ + 'name' => 'Taxes and government fees', + 'icon' => 'FileText', + 'color' => 'stone', + ], + [ + 'name' => 'Invoices', + 'icon' => 'FileInvoice', + 'color' => 'stone', + ], + [ + 'name' => 'Personal transfers', + 'icon' => 'ArrowLeftRight', + 'color' => 'cyan', + ], + [ + 'name' => 'Other personal transfers', + 'icon' => 'ArrowLeftRight', + 'color' => 'cyan', + ], + [ + 'name' => 'Administrative violations', + 'icon' => 'BadgeAlert', + 'color' => 'stone', + ], + [ + 'name' => 'Other transfers', + 'icon' => 'Split', + 'color' => 'stone', + ], + [ + 'name' => 'Other payments', + 'icon' => 'Wallet', + 'color' => 'stone', + ], + [ + 'name' => 'Salary', + 'icon' => 'Coins', + 'color' => 'green', + ], + [ + 'name' => 'Regular income', + 'icon' => 'Coins', + 'color' => 'green', + ], + [ + 'name' => 'Work on demand', + 'icon' => 'Briefcase', + 'color' => 'green', + ], + [ + 'name' => 'Income from rent', + 'icon' => 'Building', + 'color' => 'green', + ], + [ + 'name' => 'Unemployment benefit', + 'icon' => 'HandCoins', + 'color' => 'green', + ], + [ + 'name' => 'Tax return', + 'icon' => 'RotateCcw', + 'color' => 'green', + ], + [ + 'name' => 'Return debit', + 'icon' => 'Undo2', + 'color' => 'green', + ], + [ + 'name' => 'Own account', + 'icon' => 'ArrowRightLeft', + 'color' => 'blue', + ], + [ + 'name' => 'From account of relatives', + 'icon' => 'Users', + 'color' => 'blue', + ], + [ + 'name' => 'Returned payments', + 'icon' => 'RotateCw', + 'color' => 'green', + ], + [ + 'name' => 'Credit cards', + 'icon' => 'CreditCard', + 'color' => 'green', + ], + [ + 'name' => 'Other incoming payments', + 'icon' => 'DollarSign', + 'color' => 'green', + ], ]; } } diff --git a/app/Http/Controllers/Sync/CategorySyncController.php b/app/Http/Controllers/Sync/CategorySyncController.php index 7dd2f824..f4677dd4 100644 --- a/app/Http/Controllers/Sync/CategorySyncController.php +++ b/app/Http/Controllers/Sync/CategorySyncController.php @@ -17,7 +17,7 @@ class CategorySyncController extends Controller $query->where('updated_at', '>', $request->input('since')); } - $categories = $query->orderBy('updated_at', 'asc')->get(); + $categories = $query->orderBy('name', 'asc')->get(); return response()->json([ 'data' => $categories, diff --git a/resources/js/components/transactions/category-select.tsx b/resources/js/components/transactions/category-select.tsx index 24def989..c93d9b72 100644 --- a/resources/js/components/transactions/category-select.tsx +++ b/resources/js/components/transactions/category-select.tsx @@ -79,7 +79,7 @@ export function CategorySelect({ )} - {categories.map((category) => { + {[...categories].sort((a, b) => a.name.localeCompare(b.name)).map((category) => { const IconComponent = Icons[ category.icon as keyof typeof Icons ] as Icons.LucideIcon; diff --git a/resources/js/pages/settings/categories.tsx b/resources/js/pages/settings/categories.tsx index fa993252..fbd77a9c 100644 --- a/resources/js/pages/settings/categories.tsx +++ b/resources/js/pages/settings/categories.tsx @@ -96,7 +96,9 @@ function CategoryActions({ category }: { category: Category }) { export default function Categories() { const categories = useLiveQuery(() => db.categories.toArray(), []) || []; - const [sorting, setSorting] = useState([]); + const [sorting, setSorting] = useState([ + { id: 'name', desc: false }, + ]); const [columnFilters, setColumnFilters] = useState([]); const [columnVisibility, setColumnVisibility] = useState( {}, @@ -122,11 +124,12 @@ export default function Categories() { const iconName = row.original.icon; const IconComponent = Icons[ iconName as keyof typeof Icons - ] as Icons.LucideIcon; + ] as Icons.LucideIcon | undefined; + const Icon = IconComponent || Icons.Tag; return (
- +
{row.getValue('name')}
diff --git a/resources/js/types/category.ts b/resources/js/types/category.ts index d9adfda4..b16d1006 100644 --- a/resources/js/types/category.ts +++ b/resources/js/types/category.ts @@ -57,6 +57,12 @@ export const CATEGORY_COLORS = [ 'pink', 'purple', 'red', + 'rose', + 'violet', + 'stone', + 'nautral', + 'lime', + 'fuchsia', 'slate', 'teal', 'yellow', @@ -80,10 +86,18 @@ export function getCategoryColorClasses(color: CategoryColor): { bg: 'bg-amber-100 dark:bg-amber-700', text: 'text-amber-700 dark:text-amber-100', }, + rose: { + bg: 'bg-rose-100 dark:bg-rose-700', + text: 'text-rose-700 dark:text-rose-100', + }, blue: { bg: 'bg-blue-100 dark:bg-blue-700', text: 'text-blue-700 dark:text-blue-100', }, + violet: { + bg: 'bg-violet-100 dark:bg-violet-700', + text: 'text-violet-700 dark:text-violet-100', + }, cyan: { bg: 'bg-cyan-100 dark:bg-cyan-700', text: 'text-cyan-700 dark:text-cyan-100', @@ -100,6 +114,14 @@ export function getCategoryColorClasses(color: CategoryColor): { bg: 'bg-green-100 dark:bg-green-700', text: 'text-green-700 dark:text-green-100', }, + lime: { + bg: 'bg-lime-100 dark:bg-lime-700', + text: 'text-lime-700 dark:text-lime-100', + }, + fuchsia: { + bg: 'bg-fuchsia-100 dark:bg-fuchsia-700', + text: 'text-fuchsia-700 dark:text-fuchsia-100', + }, indigo: { bg: 'bg-indigo-100 dark:bg-indigo-700', text: 'text-indigo-700 dark:text-indigo-100', @@ -124,6 +146,14 @@ export function getCategoryColorClasses(color: CategoryColor): { bg: 'bg-slate-100 dark:bg-slate-700', text: 'text-slate-700 dark:text-slate-100', }, + stone: { + bg: 'bg-stone-100 dark:bg-stone-700', + text: 'text-stone-700 dark:text-stone-100', + }, + neutral: { + bg: 'bg-neutral-100 dark:bg-neutral-700', + text: 'text-neutral-700 dark:text-neutral-100', + }, teal: { bg: 'bg-teal-100 dark:bg-teal-700', text: 'text-teal-700 dark:text-teal-100',