📦 EqualifyEverything / equalify-dashboard

📄 report-form.tsx · 112 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import { useSubmit } from 'react-router-dom';
import { z } from 'zod';

import { Input } from '~/components/inputs';
import {
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  Form as HookFormProvider,
} from '..';
import ReportFilter from './report-filter';

const ReportSchema = z.object({
  reportName: z.string().min(1, 'Please enter a report name.'),
  filters: z.any(),
});

type ReportFormInputs = z.infer<typeof ReportSchema>;

interface ReportFormProps {
  actionUrl: string;
  defaultValues: ReportFormInputs;
  formId: 'create-report-form' | 'edit-report-form';
  onChange?: (
    event:
      | React.ChangeEvent<HTMLInputElement>
      | { target: { name: string; value: string } },
  ) => void;
  onFilterChange: () => void;
  error?: string;
}

const ReportForm: React.FC<ReportFormProps> = ({
  actionUrl,
  defaultValues,
  formId,
  onChange,
  onFilterChange,
  error,
}) => {
  const submit = useSubmit();
  const form = useForm<ReportFormInputs>({
    resolver: zodResolver(ReportSchema),
    defaultValues,
  });

  const handleChange = (
    event:
      | React.ChangeEvent<HTMLInputElement>
      | { target: { name: string; value: string } },
  ) => {
    form.setValue(
      event.target.name as keyof ReportFormInputs,
      event.target.value,
    );
    if (onChange) {
      onChange(event as unknown as React.ChangeEvent<HTMLInputElement>);
    }
  };

  return (
    <HookFormProvider {...form}>
      <form
        method="post"
        action={actionUrl}
        onSubmit={(event) => {
          const target = event.currentTarget;
          form.handleSubmit(() => {
            submit(target, { method: 'post' });
          })(event);
        }}
        id={formId}
      >
        <FormField
          control={form.control}
          name="reportName"
          render={({ field }) => (
            <FormItem>
              <FormLabel htmlFor="reportName">Report Name</FormLabel>
              <FormControl>
                <Input
                  type="text"
                  id="reportName"
                  className="h-12 bg-white"
                  {...field}
                  onChange={(event) => {
                    handleChange(event);
                    field.onChange(event);
                  }}
                />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <ReportFilter
          defaultFilters={defaultValues?.filters}
          onChange={handleChange}
          onFilterChange={onFilterChange}
          filterError={error}
        />
      </form>
    </HookFormProvider>
  );
};

export default ReportForm;