'use client'; import { useCallback } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { toast } from 'sonner'; import type { Tenant } from '@/types'; import { useSaveTenantMutation } from './useTenantMutations'; export interface TenantFormValues { id?: number; name: string; slug: string; client_id: string; plan_id: string; domain: string; description: string; admin_first_name: string; admin_last_name: string; admin_email: string; admin_phone_number: string; } const defaultValues: TenantFormValues = { name: '', slug: '', client_id: '', plan_id: '', domain: '', description: '', admin_first_name: '', admin_last_name: '', admin_email: '', admin_phone_number: '', }; function createSlug(value: string) { return value .trim() .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, ''); } function splitContactName(contactName: string) { const parts = contactName.trim().split(/\s+/).filter(Boolean); if (parts.length === 0) return { firstName: '', lastName: '' }; if (parts.length === 1) return { firstName: parts[0], lastName: '' }; return { firstName: parts[0], lastName: parts.slice(1).join(' ') }; } export function useTenantForm({ onSaved }: { onSaved: () => void }) { const { register, handleSubmit: submitForm, reset, control, setValue, formState: { isSubmitting }, } = useForm({ defaultValues, }); const saveMutation = useSaveTenantMutation({ onSaved: () => { reset(defaultValues); onSaved(); }, }); const tenantId = useWatch({ control, name: 'id' }); const clientId = useWatch({ control, name: 'client_id' }) || ''; const planId = useWatch({ control, name: 'plan_id' }) || ''; const adminEmail = useWatch({ control, name: 'admin_email' }) || ''; const isEditMode = Boolean(tenantId); const handleSubmit = submitForm( (values) => { if (!values.client_id || !values.plan_id) { toast.error('Select a client and plan'); return; } if (!isEditMode) { if ( !values.admin_first_name.trim() || !values.admin_last_name.trim() || !values.admin_email.trim() ) { toast.error('Complete all required admin fields'); return; } } saveMutation.mutate(values); }, () => toast.error('Complete all required tenant fields'), ); const openCreate = useCallback(() => { reset(defaultValues); }, [reset]); const openEdit = useCallback( (tenant: Tenant) => { reset({ id: tenant.id, name: tenant.name || '', slug: tenant.slug || '', client_id: String(tenant.client_id ?? ''), plan_id: String(tenant.plan_id ?? ''), domain: tenant.domain || '', description: tenant.description || '', admin_first_name: '', admin_last_name: '', admin_email: tenant.admin_email || '', admin_phone_number: '', }); }, [reset], ); const applyClientAdminDefaults = useCallback( (contactName: string, contactEmail: string, contactPhone: string) => { if (isEditMode) return; const { firstName, lastName } = splitContactName(contactName); setValue('admin_first_name', firstName, { shouldDirty: true }); setValue('admin_last_name', lastName, { shouldDirty: true }); setValue('admin_email', contactEmail, { shouldDirty: true }); setValue('admin_phone_number', contactPhone, { shouldDirty: true }); }, [isEditMode, setValue], ); const syncSlugFromName = useCallback( (name: string) => { if (isEditMode) return; setValue('slug', createSlug(name), { shouldDirty: true }); }, [isEditMode, setValue], ); return { register, handleSubmit, reset, control, setValue, openCreate, openEdit, tenantId, clientId, planId, adminEmail, isEditMode, applyClientAdminDefaults, syncSlugFromName, isSaving: isSubmitting || saveMutation.isPending, }; }