import { useState, type FormEvent } from 'react'; import { useMutation } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { Link, useLocation, useNavigate } from 'react-router'; import { login } from '@/api/auth'; import { ErrorNotice } from '@/components/ui/ErrorNotice'; import { Field } from '@/components/ui/Field'; import { Button, Card } from '@/components/ui/primitives'; import { getQueryClient } from '@/lib/queryClient'; import { useInstance } from '@/lib/hooks'; import { errorCode } from '@/lib/format'; interface LocationState { from?: string; } /** Форма входа: поле кода 2FA появляется при ответе `auth.2fa_required`. */ export default function LoginPage() { const { t } = useTranslation(); const navigate = useNavigate(); const location = useLocation(); const instance = useInstance(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [totpCode, setTotpCode] = useState(''); const [needsTotp, setNeedsTotp] = useState(false); const from = (location.state as LocationState | null)?.from ?? '/app'; const submit = useMutation({ mutationFn: () => login(needsTotp ? { email, password, totp_code: totpCode } : { email, password }), onSuccess: async () => { // Профиль перечитываем заново: cookie уже выставлена сервером. await getQueryClient().invalidateQueries(); void navigate(from === '/login' ? '/app' : from, { replace: true }); }, onError: (error: unknown) => { if (errorCode(error) === 'auth.2fa_required') { setNeedsTotp(true); } }, }); const onSubmit = (event: FormEvent): void => { event.preventDefault(); submit.mutate(); }; const registrationEnabled = instance.data?.registration_enabled === true; return (

{t('auth.login.title')}

{t('auth.login.subtitle')}

setEmail(event.target.value)} required /> setPassword(event.target.value)} required /> {needsTotp ? ( setTotpCode(event.target.value)} autoFocus /> ) : null} {submit.isError ? : null}

{t('auth.login.noAccount')}{' '} {registrationEnabled ? ( {t('auth.login.registerLink')} ) : ( {t('auth.login.registrationDisabled')} )}

{t('auth.login.forgot')}

); }