Files
finance-app/src/components/graphs/NetWorthTrendChart.tsx
2026-04-19 00:44:43 -04:00

69 lines
2.0 KiB
TypeScript

'use client'
import {
AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer,
} from 'recharts'
import { formatCents, formatCentsAbbrev } from '@/lib/utils/currency'
interface DataPoint {
label: string
totalCents: number
}
function ChartTooltip({ active, payload, label }: {
active?: boolean
payload?: Array<{ value: number }>
label?: string
}) {
if (!active || !payload?.length) return null
return (
<div className="rounded-md border bg-card p-3 shadow-md text-sm">
<p className="font-medium mb-1">{label}</p>
<p className="text-primary">{formatCents(payload[0].value)}</p>
</div>
)
}
export function NetWorthTrendChart({ data }: { data: DataPoint[] }) {
if (data.length === 0) {
return (
<div className="flex h-[300px] items-center justify-center text-sm text-muted-foreground">
No snapshot data yet upload transactions to populate this chart.
</div>
)
}
return (
<ResponsiveContainer width="100%" height={300}>
<AreaChart data={data} margin={{ top: 4, right: 16, left: 16, bottom: 0 }}>
<defs>
<linearGradient id="netWorthGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#6366f1" stopOpacity={0.3} />
<stop offset="95%" stopColor="#6366f1" stopOpacity={0} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
<XAxis dataKey="label" tick={{ fontSize: 12 }} tickLine={false} axisLine={false} />
<YAxis
tickFormatter={formatCentsAbbrev}
tick={{ fontSize: 12 }}
tickLine={false}
axisLine={false}
width={64}
/>
<Tooltip content={<ChartTooltip />} />
<Area
type="monotone"
dataKey="totalCents"
name="Net Worth"
stroke="#6366f1"
strokeWidth={2}
fill="url(#netWorthGradient)"
dot={false}
activeDot={{ r: 4 }}
/>
</AreaChart>
</ResponsiveContainer>
)
}