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