import * as React from "react"; import { Box, Container, Grid, CircularProgress, Alert, ToggleButton, ToggleButtonGroup } from "@mui/material"; import LatestItemsList, { LatestItem } from "./components/LatestItemsList"; import HistoryChart from "./components/HistoryChart"; import { AggregatedDashboardData } from "./components/HistoryChart"; import { fetchLatestTransactions, fetchAggregatedExpenses, fetchAggregatedIncome, } from "./utils/dashboardLoader"; export default function Dashboard() { const [latest, setLatest] = React.useState<{ expense: LatestItem[]; income: LatestItem[]; }>({ expense: [], income: [] }); const palette = { expense: { primary: "#d32f2f", light: "#fdecea", dark: "#9a0007", text: "#b71c1c" }, income: { primary: "#2e7d32", light: "#e8f5e9", dark: "#1b5e20", text: "#1b5e20" } }; const [aggregated, setAggregated] = React.useState<{ expense: AggregatedDashboardData | null; income: AggregatedDashboardData | null; }>({ expense: null, income: null }); const [mode, setMode] = React.useState<"expense" | "income">("expense"); const [period, setPeriod] = React.useState<"rolling" | "calendar">("rolling"); const [comparison, setComparison] = React.useState(false); const [loading, setLoading] = React.useState(true); const [error, setError] = React.useState(null); const colors = palette[mode]; // -------- LOAD ONCE -------- React.useEffect(() => { async function loadData() { try { setLoading(true); const [ latestExpense, latestIncome, expenseData, incomeData ] = await Promise.all([ fetchLatestTransactions("expense"), fetchLatestTransactions("income"), fetchAggregatedExpenses(), fetchAggregatedIncome() ]); setLatest({ expense: latestExpense, income: latestIncome }); setAggregated({ expense: expenseData, income: incomeData }); } catch (err: any) { console.error(err); setError(err.message || "Failed to load dashboard data"); } finally { setLoading(false); } } loadData(); }, []); const currentData = aggregated[mode]; if (!currentData) { return ( ); } const currentLatest = latest[mode]; // -------- UI STATES -------- if (loading) { return ( ); } if (error) { return ( {error} ); } return ( {/* -------- TOGGLE -------- */} val && setMode(val)} sx={{ borderRadius: 3, overflow: "hidden", "& .MuiToggleButton-root": { px: 3, textTransform: "none", color: "text.secondary" }, "&.Mui-selected": { bgcolor: colors.primary, color: "white", borderColor: colors.primary }, }} > Expenses Income {}} accentColor={colors.primary} /> ); }