cnmksjs's picture
Upload 49 files
24fd742 verified
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { UserPlus, Mail, Lock, User as UserIcon, AlertCircle } from 'lucide-react';
import { authAPI } from '../utils/api';
import { User } from '../types';
interface RegisterProps {
onRegister: (user: User, token: string) => void;
}
const Register: React.FC<RegisterProps> = ({ onRegister }) => {
const [formData, setFormData] = useState({
username: '',
email: '',
password: '',
confirmPassword: '',
});
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('');
if (formData.password !== formData.confirmPassword) {
setError('两次输入的密码不一致');
setLoading(false);
return;
}
if (formData.password.length < 6) {
setError('密码长度至少为6位');
setLoading(false);
return;
}
try {
const { confirmPassword, ...registerData } = formData;
const response = await authAPI.register(registerData);
onRegister(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">
<UserPlus 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="/login"
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="username" 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">
<UserIcon className="h-5 w-5 text-gray-400" />
</div>
<input
id="username"
name="username"
type="text"
required
value={formData.username}
onChange={handleChange}
className="input-field pl-10"
placeholder="请输入用户名"
/>
</div>
</div>
<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="请输入密码(至少6位)"
/>
</div>
</div>
<div>
<label htmlFor="confirmPassword" 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="confirmPassword"
name="confirmPassword"
type="password"
required
value={formData.confirmPassword}
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 Register;