Files
ga-commission-system/ga-frontend/src/pages/LoginPage.tsx
T
2026-05-14 01:21:27 +09:00

142 lines
4.5 KiB
TypeScript

import { Button, Divider, Form, Input, Typography } from 'antd';
import { LockOutlined, UserOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { authApi } from '@/api/auth';
import { useAuthStore } from '@/stores/auth';
import { COLOR_PRIMARY, GRAY, SHADOW } from '@/theme/tokens';
const { Title, Text } = Typography;
export default function LoginPage() {
const navigate = useNavigate();
const setAuth = useAuthStore((s) => s.setAuth);
const onFinish = async (values: { loginId: string; password: string }) => {
try {
const resp = await authApi.login(values);
localStorage.setItem('accessToken', resp.accessToken);
if (resp.refreshToken) localStorage.setItem('refreshToken', resp.refreshToken);
setAuth({
userId: resp.userId,
loginId: resp.loginId,
userName: resp.userName,
roles: resp.roles,
});
navigate('/');
} catch {
// 인터셉터에서 메시지 처리
}
};
return (
<div
style={{
minHeight: '100vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: GRAY[50],
padding: 24,
}}
>
<div
style={{
width: 440,
background: '#ffffff',
borderRadius: 20,
boxShadow: SHADOW.lg,
overflow: 'hidden',
}}
>
{/* 상단 브랜드 헤더 */}
<div
style={{
background: COLOR_PRIMARY,
padding: '36px 40px 32px',
textAlign: 'center',
}}
>
<div
style={{
width: 52, height: 52,
borderRadius: 14,
background: 'rgba(255,255,255,0.18)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 16px',
color: '#fff',
fontWeight: 800,
fontSize: 20,
letterSpacing: -0.5,
}}
>
GA
</div>
<Title level={3} style={{ color: '#ffffff', margin: 0, fontWeight: 700, fontSize: 22 }}>
GA
</Title>
<Text style={{ color: 'rgba(255,255,255,0.7)', fontSize: 13, marginTop: 6, display: 'block' }}>
GA Commission Management System
</Text>
</div>
{/* 로그인 폼 */}
<div style={{ padding: '36px 40px 40px' }}>
<Form layout="vertical" onFinish={onFinish} autoComplete="off">
<Form.Item
label={<Text style={{ fontSize: 13, fontWeight: 500, color: GRAY[600] }}></Text>}
name="loginId"
rules={[{ required: true, message: '아이디를 입력하세요' }]}
style={{ marginBottom: 16 }}
>
<Input
prefix={<UserOutlined style={{ color: GRAY[400] }} />}
placeholder="아이디 입력"
size="large"
autoFocus
style={{ height: 52, borderRadius: 12, fontSize: 15 }}
/>
</Form.Item>
<Form.Item
label={<Text style={{ fontSize: 13, fontWeight: 500, color: GRAY[600] }}></Text>}
name="password"
rules={[{ required: true, message: '비밀번호를 입력하세요' }]}
style={{ marginBottom: 28 }}
>
<Input.Password
prefix={<LockOutlined style={{ color: GRAY[400] }} />}
placeholder="비밀번호 입력"
size="large"
style={{ height: 52, borderRadius: 12, fontSize: 15 }}
/>
</Form.Item>
<Button
type="primary"
htmlType="submit"
block
style={{
fontWeight: 700,
fontSize: 16,
height: 56,
borderRadius: 12,
letterSpacing: 0.3,
}}
>
</Button>
</Form>
<Divider style={{ margin: '28px 0 20px', borderColor: GRAY[100] }} />
<Text style={{ fontSize: 13, color: GRAY[400], display: 'block', textAlign: 'center' }}>
문의: 시스템 · 1234
</Text>
</div>
</div>
</div>
);
}