Init
This commit is contained in:
59
frontend/src/components/AvailableBalance.tsx
Normal file
59
frontend/src/components/AvailableBalance.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user