gitscope
← marzneshin / v0.3.0-alpha9 / 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}
16
17/** useMutationDialog - Dialog mutation hook
18 *
19 * @param entity - Entity value for update, leave empty for creation 
20 * @param createMutation - react-query mutation hook for entity creation
21 * @param updateMutation - react-query mutation hook for entity edition
22 * @param entity - Entity value for update, leave empty for creation 
23 * @param schema - Entity schema validated by zodResolver
24 * @param getDefaultValue - Default value function return the default value for function
25 *  - Must be wrapped in useCallback to avoid infinite useEffect loop
26 * @param onOpenChange - Dialog state callback to change the dialog openness state
27 *
28 * @returns react-hook-form and submit handler 
29 *
30 * @template TData - Mutation Type of Schema
31 * @template TError = unknown 
32 * @template TVariables = unknown
33 */
34
35export const useMutationDialog = <TData, TError = unknown, TVariables = unknown>({
36    entity,
37    onOpenChange,
38    createMutation,
39    updateMutation,
40    schema,
41    getDefaultValue,
42}: IMutationDialog<TData, TError, TVariables>) => {
43    const form = useForm({
44        defaultValues: entity ? (entity as FieldValues) : (getDefaultValue()),
45        resolver: zodResolver(schema)
46    });
47
48    const submit: SubmitHandler<FieldValues> = async (values) => {
49        if (entity) {
50            updateMutation.mutate(values as TVariables);
51        } else {
52            createMutation.mutate(values as TVariables);
53        }
54        onOpenChange(false);
55    };
56
57    useEffect(() => {
58        if (entity) {
59            form.reset(entity)
60        } else {
61            form.reset(getDefaultValue());
62        }
63    }, [entity, form, getDefaultValue]);
64
65    const handleSubmit = form.handleSubmit(submit as SubmitHandler<FieldValues>);
66
67    return {
68        form,
69        handleSubmit
70    };
71};