import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { useNavigate, useSearch } from '@tanstack/react-router'; import { useTranslation } from 'react-i18next'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { useAuth } from '@/features/auth/context/auth-context'; import { NetworkError, ProblemDetailsError } from '@/lib/api-client'; import { loginFormSchema, type LoginFormData } from '@/features/auth/schemas/auth'; export function LoginPage() { const { t } = useTranslation(); const { login } = useAuth(); const navigate = useNavigate(); const search = useSearch({ strict: false }) as { redirect?: string }; const [serverError, setServerError] = useState(null); const { register, handleSubmit, formState: { errors, isSubmitting }, } = useForm({ resolver: zodResolver(loginFormSchema), mode: 'onTouched', defaultValues: { email: '', password: '' }, }); const onSubmit = handleSubmit(async (values) => { setServerError(null); try { await login(values.email, values.password); await navigate({ to: (search.redirect as string | undefined) ?? '/dashboard' }); } catch (err) { if (err instanceof ProblemDetailsError && err.status === 401) { setServerError(t('login.errors.invalidCredentials')); } else if (err instanceof NetworkError) { setServerError(t('errors.network')); } else { setServerError(t('login.errors.generic')); } } }); return (
{t('login.title')} {t('login.subtitle')}
{serverError !== null && (
{serverError}
)}
{errors.email && (

{errors.email.message}

)}
{errors.password && (

{errors.password.message}

)}
); }