dashboard feature to use dashboard data
This commit is contained in:
@@ -9,25 +9,18 @@ import {
|
||||
ToggleButtonGroup
|
||||
} from "@mui/material";
|
||||
|
||||
import LatestItemsList, { LatestItem } from "./components/LatestItems";
|
||||
import HistoryChart, { AggregatedDashboardData } from "./components/HistoryChart";
|
||||
import LatestItems from "./components/LatestItems";
|
||||
import HistoryChart from "./components/HistoryChart";
|
||||
|
||||
import {
|
||||
fetchLatestTransactions,
|
||||
fetchAggregatedExpenses,
|
||||
fetchAggregatedIncome,
|
||||
} from "./utils/dashboardLoader";
|
||||
import { useDashboardData } from "./features/dashboard";
|
||||
|
||||
export default function Dashboard() {
|
||||
const [latest, setLatest] = React.useState<{
|
||||
expense: LatestItem[];
|
||||
income: LatestItem[];
|
||||
}>({
|
||||
expense: [],
|
||||
income: []
|
||||
});
|
||||
const [mode, setMode] = React.useState<"expense" | "income">("expense");
|
||||
const [period, setPeriod] = React.useState<"rolling" | "calendar">("rolling");
|
||||
const [comparison, setComparison] = React.useState(false);
|
||||
|
||||
const palette = {
|
||||
expense: {
|
||||
expense: {
|
||||
primary: "#d32f2f",
|
||||
light: "#fdecea",
|
||||
dark: "#9a0007",
|
||||
@@ -41,73 +34,11 @@ export default function Dashboard() {
|
||||
}
|
||||
};
|
||||
|
||||
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<string | null>(null);
|
||||
const { data, latest, isLoading, error } = useDashboardData(mode);
|
||||
|
||||
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 (
|
||||
<Box sx={{ display: "flex", justifyContent: "center", alignItems: "center", height: "60vh" }}>
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
const currentLatest = latest[mode];
|
||||
|
||||
// -------- UI STATES --------
|
||||
if (loading) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Box sx={{ display: "flex", justifyContent: "center", alignItems: "center", height: "60vh" }}>
|
||||
<CircularProgress />
|
||||
@@ -118,11 +49,15 @@ export default function Dashboard() {
|
||||
if (error) {
|
||||
return (
|
||||
<Container sx={{ mt: 4 }}>
|
||||
<Alert severity="error">{error}</Alert>
|
||||
<Alert severity="error">{String(error)}</Alert>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Container
|
||||
sx={{
|
||||
@@ -133,7 +68,6 @@ export default function Dashboard() {
|
||||
p: 2
|
||||
}}
|
||||
>
|
||||
{/* -------- TOGGLE -------- */}
|
||||
<Box sx={{ display: "flex", justifyContent: "center", mb: 3 }}>
|
||||
<ToggleButtonGroup
|
||||
value={mode}
|
||||
@@ -160,13 +94,12 @@ export default function Dashboard() {
|
||||
</Box>
|
||||
|
||||
<Grid container spacing={4} direction="row">
|
||||
|
||||
<Grid size={12}>
|
||||
<HistoryChart
|
||||
header={`${mode === "expense" ? "Expense" : "Income"} Breakdown`}
|
||||
summary="Interactive chronological tracking"
|
||||
tabs={["Daily", "Weekly", "Monthly"]}
|
||||
data={currentData.chartData}
|
||||
data={data.chartData}
|
||||
period={period}
|
||||
onPeriodChange={setPeriod}
|
||||
comparison={comparison}
|
||||
@@ -176,15 +109,14 @@ export default function Dashboard() {
|
||||
</Grid>
|
||||
|
||||
<Grid size={12}>
|
||||
<LatestItemsList
|
||||
<LatestItems
|
||||
title={`Recent ${mode === "expense" ? "Expenses" : "Income"}`}
|
||||
items={currentLatest}
|
||||
items={latest || []}
|
||||
onViewAll={() => {}}
|
||||
accentColor={colors.primary}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user