112 lines
5.2 KiB
TypeScript
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>
|
|
);
|
|
}
|