import { useMemo, useState } from "react"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { DonutChart } from "@/components/charts/DonutChart"; import { BubbleChart } from "@/components/charts/BubbleChart"; import { ChartTypeToggle } from "@/components/charts/ChartTypeToggle"; import { SegmentedControl } from "@/components/charts/SegmentedControl"; import { shareColor } from "@/components/dashboard/shareColors"; import { allocationBreakdown, type AllocationMode } from "@/lib/holdings"; import { usePrivacy } from "@/lib/privacy"; import { formatMoney } from "@/lib/format"; import type { Holding } from "@/types/finance"; import { PieChart, Circle } from "lucide-react"; // "currency" is deliberately not offered here: this panel receives holdings // already scoped to one currency (the caller filters, same as the headline // stats), so a currency breakdown of them would always be a single 100% slice. const MODES: { value: AllocationMode; label: string }[] = [ { value: "asset", label: "Asset" }, { value: "account", label: "Account" }, ]; const CHART_TYPES = [ { value: "donut", icon: PieChart, label: "Donut" }, { value: "bubbles", icon: Circle, label: "Bubbles" }, ] as const; function fmt(v: number, c: string) { return formatMoney(v, c, { decimals: 0 }); } export function AllocationPanel({ holdings, investmentAccounts, currency, }: { holdings: Holding[]; investmentAccounts: { id: string; label: string }[]; currency: string; }) { usePrivacy(); const [mode, setMode] = useState("asset"); const [chartType, setChartType] = useState<"donut" | "bubbles">("donut"); const rows = useMemo(() => allocationBreakdown(holdings, mode, investmentAccounts), [holdings, mode, investmentAccounts]); const total = rows.reduce((s, r) => s + r.value, 0); const slices = rows.map((r, i) => ({ name: r.label, value: r.value, color: shareColor(i) })); return (
Allocation
{rows.length === 0 ? (

No holdings to allocate yet.

) : (
{chartType === "donut" ? ( fmt(v, currency)} centerLabel={`${rows.length} ${rows.length === 1 ? "group" : "groups"}`} centerValue={fmt(total, currency)} /> ) : ( fmt(v, currency)} /> )}
{rows.map((r, i) => { const pct = total > 0 ? (r.value / total) * 100 : 0; return (
{r.label} {pct.toFixed(1)}%
); })}
)}
); }