119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
import { useState } from 'react';
|
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
import { ArrowLeft } from 'lucide-react';
|
|
import { Button } from '@components/atoms/Button';
|
|
import { Spinner } from '@components/atoms/Spinner';
|
|
import { Card, CardHeader, CardTitle, CardContent } from '@components/molecules/Card';
|
|
import { Alert } from '@components/molecules/Alert';
|
|
import { Breadcrumbs } from '@components/organisms/Breadcrumbs';
|
|
import { useToast } from '@components/organisms/Toast';
|
|
import { ErrorEmptyState } from '@components/templates/EmptyState';
|
|
import { UserForm } from '@features/users/components/UserForm';
|
|
import { useUser } from '@features/users/hooks';
|
|
import { usersApi } from '@features/users/api';
|
|
import type { UpdateUserDto } from '@features/users/types';
|
|
|
|
export function UserEditPage() {
|
|
const { id } = useParams<{ id: string }>();
|
|
const navigate = useNavigate();
|
|
const { showToast } = useToast();
|
|
const { user, isLoading, error: fetchError, refresh } = useUser(id);
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const handleSubmit = async (data: UpdateUserDto) => {
|
|
if (!id) return;
|
|
|
|
setIsSubmitting(true);
|
|
setError(null);
|
|
|
|
try {
|
|
await usersApi.update(id, data);
|
|
showToast({
|
|
type: 'success',
|
|
title: 'Usuario actualizado',
|
|
message: 'Los cambios han sido guardados exitosamente.',
|
|
});
|
|
navigate('/users');
|
|
} catch (err) {
|
|
const message = err instanceof Error ? err.message : 'Error al actualizar usuario';
|
|
setError(message);
|
|
} finally {
|
|
setIsSubmitting(false);
|
|
}
|
|
};
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="flex h-96 items-center justify-center">
|
|
<Spinner size="lg" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (fetchError || !user) {
|
|
return (
|
|
<div className="p-6">
|
|
<ErrorEmptyState
|
|
title="Usuario no encontrado"
|
|
description="No se pudo cargar la información del usuario."
|
|
onRetry={refresh}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-6 p-6">
|
|
<Breadcrumbs
|
|
items={[
|
|
{ label: 'Usuarios', href: '/users' },
|
|
{ label: `${user.firstName} ${user.lastName}`, href: `/users/${id}` },
|
|
{ label: 'Editar' },
|
|
]}
|
|
/>
|
|
|
|
<div className="flex items-center gap-4">
|
|
<Button variant="ghost" size="sm" onClick={() => navigate(`/users/${id}`)}>
|
|
<ArrowLeft className="mr-2 h-4 w-4" />
|
|
Volver
|
|
</Button>
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-gray-900">Editar usuario</h1>
|
|
<p className="text-sm text-gray-500">
|
|
Modifica la información de {user.firstName} {user.lastName}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mx-auto max-w-2xl">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Información del usuario</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{error && (
|
|
<Alert
|
|
variant="danger"
|
|
title="Error"
|
|
className="mb-4"
|
|
onClose={() => setError(null)}
|
|
>
|
|
{error}
|
|
</Alert>
|
|
)}
|
|
|
|
<UserForm
|
|
user={user}
|
|
onSubmit={handleSubmit}
|
|
onCancel={() => navigate(`/users/${id}`)}
|
|
isLoading={isSubmitting}
|
|
/>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
export default UserEditPage;
|