gitscope
← marzneshin / v0.3.0-alpha11 / dashboard/src/hooks/use-mutation-dialog/index.ts
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/hooks/use-mutation-dialog/index.ts · TypeScript
Blame Raw
 1
 2import { zodResolver } from "@hookform/resolvers/zod";
 3import { UseMutationResult } from "@tanstack/react-query";
 4import { useEffect } from "react";
 5import { FieldValues, SubmitHandler, useForm } from "react-hook-form";
 6import { ZodSchema } from "zod";
 7
 8interface IMutationDialog<TData, TError = unknown, TVariables = unknown> {
 9    entity: TData | null
10    onOpenChange: (s: boolean) => void
11    createMutation: UseMutationResult<TData, TError, TVariables>
12    updateMutation: UseMutationResult<TData, TError, TVariables>
13    schema: ZodSchema
14    getDefaultValue: () => FieldValues
15    loadFormtter?: (d: FieldValues) => FieldValues
16}
17
18/** useMutationDialog - Dialog mutation hook
19 *
20 * @param entity - Entity value for update, leave empty for creation 
21 * @param createMutation - react-query mutation hook for entity creation
22 * @param updateMutation - react-query mutation hook for entity edition
23 * @param entity - Entity value for update, leave empty for creation 
24 * @param schema - Entity schema validated by zodResolver
25 * @param getDefaultValue - Default value function return the default value for function
26 *  - Must be wrapped in useCallback to avoid infinite useEffect loop
27 * @param onOpenChange - Dialog state callback to change the dialog openness state
28 *
29 * @returns react-hook-form and submit handler 
30 *
31 * @template TData - Mutation Type of Schema
32 * @template TError = unknown 
33 * @template TVariables = unknown
34 */
35
36export const useMutationDialog = <TData, TError = unknown, TVariables = unknown>({
37    entity,
38    onOpenChange,
39    createMutation,
40    updateMutation,
41    schema,
42    getDefaultValue,
43    loadFormtter = (s) => s,
44}: IMutationDialog<TData, TError, TVariables>) => {
45
46    const form = useForm({
47        defaultValues: entity ? loadFormtter(entity) : getDefaultValue(),
48        resolver: zodResolver(schema)
49    });
50
51    const submit: SubmitHandler<FieldValues> = async (values) => {
52        if (entity) {
53            updateMutation.mutate(values as TVariables);
54        } else {
55            createMutation.mutate(values as TVariables);
56        }
57        onOpenChange(false);
58    };
59
60    useEffect(() => {
61        if (entity) {
62            form.reset(loadFormtter(entity))
63        } else {
64            form.reset(getDefaultValue());
65        }
66        // eslint-disable-next-line
67    }, [entity, form, getDefaultValue]);
68
69    const handleSubmit = form.handleSubmit(submit as SubmitHandler<FieldValues>);
70
71    return {
72        form,
73        handleSubmit
74    };
75};