state controlled by Dashboard.models.ts

This commit is contained in:
2026-05-05 12:26:02 +05:30
parent a0e62b1bc4
commit 30cf227050
5 changed files with 51 additions and 32 deletions

View File

@@ -11,9 +11,7 @@ import { configuration } from "./dashboard-config";
import { useDashboardData } from "./features/dashboard"; import { useDashboardData } from "./features/dashboard";
export default function Dashboard() { export default function Dashboard() {
const [mode, setMode] = React.useState<"expense" | "income">("expense"); const { data, isLoading, error } = useDashboardData();
const [selectedPeriodId, setSelectedPeriodId] = React.useState<string | null>(null);
const { data, isLoading, error } = useDashboardData(mode);
if (isLoading) { if (isLoading) {
return ( return (
@@ -39,9 +37,6 @@ export default function Dashboard() {
<ConfigurableDashboard <ConfigurableDashboard
config={configuration} config={configuration}
data={data} data={data}
onModeChange={(newMode) => setMode(newMode)}
selectedPeriodId={selectedPeriodId}
onSelectPeriodId={(newPeriodId) => setSelectedPeriodId(newPeriodId)}
/> />
); );
} }

View File

@@ -2,10 +2,12 @@ import * as React from "react";
export type DashboardMode = "expense" | "income"; export type DashboardMode = "expense" | "income";
export type DashboardPeriodType = "rolling" | "calendar"; export type DashboardPeriodType = "rolling" | "calendar";
export type DashboardSelectedPeriodId = string | null;
export interface DashboardState { export interface DashboardState {
mode: DashboardMode; mode: DashboardMode;
periodType: DashboardPeriodType; periodType: DashboardPeriodType;
selectedPeriodId: DashboardSelectedPeriodId;
comparison: boolean; comparison: boolean;
} }
@@ -43,8 +45,8 @@ export interface DashboardConfig {
export interface DashboardProps { export interface DashboardProps {
config: DashboardConfig; config: DashboardConfig;
data: any; // Aggregated data from features data: any;
onModeChange?: (mode: DashboardMode) => void; toggleMode: () => void;
selectedPeriodId: string | null; togglePeriodType: () => void;
onSelectPeriodId: (id: string | null) => void; setSelectedPeriodId: (id: string | null) => void;
} }

View File

@@ -6,14 +6,36 @@ export default function Dashboard(props: DashboardProps) {
const [state, setState] = React.useState<DashboardState>({ const [state, setState] = React.useState<DashboardState>({
mode: "expense", mode: "expense",
periodType: "rolling", periodType: "rolling",
selectedPeriodId: null,
comparison: false, comparison: false,
}); });
const toggleMode = () => {
setState(prev => ({
...prev,
mode: prev.mode === "expense" ? "income" : "expense",
}));
};
const togglePeriodType = () => {
setState(prev => ({
...prev,
periodType: prev.periodType === "rolling" ? "calendar" : "rolling",
}));
};
const setSelectedPeriodId = (selectedPeriodId: typeof state.selectedPeriodId) => {
setState(prev => ({ ...prev, selectedPeriodId }));
};
return ( return (
<DashboardView <DashboardView
{...props} {...props}
state={state} state={state}
setState={setState} setState={setState}
toggleMode={toggleMode}
togglePeriodType={togglePeriodType}
setSelectedPeriodId={setSelectedPeriodId}
/> />
); );
} }

View File

@@ -18,16 +18,15 @@ interface ViewProps extends DashboardProps {
export default function DashboardView({ export default function DashboardView({
config, config,
data, data,
latest,
state, state,
setState, setState,
onModeChange, toggleMode,
selectedPeriodId, togglePeriodType,
onSelectPeriodId, setSelectedPeriodId,
}: ViewProps) { }: ViewProps) {
const theme = useTheme(); const theme = useTheme();
const themeMode = theme.palette.mode; const themeMode = theme.palette.mode;
const { mode, periodType, comparison } = state; const { mode, periodType, selectedPeriodId, comparison } = state;
// Resolve colors with fallbacks // Resolve colors with fallbacks
const colors = React.useMemo(() => { const colors = React.useMemo(() => {
@@ -51,13 +50,6 @@ export default function DashboardView({
}; };
}, [config.style?.palette, mode, themeMode, theme.palette]); }, [config.style?.palette, mode, themeMode, theme.palette]);
const handleModeChange = (_: any, newMode: any) => {
if (newMode && onModeChange) {
onModeChange(newMode);
setState(prev => ({ ...prev, mode: newMode }));
}
};
return ( return (
<Container <Container
sx={{ sx={{
@@ -73,7 +65,7 @@ export default function DashboardView({
<ToggleButtonGroup <ToggleButtonGroup
value={mode} value={mode}
exclusive exclusive
onChange={handleModeChange} onChange={toggleMode}
sx={{ sx={{
borderRadius: 3, borderRadius: 3,
overflow: "hidden", overflow: "hidden",
@@ -137,7 +129,6 @@ export default function DashboardView({
header={section.title} header={section.title}
summary={section.summary} summary={section.summary}
data={section.dataKey ? data[section.dataKey] : data.chartData} data={section.dataKey ? data[section.dataKey] : data.chartData}
items={section.dataKey === 'latest' ? latest : (data[section.dataKey || ''] || [])}
title={section.title} title={section.title}
accentColor={colors.primary} accentColor={colors.primary}
colorScheme={colors} colorScheme={colors}
@@ -146,7 +137,7 @@ export default function DashboardView({
comparison={comparison} comparison={comparison}
setComparison={(c: any) => setState(prev => ({ ...prev, comparison: c }))} setComparison={(c: any) => setState(prev => ({ ...prev, comparison: c }))}
selectedPeriodId={selectedPeriodId} selectedPeriodId={selectedPeriodId}
onSelectPeriodId={onSelectPeriodId} onSelectPeriodId={setSelectedPeriodId}
/> />
)} )}
</Grid> </Grid>

View File

@@ -1,7 +1,7 @@
import { useReport } from "../report"; import { useReport } from "../report";
import { mapReportToDashboard } from "./dashboard.mapper"; import { mapReportToDashboard } from "./dashboard.mapper";
export function useDashboardData(type: "expense" | "income") { export function useDashboardData() {
// Fetch reports for aggregation // Fetch reports for aggregation
const weeklyReport = useReport({ period: "weekly", rolling: true }); const weeklyReport = useReport({ period: "weekly", rolling: true });
const monthlyReport = useReport({ period: "monthly", rolling: true }); const monthlyReport = useReport({ period: "monthly", rolling: true });
@@ -17,15 +17,24 @@ export function useDashboardData(type: "expense" | "income") {
monthlyReport.error || monthlyReport.error ||
payeeReport.error; payeeReport.error;
const aggregatedData = const aggregatedData = {
weeklyReport.data?.data && monthlyReport.data?.data && payeeReport.data?.data expense: weeklyReport.data?.data && monthlyReport.data?.data && payeeReport.data?.data
? mapReportToDashboard( ? mapReportToDashboard(
(weeklyReport.data.data as any).buckets, (weeklyReport.data.data as any).buckets,
(monthlyReport.data.data as any).buckets, (monthlyReport.data.data as any).buckets,
(payeeReport.data.data as any).buckets, (payeeReport.data.data as any).buckets,
type "expense"
) )
: null; : null,
income: weeklyReport.data?.data && monthlyReport.data?.data && payeeReport.data?.data
? mapReportToDashboard(
(weeklyReport.data.data as any).buckets,
(monthlyReport.data.data as any).buckets,
(payeeReport.data.data as any).buckets,
"income"
)
: null,
}
return { return {
data: aggregatedData, data: aggregatedData,