import { useHookForm } from "@erp/core/hooks"; import { showErrorToast, showSuccessToast, showWarningToast } from "@repo/rdx-ui/helpers"; import { useId } from "react"; import type { FieldErrors } from "react-hook-form"; import { useTranslation } from "../../i18n"; import type { Customer } from "../../shared"; import { useCustomerCreateMutation } from "../../shared/hooks/use-customer-create-mutation"; import { type CustomerCreateForm, CustomerCreateFormSchema, type CustomerCreatePayload, defaultCustomerCreateForm, } from "../entities"; import { buildCustomerCreatePayload } from "../utils"; export interface UseCustomerCreateControllerOptions { onCreated?(created: Customer): void; successToasts?: boolean; // mostrar o no toast automáticcamente onError?(error: Error, payloadData: CustomerCreatePayload): void; errorToasts?: boolean; // mostrar o no toast automáticcamente } export const useCustomerCreateController = (options?: UseCustomerCreateControllerOptions) => { const { t } = useTranslation(); const formId = useId(); // id único por instancia // 1) Estado de creación (mutación) const { mutateAsync, isPending: isCreating, isError: isCreateError, error: createError, } = useCustomerCreateMutation(); // 2) Form hook const form = useHookForm({ resolverSchema: CustomerCreateFormSchema, initialValues: defaultCustomerCreateForm, disabled: isCreating, }); /** Handlers */ const resetForm = () => { form.reset(defaultCustomerCreateForm, { keepDirty: false }); }; const submitHandler = form.handleSubmit( async (formData) => { const payloadData: CustomerCreatePayload = buildCustomerCreatePayload(formData); try { // Enviamos cambios al servidor const created = await mutateAsync(payloadData); if (options?.successToasts !== false) { showSuccessToast( t("pages.create.success.title", "Cliente creado"), t("pages.create.success.message", "Se ha creado el cliente correctamente.") ); } options?.onCreated?.(created); } catch (error: unknown) { const normalizedError = error instanceof Error ? error : new Error(t("pages.create.error.unknown")); if (options?.errorToasts !== false) { showErrorToast(t("pages.create.error.title"), normalizedError.message); } options?.onError?.(normalizedError, payloadData); } }, (errors: FieldErrors) => { const firstKey = Object.keys(errors)[0] as keyof CustomerCreateForm | undefined; if (firstKey) { document.querySelector(`[name="${String(firstKey)}"]`)?.focus(); } showWarningToast( t("forms.validation.title", "Revisa los campos"), t("forms.validation.message", "Hay errores de validación en el formulario.") ); } ); // Evento onSubmit ya preparado para el
const onSubmit = (event: React.FormEvent) => { event.stopPropagation(); // <-- evita que el submit se propage por los padre en el árbol DOM submitHandler(event); }; return { // form form, formId, // handlers del form onSubmit, resetForm, // mutation isCreating, isCreateError, createError, // No devolver FormProvider, así el controller es más // flexible y reusable (p.ej. para un modal) // FormProvider, }; };