blob: 19434a4f35a8fa3c3dad92b1474d9aa033379301 [file] [log] [blame]
ybtda5978b2025-05-31 15:58:05 +08001// src/features/auth/pages/LoginPage.jsx
2import React, { useState } from "react";
3import { useNavigate, Link } from "react-router-dom";
4import {
5 Form,
6 Input,
7 Button,
8 Checkbox,
9 Card,
10 Typography,
11 Space,
12 Divider,
13 message,
14} from "antd";
15import { UserOutlined, LockOutlined } from "@ant-design/icons";
16import { useAuth } from "../contexts/AuthContext"; // 使用新的 AuthContext
17// import { loginUser } from '../services/authApi'; // 如果不直接在 context 中调用 API
18
19const { Title, Text } = Typography;
20
21const LoginPage = () => {
22 const [loading, setLoading] = useState(false);
23 const navigate = useNavigate();
24 const { login, isAuthenticated, user } = useAuth(); // 从 Context 获取 login 方法等
25
26 React.useEffect(() => {
27 // 如果已经登录,并且有用户信息,则重定向到首页
28 if (isAuthenticated && user) {
29 navigate("/");
30 }
31 }, [isAuthenticated, user, navigate]);
32
33 const onFinish = async (values) => {
34 setLoading(true);
35 try {
36 await login({ username: values.username, password: values.password });
37 // 登录成功后的导航由 AuthContext 内部或 ProtectedRoute 处理
38 // AuthContext 已经包含成功提示,这里不再重复提示
39 navigate("/"); // 或者根据用户角色导航到不同页面
40 } catch (error) {
41 // 错误消息由 AuthContext 中的 login 方法或 request 拦截器处理
42 console.error("Login page error:", error);
43 } finally {
44 setLoading(false);
45 }
46 };
47
48 return (
49 <div className="flex justify-center items-center min-h-screen bg-slate-100 p-4">
50 {" "}
51 {/* Tailwind: bg-gray-100 -> bg-slate-100 */}
52 <Card className="w-full max-w-md shadow-lg rounded-lg">
53 {" "}
54 {/* Tailwind: rounded-lg */}
55 <div className="text-center mb-8">
56 {" "}
57 {/* Tailwind: mb-6 -> mb-8 */}
58 <Title level={2} className="!mb-2 text-slate-700">
59 PT站登录
60 </Title>{" "}
61 {/* Tailwind: text-slate-700 */}
62 <Text type="secondary">欢迎回来,请登录您的账号</Text>
63 </div>
64 <Form
65 name="login_form" // 最好给表单一个唯一的名字
66 initialValues={{ remember: true }}
67 onFinish={onFinish}
68 size="large"
69 layout="vertical"
70 className="space-y-6" // Tailwind: 间距控制
71 >
72 <Form.Item
73 name="username"
74 rules={[{ required: true, message: "请输入您的用户名!" }]}
75 >
76 <Input
77 prefix={<UserOutlined className="site-form-item-icon" />}
78 placeholder="用户名"
79 />
80 </Form.Item>
81 <Form.Item
82 name="password"
83 rules={[{ required: true, message: "请输入您的密码!" }]}
84 >
85 <Input.Password
86 prefix={<LockOutlined className="site-form-item-icon" />}
87 placeholder="密码"
88 />
89 </Form.Item>
90 <Form.Item className="!mb-0">
91 {" "}
92 {/* Tailwind: !mb-0 覆盖antd默认margin */}
93 <div className="flex justify-between items-center">
94 <Form.Item name="remember" valuePropName="checked" noStyle>
95 <Checkbox>记住我</Checkbox>
96 </Form.Item>
97 <Link
98 to="/forgot-password"
99 className="text-blue-600 hover:text-blue-700 hover:underline"
100 >
101 {" "}
102 {/* Tailwind: hover:underline */}
103 忘记密码?
104 </Link>
105 </div>
106 </Form.Item>
107 <Form.Item>
108 <Button
109 type="primary"
110 htmlType="submit"
111 className="w-full !text-base"
112 loading={loading}
113 >
114 {" "}
115 {/* Tailwind: !text-base (示例) */}登
116 </Button>
117 </Form.Item>
118 <Divider plain>
119 <span className="text-slate-500">或</span>
120 </Divider>{" "}
121 {/* Tailwind: text-slate-500 */}
122 <div className="text-center">
123 <Text type="secondary" className="mr-1">
124 还没有账号?
125 </Text>
126 <Link
127 to="/register"
128 className="font-medium text-blue-600 hover:text-blue-700 hover:underline"
129 >
130 立即注册
131 </Link>
132 </div>
133 </Form>
134 {/* 提示信息部分可以保留或移除 */}
135 <div className="mt-8 p-4 bg-slate-50 rounded-md border border-slate-200">
136 {" "}
137 {/* Tailwind: border, border-slate-200 */}
138 <Text
139 type="secondary"
140 className="block mb-2 font-semibold text-slate-600"
141 >
142 测试账号提示
143 </Text>
144 <ul className="space-y-1 text-sm text-slate-500 list-disc list-inside">
145 <li>管理员: admin / admin123</li>
146 <li>普通用户: user / user123</li>
147 {/* ...其他测试账号 */}
148 </ul>
149 </div>
150 </Card>
151 </div>
152 );
153};
154
155export default LoginPage;