import { format } from 'date-fns' import dayjs from 'dayjs' import { ArrowRight, ChevronLeft, ChevronRight, Calendar } from 'lucide-react' import React, { useEffect, useState } from 'react' import DatePicker from 'react-datepicker' import type { DatePickerToFrom } from 'components/interfaces/Settings/Logs/Logs.types' import { Button, Popover, PopoverContent_Shadcn_, PopoverTrigger_Shadcn_, Popover_Shadcn_, } from 'ui' import { ButtonProps } from 'ui/src/components/Button/Button' import TimeSplitInput from './TimeSplitInput' export interface DatePickerProps { onChange?: (args: DatePickerToFrom) => void to?: string // ISO string from?: string // ISO string triggerButtonType?: ButtonProps['type'] triggerButtonClassName?: string triggerButtonTitle?: string minDate?: Date maxDate?: Date hideTime?: boolean hideClear?: boolean selectsRange?: boolean renderFooter?: (args: DatePickerToFrom) => React.ReactNode | void children?: React.ReactNode | React.ReactNode[] | null } const START_DATE_DEFAULT = new Date() const END_DATE_DEFAULT = new Date() const START_TIME_DEFAULT = { HH: '00', mm: '00', ss: '00' } const END_TIME_DEFAULT = { HH: '23', mm: '59', ss: '59' } function _DatePicker({ to, from, onChange, triggerButtonType = 'default', triggerButtonClassName = '', triggerButtonTitle, minDate, maxDate, hideTime = false, hideClear = false, selectsRange = true, renderFooter = () => null, children, }: DatePickerProps) { const [open, setOpen] = useState(false) const [appliedStartDate, setAppliedStartDate] = useState(null) const [appliedEndDate, setAppliedEndDate] = useState(null) const [startDate, setStartDate] = useState(START_DATE_DEFAULT) const [endDate, setEndDate] = useState(END_DATE_DEFAULT) const [startTime, setStartTime] = useState(START_TIME_DEFAULT) const [endTime, setEndTime] = useState(END_TIME_DEFAULT) useEffect(() => { if (!from) { setAppliedStartDate(null) } else if (from !== appliedStartDate?.toISOString()) { const start = dayjs(from) const startDate = start.toDate() setAppliedStartDate(startDate) setStartDate(startDate) setStartTime({ HH: start.format('HH'), mm: start.format('mm'), ss: start.format('ss'), }) } if (!to) { setAppliedEndDate(null) } else if (to !== appliedEndDate?.toISOString()) { const end = dayjs(to) const endDate = end.toDate() setAppliedEndDate(endDate) setEndDate(endDate) setEndTime({ HH: end.format('HH'), mm: end.format('mm'), ss: end.format('ss'), }) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [to, from]) function handleDatePickerChange(dates: Date | [from: Date | null, to: Date | null] | null) { if (!dates) { setStartDate(null) setEndDate(null) } else if (dates instanceof Date) { setStartDate(dates) setEndDate(dates) } else { const [from, to] = dates setStartDate(from) setEndDate(to) } } function handleSubmit() { setOpen(false) setAppliedStartDate(startDate) setAppliedEndDate(endDate) const payload = { from: dayjs(startDate) .second(Number(startTime.ss)) .minute(Number(startTime.mm)) .hour(Number(startTime.HH)) .toISOString(), to: dayjs(endDate || startDate) .second(Number(endTime.ss)) .minute(Number(endTime.mm)) .hour(Number(endTime.HH)) .toISOString(), } if (onChange) onChange(payload) } function handleClear() { setOpen(false) setStartDate(START_DATE_DEFAULT) setEndDate(END_DATE_DEFAULT) setStartTime(START_TIME_DEFAULT) setEndTime(END_TIME_DEFAULT) setAppliedStartDate(null) setAppliedEndDate(null) if (onChange) onChange({ from: null, to: null }) } return ( <> {hideTime ? null : ( <>
{!selectsRange ? null : ( <>
)}
)}
{ handleDatePickerChange(dates) }} dateFormat="MMMM d, yyyy h:mm aa" startDate={startDate} endDate={endDate} minDate={minDate} maxDate={maxDate} dayClassName={() => 'cursor-pointer'} renderCustomHeader={({ date, decreaseMonth, increaseMonth, prevMonthButtonDisabled, nextMonthButtonDisabled, }) => (
{format(date, 'MMMM yyyy')}
)} />
{renderFooter({ from: startDate?.toISOString() || null, to: endDate?.toISOString() || null, })}
{!hideClear && ( )}
) } export default _DatePicker