import { Button } from '@/components/ui/button'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { UserAvatar } from '@/components/user-avatar'; import { apiClient } from '@/lib/api-client'; import { useAuth } from '@/lib/auth'; import { zodResolver } from '@hookform/resolvers/zod'; import type { UserProfileResponse } from '@repo/api-contract'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { Link } from '@tanstack/react-router'; import { useEffect } from 'react'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; const updateProfileSchema = z.object({ fullName: z.string().min(1, 'El nombre es requerido'), }); const updatePasswordSchema = z .object({ currentPassword: z.string().min(1, 'La contraseña actual es requerida'), newPassword: z.string().min(6, 'La nueva contraseña debe tener al menos 6 caracteres'), confirmPassword: z.string().min(1, 'La confirmación de contraseña es requerida'), }) .refine((data) => data.newPassword === data.confirmPassword, { message: 'Las contraseñas no coinciden', path: ['confirmPassword'], }); type UpdateProfileForm = z.infer; type UpdatePasswordForm = z.infer; export function ProfilePage() { const { user, displayName, avatarUrl, isAuthenticated, updateProfile, updatePassword } = useAuth(); const queryClient = useQueryClient(); const profileQuery = useQuery({ queryKey: ['user-profile'], enabled: isAuthenticated, queryFn: (): Promise => apiClient.user.getProfile(), }); const updateProfileForm = useForm({ resolver: zodResolver(updateProfileSchema), defaultValues: { fullName: displayName, }, }); const updatePasswordForm = useForm({ resolver: zodResolver(updatePasswordSchema), defaultValues: { currentPassword: '', newPassword: '', confirmPassword: '', }, }); // Sync form with displayName when session data is loaded or updated elsewhere useEffect(() => { if (displayName && !updateProfileForm.formState.isDirty) { updateProfileForm.reset({ fullName: displayName }); } }, [displayName, updateProfileForm]); const updateProfileMutation = useMutation({ mutationFn: updateProfile, onSuccess: (_, variables) => { queryClient.invalidateQueries({ queryKey: ['user-profile'] }); updateProfileForm.reset({ fullName: variables.fullName }); }, }); const updatePasswordMutation = useMutation({ mutationFn: async (data: UpdatePasswordForm) => { await updatePassword({ currentPassword: data.currentPassword, password: data.newPassword, }); }, onSuccess: () => { updatePasswordForm.reset(); }, }); const onUpdateProfile = (data: UpdateProfileForm) => { updateProfileMutation.mutate(data); }; const onUpdatePassword = (data: UpdatePasswordForm) => { updatePasswordMutation.mutate(data); }; if (!isAuthenticated) { return (

Perfil

Necesitás iniciar sesión para ver tu perfil.

); } return (

{displayName}

{profileQuery.data?.email ?? user?.email}

{profileQuery.data?.role && (

Rol: {profileQuery.data.role}

)}
{profileQuery.isLoading && (

Cargando perfil...

)} {profileQuery.isError && (

No se pudo cargar el perfil desde el backend.

)}

Editar Perfil

( Nombre completo )} /> {updateProfileMutation.isError && (

Error al actualizar el perfil: {updateProfileMutation.error?.message}

)} {updateProfileMutation.isSuccess && (

Perfil actualizado exitosamente.

)}

Cambiar Contraseña

( Contraseña actual )} /> ( Nueva contraseña )} /> ( Confirmar nueva contraseña )} /> {updatePasswordMutation.isError && (

Error al cambiar la contraseña: {updatePasswordMutation.error?.message}

)} {updatePasswordMutation.isSuccess && (

Contraseña cambiada exitosamente.

)}
); }