import { useMemo } from 'react'; import { Card, Title, Text, Group, Badge, SegmentedControl, Stack } from '@mantine/core'; import { useState } from 'react'; import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, ReferenceLine, } from 'recharts'; const fmt = (v: number) => v.toLocaleString('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }); interface Datapoint { month: string; year: number; monthNum: number; is_forecast: boolean; operating_cash: number; operating_investments: number; reserve_cash: number; reserve_investments: number; } interface Props { datapoints: Datapoint[]; title?: string; summary?: any; } export function ProjectionChart({ datapoints, title = 'Financial Projection', summary }: Props) { const [fundFilter, setFundFilter] = useState('all'); const chartData = useMemo(() => { return datapoints.map((d) => ({ ...d, label: `${d.month}`, total: d.operating_cash + d.operating_investments + d.reserve_cash + d.reserve_investments, })); }, [datapoints]); // Find first forecast month for reference line const forecastStart = chartData.findIndex((d) => d.is_forecast); const CustomTooltip = ({ active, payload, label }: any) => { if (!active || !payload?.length) return null; return ( {label} {payload.map((p: any) => ( {p.name} {fmt(p.value)} ))} ); }; const showOp = fundFilter === 'all' || fundFilter === 'operating'; const showRes = fundFilter === 'all' || fundFilter === 'reserve'; return ( {title} {summary && ( End Liquidity: {fmt(summary.end_liquidity || 0)} Min Liquidity: {fmt(summary.min_liquidity || 0)} {summary.reserve_coverage_months != null && ( Reserve Coverage: {summary.reserve_coverage_months.toFixed(1)} mo )} )} `$${(v / 1000).toFixed(0)}k`} /> } /> {forecastStart > 0 && ( )} {showOp && } {showOp && } {showRes && } {showRes && } ); }