/** * Simple Zod Form Hook for React * Just uses Zod as-is with React state management */ import { useState, useCallback } from 'react'; import { ZodSchema, ZodError } from 'zod'; export interface ZodFormOptions { schema: ZodSchema; initialValues: T; onSubmit?: (data: T) => Promise | void; } export function useZodForm>({ schema, initialValues, onSubmit }: ZodFormOptions) { const [values, setValues] = useState(initialValues); const [errors, setErrors] = useState>>({}); const [isSubmitting, setIsSubmitting] = useState(false); const validate = useCallback(() => { try { schema.parse(values); setErrors({}); return true; } catch (error) { if (error instanceof ZodError) { const fieldErrors: Partial> = {}; error.issues.forEach(issue => { const field = issue.path[0] as keyof T; if (field) { fieldErrors[field] = issue.message; } }); setErrors(fieldErrors); } return false; } }, [schema, values]); const setValue = useCallback((field: K, value: T[K]) => { setValues(prev => ({ ...prev, [field]: value })); // Clear error when user starts typing if (errors[field]) { setErrors(prev => ({ ...prev, [field]: undefined })); } }, [errors]); const handleSubmit = useCallback(async (e?: React.FormEvent) => { if (e) e.preventDefault(); if (!validate()) return; if (!onSubmit) return; setIsSubmitting(true); try { await onSubmit(values); } catch (error) { // Form submission error - logging handled by consuming application } finally { setIsSubmitting(false); } }, [validate, onSubmit, values]); const reset = useCallback(() => { setValues(initialValues); setErrors({}); setIsSubmitting(false); }, [initialValues]); return { values, errors, isSubmitting, setValue, handleSubmit, reset, validate }; }