full-stack/client-temp/src/pages/Login.tsx
2025-06-17 17:40:11 +08:00

117 lines
3.9 KiB
TypeScript

import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Form, Input, Button, Card, Space, Typography, Alert, Checkbox, Divider } from 'antd';
import { UserOutlined, LockOutlined, CheckSquareOutlined } from '@ant-design/icons';
import { api } from '../api/axios';
const { Title, Text, Link } = Typography;
function Login() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const navigate = useNavigate();
const onFinish = async (values: any) => {
setLoading(true);
setError(null);
try {
const response = await api.post('/auth/login', {
username: values.username,
password: values.password,
});
localStorage.setItem('token', response.data.token);
localStorage.setItem('username', values.username);
navigate('/');
} catch (err: any) {
const errorMessage = err.response?.data?.message || '登录失败,请检查用户名或密码。';
setError(errorMessage);
} finally {
setLoading(false);
}
};
return (
<div className="flex items-center justify-center min-h-screen bg-gray-100" style={{ background: '#f0f2f5',height: '100vh',display: 'flex',alignItems: 'center',justifyContent: 'center' }}>
<Card
className="w-full max-w-sm"
variant="borderless"
style={{
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
padding: '40px 24px 24px',
textAlign: 'center',
width: '500px',
margin: '0 auto 200px',
}}
>
<Space direction="vertical" size="large" style={{ width: '100%' }}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', marginBottom: 24 }}>
<CheckSquareOutlined style={{ fontSize: '48px', color: '#1890ff' }} />
<Title level={2} style={{ margin: '8px 0 0' }}>Todo List</Title>
<Text type="secondary"></Text>
</div>
{error && (
<Alert
message="账户或密码错误"
description={error}
type="error"
showIcon
closable
onClose={() => setError(null)}
style={{ marginBottom: 24 }}
/>
)}
<Form
name="login"
initialValues={{ remember: true }}
onFinish={onFinish}
autoComplete="off"
layout="vertical"
style={{ width: '100%' }}
>
<Form.Item
name="username"
rules={[{ required: true, message: '请输入用户名!' }]}
>
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder="账户"
size="large"
/>
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: '请输入密码!' }]}
>
<Input.Password
prefix={<LockOutlined className="site-form-item-icon" />}
placeholder="密码"
size="large"
/>
</Form.Item>
<Form.Item>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Checkbox></Checkbox>
<Space>
<Link href="/forgot-password"></Link>
<Link href="/register"></Link>
</Space>
</div>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="w-full" size="large" loading={loading} style={{width: '100%',}}>
</Button>
</Form.Item>
</Form>
</Space>
</Card>
</div>
);
}
export default Login;