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