1import { FC, useEffect, useState } from 'react';
2import { format } from 'date-fns';
3import { CalendarIcon } from '@radix-ui/react-icons';
4import { cn } from '@marzneshin/utils';
5import { useFormContext, FieldValues } from 'react-hook-form';
6import { useTranslation } from 'react-i18next';
7import { Popover, PopoverTrigger, FormControl, Button, Calendar, PopoverContent, FormLabel, FormItem, FormField, FormMessage } from '@marzneshin/components';
8
9interface DateFieldProps {
10 name: keyof FieldValues;
11 label: string;
12}
13
14function parseISODate(isoDateString: string | undefined): Date | undefined {
15 if (!isoDateString) return undefined;
16 const date = new Date(isoDateString);
17 return isNaN(date.getTime()) ? undefined : date;
18}
19
20export const DateField: FC<DateFieldProps> = ({ name, label }) => {
21 const { t } = useTranslation();
22 const form = useFormContext();
23 const [selectedDate, setSelectedDate] = useState<Date | undefined>(parseISODate(form.getValues(name)));
24
25 useEffect(() => {
26 const newValue = selectedDate?.toISOString().slice(0, -5);
27 const prevValue = form.getValues(name);
28 if (newValue !== prevValue) {
29 form.setValue(name, newValue, { shouldValidate: true, shouldTouch: true });
30 }
31 }, [form, name, selectedDate]);
32
33 return (
34 <FormField
35 control={form.control}
36 name={name}
37 render={({ field }) => (
38 <FormItem className="flex flex-col mt-2 w-full">
39 <FormLabel>{t(label)}</FormLabel>
40 <Popover>
41 <PopoverTrigger asChild>
42 <FormControl>
43 <Button
44 variant={"outline"}
45 className={cn(
46 "w-full pl-3 text-left font-normal",
47 !field.value && "text-muted-foreground"
48 )}
49 >
50 {field.value ? (
51 format(field.value + 'Z', "PPP")
52 ) : (
53 <span>Pick a date</span>
54 )}
55 <CalendarIcon className="ml-auto w-4 h-4 opacity-50" />
56 </Button>
57 </FormControl>
58 </PopoverTrigger>
59 <PopoverContent className="p-0 w-auto" align="start">
60 <Calendar
61 mode="single"
62 {...field}
63 selected={selectedDate}
64 onSelect={(date) => {
65 setSelectedDate(date);
66 }}
67 disabled={(date) =>
68 date < new Date()
69 }
70 initialFocus
71 />
72 </PopoverContent>
73 </Popover>
74 <FormMessage />
75 </FormItem>
76 )}
77 />
78 );
79};