import { useEffect, useRef, useState } from 'react'; import { clearAuthState, storeAuthState } from '../../auth-session.js'; import { initializeTelemetry } from '../../telemetry.js'; import { LOGIN_ERROR_MESSAGES, requestLogin, validateLogin } from './login-service.js'; import { FormAlert } from '../shared/ui/FormAlert.jsx'; void initializeTelemetry(); const EMPTY_CREDENTIALS = Object.freeze({ password: '', username: '' }); function BrandIcon() { return ( ); } function UserIcon() { return ( ); } function LockIcon() { return ( ); } function EyeIcon() { return ( ); } function Spinner() { return ( ); } export function LoginApp() { const [credentials, setCredentials] = useState(EMPTY_CREDENTIALS); const [errors, setErrors] = useState({}); const [alert, setAlert] = useState(null); const [loading, setLoading] = useState(false); const [passwordVisible, setPasswordVisible] = useState(false); const [rippleVisible, setRippleVisible] = useState(false); const redirectTimer = useRef(null); useEffect(() => () => { if (redirectTimer.current) { window.clearTimeout(redirectTimer.current); } }, []); const updateField = event => { const { name, value } = event.target; setCredentials(current => ({ ...current, [name]: value })); setErrors(current => ({ ...current, [name]: undefined })); }; const submit = async event => { event.preventDefault(); const nextErrors = validateLogin(credentials); setErrors(nextErrors); setAlert(null); if (Object.keys(nextErrors).length > 0) { return; } setLoading(true); try { const result = await requestLogin(credentials); if (!result.ok) { setAlert({ message: result.message, type: 'error' }); return; } clearAuthState(); const session = storeAuthState(result.data); if (!session) { setAlert({ message: LOGIN_ERROR_MESSAGES.invalidResponse, type: 'error' }); return; } setAlert({ message: 'Вход выполнен успешно!', type: 'success' }); redirectTimer.current = window.setTimeout(() => { window.location.assign(session.redirect || '/'); }, 400); } catch (error) { setAlert({ message: LOGIN_ERROR_MESSAGES.connection, type: 'error' }); } finally { setLoading(false); } }; const showRipple = () => { setRippleVisible(false); window.requestAnimationFrame(() => setRippleVisible(true)); }; return ( <>