This commit is contained in:
2026-03-06 19:42:15 +00:00
parent abcbe3e1e5
commit 04cbb846d1
99 changed files with 11724 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
import { useTranslation } from 'react-i18next'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { PieChart, Pie, Cell, ResponsiveContainer } from 'recharts'
import type { BudgetDetail } from '@/lib/api'
import { formatCurrency } from '@/lib/format'
interface Props {
budget: BudgetDetail
}
const PASTEL_COLORS = ['#93c5fd', '#f9a8d4', '#fcd34d', '#a5b4fc', '#86efac', '#c4b5fd']
export function AvailableBalance({ budget }: Props) {
const { t } = useTranslation()
const { totals } = budget
const available = totals.available
const data = [
{ name: t('dashboard.remaining'), value: Math.max(0, available) },
{ name: t('dashboard.bills'), value: totals.bills_actual },
{ name: t('dashboard.expenses'), value: totals.expenses_actual },
{ name: t('dashboard.debts'), value: totals.debts_actual },
{ name: t('dashboard.savings'), value: totals.savings_actual },
{ name: t('dashboard.investments'), value: totals.investments_actual },
].filter((d) => d.value > 0)
return (
<Card>
<CardHeader className="bg-gradient-to-r from-sky-50 to-cyan-50">
<CardTitle>{t('dashboard.availableAmount')}</CardTitle>
</CardHeader>
<CardContent className="flex flex-col items-center gap-4 pt-6">
<div className="relative size-48">
<ResponsiveContainer width="100%" height="100%">
<PieChart>
<Pie
data={data}
cx="50%"
cy="50%"
innerRadius={55}
outerRadius={80}
paddingAngle={2}
dataKey="value"
>
{data.map((_, index) => (
<Cell key={index} fill={PASTEL_COLORS[index % PASTEL_COLORS.length]} />
))}
</Pie>
</PieChart>
</ResponsiveContainer>
<div className="absolute inset-0 flex flex-col items-center justify-center">
<span className="text-2xl font-bold">{formatCurrency(available, budget.currency)}</span>
</div>
</div>
</CardContent>
</Card>
)
}