fix: remove cash flow summary cards and restore area chart shading

Remove the 4 summary cards from the Cash Flow page as they don't
properly represent the story over time. Increase gradient opacity
on stacked area charts (cash flow and investment scenarios) from
0.3-0.4/0-0.05 to 0.6/0.15 for better visual shading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-17 20:41:13 -04:00
parent 170461c359
commit 5845334454
2 changed files with 17 additions and 101 deletions

View File

@@ -89,20 +89,20 @@ export function ProjectionChart({ datapoints, title = 'Financial Projection', su
<AreaChart data={chartData}> <AreaChart data={chartData}>
<defs> <defs>
<linearGradient id="opCash" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="opCash" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#228be6" stopOpacity={0.3} /> <stop offset="5%" stopColor="#228be6" stopOpacity={0.6} />
<stop offset="95%" stopColor="#228be6" stopOpacity={0} /> <stop offset="95%" stopColor="#228be6" stopOpacity={0.15} />
</linearGradient> </linearGradient>
<linearGradient id="opInv" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="opInv" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#74c0fc" stopOpacity={0.3} /> <stop offset="5%" stopColor="#74c0fc" stopOpacity={0.6} />
<stop offset="95%" stopColor="#74c0fc" stopOpacity={0} /> <stop offset="95%" stopColor="#74c0fc" stopOpacity={0.15} />
</linearGradient> </linearGradient>
<linearGradient id="resCash" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="resCash" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#7950f2" stopOpacity={0.3} /> <stop offset="5%" stopColor="#7950f2" stopOpacity={0.6} />
<stop offset="95%" stopColor="#7950f2" stopOpacity={0} /> <stop offset="95%" stopColor="#7950f2" stopOpacity={0.15} />
</linearGradient> </linearGradient>
<linearGradient id="resInv" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="resInv" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#b197fc" stopOpacity={0.3} /> <stop offset="5%" stopColor="#b197fc" stopOpacity={0.6} />
<stop offset="95%" stopColor="#b197fc" stopOpacity={0} /> <stop offset="95%" stopColor="#b197fc" stopOpacity={0.15} />
</linearGradient> </linearGradient>
</defs> </defs>
<CartesianGrid strokeDasharray="3 3" opacity={0.3} /> <CartesianGrid strokeDasharray="3 3" opacity={0.3} />

View File

@@ -1,10 +1,9 @@
import { useState, useMemo } from 'react'; import { useState, useMemo } from 'react';
import { import {
Title, Text, Stack, Card, Group, SimpleGrid, ThemeIcon, Title, Text, Stack, Card, Group,
SegmentedControl, Loader, Center, ActionIcon, Tooltip, Badge, SegmentedControl, Loader, Center, ActionIcon, Tooltip, Badge,
} from '@mantine/core'; } from '@mantine/core';
import { import {
IconCash, IconBuildingBank, IconChartAreaLine,
IconArrowLeft, IconArrowRight, IconCalendar, IconArrowLeft, IconArrowRight, IconCalendar,
} from '@tabler/icons-react'; } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
@@ -108,30 +107,6 @@ export function CashFlowForecastPage() {
return datapoints.slice(viewStartIndex, viewStartIndex + 12); return datapoints.slice(viewStartIndex, viewStartIndex + 12);
}, [datapoints, viewStartIndex]); }, [datapoints, viewStartIndex]);
// Compute summary stats for the current view
const summaryStats = useMemo(() => {
if (!viewData.length) return null;
const last = viewData[viewData.length - 1];
const first = viewData[0];
const totalOperating = last.operating_cash + last.operating_investments;
const totalReserve = last.reserve_cash + last.reserve_investments;
const totalAll = totalOperating + totalReserve;
const firstTotal = first.operating_cash + first.operating_investments +
first.reserve_cash + first.reserve_investments;
const netChange = totalAll - firstTotal;
return {
totalOperating,
totalReserve,
totalAll,
netChange,
periodStart: first.month,
periodEnd: last.month,
};
}, [viewData]);
// Determine the first forecast month index within the view // Determine the first forecast month index within the view
const forecastStartLabel = useMemo(() => { const forecastStartLabel = useMemo(() => {
const idx = viewData.findIndex((d) => d.is_forecast); const idx = viewData.findIndex((d) => d.is_forecast);
@@ -181,65 +156,6 @@ export function CashFlowForecastPage() {
/> />
</Group> </Group>
{/* Summary Cards */}
{summaryStats && (
<SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }}>
<Card withBorder p="md">
<Group gap="xs" mb={4}>
<ThemeIcon variant="light" color="blue" size="sm">
<IconCash size={14} />
</ThemeIcon>
<Text size="xs" c="dimmed" tt="uppercase" fw={700}>Operating Total</Text>
</Group>
<Text fw={700} size="xl" ff="monospace">
{fmt(summaryStats.totalOperating)}
</Text>
</Card>
<Card withBorder p="md">
<Group gap="xs" mb={4}>
<ThemeIcon variant="light" color="violet" size="sm">
<IconBuildingBank size={14} />
</ThemeIcon>
<Text size="xs" c="dimmed" tt="uppercase" fw={700}>Reserve Total</Text>
</Group>
<Text fw={700} size="xl" ff="monospace">
{fmt(summaryStats.totalReserve)}
</Text>
</Card>
<Card withBorder p="md">
<Group gap="xs" mb={4}>
<ThemeIcon variant="light" color="teal" size="sm">
<IconChartAreaLine size={14} />
</ThemeIcon>
<Text size="xs" c="dimmed" tt="uppercase" fw={700}>Combined Total</Text>
</Group>
<Text fw={700} size="xl" ff="monospace">
{fmt(summaryStats.totalAll)}
</Text>
</Card>
<Card withBorder p="md">
<Group gap="xs" mb={4}>
<ThemeIcon
variant="light"
color={summaryStats.netChange >= 0 ? 'green' : 'red'}
size="sm"
>
<IconCash size={14} />
</ThemeIcon>
<Text size="xs" c="dimmed" tt="uppercase" fw={700}>Period Change</Text>
</Group>
<Text
fw={700}
size="xl"
ff="monospace"
c={summaryStats.netChange >= 0 ? 'green' : 'red'}
>
{fmt(summaryStats.netChange)}
</Text>
</Card>
</SimpleGrid>
)}
{/* Chart Navigation */} {/* Chart Navigation */}
<Card withBorder p="lg"> <Card withBorder p="lg">
<Group justify="space-between" mb="md"> <Group justify="space-between" mb="md">
@@ -287,20 +203,20 @@ export function CashFlowForecastPage() {
<AreaChart data={chartData} margin={{ top: 10, right: 30, left: 10, bottom: 0 }}> <AreaChart data={chartData} margin={{ top: 10, right: 30, left: 10, bottom: 0 }}>
<defs> <defs>
<linearGradient id="opCash" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="opCash" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#339af0" stopOpacity={0.4} /> <stop offset="5%" stopColor="#339af0" stopOpacity={0.6} />
<stop offset="95%" stopColor="#339af0" stopOpacity={0.05} /> <stop offset="95%" stopColor="#339af0" stopOpacity={0.15} />
</linearGradient> </linearGradient>
<linearGradient id="opInv" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="opInv" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#74c0fc" stopOpacity={0.4} /> <stop offset="5%" stopColor="#74c0fc" stopOpacity={0.6} />
<stop offset="95%" stopColor="#74c0fc" stopOpacity={0.05} /> <stop offset="95%" stopColor="#74c0fc" stopOpacity={0.15} />
</linearGradient> </linearGradient>
<linearGradient id="resCash" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="resCash" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#7950f2" stopOpacity={0.4} /> <stop offset="5%" stopColor="#7950f2" stopOpacity={0.6} />
<stop offset="95%" stopColor="#7950f2" stopOpacity={0.05} /> <stop offset="95%" stopColor="#7950f2" stopOpacity={0.15} />
</linearGradient> </linearGradient>
<linearGradient id="resInv" x1="0" y1="0" x2="0" y2="1"> <linearGradient id="resInv" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#b197fc" stopOpacity={0.4} /> <stop offset="5%" stopColor="#b197fc" stopOpacity={0.6} />
<stop offset="95%" stopColor="#b197fc" stopOpacity={0.05} /> <stop offset="95%" stopColor="#b197fc" stopOpacity={0.15} />
</linearGradient> </linearGradient>
</defs> </defs>
<CartesianGrid strokeDasharray="3 3" stroke="#e9ecef" /> <CartesianGrid strokeDasharray="3 3" stroke="#e9ecef" />