import { useEffect, useState } from 'react' import { cn } from '@/lib/utils' import type { ComponentPropsWithoutRef, FC, FocusEvent } from 'react' const pad = (n: number): string => n.toString ().padStart (2, '0') const toDateTimeLocalValue = (value: Date, seconds = false) => { const y = value.getFullYear () const m = pad (value.getMonth () + 1) const day = pad (value.getDate ()) const h = pad (value.getHours ()) const min = pad (value.getMinutes ()) return `${ y }-${ m }-${ day }T${ h }:${ min }${seconds ? `:${pad (value.getSeconds ())}` : ''}` } const toMinutePrecisionIsoUtc = (value: string) => { const date = new Date (value) if (Number.isNaN (date.getTime ())) return value const y = date.getUTCFullYear () const m = pad (date.getUTCMonth () + 1) const day = pad (date.getUTCDate ()) const h = pad (date.getUTCHours ()) const min = pad (date.getUTCMinutes ()) return `${ y }-${ m }-${ day }T${ h }:${ min }Z` } type Props = Omit, 'onChange'> & { value?: string onChange?: (isoUTC: string | null) => void className?: string onBlur?: (ev: FocusEvent) => void invalid?: boolean precision?: 'minute' | 'second' } const DateTimeField: FC = props => { const { value, onChange, className, onBlur, invalid, precision = 'minute', ...rest } = props const [local, setLocal] = useState ('') useEffect (() => { setLocal (value ? toDateTimeLocalValue (new Date (value), precision === 'second') : '') }, [value, precision]) return ( { const v = ev.target.value setLocal (v) const iso = v ? (precision === 'second' ? new Date (v).toISOString () : toMinutePrecisionIsoUtc (v)) : null onChange?.(iso) }} onBlur={onBlur}/>) } export default DateTimeField export { toMinutePrecisionIsoUtc }