From 6bfbed8fb69c59fb752995778130d0da0abc1d59 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 13 Sep 2025 20:56:57 +0000 Subject: [PATCH] Fix date parsing and add time period filters to Analytics dashboard Co-authored-by: elisiariocouto <818914+elisiariocouto@users.noreply.github.com> --- .../src/components/analytics/BalanceChart.tsx | 12 +++--- .../components/analytics/MonthlyTrends.tsx | 10 ++--- .../components/analytics/TimePeriodFilter.tsx | 39 +++++++++++++++++++ frontend/src/lib/timePeriods.ts | 19 +++++++++ frontend/src/routes/analytics.tsx | 26 ++++++++++--- 5 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 frontend/src/components/analytics/TimePeriodFilter.tsx create mode 100644 frontend/src/lib/timePeriods.ts diff --git a/frontend/src/components/analytics/BalanceChart.tsx b/frontend/src/components/analytics/BalanceChart.tsx index 9eba397..897a194 100644 --- a/frontend/src/components/analytics/BalanceChart.tsx +++ b/frontend/src/components/analytics/BalanceChart.tsx @@ -59,11 +59,11 @@ export default function BalanceChart({ data, accounts, className }: BalanceChart const chartData = data .filter((balance) => balance.balance_type === "closingBooked") .map((balance) => ({ - date: new Date(balance.reference_date).toLocaleDateString(), + date: new Date(balance.reference_date).toLocaleDateString('en-GB'), // DD/MM/YYYY format balance: balance.balance_amount, account_id: balance.account_id, })) - .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()); + .sort((a, b) => new Date(a.date.split('/').reverse().join('/')).getTime() - new Date(b.date.split('/').reverse().join('/')).getTime()); // Group by account and aggregate const accountBalances: { [key: string]: ChartDataPoint[] } = {}; @@ -86,7 +86,7 @@ export default function BalanceChart({ data, accounts, className }: BalanceChart }); const finalData = Object.values(aggregatedData).sort( - (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime() + (a, b) => new Date(a.date.split('/').reverse().join('/')).getTime() - new Date(b.date.split('/').reverse().join('/')).getTime() ); const colors = ["#3B82F6", "#10B981", "#F59E0B", "#EF4444", "#8B5CF6"]; @@ -117,8 +117,10 @@ export default function BalanceChart({ data, accounts, className }: BalanceChart dataKey="date" tick={{ fontSize: 12 }} tickFormatter={(value) => { - const date = new Date(value); - return date.toLocaleDateString(undefined, { + // Convert DD/MM/YYYY back to a proper date for formatting + const [day, month, year] = value.split('/'); + const date = new Date(year, month - 1, day); + return date.toLocaleDateString('en-GB', { month: "short", day: "numeric", }); diff --git a/frontend/src/components/analytics/MonthlyTrends.tsx b/frontend/src/components/analytics/MonthlyTrends.tsx index 800f0ec..7e88454 100644 --- a/frontend/src/components/analytics/MonthlyTrends.tsx +++ b/frontend/src/components/analytics/MonthlyTrends.tsx @@ -12,6 +12,7 @@ import apiClient from "../../lib/api"; interface MonthlyTrendsProps { className?: string; + days?: number; } interface MonthlyData { @@ -31,13 +32,12 @@ interface TooltipProps { label?: string; } -export default function MonthlyTrends({ className }: MonthlyTrendsProps) { - // Get transactions for the last 12 months using analytics endpoint +export default function MonthlyTrends({ className, days = 365 }: MonthlyTrendsProps) { + // Get transactions for the specified period using analytics endpoint const { data: transactions, isLoading } = useQuery({ - queryKey: ["transactions", "monthly-trends"], + queryKey: ["transactions", "monthly-trends", days], queryFn: async () => { - // Get last 365 days of transactions for monthly trends - return await apiClient.getTransactionsForAnalytics(365); + return await apiClient.getTransactionsForAnalytics(days); }, }); diff --git a/frontend/src/components/analytics/TimePeriodFilter.tsx b/frontend/src/components/analytics/TimePeriodFilter.tsx new file mode 100644 index 0000000..e9ecdec --- /dev/null +++ b/frontend/src/components/analytics/TimePeriodFilter.tsx @@ -0,0 +1,39 @@ +import { Calendar } from "lucide-react"; +import type { TimePeriod } from "../../lib/timePeriods"; +import { TIME_PERIODS } from "../../lib/timePeriods"; + +interface TimePeriodFilterProps { + selectedPeriod: TimePeriod; + onPeriodChange: (period: TimePeriod) => void; + className?: string; +} + +export default function TimePeriodFilter({ + selectedPeriod, + onPeriodChange, + className = "", +}: TimePeriodFilterProps) { + return ( +