import * as React from "react"; import { format } from "date-fns"; import { CalendarIcon } from "lucide-react"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { DatePicker } from "@/components/ui/date-picker"; import { MonthYearPicker } from "@/components/ui/month-year-picker"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { toDateOnly, toDateWithPrecision } from "@/lib/dateUtils"; export type DatePrecision = 'day' | 'month' | 'year'; interface FlexibleDateInputProps { value?: Date; precision?: DatePrecision; onChange: (date: Date | undefined, precision: DatePrecision) => void; placeholder?: string; disabled?: boolean; className?: string; disableFuture?: boolean; disablePast?: boolean; fromYear?: number; toYear?: number; label?: string; } export function FlexibleDateInput({ value, precision = 'day', onChange, placeholder = "Select date", disabled = false, className, disableFuture = false, disablePast = false, fromYear = 1800, toYear = new Date().getFullYear() + 10, label, }: FlexibleDateInputProps) { const [localPrecision, setLocalPrecision] = React.useState(precision); const [yearValue, setYearValue] = React.useState( value && precision === 'year' ? value.getFullYear().toString() : '' ); React.useEffect(() => { setLocalPrecision(precision); }, [precision]); React.useEffect(() => { if (value && precision === 'year') { setYearValue(value.getFullYear().toString()); } }, [value, precision]); const handlePrecisionChange = (newPrecision: DatePrecision) => { setLocalPrecision(newPrecision); // If we have a value, adjust it to the new precision if (value) { const year = value.getFullYear(); const month = value.getMonth(); let newDate: Date; switch (newPrecision) { case 'year': newDate = new Date(year, 0, 1); // January 1st (local timezone) setYearValue(year.toString()); break; case 'month': newDate = new Date(year, month, 1); // 1st of month (local timezone) break; case 'day': default: newDate = value; // Keep existing date break; } onChange(newDate, newPrecision); } else { onChange(undefined, newPrecision); } }; const handleYearChange = (e: React.ChangeEvent) => { const yearStr = e.target.value; setYearValue(yearStr); const yearNum = parseInt(yearStr, 10); if (yearStr && !isNaN(yearNum) && yearNum >= fromYear && yearNum <= toYear) { const newDate = new Date(yearNum, 0, 1); onChange(newDate, 'year'); } else if (!yearStr) { onChange(undefined, 'year'); } }; const getPlaceholderText = () => { switch (localPrecision) { case 'year': return 'Enter year (e.g., 2005)'; case 'month': return 'Select month and year'; case 'day': default: return placeholder; } }; return (
{label && }
{localPrecision === 'day' && ( onChange(date, 'day')} placeholder={getPlaceholderText()} disabled={disabled} disableFuture={disableFuture} disablePast={disablePast} fromYear={fromYear} toYear={toYear} /> )} {localPrecision === 'month' && ( onChange(date, 'month')} placeholder={getPlaceholderText()} disabled={disabled} fromYear={fromYear} toYear={toYear} /> )} {localPrecision === 'year' && ( )}
); }