import { useState } from 'react' import { useTranslation } from 'react-i18next' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' import { Skeleton } from '@/components/ui/skeleton' import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts' import type { BudgetDetail } from '@/lib/api' import { formatCurrency } from '@/lib/format' import { headerGradient, amountColorClass, palette } from '@/lib/palette' import { InlineEditCell } from '@/components/InlineEditCell' import { Badge } from '@/components/ui/badge' interface Props { budget: BudgetDetail onUpdate: (itemId: string, data: { actual_amount?: number }) => Promise } export function VariableExpenses({ budget, onUpdate }: Props) { const { t } = useTranslation() const expenses = budget.items.filter((i) => i.category_type === 'variable_expense') const [flashRowId, setFlashRowId] = useState(null) const [errorRowId, setErrorRowId] = useState(null) const triggerFlash = (id: string, type: 'success' | 'error') => { if (type === 'success') { setFlashRowId(id) setTimeout(() => setFlashRowId(null), 600) } else { setErrorRowId(id) setTimeout(() => setErrorRowId(null), 600) } } const chartData = expenses.map((item) => ({ name: item.category_name, [t('dashboard.budget')]: item.budgeted_amount, [t('dashboard.actual')]: item.actual_amount, })) if (expenses.length === 0) { return ( {t('dashboard.variableExpenses')} {[1, 2, 3].map((i) => ( ))} ) } return ( {t('dashboard.variableExpenses')} {t('dashboard.budget')} {t('dashboard.actual')} {t('dashboard.remaining')} {expenses.map((item) => { const remaining = item.budgeted_amount - item.actual_amount return ( {item.category_name} {t(`template.${item.item_tier === 'one_off' ? 'oneOff' : item.item_tier}`)} {formatCurrency(item.budgeted_amount, budget.currency)} onUpdate(item.id, { actual_amount: actual })} onSaveSuccess={() => triggerFlash(item.id, 'success')} onSaveError={() => triggerFlash(item.id, 'error')} className={amountColorClass({ type: 'variable_expense', actual: item.actual_amount, budgeted: item.budgeted_amount })} /> {formatCurrency(remaining, budget.currency)} ) })} {t('dashboard.budget')} {formatCurrency(expenses.reduce((s, i) => s + i.budgeted_amount, 0), budget.currency)} {formatCurrency(expenses.reduce((s, i) => s + i.actual_amount, 0), budget.currency)} {formatCurrency(expenses.reduce((s, i) => s + (i.budgeted_amount - i.actual_amount), 0), budget.currency)}
{chartData.length > 0 && (
)}
) }