This commit is contained in:
2026-04-29 19:05:47 +08:00
parent b98c66ca21
commit 88c2fa5d03
40 changed files with 1781 additions and 2068 deletions
@@ -1,151 +1,69 @@
import { Component } from "react";
import { Navigate } from "react-router-dom";
import { Formik, Field, Form, ErrorMessage } from "formik";
import * as Yup from "yup";
/**
* @deprecated Use src/pages/sign-in.tsx instead.
* This file is kept for reference and is not used in the router.
*/
import { useState } from 'react';
import type { FormEvent } from 'react';
import { Navigate } from 'react-router';
import authService from '../services/auth.service';
import { useAuthStore } from '../stores/useAuthStore';
import AuthService from "../services/auth.service";
export default function Login() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [message, setMessage] = useState('');
const [redirect, setRedirect] = useState<string | null>(null);
type Props = {};
const user = useAuthStore((s) => s.user);
if (user || redirect) return <Navigate to={redirect ?? '/home'} />;
type State = {
redirect: string | null,
username: string,
password: string,
loading: boolean,
message: string
};
export default class Login extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.handleLogin = this.handleLogin.bind(this);
this.state = {
redirect: null,
username: "",
password: "",
loading: false,
message: ""
};
}
componentDidMount() {
const currentUser = AuthService.getCurrentUser();
if (currentUser) {
this.setState({ redirect: "/profile" });
};
}
componentWillUnmount() {
window.location.reload();
}
validationSchema() {
return Yup.object().shape({
username: Yup.string().required("This field is required!"),
password: Yup.string().required("This field is required!"),
});
}
handleLogin(formValue: { username: string; password: string }) {
const { username, password } = formValue;
this.setState({
message: "",
loading: true
});
AuthService.login(username, password).then(
() => {
this.setState({
redirect: "/profile"
});
},
error => {
const resMessage =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
this.setState({
loading: false,
message: resMessage
});
}
);
}
render() {
if (this.state.redirect) {
return <Navigate to={this.state.redirect} />
const handleLogin = async (e: FormEvent) => {
e.preventDefault();
setMessage('');
try {
await authService.login(username, password);
setRedirect('/home');
} catch (error: unknown) {
setMessage(error instanceof Error ? error.message : '登录失败');
}
};
const { loading, message } = this.state;
const initialValues = {
username: "",
password: "",
};
return (
<div className="col-md-12">
<div className="card card-container">
<img
src="//ssl.gstatic.com/accounts/ui/avatar_2x.png"
alt="profile-img"
className="profile-img-card"
/>
<Formik
initialValues={initialValues}
validationSchema={this.validationSchema}
onSubmit={this.handleLogin}
>
<Form>
<div className="form-group">
<label htmlFor="username">Username</label>
<Field name="username" type="text" className="form-control" />
<ErrorMessage
name="username"
component="div"
className="alert alert-danger"
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<Field name="password" type="password" className="form-control" />
<ErrorMessage
name="password"
component="div"
className="alert alert-danger"
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary btn-block" disabled={loading}>
{loading && (
<span className="spinner-border spinner-border-sm"></span>
)}
<span>Login</span>
</button>
</div>
{message && (
<div className="form-group">
<div className="alert alert-danger" role="alert">
{message}
</div>
</div>
)}
</Form>
</Formik>
</div>
return (
<div className="col-md-12">
<div className="card card-container">
<form onSubmit={(e) => void handleLogin(e)}>
<div className="form-group">
<label htmlFor="username">Username</label>
<input
id="username"
type="text"
className="form-control"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
className="form-control"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary btn-block">
Login
</button>
</div>
{message && (
<div className="alert alert-danger" role="alert">
{message}
</div>
)}
</form>
</div>
);
}
</div>
);
}