From 58b47318e9c8f8b304a5d01d484473e0941eb438 Mon Sep 17 00:00:00 2001 From: Nathnael Date: Thu, 13 Aug 2026 08:45:29 +0000 Subject: [PATCH] feat(freight-backoffice): consolidate Mantine from/to date filters into range pickers Replaces every remaining split from/to Mantine DateInput/DatePickerInput pair with a single DatePickerInput type="range", sharing one preset list (Today, Last 7/30 days, this/last month, YTD) via getDateRangePresets(). Covers ListControls (18 consumers), FleetResourcePage, ContractRequestsPage, BookingRequestsPage (created + scheduled ranges), WagonCancellationsPage, BatchBoardPage, ClearanceDocumentsPage, ShipmentRequestsPage. Native Mantine range picker, not the shadcn DateRangePicker, to match each page's existing design system instead of clashing with it. Reports date-range filter (ReportFilters.tsx) intentionally left untouched. --- .../src/components/common/ListControls.tsx | 36 +++++------ .../src/components/common/dateRangePresets.ts | 41 +++++++++++++ .../pages/bookings/BookingRequestsPage.tsx | 59 +++++++------------ .../pages/bookings/WagonCancellationsPage.tsx | 31 ++++------ .../contracts/ClearanceDocumentsPage.tsx | 34 ++++------- .../pages/contracts/ContractRequestsPage.tsx | 34 ++++------- .../pages/contracts/ShipmentRequestsPage.tsx | 31 ++++------ .../src/pages/fleet/FleetResourcePage.tsx | 28 ++++----- .../pages/trainScheduling/BatchBoardPage.tsx | 28 ++++----- 9 files changed, 146 insertions(+), 176 deletions(-) create mode 100644 apps/edr-freight-web/backoffice/src/components/common/dateRangePresets.ts diff --git a/apps/edr-freight-web/backoffice/src/components/common/ListControls.tsx b/apps/edr-freight-web/backoffice/src/components/common/ListControls.tsx index 92ab514ad..8ca604ba4 100644 --- a/apps/edr-freight-web/backoffice/src/components/common/ListControls.tsx +++ b/apps/edr-freight-web/backoffice/src/components/common/ListControls.tsx @@ -2,6 +2,7 @@ import { Button, Group, TextInput } from "@mantine/core"; import { DatePickerInput } from "@mantine/dates"; import { Search, X } from "lucide-react"; import type { ReactNode } from "react"; +import { getDateRangePresets } from "./dateRangePresets"; export interface ListControlsProps { search: string; @@ -54,28 +55,19 @@ const ListControls = ({ )} {showDateRange && ( - <> - - - + { + onDateFromChange(from); + onDateToChange(to); + }} + presets={getDateRangePresets()} + clearable + w={230} + /> )} {children} diff --git a/apps/edr-freight-web/backoffice/src/components/common/dateRangePresets.ts b/apps/edr-freight-web/backoffice/src/components/common/dateRangePresets.ts new file mode 100644 index 000000000..e59e3bb84 --- /dev/null +++ b/apps/edr-freight-web/backoffice/src/components/common/dateRangePresets.ts @@ -0,0 +1,41 @@ +import { + format, + startOfDay, + endOfDay, + startOfMonth, + endOfMonth, + startOfYear, + subDays, + subMonths, +} from "date-fns"; +import type { DatePickerPreset } from "@mantine/dates"; + +const iso = (date: Date) => format(date, "yyyy-MM-dd"); + +/** + * Shared "Today / Last 7 days / …" presets for every Mantine + * `` in the app, + * so every from/to filter offers the same shortcuts. Computed fresh per call + * (not a module-level constant) so "Today" stays today. + */ +export function getDateRangePresets(): DatePickerPreset<"range">[] { + const today = new Date(); + return [ + { label: "Today", value: [iso(startOfDay(today)), iso(endOfDay(today))] }, + { + label: "Yesterday", + value: [iso(startOfDay(subDays(today, 1))), iso(endOfDay(subDays(today, 1)))], + }, + { label: "Last 7 days", value: [iso(startOfDay(subDays(today, 6))), iso(endOfDay(today))] }, + { label: "Last 30 days", value: [iso(startOfDay(subDays(today, 29))), iso(endOfDay(today))] }, + { label: "This month", value: [iso(startOfMonth(today)), iso(endOfDay(today))] }, + { + label: "Last month", + value: [ + iso(startOfMonth(subMonths(today, 1))), + iso(endOfMonth(subMonths(today, 1))), + ], + }, + { label: "Year to date", value: [iso(startOfYear(today)), iso(endOfDay(today))] }, + ]; +} diff --git a/apps/edr-freight-web/backoffice/src/pages/bookings/BookingRequestsPage.tsx b/apps/edr-freight-web/backoffice/src/pages/bookings/BookingRequestsPage.tsx index 91eb52033..d55c45c3a 100644 --- a/apps/edr-freight-web/backoffice/src/pages/bookings/BookingRequestsPage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/bookings/BookingRequestsPage.tsx @@ -13,7 +13,8 @@ import { Text, TextInput, } from "@mantine/core"; -import { DateInput } from "@mantine/dates"; +import { DatePickerInput } from "@mantine/dates"; +import { getDateRangePresets } from "@/components/common/dateRangePresets"; import { useDebouncedValue } from "@mantine/hooks"; import { AlertTriangle, @@ -764,53 +765,33 @@ export default function BookingRequestsPage() { radius="lg" style={{ minWidth: 140 }} /> - { - setCreatedFrom(v ? new Date(v) : null); + { + setCreatedFrom(from ? new Date(from) : null); + setCreatedTo(to ? new Date(to) : null); resetPage(); }} - maxDate={createdTo ?? undefined} + presets={getDateRangePresets()} clearable radius="lg" - style={{ minWidth: 140 }} + style={{ minWidth: 220 }} /> - { - setCreatedTo(v ? new Date(v) : null); + { + setScheduledFrom(from ? new Date(from) : null); + setScheduledTo(to ? new Date(to) : null); resetPage(); }} - minDate={createdFrom ?? undefined} + presets={getDateRangePresets()} clearable radius="lg" - style={{ minWidth: 140 }} - /> - { - setScheduledFrom(v ? new Date(v) : null); - resetPage(); - }} - maxDate={scheduledTo ?? undefined} - clearable - radius="lg" - style={{ minWidth: 150 }} - /> - { - setScheduledTo(v ? new Date(v) : null); - resetPage(); - }} - minDate={scheduledFrom ?? undefined} - clearable - radius="lg" - style={{ minWidth: 150 }} + style={{ minWidth: 230 }} /> {activeFilterCount > 0 ? (