gitscope
← marzneshin / v0.3.0-alpha / dashboard/src/features/users/components/date-field.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/users/components/date-field.tsx · TypeScript
Blame Raw
 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, "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};