import type {Path, UseFormProps, UseFormReturn} from 'react-hook-form' import {useForm} from 'react-hook-form' import type {ZodObject} from 'zod/v4' import {useActionState, useEffect} from 'react' import type {FormAction, FormActionDispatch, FormActionResponse} from '@/models/serverFunctions' import {standardSchemaResolver} from '@hookform/resolvers/standard-schema' import type {input, output} from 'zod' const initialFormState = { success: false, } type UseZodValidatedFormReturn = [ UseFormReturn, unknown, output>, FormActionDispatch, FormActionResponse, boolean, ] export function useZodValidatedForm( schema: Schema, action: FormAction, props?: UseFormProps, unknown, output>, ): UseZodValidatedFormReturn { const [state, dispatch, isPending] = useActionState(action, initialFormState as FormActionResponse) const form = useForm, unknown, output>({ resolver: standardSchemaResolver(schema), ...props, }) useEffect(() => { if (state?.submittedData) { // Reset the form with the data which was returned from the server. form.reset(state.submittedData as input) } if (state?.errors) { Object.keys(state.errors).forEach(field => form.setError(field === 'errors' ? 'root' : (field as Path>), { type: 'manual', message: state.errors![field]?.join(', '), }), ) } }, [state, form]) return [form, dispatch, state.data as FormActionResponse, isPending] }