moex-vibe/apps/frontend/src/pages/RegisterPage.tsx
Sergey Krylov 8e9fdbe70a refactor(frontend): migrate app layer and auth to FSD
- Create app/ layer: App.tsx, providers, routing, layouts
- Create entities/session/ for auth domain
- Extract SessionProvider + AppProviders composition
- Add ProtectedRoute, AppRoutes to app/routing/
- Add AppLayout to app/layouts/
- Convert legacy files to re-export shims
- Update Login/Register/Profile pages to useSession
2026-06-20 14:54:53 +03:00

160 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, type FormEvent } from 'react';
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { useSession } from '@/entities/session';
export function RegisterPage() {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const { register } = useSession();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [name, setName] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const redirect = searchParams.get('redirect') || '/';
async function handleSubmit(e: FormEvent) {
e.preventDefault();
setError('');
if (password !== confirmPassword) {
setError('Пароли не совпадают');
return;
}
setLoading(true);
try {
await register(email, password, name || undefined);
navigate(redirect);
} catch (err) {
setError(err instanceof Error ? err.message : 'Ошибка регистрации');
} finally {
setLoading(false);
}
}
return (
<div style={{ maxWidth: 400, margin: '60px auto' }}>
<h1 style={{ marginBottom: 24, fontSize: 24, fontWeight: 700 }}>Регистрация</h1>
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
{error && <div style={{ color: 'var(--color-negative)', fontSize: 14 }}>{error}</div>}
<div>
<label
style={{
display: 'block',
marginBottom: 4,
fontSize: 14,
color: 'var(--color-text-secondary)',
}}
>
Имя (необязательно)
</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
style={inputStyle}
placeholder="Иван Иванов"
/>
</div>
<div>
<label
style={{
display: 'block',
marginBottom: 4,
fontSize: 14,
color: 'var(--color-text-secondary)',
}}
>
Email
</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
style={inputStyle}
placeholder="email@example.com"
/>
</div>
<div>
<label
style={{
display: 'block',
marginBottom: 4,
fontSize: 14,
color: 'var(--color-text-secondary)',
}}
>
Пароль
</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
minLength={6}
style={inputStyle}
placeholder="Минимум 6 символов"
/>
</div>
<div>
<label
style={{
display: 'block',
marginBottom: 4,
fontSize: 14,
color: 'var(--color-text-secondary)',
}}
>
Подтверждение пароля
</label>
<input
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
style={inputStyle}
placeholder="Повторите пароль"
/>
</div>
<button type="submit" disabled={loading} style={buttonStyle}>
{loading ? 'Регистрация...' : 'Зарегистрироваться'}
</button>
<p style={{ textAlign: 'center', fontSize: 14, color: 'var(--color-text-secondary)' }}>
Уже есть аккаунт?{' '}
<Link
to={`/login${redirect !== '/' ? `?redirect=${encodeURIComponent(redirect)}` : ''}`}
style={{ color: 'var(--color-primary)' }}
>
Войти
</Link>
</p>
</form>
</div>
);
}
const inputStyle: React.CSSProperties = {
width: '100%',
padding: '10px 12px',
border: '1px solid #e0e0e0',
borderRadius: 'var(--border-radius)',
fontSize: 16,
outline: 'none',
boxSizing: 'border-box',
};
const buttonStyle: React.CSSProperties = {
padding: '12px 24px',
background: 'var(--color-primary)',
color: '#fff',
border: 'none',
borderRadius: 'var(--border-radius)',
fontSize: 16,
fontWeight: 600,
cursor: 'pointer',
};