From 448195016fc433c0fe24d9eba46cf5b43973d333 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 16 Mar 2026 13:02:29 +0100 Subject: [PATCH] feat(02-01): create useMonthParam hook and MonthNavigator component - useMonthParam reads/writes month URL search param with YYYY-MM fallback - navigateMonth handles year rollover via Date constructor - MonthNavigator renders prev/next arrows with Select dropdown - Dropdown lists available budget months with locale-aware formatting --- src/components/dashboard/MonthNavigator.tsx | 60 +++++++++++++++++++++ src/hooks/useMonthParam.ts | 26 +++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/components/dashboard/MonthNavigator.tsx create mode 100644 src/hooks/useMonthParam.ts diff --git a/src/components/dashboard/MonthNavigator.tsx b/src/components/dashboard/MonthNavigator.tsx new file mode 100644 index 0000000..7da890e --- /dev/null +++ b/src/components/dashboard/MonthNavigator.tsx @@ -0,0 +1,60 @@ +import { ChevronLeft, ChevronRight } from "lucide-react" +import { Button } from "@/components/ui/button" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { useMonthParam } from "@/hooks/useMonthParam" + +interface MonthNavigatorProps { + availableMonths: string[] + t: (key: string) => string +} + +function formatMonthLabel(yyyyMm: string): string { + const [year, mo] = yyyyMm.split("-").map(Number) + const date = new Date(year, mo - 1, 1) + return date.toLocaleDateString(undefined, { month: "long", year: "numeric" }) +} + +export function MonthNavigator({ availableMonths, t: _t }: MonthNavigatorProps) { + const { month, setMonth, navigateMonth } = useMonthParam() + + return ( +
+ + + + + +
+ ) +} diff --git a/src/hooks/useMonthParam.ts b/src/hooks/useMonthParam.ts new file mode 100644 index 0000000..1c94a69 --- /dev/null +++ b/src/hooks/useMonthParam.ts @@ -0,0 +1,26 @@ +import { useSearchParams } from "react-router-dom" + +export function useMonthParam() { + const [searchParams, setSearchParams] = useSearchParams() + + const monthParam = searchParams.get("month") + const now = new Date() + const currentMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}` + const month = monthParam || currentMonth + + const setMonth = (newMonth: string) => { + setSearchParams((prev) => { + prev.set("month", newMonth) + return prev + }) + } + + const navigateMonth = (delta: number) => { + const [year, mo] = month.split("-").map(Number) + const d = new Date(year, mo - 1 + delta, 1) + const next = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}` + setMonth(next) + } + + return { month, setMonth, navigateMonth } +}