aboutsummaryrefslogtreecommitdiff
path: root/src/components/metrics/DatePickerForm.tsx
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-01-24 13:09:50 +0000
committerFuwn <[email protected]>2026-01-24 13:09:50 +0000
commit396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b (patch)
treeb9df4ca6a70db45cfffbae6fdd7252e20fb8e93c /src/components/metrics/DatePickerForm.tsx
downloadumami-396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b.tar.xz
umami-396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b.zip
Initial commitHEADmain
Created from https://vercel.com/new
Diffstat (limited to 'src/components/metrics/DatePickerForm.tsx')
-rw-r--r--src/components/metrics/DatePickerForm.tsx74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/components/metrics/DatePickerForm.tsx b/src/components/metrics/DatePickerForm.tsx
new file mode 100644
index 0000000..59d1709
--- /dev/null
+++ b/src/components/metrics/DatePickerForm.tsx
@@ -0,0 +1,74 @@
+import { Button, Calendar, Column, Row, ToggleGroup, ToggleGroupItem } from '@umami/react-zen';
+import { endOfDay, isAfter, isBefore, isSameDay, startOfDay } from 'date-fns';
+import { useState } from 'react';
+import { useMessages } from '@/components/hooks';
+
+const FILTER_DAY = 'filter-day';
+const FILTER_RANGE = 'filter-range';
+
+export function DatePickerForm({
+ startDate: defaultStartDate,
+ endDate: defaultEndDate,
+ minDate,
+ maxDate,
+ onChange,
+ onClose,
+}) {
+ const [selected, setSelected] = useState<any>([
+ isSameDay(defaultStartDate, defaultEndDate) ? FILTER_DAY : FILTER_RANGE,
+ ]);
+ const [date, setDate] = useState(defaultStartDate || new Date());
+ const [startDate, setStartDate] = useState(defaultStartDate || new Date());
+ const [endDate, setEndDate] = useState(defaultEndDate || new Date());
+ const { formatMessage, labels } = useMessages();
+
+ const disabled = selected.includes(FILTER_DAY)
+ ? isAfter(minDate, date) && isBefore(maxDate, date)
+ : isAfter(startDate, endDate);
+
+ const handleSave = () => {
+ if (selected.includes(FILTER_DAY)) {
+ onChange(`range:${startOfDay(date).getTime()}:${endOfDay(date).getTime()}`);
+ } else {
+ onChange(`range:${startOfDay(startDate).getTime()}:${endOfDay(endDate).getTime()}`);
+ }
+ };
+
+ return (
+ <Column gap>
+ <Row justifyContent="center">
+ <ToggleGroup disallowEmptySelection value={selected} onChange={setSelected}>
+ <ToggleGroupItem id={FILTER_DAY}>{formatMessage(labels.singleDay)}</ToggleGroupItem>
+ <ToggleGroupItem id={FILTER_RANGE}>{formatMessage(labels.dateRange)}</ToggleGroupItem>
+ </ToggleGroup>
+ </Row>
+ <Column>
+ {selected.includes(FILTER_DAY) && (
+ <Calendar value={date} minValue={minDate} maxValue={maxDate} onChange={setDate} />
+ )}
+ {selected.includes(FILTER_RANGE) && (
+ <Row gap wrap="wrap" style={{ margin: '0 auto' }}>
+ <Calendar
+ value={startDate}
+ minValue={minDate}
+ maxValue={endDate}
+ onChange={setStartDate}
+ />
+ <Calendar
+ value={endDate}
+ minValue={startDate}
+ maxValue={maxDate}
+ onChange={setEndDate}
+ />
+ </Row>
+ )}
+ </Column>
+ <Row justifyContent="end" gap>
+ <Button onPress={onClose}>{formatMessage(labels.cancel)}</Button>
+ <Button variant="primary" onPress={handleSave} isDisabled={disabled}>
+ {formatMessage(labels.apply)}
+ </Button>
+ </Row>
+ </Column>
+ );
+}