From 3f96c9c6502243b06efd4bb34a189e72e3a5557c Mon Sep 17 00:00:00 2001
From: yearning <10538594+wangweifeng1999@user.noreply.gitee.com>
Date: 星期一, 28 九月 2026 19:24:55 +0800
Subject: [PATCH] 复制项目
---
frontend/src/pages/LoginPage.tsx | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/frontend/src/pages/LoginPage.tsx b/frontend/src/pages/LoginPage.tsx
new file mode 100644
index 0000000..884d325
--- /dev/null
+++ b/frontend/src/pages/LoginPage.tsx
@@ -0,0 +1,48 @@
+import { useState } from "react";
+import { Button, Card, Form, Input, message } from "antd";
+import { useNavigate } from "react-router-dom";
+import { api, setToken } from "../api";
+import type { UserMe } from "../App";
+import "./LoginPage.css";
+import SystemBrand from "../components/SystemBrand";
+
+export default function LoginPage({ onLogin }: { onLogin: (u: UserMe) => void }) {
+ const nav = useNavigate();
+ const [loading, setLoading] = useState(false);
+ return (
+ <div className="login-page">
+ <div className="login-page__brand login-glass">
+ <SystemBrand size="lg" />
+ </div>
+ <Card title="鐧诲綍" className="login-page__card">
+ <Form
+ layout="vertical"
+ onFinish={async (v) => {
+ setLoading(true);
+ try {
+ const { data } = await api.post<{ access_token: string }>("/api/auth/login", v);
+ setToken(data.access_token);
+ const me = await api.get<UserMe>("/api/auth/me");
+ onLogin(me.data);
+ nav("/scores");
+ } catch {
+ message.error("鐧诲綍澶辫触");
+ } finally {
+ setLoading(false);
+ }
+ }}
+ >
+ <Form.Item name="username" label="璐﹀彿" rules={[{ required: true }]}>
+ <Input />
+ </Form.Item>
+ <Form.Item name="password" label="瀵嗙爜" rules={[{ required: true }]}>
+ <Input.Password />
+ </Form.Item>
+ <Button type="primary" htmlType="submit" block loading={loading}>
+ 鐧诲綍
+ </Button>
+ </Form>
+ </Card>
+ </div>
+ );
+}
--
Gitblit v1.8.0