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