feat(category): Update default categories list and sorting logic

This commit is contained in:
Víctor Falcón 2025-11-14 15:28:44 +01:00
parent fb2f856360
commit 73d847f38b
5 changed files with 353 additions and 61 deletions

View File

@ -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',
],
];
}
}

View File

@ -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,

View File

@ -79,7 +79,7 @@ export function CategorySelect({
</Badge>
</SelectItem>
)}
{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;

View File

@ -96,7 +96,9 @@ function CategoryActions({ category }: { category: Category }) {
export default function Categories() {
const categories = useLiveQuery(() => db.categories.toArray(), []) || [];
const [sorting, setSorting] = useState<SortingState>([]);
const [sorting, setSorting] = useState<SortingState>([
{ id: 'name', desc: false },
]);
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>(
{},
@ -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 (
<div className="flex items-center gap-3 pl-3">
<IconComponent className="h-4 w-4 opacity-80" />
<Icon className="h-4 w-4 opacity-80" />
<div className="font-medium">
{row.getValue('name')}
</div>

View File

@ -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',