210 lines
5.5 KiB
JavaScript
210 lines
5.5 KiB
JavaScript
import React, { useState } from 'react'
|
||
import { Link, Navigate } from 'react-router-dom'
|
||
import { useAuth } from '../contexts/AuthContext'
|
||
import {
|
||
Container,
|
||
Paper,
|
||
TextField,
|
||
Button,
|
||
Typography,
|
||
Box,
|
||
Alert,
|
||
InputAdornment,
|
||
IconButton
|
||
} from '@mui/material'
|
||
import { Visibility, VisibilityOff, PersonAdd as RegisterIcon } from '@mui/icons-material'
|
||
|
||
const Register = () => {
|
||
const { register, user } = useAuth()
|
||
const [formData, setFormData] = useState({
|
||
username: '',
|
||
email: '',
|
||
password: '',
|
||
confirmPassword: ''
|
||
})
|
||
const [showPassword, setShowPassword] = useState(false)
|
||
const [showConfirmPassword, setShowConfirmPassword] = useState(false)
|
||
const [error, setError] = useState('')
|
||
const [loading, setLoading] = useState(false)
|
||
|
||
if (user) {
|
||
return <Navigate to="/dashboard" replace />
|
||
}
|
||
|
||
const handleChange = (e) => {
|
||
setFormData({
|
||
...formData,
|
||
[e.target.name]: e.target.value
|
||
})
|
||
}
|
||
|
||
const validateForm = () => {
|
||
if (formData.password !== formData.confirmPassword) {
|
||
setError('两次输入的密码不一致')
|
||
return false
|
||
}
|
||
if (formData.password.length < 6) {
|
||
setError('密码长度至少6位')
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
const handleSubmit = async (e) => {
|
||
e.preventDefault()
|
||
setError('')
|
||
|
||
if (!validateForm()) {
|
||
return
|
||
}
|
||
|
||
setLoading(true)
|
||
|
||
const { confirmPassword, ...userData } = formData
|
||
const result = await register(userData)
|
||
if (!result.success) {
|
||
setError(result.message)
|
||
}
|
||
setLoading(false)
|
||
}
|
||
|
||
return (
|
||
<Container maxWidth="sm">
|
||
<Box
|
||
sx={{
|
||
minHeight: '100vh',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center'
|
||
}}
|
||
>
|
||
<Paper
|
||
elevation={3}
|
||
sx={{
|
||
p: 4,
|
||
width: '100%',
|
||
maxWidth: 400
|
||
}}
|
||
>
|
||
<Box textAlign="center" mb={3}>
|
||
<RegisterIcon sx={{ fontSize: 48, color: 'primary.main', mb: 2 }} />
|
||
<Typography variant="h4" component="h1" gutterBottom>
|
||
注册
|
||
</Typography>
|
||
<Typography variant="body2" color="text.secondary">
|
||
创建您的账户
|
||
</Typography>
|
||
</Box>
|
||
|
||
{error && (
|
||
<Alert severity="error" sx={{ mb: 2 }}>
|
||
{error}
|
||
</Alert>
|
||
)}
|
||
|
||
<form onSubmit={handleSubmit}>
|
||
<TextField
|
||
fullWidth
|
||
label="用户名"
|
||
name="username"
|
||
value={formData.username}
|
||
onChange={handleChange}
|
||
margin="normal"
|
||
required
|
||
autoComplete="username"
|
||
/>
|
||
|
||
<TextField
|
||
fullWidth
|
||
label="邮箱"
|
||
name="email"
|
||
type="email"
|
||
value={formData.email}
|
||
onChange={handleChange}
|
||
margin="normal"
|
||
required
|
||
autoComplete="email"
|
||
/>
|
||
|
||
<TextField
|
||
fullWidth
|
||
label="密码"
|
||
name="password"
|
||
type={showPassword ? 'text' : 'password'}
|
||
value={formData.password}
|
||
onChange={handleChange}
|
||
margin="normal"
|
||
required
|
||
autoComplete="new-password"
|
||
InputProps={{
|
||
endAdornment: (
|
||
<InputAdornment position="end">
|
||
<IconButton
|
||
onClick={() => setShowPassword(!showPassword)}
|
||
edge="end"
|
||
>
|
||
{showPassword ? <VisibilityOff /> : <Visibility />}
|
||
</IconButton>
|
||
</InputAdornment>
|
||
)
|
||
}}
|
||
/>
|
||
|
||
<TextField
|
||
fullWidth
|
||
label="确认密码"
|
||
name="confirmPassword"
|
||
type={showConfirmPassword ? 'text' : 'password'}
|
||
value={formData.confirmPassword}
|
||
onChange={handleChange}
|
||
margin="normal"
|
||
required
|
||
autoComplete="new-password"
|
||
InputProps={{
|
||
endAdornment: (
|
||
<InputAdornment position="end">
|
||
<IconButton
|
||
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
|
||
edge="end"
|
||
>
|
||
{showConfirmPassword ? <VisibilityOff /> : <Visibility />}
|
||
</IconButton>
|
||
</InputAdornment>
|
||
)
|
||
}}
|
||
/>
|
||
|
||
<Button
|
||
type="submit"
|
||
fullWidth
|
||
variant="contained"
|
||
size="large"
|
||
disabled={loading}
|
||
sx={{ mt: 3, mb: 2 }}
|
||
>
|
||
{loading ? '注册中...' : '注册'}
|
||
</Button>
|
||
|
||
<Box textAlign="center">
|
||
<Typography variant="body2">
|
||
已有账户?{' '}
|
||
<Link to="/login" style={{ textDecoration: 'none' }}>
|
||
<Typography
|
||
component="span"
|
||
variant="body2"
|
||
color="primary"
|
||
sx={{ cursor: 'pointer' }}
|
||
>
|
||
立即登录
|
||
</Typography>
|
||
</Link>
|
||
</Typography>
|
||
</Box>
|
||
</form>
|
||
</Paper>
|
||
</Box>
|
||
</Container>
|
||
)
|
||
}
|
||
|
||
export default Register
|