// src\views\Authentication\SignUp/SignUpIllustration.js import React, { useState, useEffect } from "react"; import { Box, Button, Flex, FormControl, Input, Text, Heading, VStack, HStack, useToast, InputGroup, InputRightElement, IconButton, Center, FormErrorMessage, Link as ChakraLink, useDisclosure } from "@chakra-ui/react"; import { ViewIcon, ViewOffIcon } from "@chakra-ui/icons"; import { useNavigate } from "react-router-dom"; import axios from "axios"; import AuthBackground from '../../../components/Auth/AuthBackground'; import AuthHeader from '../../../components/Auth/AuthHeader'; import AuthFooter from '../../../components/Auth/AuthFooter'; import VerificationCodeInput from '../../../components/Auth/VerificationCodeInput'; import WechatRegister from '../../../components/Auth/WechatRegister'; import PrivacyPolicyModal from '../../../components/PrivacyPolicyModal'; import UserAgreementModal from '../../../components/UserAgreementModal'; const isProduction = process.env.NODE_ENV === 'production'; const API_BASE_URL = isProduction ? "" : process.env.REACT_APP_API_URL; export default function SignUpPage() { const [showPassword, setShowPassword] = useState(false); const [isLoading, setIsLoading] = useState(false); const [countdown, setCountdown] = useState(0); const [errors, setErrors] = useState({}); const [formData, setFormData] = useState({ username: "", email: "", phone: "", password: "", confirmPassword: "", verificationCode: "" }); const navigate = useNavigate(); const toast = useToast(); // 隐私政策弹窗状态 const { isOpen: isPrivacyModalOpen, onOpen: onPrivacyModalOpen, onClose: onPrivacyModalClose } = useDisclosure(); // 用户协议弹窗状态 const { isOpen: isUserAgreementModalOpen, onOpen: onUserAgreementModalOpen, onClose: onUserAgreementModalClose } = useDisclosure(); // 验证码登录状态 是否开启验证码 const [useVerificationCode, setUseVerificationCode] = useState(false); // 切换注册方式 const handleChangeMethod = () => { setUseVerificationCode(!useVerificationCode); // 切换到密码模式时清空验证码 if (useVerificationCode) { setFormData(prev => ({ ...prev, verificationCode: "" })); } }; // 发送验证码 const sendVerificationCode = async () => { const contact = formData.phone; const endpoint = "send-sms-code"; const fieldName = "phone"; if (!contact) { toast({ title: "请输入手机号", status: "warning", duration: 2000, }); return; } if (!/^1[3-9]\d{9}$/.test(contact)) { toast({ title: "请输入正确的手机号", status: "warning", duration: 2000, }); return; } try { setIsLoading(true); await axios.post(`${API_BASE_URL}/api/auth/${endpoint}`, { [fieldName]: contact }); toast({ title: "验证码已发送", description: "请查收短信", status: "success", duration: 3000, }); setCountdown(60); } catch (error) { toast({ title: "发送失败", description: error.response?.data?.error || "请稍后重试", status: "error", duration: 3000, }); } finally { setIsLoading(false); } }; // 倒计时效果 useEffect(() => { if (countdown > 0) { const timer = setTimeout(() => setCountdown(countdown - 1), 1000); return () => clearTimeout(timer); } }, [countdown]); // 表单验证 const validateForm = () => { const newErrors = {}; // 手机号验证(两种方式都需要) if (!formData.phone) { newErrors.phone = "请输入手机号"; } else if (!/^1[3-9]\d{9}$/.test(formData.phone)) { newErrors.phone = "请输入正确的手机号"; } if (useVerificationCode) { // 验证码注册方式:只验证手机号和验证码 if (!formData.verificationCode) { newErrors.verificationCode = "请输入验证码"; } } else { // 密码注册方式:验证用户名、密码和确认密码 if (!formData.password || formData.password.length < 6) { newErrors.password = "密码至少6个字符"; } if (formData.password !== formData.confirmPassword) { newErrors.confirmPassword = "两次密码不一致"; } } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; // 处理注册提交 const handleSubmit = async (e) => { e.preventDefault(); if (!validateForm()) { return; } setIsLoading(true); try { let endpoint, data; if (useVerificationCode) { // 验证码注册:只发送手机号和验证码 endpoint = "/api/auth/register/phone-code"; data = { phone: formData.phone, code: formData.verificationCode }; } else { // 密码注册:发送手机号、用户名和密码 endpoint = "/api/auth/register/phone"; data = { phone: formData.phone, username: formData.username, password: formData.password }; } await axios.post(`${API_BASE_URL}${endpoint}`, data); toast({ title: "注册成功", description: "即将跳转到登录页面", status: "success", duration: 2000, }); setTimeout(() => { navigate("/auth/sign-in"); }, 2000); } catch (error) { toast({ title: "注册失败", description: error.response?.data?.error || "请稍后重试", status: "error", duration: 3000, }); } finally { setIsLoading(false); } }; const handleInputChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); if (errors[name]) { setErrors(prev => ({ ...prev, [name]: "" })); } }; // 公用的用户名和密码输入框组件 const commonAuthFields = ( : } onClick={() => setShowPassword(!showPassword)} aria-label={showPassword ? "Hide password" : "Show password"} /> {errors.password} {errors.confirmPassword} ); return ( {/* 背景 */} {/* 主要内容 */} {/* 头部区域 */} {/* 左右布局 */} {/* 左侧:手机号注册 - 80% 宽度 */}
注册 {errors.phone} {/* 表单字段区域 */} { useVerificationCode ? ( {/* 隐藏的占位元素,保持与密码模式相同的高度 */} ) : ( <> {commonAuthFields} ) } {/* 协议同意文本 */} 注册登录即表示阅读并同意{" "} 《用户协议》 {" "}和{" "} 《隐私政策》
{/* 右侧:微信注册 - 20% 宽度 */}
{/* 隐私政策弹窗 */} {/* 用户协议弹窗 */}
); }