cnmksjs's picture
Upload 49 files
40e991e verified
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { LogIn, Mail, Lock, AlertCircle } from 'lucide-react';
import { authAPI } from '../utils/api';
import { User } from '../types';
interface LoginProps {
onLogin: (user: User, token: string) => void;
}
const Login: React.FC<LoginProps> = ({ onLogin }) => {
const [formData, setFormData] = useState({
email: '',
password: '',
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
setError('');
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setError('');
try {
const response = await authAPI.login(formData);
onLogin(response.user, response.token);
} catch (error: any) {
setError(error.response?.data?.message || '登录失败,请重试');
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div className="text-center">
<div className="mx-auto h-12 w-12 bg-primary-600 rounded-full flex items-center justify-center">
<LogIn className="h-6 w-6 text-white" />
</div>
<h2 className="mt-6 text-3xl font-bold text-gray-900">
登录到聊天室
</h2>
<p className="mt-2 text-sm text-gray-600">
还没有账号?{' '}
<Link
to="/register"
className="font-medium text-primary-600 hover:text-primary-500"
>
立即注册
</Link>
</p>
</div>
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
{error && (
<div className="bg-red-50 border border-red-200 rounded-lg p-4 flex items-center space-x-2">
<AlertCircle className="h-5 w-5 text-red-500" />
<span className="text-red-700 text-sm">{error}</span>
</div>
)}
<div className="space-y-4">
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
邮箱地址
</label>
<div className="mt-1 relative">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Mail className="h-5 w-5 text-gray-400" />
</div>
<input
id="email"
name="email"
type="email"
required
value={formData.email}
onChange={handleChange}
className="input-field pl-10"
placeholder="请输入邮箱地址"
/>
</div>
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
密码
</label>
<div className="mt-1 relative">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Lock className="h-5 w-5 text-gray-400" />
</div>
<input
id="password"
name="password"
type="password"
required
value={formData.password}
onChange={handleChange}
className="input-field pl-10"
placeholder="请输入密码"
/>
</div>
</div>
</div>
<button
type="submit"
disabled={loading}
className="w-full btn-primary disabled:opacity-50 disabled:cursor-not-allowed"
>
{loading ? (
<div className="flex items-center justify-center">
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
登录中...
</div>
) : (
'登录'
)}
</button>
</form>
</div>
</div>
);
};
export default Login;