diff options
| author | Fuwn <[email protected]> | 2026-01-24 13:09:50 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-01-24 13:09:50 +0000 |
| commit | 396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b (patch) | |
| tree | b9df4ca6a70db45cfffbae6fdd7252e20fb8e93c /src/components/metrics/DatePickerForm.tsx | |
| download | umami-396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b.tar.xz umami-396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b.zip | |
Created from https://vercel.com/new
Diffstat (limited to 'src/components/metrics/DatePickerForm.tsx')
| -rw-r--r-- | src/components/metrics/DatePickerForm.tsx | 74 |
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> + ); +} |