Files
pdnode-account/src/pages/Register.jsx
2025-07-29 15:36:25 -07:00

210 lines
5.5 KiB
JavaScript
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 } 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