dashboard fixes

This commit is contained in:
2026-04-04 22:08:39 +05:30
parent 68337ba312
commit 214c0be44e
2 changed files with 232 additions and 155 deletions

View File

@@ -1,26 +1,53 @@
import * as React from "react";
import { Box, Container, Grid, Typography, Avatar, CircularProgress, Alert } from "@mui/material";
import {
Box,
Container,
Grid,
Typography,
CircularProgress,
Alert,
ToggleButton,
ToggleButtonGroup
} from "@mui/material";
import LatestItemsList, { LatestItem } from "./components/LatestItemsList";
import ProgressCard from "./components/ProgressCard";
import HistoryChart from "./components/HistoryChart";
import { fetchLatestExpenses, fetchAggregatedExpenses, AggregatedDashboardData } from "./utils/dashboardLoader";
import {
fetchLatestExpenses,
fetchAggregatedExpenses,
fetchAggregatedIncome,
AggregatedDashboardData
} from "./utils/dashboardLoader";
export default function Dashboard() {
const [latest, setLatest] = React.useState<LatestItem[]>([]);
const [aggregated, setAggregated] = React.useState<AggregatedDashboardData | null>(null);
const [aggregated, setAggregated] =
React.useState<AggregatedDashboardData | null>(null);
const [mode, setMode] =
React.useState<"expense" | "income">("expense");
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState<string | null>(null);
// -------- LOAD DATA --------
React.useEffect(() => {
async function loadData() {
try {
setLoading(true);
const [latestData, aggData] = await Promise.all([
fetchLatestExpenses(),
fetchAggregatedExpenses()
]);
const latestData = await fetchLatestExpenses();
const aggData =
mode === "expense"
? await fetchAggregatedExpenses()
: await fetchAggregatedIncome();
setLatest(latestData);
setAggregated(aggData);
} catch (err: any) {
console.error(err);
setError(err.message || "Failed to load dashboard data");
@@ -28,12 +55,14 @@ export default function Dashboard() {
setLoading(false);
}
}
loadData();
}, []);
loadData();
}, [mode]);
// -------- UI STATES --------
if (loading) {
return (
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '60vh' }}>
<Box sx={{ display: "flex", justifyContent: "center", alignItems: "center", height: "60vh" }}>
<CircularProgress />
</Box>
);
@@ -51,57 +80,38 @@ export default function Dashboard() {
return (
<Container maxWidth="xl" sx={{ mt: 4, mb: 4 }}>
{/* -------- TOGGLE -------- */}
<Box sx={{ display: "flex", justifyContent: "center", mb: 3 }}>
<ToggleButtonGroup
value={mode}
exclusive
onChange={(_, val) => val && setMode(val)}
>
<ToggleButton value="expense">Expenses</ToggleButton>
<ToggleButton value="income">Income</ToggleButton>
</ToggleButtonGroup>
</Box>
<Grid container spacing={4}>
{/* Column 1: Latest Transactions */}
{/* Column 1 */}
<Grid item xs={12} md={4}>
<LatestItemsList
title="Recent Transactions"
items={latest}
onViewAll={() => {}}
<LatestItemsList
title="Recent Transactions"
items={latest}
onViewAll={() => {}}
/>
</Grid>
{/* Column 2: Breakdown Graph */}
<Grid item xs={12} md={4}>
<Box sx={{ mb: 4, display: 'flex', justifyContent: 'center', visibility: 'hidden' }}>
<Typography variant="h6">Spacer</Typography>
</Box>
{/* Column 2 */}
<Grid item xs={12} md={8}>
<HistoryChart
header="Expense Breakdown"
header={`${mode === "expense" ? "Expense" : "Income"} Breakdown`}
summary="Interactive chronological tracking"
tabs={["Today", "Week", "Month", "Year"]}
data={aggregated?.chartData || {}}
/>
</Grid>
{/* Column 3: Top Payees Progress */}
<Grid item xs={12} md={4}>
<Box sx={{ mb: 4, display: 'flex', justifyContent: 'center' }}>
<Typography variant="h6" fontWeight={700}>Top Analytics</Typography>
</Box>
<Box sx={{ mb: 4 }}>
<ProgressCard
header="Total Expenses"
progressAmount={aggregated?.totalAmount || 0}
totalAmount={aggregated?.totalAmount || 0}
summary={`Rs ${aggregated?.totalAmount || 0}`}
colorTheme="error" // Highlight total in red/error or use info
/>
</Box>
<Typography variant="h6" fontWeight={600} mb={2} px={1}>Top 5 Payees</Typography>
{aggregated?.topPayees.map((payee, idx) => (
<Box sx={{ mb: 2 }} key={payee.payeeName}>
<ProgressCard
header={payee.payeeName}
progressAmount={payee.amount}
totalAmount={aggregated?.totalAmount || 1}
colorTheme={themes[idx % themes.length]}
/>
</Box>
))}
</Grid>
</Grid>
</Container>
);