Uecko_ERP/modules/customers/src/web/pages/update/update.tsx

146 lines
4.7 KiB
TypeScript
Raw Normal View History

2025-09-16 17:29:37 +00:00
import { AppBreadcrumb, AppContent, BackHistoryButton, ButtonGroup } from "@repo/rdx-ui/components";
import { Button } from "@repo/shadcn-ui/components";
import { useNavigate } from "react-router-dom";
import { useUrlParamId } from "@erp/core/hooks";
2025-09-17 17:37:41 +00:00
import { showErrorToast, showSuccessToast } from "@repo/shadcn-ui/lib/utils";
2025-09-19 09:29:49 +00:00
import { FieldErrors } from "react-hook-form";
2025-09-17 17:37:41 +00:00
import { CustomerEditorSkeleton, ErrorAlert, NotFoundCard } from "../../components";
2025-09-16 17:29:37 +00:00
import { useCustomerQuery, useUpdateCustomerMutation } from "../../hooks";
import { useTranslation } from "../../i18n";
2025-09-17 17:37:41 +00:00
import { CustomerUpdateData } from "../../schemas";
2025-09-16 17:29:37 +00:00
import { CustomerEditForm } from "./customer-edit-form";
export const CustomerUpdate = () => {
const { t } = useTranslation();
const customerId = useUrlParamId();
const navigate = useNavigate();
// 1) Estado de carga del cliente (query)
const {
data: customerData,
isLoading: isLoadingCustomer,
isError: isLoadError,
error: loadError,
} = useCustomerQuery(customerId, { enabled: !!customerId });
// 2) Estado de actualización (mutación)
const {
2025-09-17 17:37:41 +00:00
mutateAsync,
2025-09-16 17:29:37 +00:00
isPending: isUpdating,
isError: isUpdateError,
error: updateError,
2025-09-17 17:37:41 +00:00
} = useUpdateCustomerMutation();
2025-09-16 17:29:37 +00:00
// 3) Submit con navegación condicionada por éxito
2025-09-17 17:37:41 +00:00
const handleSubmit = async (formData: CustomerUpdateData) => {
2025-09-16 17:29:37 +00:00
try {
2025-09-17 17:37:41 +00:00
const result = await mutateAsync({ id: customerId!, data: formData });
if (result) {
showSuccessToast(t("pages.update.successTitle"), t("pages.update.successMsg"));
navigate("/customers/list");
}
2025-09-16 17:29:37 +00:00
} catch (e) {
2025-09-17 17:37:41 +00:00
showErrorToast(t("pages.update.errorTitle"), (e as Error).message);
} finally {
2025-09-16 17:29:37 +00:00
}
};
2025-09-19 09:29:49 +00:00
const handleError = (errors: FieldErrors<CustomerUpdateData>) => {
console.error("Errores en el formulario:", errors);
// Aquí puedes manejar los errores, por ejemplo, mostrar un mensaje al usuario
};
2025-09-16 17:29:37 +00:00
if (isLoadingCustomer) {
2025-09-17 17:37:41 +00:00
return <CustomerEditorSkeleton />;
2025-09-16 17:29:37 +00:00
}
if (isLoadError) {
return (
<>
<AppBreadcrumb />
<AppContent>
2025-09-17 17:37:41 +00:00
<ErrorAlert
title={t("pages.update.loadErrorTitle", "No se pudo cargar el cliente")}
message={
(loadError as Error)?.message ??
t("pages.update.loadErrorMsg", "Inténtalo de nuevo más tarde.")
}
/>
2025-09-16 17:29:37 +00:00
<div className='flex items-center justify-end'>
<BackHistoryButton />
</div>
</AppContent>
</>
);
}
2025-09-17 17:37:41 +00:00
if (!customerData)
2025-09-16 17:29:37 +00:00
return (
<>
<AppBreadcrumb />
<AppContent>
2025-09-17 17:37:41 +00:00
<NotFoundCard
title={t("pages.update.notFoundTitle", "Cliente no encontrado")}
message={t("pages.update.notFoundMsg", "Revisa el identificador o vuelve al listado.")}
/>
2025-09-16 17:29:37 +00:00
</AppContent>
</>
);
return (
<>
<AppBreadcrumb />
<AppContent>
<div className='flex items-center justify-between space-y-2'>
<div>
<h2 className='text-2xl font-bold tracking-tight text-balance scroll-m-2'>
{t("pages.update.title")}
</h2>
<p className='text-muted-foreground scroll-m-20 tracking-tight text-balance'>
{t("pages.update.description")}
</p>
</div>
<ButtonGroup>
<BackHistoryButton />
<Button
type='submit'
form='customer-edit-form'
className='cursor-pointer'
disabled={isUpdating || isLoadingCustomer}
aria-busy={isUpdating}
aria-disabled={isUpdating || isLoadingCustomer}
data-state={isUpdating ? "loading" : "idle"}
>
{t("pages.update.submit")}
</Button>
</ButtonGroup>
</div>
{/* Alerta de error de actualización (si ha fallado el último intento) */}
{isUpdateError && (
2025-09-17 17:37:41 +00:00
<ErrorAlert
title={t("pages.update.errorTitle", "No se pudo guardar los cambios")}
message={
(updateError as Error)?.message ??
t("pages.update.errorMsg", "Revisa los datos e inténtalo de nuevo.")
}
/>
2025-09-16 17:29:37 +00:00
)}
<div className='flex flex-1 flex-col gap-4 p-4'>
{/* Importante: proveemos un formId para que el botón del header pueda hacer submit */}
<CustomerEditForm
formId='customer-edit-form'
2025-09-19 09:29:49 +00:00
defaultValues={defaultValues}
2025-09-16 17:29:37 +00:00
onSubmit={handleSubmit}
isPending={isUpdating}
2025-09-19 09:29:49 +00:00
errorMessage={isUpdateError ? getErrorMessage(updateError) : undefined}
2025-09-16 17:29:37 +00:00
/>
</div>
</AppContent>
</>
);
};