major refactor of the dashboard and react-openapi integration #1
@@ -11,9 +11,7 @@ import { configuration } from "./dashboard-config";
|
||||
import { useDashboardData } from "./features/dashboard";
|
||||
|
||||
export default function Dashboard() {
|
||||
const [mode, setMode] = React.useState<"expense" | "income">("expense");
|
||||
const [selectedPeriodId, setSelectedPeriodId] = React.useState<string | null>(null);
|
||||
const { data, isLoading, error } = useDashboardData(mode);
|
||||
const { data, isLoading, error } = useDashboardData();
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -39,9 +37,6 @@ export default function Dashboard() {
|
||||
<ConfigurableDashboard
|
||||
config={configuration}
|
||||
data={data}
|
||||
onModeChange={(newMode) => setMode(newMode)}
|
||||
selectedPeriodId={selectedPeriodId}
|
||||
onSelectPeriodId={(newPeriodId) => setSelectedPeriodId(newPeriodId)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ import * as React from "react";
|
||||
|
||||
export type DashboardMode = "expense" | "income";
|
||||
export type DashboardPeriodType = "rolling" | "calendar";
|
||||
export type DashboardSelectedPeriodId = string | null;
|
||||
|
||||
export interface DashboardState {
|
||||
mode: DashboardMode;
|
||||
periodType: DashboardPeriodType;
|
||||
selectedPeriodId: DashboardSelectedPeriodId;
|
||||
comparison: boolean;
|
||||
}
|
||||
|
||||
@@ -43,8 +45,8 @@ export interface DashboardConfig {
|
||||
|
||||
export interface DashboardProps {
|
||||
config: DashboardConfig;
|
||||
data: any; // Aggregated data from features
|
||||
onModeChange?: (mode: DashboardMode) => void;
|
||||
selectedPeriodId: string | null;
|
||||
onSelectPeriodId: (id: string | null) => void;
|
||||
data: any;
|
||||
toggleMode: () => void;
|
||||
togglePeriodType: () => void;
|
||||
setSelectedPeriodId: (id: string | null) => void;
|
||||
}
|
||||
|
||||
@@ -6,14 +6,36 @@ export default function Dashboard(props: DashboardProps) {
|
||||
const [state, setState] = React.useState<DashboardState>({
|
||||
mode: "expense",
|
||||
periodType: "rolling",
|
||||
selectedPeriodId: null,
|
||||
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 (
|
||||
<DashboardView
|
||||
{...props}
|
||||
state={state}
|
||||
setState={setState}
|
||||
toggleMode={toggleMode}
|
||||
togglePeriodType={togglePeriodType}
|
||||
setSelectedPeriodId={setSelectedPeriodId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,16 +18,15 @@ interface ViewProps extends DashboardProps {
|
||||
export default function DashboardView({
|
||||
config,
|
||||
data,
|
||||
latest,
|
||||
state,
|
||||
setState,
|
||||
onModeChange,
|
||||
selectedPeriodId,
|
||||
onSelectPeriodId,
|
||||
toggleMode,
|
||||
togglePeriodType,
|
||||
setSelectedPeriodId,
|
||||
}: ViewProps) {
|
||||
const theme = useTheme();
|
||||
const themeMode = theme.palette.mode;
|
||||
const { mode, periodType, comparison } = state;
|
||||
const { mode, periodType, selectedPeriodId, comparison } = state;
|
||||
|
||||
// Resolve colors with fallbacks
|
||||
const colors = React.useMemo(() => {
|
||||
@@ -51,13 +50,6 @@ export default function DashboardView({
|
||||
};
|
||||
}, [config.style?.palette, mode, themeMode, theme.palette]);
|
||||
|
||||
const handleModeChange = (_: any, newMode: any) => {
|
||||
if (newMode && onModeChange) {
|
||||
onModeChange(newMode);
|
||||
setState(prev => ({ ...prev, mode: newMode }));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Container
|
||||
sx={{
|
||||
@@ -73,7 +65,7 @@ export default function DashboardView({
|
||||
<ToggleButtonGroup
|
||||
value={mode}
|
||||
exclusive
|
||||
onChange={handleModeChange}
|
||||
onChange={toggleMode}
|
||||
sx={{
|
||||
borderRadius: 3,
|
||||
overflow: "hidden",
|
||||
@@ -137,7 +129,6 @@ export default function DashboardView({
|
||||
header={section.title}
|
||||
summary={section.summary}
|
||||
data={section.dataKey ? data[section.dataKey] : data.chartData}
|
||||
items={section.dataKey === 'latest' ? latest : (data[section.dataKey || ''] || [])}
|
||||
title={section.title}
|
||||
accentColor={colors.primary}
|
||||
colorScheme={colors}
|
||||
@@ -146,7 +137,7 @@ export default function DashboardView({
|
||||
comparison={comparison}
|
||||
setComparison={(c: any) => setState(prev => ({ ...prev, comparison: c }))}
|
||||
selectedPeriodId={selectedPeriodId}
|
||||
onSelectPeriodId={onSelectPeriodId}
|
||||
onSelectPeriodId={setSelectedPeriodId}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useReport } from "../report";
|
||||
import { mapReportToDashboard } from "./dashboard.mapper";
|
||||
|
||||
export function useDashboardData(type: "expense" | "income") {
|
||||
export function useDashboardData() {
|
||||
// Fetch reports for aggregation
|
||||
const weeklyReport = useReport({ period: "weekly", rolling: true });
|
||||
const monthlyReport = useReport({ period: "monthly", rolling: true });
|
||||
@@ -17,15 +17,24 @@ export function useDashboardData(type: "expense" | "income") {
|
||||
monthlyReport.error ||
|
||||
payeeReport.error;
|
||||
|
||||
const aggregatedData =
|
||||
weeklyReport.data?.data && monthlyReport.data?.data && payeeReport.data?.data
|
||||
const aggregatedData = {
|
||||
expense: weeklyReport.data?.data && monthlyReport.data?.data && payeeReport.data?.data
|
||||
? mapReportToDashboard(
|
||||
(weeklyReport.data.data as any).buckets,
|
||||
(monthlyReport.data.data as any).buckets,
|
||||
(weeklyReport.data.data as any).buckets,
|
||||
(monthlyReport.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 {
|
||||
data: aggregatedData,
|
||||
|
||||
Reference in New Issue
Block a user