'use client'; import { zodResolver } from '@hookform/resolvers/zod'; import { useCallback } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { toast } from 'sonner'; import { z } from 'zod'; import type { Client } from '@/types'; import { useSaveClientMutation } from './useClientMutations'; const phoneSchema = z .string() .trim() .min(1, 'Phone number is required') .regex(/^\+(?:[0-9] ?|-){6,18}[0-9]$/, 'Please enter a valid phone number'); const optionalTaxIdSchema = z.string().trim(); const clientFormSchema = z.object({ id: z.number().optional(), name: z.string().trim().min(1, 'Client name is required'), email: z.string().trim().min(1, 'Email is required').email('Invalid email'), landline_number: phoneSchema, address: z.string().trim().min(1, 'Address is required'), gst: optionalTaxIdSchema, pan: optionalTaxIdSchema, tan: optionalTaxIdSchema, contact_name: z.string().trim().min(1, 'Contact name is required'), contact_phone_number: phoneSchema, contact_email: z .string() .trim() .min(1, 'Contact email is required') .email('Invalid contact email'), is_active: z.boolean(), }); export type ClientFormValues = z.infer; const defaultValues: ClientFormValues = { name: '', email: '', landline_number: '', address: '', gst: '', pan: '', tan: '', contact_name: '', contact_phone_number: '', contact_email: '', is_active: true, }; export function useClientForm({ onSaved }: { onSaved: () => void }) { const { register, handleSubmit: submitForm, reset, control, formState: { isSubmitting, errors, isSubmitted }, } = useForm({ defaultValues, mode: 'onSubmit', reValidateMode: 'onChange', resolver: zodResolver(clientFormSchema), }); const saveMutation = useSaveClientMutation({ onSaved: () => { reset(defaultValues); onSaved(); }, }); const clientId = useWatch({ control, name: 'id' }); const name = useWatch({ control, name: 'name' }) || ''; const email = useWatch({ control, name: 'email' }) || ''; const landlineNumber = useWatch({ control, name: 'landline_number' }) || ''; const address = useWatch({ control, name: 'address' }) || ''; const contactName = useWatch({ control, name: 'contact_name' }) || ''; const contactPhoneNumber = useWatch({ control, name: 'contact_phone_number' }) || ''; const contactEmail = useWatch({ control, name: 'contact_email' }) || ''; const canSubmit = name.trim().length > 0 && email.trim().length > 0 && landlineNumber.trim().length > 0 && address.trim().length > 0 && contactName.trim().length > 0 && contactPhoneNumber.trim().length > 0 && contactEmail.trim().length > 0; const handleSubmit = submitForm( (values) => saveMutation.mutate(values), (formErrors) => { const firstError = Object.values(formErrors).find( (error) => error?.message, ); if (firstError?.message) { toast.error(firstError.message); } }, ); const openCreate = useCallback(() => { reset(defaultValues); }, [reset]); const openEdit = useCallback( (client: Client) => { reset({ id: client.id, name: client.name || '', email: client.email || '', landline_number: client.landline_number || '', address: client.address || '', gst: client.gst || '', pan: client.pan || '', tan: client.tan || '', contact_name: client.contact_name || '', contact_phone_number: client.contact_phone_number || '', contact_email: client.contact_email || '', is_active: client.is_active, }); }, [reset], ); return { register, handleSubmit, reset, openCreate, openEdit, clientId, errors, isSubmitted, canSubmit, isSaving: isSubmitting || saveMutation.isPending, }; }