import { useState } from 'react'; import axios from 'axios'; import { startAuthentication, browserSupportsWebAuthn } from '@simplewebauthn/browser'; import { AlertCircle, ArrowLeft, Loader2, Lock, User } from 'lucide-react'; import { useAuth } from '../contexts/AuthContext'; import BrandLogo from '../components/BrandLogo'; import passkeyIcon from '../assets/passkey.svg'; import devicesIllustration from '../assets/login-devices.svg'; import { getApiBaseUrl } from '../utils/apiBaseUrl'; const API_BASE_URL = getApiBaseUrl(); function getPasskeyErrorMessage(error) { if (error?.name === 'NotAllowedError') { return 'Запрос на использование passkey отменён или истёк.'; } if (error?.name === 'InvalidStateError') { return 'Этот passkey уже используется в другом запросе. Попробуйте ещё раз.'; } return error?.response?.data?.error || error?.message || 'Не удалось выполнить вход по passkey.'; } export default function LoginPage() { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [showPasswordForm, setShowPasswordForm] = useState(false); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const { login, loginWithPasskey } = useAuth(); const passkeysSupported = browserSupportsWebAuthn(); const handlePasswordLogin = async (event) => { event.preventDefault(); setError(''); setLoading(true); const result = await login(username, password); if (!result.success) { setError(result.error); setLoading(false); } }; const handlePasskeyLogin = async () => { if (!passkeysSupported) { setError('Этот браузер не поддерживает вход по passkey. Используйте пароль.'); return; } setError(''); setLoading(true); try { const optionsResponse = await axios.post(`${API_BASE_URL}/auth/passkeys/authentication/options`); const credential = await startAuthentication({ optionsJSON: optionsResponse.data }); const result = await loginWithPasskey(credential); if (!result.success) { setError(result.error); setLoading(false); } } catch (passkeyError) { setError(getPasskeyErrorMessage(passkeyError)); setLoading(false); } }; const returnToLoginMethods = () => { setShowPasswordForm(false); setError(''); setPassword(''); }; return (

RideBus DE

{error && (
)} {showPasswordForm ? (

Войти с паролем

) : (

Вход в административную панель

Вход без пароля — с отпечатком пальца, Face ID или PIN-кодом устройства.

)}
); }