From c5046d0043bd95cdea994808429fe577a8134015 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Tue, 30 Jan 2024 13:46:16 -0800 Subject: [PATCH] Refactored date navigation. --- src/components/hooks/useDateRange.ts | 7 +- src/components/input/DateFilter.tsx | 50 +++-- src/components/input/WebsiteDateFilter.tsx | 25 ++- src/lib/date.ts | 215 +++++++++++++-------- src/lib/types.ts | 5 +- 5 files changed, 181 insertions(+), 121 deletions(-) diff --git a/src/components/hooks/useDateRange.ts b/src/components/hooks/useDateRange.ts index 7e3b8bcb..e022d960 100644 --- a/src/components/hooks/useDateRange.ts +++ b/src/components/hooks/useDateRange.ts @@ -7,7 +7,7 @@ import { DateRange } from 'lib/types'; import { useLocale } from './useLocale'; import { useApi } from './queries/useApi'; -export function useDateRange(websiteId?: string) { +export function useDateRange(websiteId?: string): [DateRange, (value: string | DateRange) => void] { const { get } = useApi(); const { locale } = useLocale(); const websiteConfig = websiteStore(state => state[websiteId]?.dateRange); @@ -45,10 +45,7 @@ export function useDateRange(websiteId?: string) { } }; - return [dateRange, saveDateRange] as [ - { startDate: Date; endDate: Date; modified?: number; value?: string; unit?: string }, - (value: string | DateRange) => void, - ]; + return [dateRange, saveDateRange]; } export default useDateRange; diff --git a/src/components/input/DateFilter.tsx b/src/components/input/DateFilter.tsx index 767f5e40..1fabc735 100644 --- a/src/components/input/DateFilter.tsx +++ b/src/components/input/DateFilter.tsx @@ -5,12 +5,13 @@ import DatePickerForm from 'components/metrics/DatePickerForm'; import { useLocale } from 'components/hooks'; import { useMessages } from 'components/hooks'; import Icons from 'components/icons'; -import { formatDate } from 'lib/date'; +import { formatDate, parseDateValue } from 'lib/date'; export interface DateFilterProps { value: string; startDate: Date; endDate: Date; + offset: number; className?: string; onChange?: (value: string) => void; selectedUnit?: string; @@ -19,17 +20,18 @@ export interface DateFilterProps { } export function DateFilter({ - value, startDate, endDate, + value, + offset, className, onChange, - selectedUnit, showAllTime = false, alignment = 'end', }: DateFilterProps) { const { formatMessage, labels } = useMessages(); const [showPicker, setShowPicker] = useState(false); + const { locale } = useLocale(); const options = [ { label: formatMessage(labels.today), value: '1day' }, @@ -76,19 +78,6 @@ export function DateFilter({ }, ].filter(n => n); - const renderValue = (value: string) => { - return value.startsWith('range') ? ( - handleChange('custom')} - /> - ) : ( - options.find(e => e.value === value).label - ); - }; - const handleChange = (value: string) => { if (value === 'custom') { setShowPicker(true); @@ -104,6 +93,31 @@ export function DateFilter({ const handleClose = () => setShowPicker(false); + const renderValue = (value: string) => { + const { unit } = parseDateValue(value); + + if (offset && unit === 'year') { + return formatDate(startDate, 'yyyy', locale); + } + + if (offset && unit === 'month') { + return formatDate(startDate, 'MMMM yyyy', locale); + } + + if (value.startsWith('range') || offset) { + return ( + handleChange('custom')} + /> + ); + } + + return options.find(e => e.value === value).label; + }; + return ( <> { +const CustomRange = ({ startDate, endDate, unit, onClick }) => { const { locale } = useLocale(); - const monthFormat = +selectedUnit?.num === 1 && selectedUnit?.unit === 'month'; + const monthFormat = unit === 'month'; function handleClick(e) { e.stopPropagation(); diff --git a/src/components/input/WebsiteDateFilter.tsx b/src/components/input/WebsiteDateFilter.tsx index 03a84146..46df3623 100644 --- a/src/components/input/WebsiteDateFilter.tsx +++ b/src/components/input/WebsiteDateFilter.tsx @@ -1,36 +1,35 @@ import { useDateRange } from 'components/hooks'; import { isAfter } from 'date-fns'; -import { incrementDateRange } from 'lib/date'; +import { getOffsetDateRange } from 'lib/date'; import { Button, Icon, Icons } from 'react-basics'; import DateFilter from './DateFilter'; import styles from './WebsiteDateFilter.module.css'; +import { DateRange } from 'lib/types'; export function WebsiteDateFilter({ websiteId }: { websiteId: string }) { const [dateRange, setDateRange] = useDateRange(websiteId); - const { value, startDate, endDate, selectedUnit } = dateRange; - const isFutureDate = - value !== 'all' && - selectedUnit && - isAfter(incrementDateRange(dateRange, -1).startDate, new Date()); + const { value, startDate, endDate, offset } = dateRange; + const disableForward = + value === 'all' || isAfter(getOffsetDateRange(dateRange, 1).startDate, new Date()); - const handleChange = value => { + const handleChange = (value: string | DateRange) => { setDateRange(value); }; - const handleIncrement = value => { - setDateRange(incrementDateRange(dateRange, value)); + const handleIncrement = (increment: number) => { + setDateRange(getOffsetDateRange(dateRange, increment)); }; return (
- {value !== 'all' && selectedUnit && ( + {value !== 'all' && (
- -