Compare commits
4 Commits
5f85abdf86
...
38f7416942
| Author | SHA1 | Date | |
|---|---|---|---|
| 38f7416942 | |||
| e82cad4f21 | |||
| 1daa90d091 | |||
| 2d0b0bc470 |
@@ -1,11 +1,11 @@
|
||||
import * as React from "react";
|
||||
|
||||
export type DashboardMode = "expense" | "income";
|
||||
export type DashboardPeriod = "rolling" | "calendar";
|
||||
export type DashboardPeriodType = "rolling" | "calendar";
|
||||
|
||||
export interface DashboardState {
|
||||
mode: DashboardMode;
|
||||
period: DashboardPeriod;
|
||||
periodType: DashboardPeriodType;
|
||||
comparison: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { DashboardProps, DashboardState } from "./Dashboard.models";
|
||||
export default function Dashboard(props: DashboardProps) {
|
||||
const [state, setState] = React.useState<DashboardState>({
|
||||
mode: "expense",
|
||||
period: "rolling",
|
||||
periodType: "rolling",
|
||||
comparison: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ export default function DashboardView({
|
||||
}: ViewProps) {
|
||||
const theme = useTheme();
|
||||
const themeMode = theme.palette.mode;
|
||||
const { mode, period, comparison } = state;
|
||||
const { mode, periodType, comparison } = state;
|
||||
|
||||
// Resolve colors with fallbacks
|
||||
const colors = React.useMemo(() => {
|
||||
@@ -139,8 +139,8 @@ export default function DashboardView({
|
||||
title={section.title}
|
||||
accentColor={colors.primary}
|
||||
colorScheme={colors}
|
||||
period={period}
|
||||
onPeriodChange={(p: any) => setState(prev => ({ ...prev, period: p }))}
|
||||
periodType={periodType}
|
||||
onPeriodTypeChange={(p: any) => setState(prev => ({ ...prev, periodType: p }))}
|
||||
comparison={comparison}
|
||||
setComparison={(c: any) => setState(prev => ({ ...prev, comparison: c }))}
|
||||
/>
|
||||
|
||||
@@ -25,8 +25,8 @@ export interface HistoryChartProps {
|
||||
summary?: string;
|
||||
tabs: string[];
|
||||
data: ChartData;
|
||||
period: "rolling" | "calendar";
|
||||
onPeriodChange: (p: "rolling" | "calendar") => void;
|
||||
periodType: "rolling" | "calendar";
|
||||
onPeriodTypeChange: (p: "rolling" | "calendar") => void;
|
||||
comparison: boolean;
|
||||
setComparison: (v: boolean) => void;
|
||||
colorScheme: {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ChartDataPoint, HistoryChartProps, ChartData } from "./HistoryChart.mod
|
||||
import HistoryChartView from "./HistoryChart.view";
|
||||
|
||||
export default function HistoryChart(props: HistoryChartProps) {
|
||||
const { tabs, data, period, comparison } = props;
|
||||
const { tabs, data, periodType, comparison } = props;
|
||||
|
||||
const [activeTab, setActiveTab] = React.useState<string>(tabs[0] || "");
|
||||
const [startIndex, setStartIndex] = React.useState(0);
|
||||
@@ -16,7 +16,7 @@ export default function HistoryChart(props: HistoryChartProps) {
|
||||
rawData = data.daily || [];
|
||||
} else {
|
||||
const section = data[activeDataKey];
|
||||
rawData = section?.[period] || [];
|
||||
rawData = section?.[periodType] || [];
|
||||
}
|
||||
|
||||
const currentData = rawData;
|
||||
|
||||
@@ -33,8 +33,8 @@ export default function HistoryChartView(props: ViewProps) {
|
||||
header,
|
||||
summary,
|
||||
tabs,
|
||||
period,
|
||||
onPeriodChange,
|
||||
periodType,
|
||||
onPeriodTypeChange,
|
||||
comparison,
|
||||
setComparison,
|
||||
colorScheme,
|
||||
@@ -99,7 +99,7 @@ export default function HistoryChartView(props: ViewProps) {
|
||||
</ToggleButtonGroup>
|
||||
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", mb: 3 }}>
|
||||
<ToggleButtonGroup value={period} exclusive onChange={(_, v) => v && onPeriodChange(v)} size="small">
|
||||
<ToggleButtonGroup value={periodType} exclusive onChange={(_, v) => v && onPeriodTypeChange(v)} size="small">
|
||||
<ToggleButton value="rolling">Rolling</ToggleButton>
|
||||
<ToggleButton value="calendar" disabled={activeDataKey === "daily"}>
|
||||
Calendar
|
||||
|
||||
@@ -25,14 +25,57 @@ const toLabel = (start: string, end: string, type: "weekly" | "monthly") => {
|
||||
})}`;
|
||||
};
|
||||
|
||||
const getWeekOfMonth = (date: Date) => {
|
||||
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
|
||||
return Math.ceil((date.getDate() + firstDay.getDay()) / 7);
|
||||
};
|
||||
|
||||
const findCompareBucket = (
|
||||
current: ReportBucket,
|
||||
buckets: ReportBucket[],
|
||||
type: "weekly" | "monthly"
|
||||
): ReportBucket | undefined => {
|
||||
const start = new Date(current.start);
|
||||
|
||||
if (type === "monthly") {
|
||||
const targetYear = start.getFullYear() - 1;
|
||||
const targetMonth = start.getMonth();
|
||||
|
||||
return buckets.find(b => {
|
||||
const d = new Date(b.start);
|
||||
return (
|
||||
d.getFullYear() === targetYear &&
|
||||
d.getMonth() === targetMonth
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (type === "weekly") {
|
||||
const weekIndex = getWeekOfMonth(start); // you must define this
|
||||
const target = new Date(start);
|
||||
target.setMonth(target.getMonth() - 1);
|
||||
|
||||
return buckets.find(b => {
|
||||
const d = new Date(b.start);
|
||||
return (
|
||||
d.getFullYear() === target.getFullYear() &&
|
||||
d.getMonth() === target.getMonth() &&
|
||||
getWeekOfMonth(d) === weekIndex
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const toPoints = (
|
||||
buckets: ReportBucket[],
|
||||
type: "weekly" | "monthly",
|
||||
flow: "expenses" | "incomes"
|
||||
): ChartDataPoint[] => {
|
||||
return buckets.map((b, i) => {
|
||||
return buckets.map((b) => {
|
||||
const amount = sumBucket(b, flow);
|
||||
const prev = buckets[i - 1];
|
||||
const prev = findCompareBucket(b, buckets, type);
|
||||
|
||||
return {
|
||||
id: toLabel(b.start, b.end, type),
|
||||
|
||||
Reference in New Issue
Block a user