/*********************************************************************************************************************************************************************** * File Name : DeadlinePicker.jsx * Type : Reusable Component * Description : Combined date + time picker for deadline fields. * Controlled via a single ISO datetime string (value / onChange). * Calendar + time input live inside a Card, matching shadcn's * "Date and Time Picker" pattern. * * Props: * value : string | null — ISO datetime string e.g. "2026-06-01T10:30" * onChange : (iso: string | null) => void * disabled?: boolean ***********************************************************************************************************************************************************************/ import { useState } from 'react'; import { format, parseISO, isValid } from 'date-fns'; import { ChevronDownIcon, Clock2Icon } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Calendar } from '@/components/ui/calendar'; import { Card, CardContent, CardFooter } from '@/components/ui/card'; import { Field, FieldGroup, FieldLabel } from '@/components/ui/field'; import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; // ── Helpers ─────────────────────────────────────────────────────────────────── function toDate(iso) { if (!iso) return undefined; const d = parseISO(iso); return isValid(d) ? d : undefined; } function toTimeString(iso) { if (!iso) return '00:00'; const d = parseISO(iso); if (!isValid(d)) return '00:00'; return format(d, 'HH:mm'); } function buildISO(date, timeStr) { if (!date) return null; const [h = '00', m = '00'] = (timeStr ?? '00:00').split(':'); const d = new Date(date); d.setHours(Number(h), Number(m), 0, 0); return d.toISOString(); } // ───────────────────────────────────────────────────────────────────────────── export default function DeadlinePicker({ value, onChange, disabled = false }) { const [open, setOpen] = useState(false); const selectedDate = toDate(value); const timeStr = toTimeString(value); const handleDateSelect = (date) => { onChange(buildISO(date, timeStr)); }; const handleTimeChange = (e) => { onChange(buildISO(selectedDate ?? new Date(), e.target.value)); }; const handleClear = () => onChange(null); return ( Time {value && ( )} ); }