ledgerone_frontend/components/growth-simulator.tsx
2026-03-18 13:02:58 -07:00

112 lines
5.2 KiB
TypeScript

"use client";
import { useState } from "react";
import { Area, AreaChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
const data = [
{ year: "2026", savings: 12000, investing: 12000 },
{ year: "2027", savings: 24000, investing: 25400 },
{ year: "2028", savings: 36000, investing: 40100 },
{ year: "2029", savings: 48000, investing: 56500 },
{ year: "2030", savings: 60000, investing: 74800 },
{ year: "2031", savings: 72000, investing: 95200 },
{ year: "2032", savings: 84000, investing: 118000 },
];
export function GrowthSimulator() {
const [monthlyContribution, setMonthlyContribution] = useState(1000);
const [mode, setMode] = useState<"savings" | "investing">("investing");
return (
<div className="glass-panel rounded-3xl p-8 shadow-glass">
<div className="flex flex-wrap items-center justify-between gap-6 mb-8">
<div>
<h3 className="text-xl font-bold text-foreground">Projected Growth</h3>
<p className="text-sm text-muted-foreground">Simulate your wealth accumulation over 6 years.</p>
</div>
<div className="flex items-center gap-2 bg-secondary rounded-full p-1">
<button
onClick={() => setMode("savings")}
className={`px-4 py-1.5 rounded-full text-sm font-medium transition-all ${mode === "savings" ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
}`}
>
Savings
</button>
<button
onClick={() => setMode("investing")}
className={`px-4 py-1.5 rounded-full text-sm font-medium transition-all ${mode === "investing" ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
}`}
>
Investing
</button>
</div>
</div>
<div className="h-[300px] w-full">
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={data}>
<defs>
<linearGradient id="colorGrowth" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="var(--primary)" stopOpacity={0.3} />
<stop offset="95%" stopColor="var(--primary)" stopOpacity={0} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="var(--border)" />
<XAxis
dataKey="year"
axisLine={false}
tickLine={false}
tick={{ fill: "var(--muted-foreground)", fontSize: 12 }}
dy={10}
/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fill: "var(--muted-foreground)", fontSize: 12 }}
tickFormatter={(value) => `$${value / 1000}k`}
/>
<Tooltip
contentStyle={{
backgroundColor: "var(--background)",
borderColor: "var(--border)",
borderRadius: "12px",
boxShadow: "0 4px 12px rgba(0,0,0,0.1)"
}}
itemStyle={{ color: "var(--foreground)" }}
/>
<Area
type="monotone"
dataKey={mode}
stroke="var(--primary)"
strokeWidth={3}
fillOpacity={1}
fill="url(#colorGrowth)"
animationDuration={1500}
/>
</AreaChart>
</ResponsiveContainer>
</div>
<div className="mt-8 space-y-4">
<div className="flex justify-between text-sm">
<span className="text-muted-foreground">Monthly Contribution</span>
<span className="font-bold text-foreground">${monthlyContribution}</span>
</div>
<input
type="range"
min="100"
max="5000"
step="100"
value={monthlyContribution}
onChange={(e) => setMonthlyContribution(Number(e.target.value))}
className="w-full h-2 bg-secondary rounded-lg appearance-none cursor-pointer accent-primary"
/>
<div className="flex justify-between text-xs text-muted-foreground">
<span>$100</span>
<span>$5,000</span>
</div>
</div>
</div>
);
}