full-stack/client/src/pages/Login.tsx
2025-06-16 18:12:26 +08:00

64 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect } from 'react';
import { login } from '../api/auth';
import { useNavigate, Link } from 'react-router-dom';
const Login: React.FC = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const navigate = useNavigate();
const [isLogin, setIsLogin] = useState(!!localStorage.getItem('token'));
useEffect(() => {
const onStorage = () => setIsLogin(!!localStorage.getItem('token'));
window.addEventListener('storage', onStorage);
return () => window.removeEventListener('storage', onStorage);
}, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
try {
const res = await login(username, password);
localStorage.setItem('token', res.token);
localStorage.setItem('username', res.username);
window.dispatchEvent(new Event('tokenChange'));
navigate('/');
} catch (err: any) {
setError(err.response?.data?.message || '登录失败');
}
};
return (
<div className="min-h-screen bg-gray-100 flex flex-col items-center justify-center py-4 sm:py-10 px-1 sm:px-2">
<div className="w-full max-w-xs sm:max-w-md bg-white rounded-lg sm:rounded-xl shadow-lg p-4 sm:p-8">
<h2 className="text-2xl sm:text-3xl font-bold text-center mb-4 sm:mb-6 text-blue-600 tracking-tight"></h2>
<form onSubmit={handleSubmit} className="flex flex-col gap-2 sm:gap-4 mb-2">
<input
className="border rounded px-2 sm:px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400 text-sm sm:text-base"
type="text"
placeholder="用户名"
value={username}
onChange={e => setUsername(e.target.value)}
required
/>
<input
className="border rounded px-2 sm:px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-400 text-sm sm:text-base"
type="password"
placeholder="密码"
value={password}
onChange={e => setPassword(e.target.value)}
required
/>
{error && <div className="text-red-500 text-xs sm:text-sm text-center">{error}</div>}
<button className="bg-blue-500 text-white py-2 rounded hover:bg-blue-600 transition text-sm sm:text-base" type="submit"></button>
</form>
<div className="text-xs sm:text-sm text-center mt-3 sm:mt-4">
<Link to="/register" className="text-blue-500 hover:underline"></Link>
</div>
</div>
</div>
);
};
export default Login;