优化加入社团页面体验

This commit is contained in:
LazuliKao 2025-11-09 00:19:18 +08:00
parent 06b8f5cf79
commit c87e7a3f61

View file

@ -25,6 +25,7 @@ export default function JoinForm() {
const [loading, setLoading] = useState(false)// 添加加载状态
const [popoverOpen, setPopoverOpen] = useState(false)// 控制 Popover 显示
const [popoverMessage, setPopoverMessage] = useState("")// Popover 显示的消息
const [errors, setErrors] = useState<Record<string, string>>({})// 表单验证错误
// 在组件挂载时加载本地存储的数据
useEffect(() => {
@ -45,10 +46,60 @@ export default function JoinForm() {
// 处理表单输入变化
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target
// 如果是邮箱字段检查是否是QQ邮箱并自动填充QQ号
if (name === "email") {
const qqEmailMatch = value.match(/^(\d+)@qq\.com$/i)
if (qqEmailMatch) {
const qqNumber = qqEmailMatch[1]
setFormData(prevData => ({
...prevData,
[name]: value,
qq: qqNumber, // 自动填充QQ号
}))
}
else {
setFormData(prevData => ({
...prevData,
[name]: value,
}))
}
}
// 如果是QQ字段检查是否需要自动填充邮箱
else if (name === "qq") {
setFormData((prevData) => {
const newData = {
...prevData,
[name]: value,
}
// 只有在邮箱为空或者邮箱是数字@qq.com格式时才自动填充
const isEmailEmpty = !prevData.email || prevData.email.trim() === ""
const isEmailQQFormat = /^\d+@qq\.com$/i.test(prevData.email)
// 如果QQ号是纯数字且满足条件自动填充邮箱
if (value && /^\d+$/.test(value) && (isEmailEmpty || isEmailQQFormat)) {
newData.email = `${value}@qq.com`
}
return newData
})
}
else {
setFormData(prevData => ({
...prevData,
[name]: value,
}))
}
// 清除该字段的错误
if (errors[name]) {
setErrors((prev) => {
const newErrors = { ...prev }
delete newErrors[name]
return newErrors
})
}
setTimeout(() => {
try {
saveToLocalStorage()
@ -59,8 +110,51 @@ export default function JoinForm() {
}, 100)
}
// 验证表单
const validateForm = (): boolean => {
const newErrors: Record<string, string> = {}
// 姓名验证
if (!formData.name || formData.name.trim().length === 0) {
newErrors.name = "姓名不能为空"
}
// 学号验证
if (!formData.number || formData.number.trim().length === 0) {
newErrors.number = "学号不能为空"
}
// 专业验证
if (!formData.major || formData.major.trim().length === 0) {
newErrors.major = "专业不能为空"
}
// 班级验证
if (!formData.class || formData.class.trim().length === 0) {
newErrors.class = "班级不能为空"
}
// 邮箱验证
if (!formData.email || formData.email.trim().length === 0) {
newErrors.email = "邮箱不能为空"
}
else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
newErrors.email = "邮箱格式不正确"
}
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
// 处理表单提交
const handleSubmit = async () => {
// 验证表单
if (!validateForm()) {
setPopoverMessage("请填写所有必填项并确保格式正确")
setPopoverOpen(true)
return
}
setLoading(true)// 设置加载状态为 true
try {
await activeClient.freshman.postFreshmanAdd({
@ -96,6 +190,8 @@ export default function JoinForm() {
value={formData.name}
onChange={handleChange}
required
isInvalid={!!errors.name}
errorMessage={errors.name}
/>
<Input
name="class"
@ -103,6 +199,8 @@ export default function JoinForm() {
value={formData.class}
onChange={handleChange}
required
isInvalid={!!errors.class}
errorMessage={errors.class}
/>
<Input
name="number"
@ -110,6 +208,8 @@ export default function JoinForm() {
value={formData.number}
onChange={handleChange}
required
isInvalid={!!errors.number}
errorMessage={errors.number}
/>
<Input
name="major"
@ -117,6 +217,8 @@ export default function JoinForm() {
value={formData.major}
onChange={handleChange}
required
isInvalid={!!errors.major}
errorMessage={errors.major}
/>
</div>
<div className="flex flex-col gap-4">
@ -124,25 +226,25 @@ export default function JoinForm() {
便
</div>
<Input
name="phone"
placeholder="电话"
value={formData.phone}
name="email"
placeholder="邮箱"
value={formData.email}
onChange={handleChange}
required
isInvalid={!!errors.email}
errorMessage={errors.email}
/>
<Input
name="qq"
placeholder="QQ"
value={formData.qq}
onChange={handleChange}
required
/>
<Input
name="email"
placeholder="邮箱"
value={formData.email}
name="phone"
placeholder="电话"
value={formData.phone}
onChange={handleChange}
required
/>
</div>
<Textarea