// Strony i komponenty procesu konta: aktywacja przez link, ustawienie nowego hasla, okno OTP telefonu. import { useEffect, useRef, useState, type FormEvent, type ReactNode } from 'react'; import { Link, useNavigate, useParams } from 'react-router-dom'; import { ROUTES } from './routes'; import { useAuth } from './auth'; const errMsg = (e: unknown) => (e instanceof Error ? e.message : 'Wystąpił błąd. Spróbuj ponownie.'); function AuthStatusCard({ children }: { children: ReactNode }) { return (
Polska Lokalnie {children}
); } // /aktywacja/:token - potwierdzenie adresu e-mail z linku. export function ActivationPage() { const { token } = useParams<{ token: string }>(); const { activateAccount } = useAuth(); const [state, setState] = useState<'loading' | 'ok' | 'error'>('loading'); const [message, setMessage] = useState(''); const ran = useRef(false); useEffect(() => { if (ran.current) { return; } ran.current = true; (async () => { try { await activateAccount(token ?? ''); setState('ok'); } catch (e) { setState('error'); setMessage(errMsg(e)); } })(); }, [token, activateAccount]); return ( {state === 'loading' &&

Aktywujemy Twoje konto...

} {state === 'ok' && ( <>

Konto zostało aktywowane!

Możesz się teraz zalogować i korzystać ze wszystkich funkcji serwisu.

Przejdź do logowania )} {state === 'error' && ( <>
!

Nie udało się aktywować konta

{message || 'Link aktywacyjny jest nieprawidłowy lub wygasł.'}

Zaloguj się i poproś o ponowne wysłanie linku aktywacyjnego.

Przejdź do logowania )}
); } // /reset-hasla/:token - ustawienie nowego hasla. export function PasswordResetPage() { const { token } = useParams<{ token: string }>(); const { resetPassword } = useAuth(); const navigate = useNavigate(); const [password, setPassword] = useState(''); const [confirm, setConfirm] = useState(''); const [error, setError] = useState(null); const [done, setDone] = useState(false); const [busy, setBusy] = useState(false); const submit = async (event: FormEvent) => { event.preventDefault(); setError(null); if (password.length < 8) { setError('Hasło musi mieć co najmniej 8 znaków.'); return; } if (password !== confirm) { setError('Hasła nie są identyczne.'); return; } setBusy(true); try { await resetPassword(token ?? '', password); setDone(true); setTimeout(() => navigate(ROUTES.login), 2500); } catch (e) { setError(errMsg(e)); } finally { setBusy(false); } }; return ( {done ? ( <>

Hasło zostało zmienione

Za chwilę przekierujemy Cię do logowania.

Przejdź do logowania ) : ( <>

Ustaw nowe hasło

Wpisz nowe hasło do swojego konta. Dotychczasowe hasło działa do momentu jego zmiany.

{error &&

{error}

}
)}
); } // Okno potwierdzenia numeru telefonu kodem SMS (OTP), pokazywane po rejestracji z podanym telefonem. export function PhoneOtpModal({ email, phone, onClose, onVerified }: { email: string; phone: string; onClose: () => void; onVerified: () => void; }) { const { verifyPhone, resendPhoneOtp } = useAuth(); const [code, setCode] = useState(''); const [error, setError] = useState(null); const [info, setInfo] = useState(null); const [busy, setBusy] = useState(false); const [cooldown, setCooldown] = useState(0); useEffect(() => { if (cooldown <= 0) { return; } const t = window.setTimeout(() => setCooldown((c) => c - 1), 1000); return () => window.clearTimeout(t); }, [cooldown]); const submit = async (event: FormEvent) => { event.preventDefault(); setError(null); setInfo(null); setBusy(true); try { await verifyPhone(email, code.trim()); onVerified(); } catch (e) { setError(errMsg(e)); } finally { setBusy(false); } }; const resend = async () => { setError(null); try { await resendPhoneOtp(email); setInfo('Wysłaliśmy nowy kod SMS.'); // Zgodne z odstepem wymuszanym przez backend (RESEND_COOLDOWN_SECONDS). setCooldown(60); } catch (e) { setError(errMsg(e)); } }; return (
📱

Potwierdź numer telefonu

Wysłaliśmy kod SMS na numer {phone}. Wpisz go poniżej, aby potwierdzić poprawność numeru.

setCode(e.target.value.replace(/\D/g, '').slice(0, 6))} placeholder="______" aria-label="Kod z SMS" autoFocus /> {error &&

{error}

} {info &&

{info}

}
); }