"use client"; import { CalendarIcon } from "@/assets/icons"; import { cn } from "@/lib/utils"; import { Control, Controller, FieldValues, Path, RegisterOptions, } from "react-hook-form"; import MultiDatePicker, { DateObject } from "react-multi-date-picker"; import TimePicker from "react-multi-date-picker/plugins/time_picker"; interface IProps { control: Control; name: Path; label: string; placeholder?: string; required?: boolean; multiple?: boolean; range?: boolean; onlyMonthPicker?: boolean; onlyYearPicker?: boolean; minDate?: number; maxDate?: number; timePicker?: boolean; clearable?: boolean; rules?: Omit< RegisterOptions>, "valueAsNumber" | "valueAsDate" | "setValueAs" | "disabled" >; } const DatePicker = ({ control, name, label, multiple = false, placeholder, required, range = false, timePicker = false, onlyMonthPicker = false, onlyYearPicker = false, rules, maxDate, minDate, clearable = false, }: IProps) => { return (
{ const error = errors[name]; const toUnixSeconds = (v: unknown): number | null => { if (v === "" || v === undefined || v === null) return null; const n = typeof v === "number" ? v : Number(v); return Number.isFinite(n) ? n : null; }; const toPickerValue = (): | DateObject | DateObject[] | undefined => { if (value === "" || value === undefined || value === null) { return undefined; } if (multiple && Array.isArray(value)) { const secs = value .map(toUnixSeconds) .filter((s): s is number => s !== null); if (!secs.length) return undefined; return secs.map((unix) => new DateObject(new Date(unix * 1000))); } if (range && Array.isArray(value)) { const secs = value .map(toUnixSeconds) .filter((s): s is number => s !== null); if (!secs.length) return undefined; return secs.map((unix) => new DateObject(new Date(unix * 1000))); } if (range && !Array.isArray(value)) { return undefined; } const unix = toUnixSeconds(value); if (unix === null) return undefined; return new DateObject(new Date(unix * 1000)); }; const pickerValue = toPickerValue(); const hasValue = pickerValue !== undefined && (Array.isArray(pickerValue) ? pickerValue.length > 0 : true); return ( <>
] : [] } onlyYearPicker={onlyYearPicker} multiple={multiple} value={pickerValue} onChange={(date: DateObject | DateObject[] | null) => { if (!date) { onChange(""); return; } if (Array.isArray(date)) { const unixTimestamps = date.map((d) => d.toUnix()); onChange(unixTimestamps); } else if (date instanceof DateObject) { onChange(date.isValid ? date.toUnix() : ""); } }} format={`YYYY/MM/DD ${timePicker ? "HH:mm" : ""}`} containerClassName="w-full" inputClass={cn( "w-full rounded-xl border border-stroke/70 bg-white/90 px-5.5 py-3 pl-12.5 text-dark shadow-[0_1px_2px_rgba(16,24,40,0.04),0_8px_20px_rgba(16,24,40,0.04)] outline-none backdrop-blur-[1px] transition-all duration-200 focus:border-primary/70 focus:bg-white focus:shadow-[0_0_0_2px_rgba(59,130,246,0.14),0_10px_24px_rgba(59,130,246,0.08)] disabled:cursor-default disabled:bg-gray-2/70 dark:border-dark-3/80 dark:bg-dark-2/85 dark:text-white dark:focus:border-primary/80 dark:focus:shadow-[0_0_0_2px_rgba(59,130,246,0.2),0_10px_24px_rgba(15,23,42,0.45)] dark:disabled:bg-dark", clearable && hasValue && "pr-11", error && "border-red/80 focus:border-red focus:shadow-[0_0_0_2px_rgba(239,68,68,0.16),0_10px_24px_rgba(239,68,68,0.1)] dark:border-red/80 dark:focus:shadow-[0_0_0_2px_rgba(239,68,68,0.24),0_10px_24px_rgba(127,29,29,0.45)]", )} placeholder={placeholder} /> {clearable && hasValue && ( )}
{error && (

{error.message as string}

)} ); }} />
); }; export default DatePicker;