'use client'; import { collectDefaultPermissionIds, collectPermissionIdsByKeys, } from '@/components/permission-tree'; import type { PermissionTreeItem, Plan } from '@/types'; import { useCallback } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { toast } from 'sonner'; import { useSavePlanMutation } from './usePlanMutations'; export interface PlanFormValues { id?: number; name: string; slug: string; description: string; price: string; billing_cycle: string; trial_days: number; max_projects: number; max_organizations: number; max_users: number; max_roles: number; permission_ids: number[]; is_active: boolean; is_custom: boolean; } const defaultValues: PlanFormValues = { name: '', slug: '', description: '', price: '', billing_cycle: 'monthly', trial_days: 0, max_projects: 0, max_organizations: 0, max_users: 0, max_roles: 0, permission_ids: [], is_active: true, is_custom: false, }; function toNumber(value: unknown) { const numberValue = Number(value); return Number.isFinite(numberValue) ? numberValue : 0; } export function usePlanForm({ permissionTree, onSaved, }: { permissionTree: PermissionTreeItem[]; onSaved: () => void; }) { const { control, register, handleSubmit, reset, setValue, formState: { isSubmitting }, } = useForm({ defaultValues, }); const saveMutation = useSavePlanMutation({ onSaved: () => { reset(defaultValues); onSaved(); }, }); const planId = useWatch({ control, name: 'id' }); const permissionIds = useWatch({ control, name: 'permission_ids' }) || []; const onSubmit = handleSubmit((values) => { if (values.permission_ids.length === 0) { toast.error('Select at least one permission'); return; } saveMutation.mutate({ ...values, name: values.name.trim(), slug: values.slug.trim(), description: values.description.trim(), price: values.price.trim(), trial_days: toNumber(values.trial_days), max_projects: toNumber(values.max_projects), max_organizations: toNumber(values.max_organizations), max_users: toNumber(values.max_users), max_roles: toNumber(values.max_roles), }); }); const openCreate = useCallback(() => { reset({ ...defaultValues, permission_ids: collectDefaultPermissionIds(permissionTree), }); }, [permissionTree, reset]); const openEdit = useCallback( (plan: Plan) => { reset({ id: plan.id, name: plan.name || '', slug: plan.slug || '', description: plan.description || '', price: plan.price || '', billing_cycle: plan.billing_cycle || 'monthly', trial_days: plan.trial_days ?? 0, max_projects: plan.max_projects ?? 0, max_organizations: plan.max_organizations ?? 0, max_users: plan.max_users ?? 0, max_roles: plan.max_roles ?? 0, permission_ids: collectPermissionIdsByKeys( permissionTree, plan.permissions || [], ), is_active: plan.is_active, is_custom: plan.is_custom, }); }, [permissionTree, reset], ); const setPermissionIds = useCallback( (ids: number[]) => setValue('permission_ids', ids, { shouldDirty: true, shouldValidate: true, }), [setValue], ); return { register, control, onSubmit, openCreate, openEdit, planId, permissionIds, setPermissionIds, isSaving: isSubmitting || saveMutation.isPending, }; }