Sergey Krylov 055bc23097
Some checks failed
CI / ci (pull_request) Failing after 2m45s
CI / ci (push) Failing after 2m41s
refactor(frontend): migrate auth/portfolio pages to FSD, add layer boundaries
- Convert LoginPage, RegisterPage, ProfilePage to FSD structure (index.ts + ui/)
- Convert PortfoliosListPage, PortfolioDetailPage to FSD structure
- Replace relative imports with @/ aliases in portfolio pages
- Add ESLint import/no-restricted-paths for FSD layer boundaries
- Refactor useSession test to mock context instead of import from app/
- Mark frontend-fsd-screener tasks as complete
2026-06-20 21:42:33 +03:00

112 lines
3.2 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 LoginPage() {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const { login } = useSession();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const redirect = searchParams.get('redirect') || '/';
async function handleSubmit(e: FormEvent) {
e.preventDefault();
setError('');
setLoading(true);
try {
await login(email, password);
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)',
}}
>
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
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={`/register${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',
};