KnowledgeBase_frontend/src/pages/auth/Signup.jsx
2025-04-12 13:37:23 -04:00

274 lines
10 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, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link, useNavigate } from 'react-router-dom';
import { checkAuthThunk, signupThunk } from '../../store/auth/auth.thunk';
// 部门和组别映射关系
const departmentGroups = {
达人部门: ['达人部门'],
商务部门: ['商务部门'],
样本中心: ['样本中心'],
产品部门: ['产品部门'],
AI自媒体: ['AI自媒体'],
HR: ['HR'],
技术部门: ['技术部门'],
};
export default function Signup() {
const dispatch = useDispatch();
const navigate = useNavigate();
const [formData, setFormData] = useState({
username: '',
email: '',
password: '',
name: '',
role: 'member',
department: '',
group: '',
});
const [errors, setErrors] = useState({});
const [submitted, setSubmitted] = useState(false);
const [availableGroups, setAvailableGroups] = useState([]);
const { user, loading } = useSelector((state) => state.auth);
useEffect(() => {
handleCheckAuth();
}, [dispatch]);
// 当部门变化时,更新可选的组别
useEffect(() => {
if (formData.department && departmentGroups[formData.department]) {
setAvailableGroups(departmentGroups[formData.department]);
// 如果已选择的组别不在新部门的选项中,则重置组别
if (!departmentGroups[formData.department].includes(formData.group)) {
setFormData(prev => ({
...prev,
group: ''
}));
}
} else {
setAvailableGroups([]);
setFormData(prev => ({
...prev,
group: ''
}));
}
}, [formData.department]);
const handleCheckAuth = async () => {
console.log('signup page handleCheckAuth');
try {
await dispatch(checkAuthThunk()).unwrap();
if (user) navigate('/');
} catch (error) {}
};
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
// 清除对应的错误信息
if (errors[name]) {
setErrors({
...errors,
[name]: '',
});
}
};
const validateForm = () => {
const newErrors = {};
if (!formData.username) {
newErrors.username = 'Username is required';
}
if (!formData.email) {
newErrors.email = 'Email is required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(formData.email)) {
newErrors.email = 'Invalid email address';
}
if (!formData.password) {
newErrors.password = 'Password is required';
} else if (formData.password.length < 6) {
newErrors.password = 'Password must be at least 6 characters';
}
if (!formData.name) {
newErrors.name = 'Name is required';
}
if (!formData.department) {
newErrors.department = '请选择部门';
}
if (!formData.group) {
newErrors.group = '请选择组别';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = async (e) => {
e.preventDefault();
setSubmitted(true);
if (validateForm()) {
console.log('Form submitted successfully!');
console.log('Registration data:', formData);
try {
await dispatch(signupThunk(formData)).unwrap();
navigate('/login');
} catch (error) {
console.error('Signup failed:', error);
}
}
};
return (
<div className='position-absolute top-50 start-50 translate-middle d-flex flex-column gap-4 align-items-center'>
<div className='title text-center h1'>OOIN 智能知识库</div>
<form
className='auth-form login-form d-flex flex-column gap-3 align-items-center'
onSubmit={handleSubmit}
noValidate
>
<div className='input-group has-validation'>
<input
type='text'
className={`form-control form-control-lg${submitted && errors.username ? ' is-invalid' : ''}`}
id='username'
name='username'
placeholder='用户名'
value={formData.username}
required
onChange={handleInputChange}
disabled={loading}
></input>
{submitted && errors.username && <div className='invalid-feedback'>{errors.username}</div>}
</div>
<div className='input-group has-validation'>
<input
type='email'
className={`form-control form-control-lg${submitted && errors.email ? ' is-invalid' : ''}`}
id='email'
name='email'
placeholder='邮箱'
value={formData.email}
required
onChange={handleInputChange}
disabled={loading}
></input>
{submitted && errors.email && <div className='invalid-feedback'>{errors.email}</div>}
</div>
<div className='input-group has-validation'>
<input
type='password'
id='password'
name='password'
placeholder='密码'
value={formData.password}
required
className={`form-control form-control-lg${submitted && errors.password ? ' is-invalid' : ''}`}
aria-describedby='passwordHelpBlock'
onChange={handleInputChange}
disabled={loading}
></input>
{submitted && errors.password && <div className='invalid-feedback'>{errors.password}</div>}
</div>
<div className='input-group has-validation'>
<input
type='text'
className={`form-control form-control-lg${submitted && errors.name ? ' is-invalid' : ''}`}
id='name'
name='name'
placeholder='姓名'
value={formData.name}
required
onChange={handleInputChange}
disabled={loading}
></input>
{submitted && errors.name && <div className='invalid-feedback'>{errors.name}</div>}
</div>
<div className='input-group has-validation'>
<select
className={`form-select form-select-lg${submitted && errors.department ? ' is-invalid' : ''}`}
id='department'
name='department'
value={formData.department}
onChange={handleInputChange}
disabled={loading}
required
>
<option value='' disabled>
选择部门
</option>
<option value='技术部'>技术部</option>
<option value='产品部'>产品部</option>
<option value='市场部'>市场部</option>
<option value='行政部'>行政部</option>
</select>
{submitted && errors.department && <div className='invalid-feedback'>{errors.department}</div>}
</div>
<div className='input-group has-validation'>
<select
className={`form-select form-select-lg${submitted && errors.group ? ' is-invalid' : ''}`}
id='group'
name='group'
value={formData.group}
onChange={handleInputChange}
disabled={loading || !formData.department}
required
>
<option value='' disabled>
{formData.department ? '选择组别' : '请先选择部门'}
</option>
{availableGroups.map((group, index) => (
<option key={index} value={group}>
{group}
</option>
))}
</select>
{submitted && errors.group && <div className='invalid-feedback'>{errors.group}</div>}
</div>
<div className='input-group'>
<select
className='form-select form-select-lg'
id='role'
name='role'
value={formData.role}
onChange={handleInputChange}
disabled={loading}
>
<option value='member'>普通成员</option>
<option value='leader'>组长</option>
<option value='admin'>管理员</option>
</select>
</div>
<button type='submit' className='btn btn-dark btn-lg w-100' disabled={loading}>
{loading ? (
<>
<span
className='spinner-border spinner-border-sm me-2'
role='status'
aria-hidden='true'
></span>
注册中...
</>
) : (
'注册'
)}
</button>
</form>
<Link to='/login' className='go-to-signup w-100 link-underline-light h5 text-center'>
已有账号立即登录
</Link>
</div>
);
}