125 lines
4.1 KiB
TypeScript
125 lines
4.1 KiB
TypeScript
|
|
import { AppBreadcrumb, AppContent, ButtonGroup } from "@repo/rdx-ui/components";
|
||
|
|
import { Button } from "@repo/shadcn-ui/components";
|
||
|
|
import { useNavigate } from "react-router-dom";
|
||
|
|
|
||
|
|
import { useUnsavedChangesNotifier } from "@erp/core/hooks";
|
||
|
|
import { showErrorToast, showSuccessToast } from "@repo/shadcn-ui/lib/utils";
|
||
|
|
import { useState } from "react";
|
||
|
|
import { FieldErrors } from "react-hook-form";
|
||
|
|
import { CustomerEditForm, ErrorAlert } from "../../components";
|
||
|
|
import { useCreateCustomerMutation } from "../../hooks";
|
||
|
|
import { useTranslation } from "../../i18n";
|
||
|
|
import { CustomerFormData, defaultCustomerFormData } from "../../schemas";
|
||
|
|
|
||
|
|
export const CustomerCreate = () => {
|
||
|
|
const { t } = useTranslation();
|
||
|
|
const navigate = useNavigate();
|
||
|
|
const [isDirty, setIsDirty] = useState(false);
|
||
|
|
|
||
|
|
// 2) Estado de creación (mutación)
|
||
|
|
const {
|
||
|
|
mutateAsync,
|
||
|
|
isPending: isCreating,
|
||
|
|
isError: isCreateError,
|
||
|
|
error: createError,
|
||
|
|
} = useCreateCustomerMutation();
|
||
|
|
|
||
|
|
const { confirm: confirmCancel } = useUnsavedChangesNotifier({
|
||
|
|
isDirty,
|
||
|
|
});
|
||
|
|
|
||
|
|
// 3) Submit con navegación condicionada por éxito
|
||
|
|
const handleSubmit = async (formData: CustomerFormData) => {
|
||
|
|
/*const changedData: Record<string, string> = {};
|
||
|
|
|
||
|
|
Object.keys(dirtyFields).forEach((field) => {
|
||
|
|
const value = String(currentValues[field as keyof CustomerFormData]);
|
||
|
|
changedData[field] = value;
|
||
|
|
});*/
|
||
|
|
|
||
|
|
try {
|
||
|
|
const result = await mutateAsync({ data: formData });
|
||
|
|
console.log(result);
|
||
|
|
|
||
|
|
if (result) {
|
||
|
|
showSuccessToast(t("pages.create.successTitle"), t("pages.create.successMsg"));
|
||
|
|
navigate("/customers/list");
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
showErrorToast(t("pages.create.errorTitle"), (e as Error).message);
|
||
|
|
} finally {
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleError = (errors: FieldErrors<CustomerFormData>) => {
|
||
|
|
console.error("Errores en el formulario:", errors);
|
||
|
|
// Aquí puedes manejar los errores, por ejemplo, mostrar un mensaje al usuario
|
||
|
|
};
|
||
|
|
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<AppBreadcrumb />
|
||
|
|
<AppContent>
|
||
|
|
<div className='flex items-center justify-between space-y-4 px-6'>
|
||
|
|
<div className='space-y-2'>
|
||
|
|
<h2 className='text-2xl font-bold tracking-tight text-balance scroll-m-2'>
|
||
|
|
{t("pages.create.title")}
|
||
|
|
</h2>
|
||
|
|
<p className='text-muted-foreground scroll-m-20 tracking-tight text-balance'>
|
||
|
|
{t("pages.create.description")}
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
<ButtonGroup>
|
||
|
|
<Button
|
||
|
|
variant={"outline"}
|
||
|
|
className='cursor-pointer'
|
||
|
|
onClick={async (e) => {
|
||
|
|
e.preventDefault();
|
||
|
|
const ok = await confirmCancel();
|
||
|
|
if (ok) {
|
||
|
|
console.log("Cambios descartados");
|
||
|
|
navigate("/customers/list");
|
||
|
|
}
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
{t("common.cancel")}
|
||
|
|
</Button>
|
||
|
|
|
||
|
|
<Button
|
||
|
|
type='submit'
|
||
|
|
form='customer-create-form'
|
||
|
|
className='cursor-pointer'
|
||
|
|
disabled={isCreating}
|
||
|
|
aria-busy={isCreating}
|
||
|
|
aria-disabled={isCreating}
|
||
|
|
data-state={isCreating ? "loading" : "idle"}
|
||
|
|
>
|
||
|
|
{t("common.save")}
|
||
|
|
</Button>
|
||
|
|
</ButtonGroup>
|
||
|
|
</div>
|
||
|
|
{/* Alerta de error de actualización (si ha fallado el último intento) */}
|
||
|
|
{isCreateError && (
|
||
|
|
<ErrorAlert
|
||
|
|
title={t("pages.create.errorTitle", "No se pudo guardar los cambios")}
|
||
|
|
message={
|
||
|
|
(createError as Error)?.message ??
|
||
|
|
t("pages.create.errorMsg", "Revisa los datos e inténtalo de nuevo.")
|
||
|
|
}
|
||
|
|
/>
|
||
|
|
)}
|
||
|
|
|
||
|
|
<div className='flex flex-1 flex-col gap-4 p-4'>
|
||
|
|
<CustomerEditForm
|
||
|
|
formId={"customer-create-form"} // para que el botón del header pueda hacer submit
|
||
|
|
initialValues={defaultCustomerFormData}
|
||
|
|
onSubmit={handleSubmit}
|
||
|
|
onError={handleError}
|
||
|
|
onDirtyChange={setIsDirty}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</AppContent>
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
};
|