| // import React, { useState } from 'react'; |
| // import Login from '../../components/Auth/Login'; |
| // import Register from '../../components/Auth/Register'; |
| |
| // const AuthPage = () => { |
| // const [isRegister, setIsRegister] = useState(false); |
| |
| // return ( |
| // <div> |
| // {isRegister ? ( |
| // <Register onLoginClick={() => setIsRegister(false)} /> |
| // ) : ( |
| // <Login onRegisterClick={() => setIsRegister(true)} /> |
| // )} |
| // </div> |
| // ); |
| // }; |
| |
| // export default AuthPage; |
| |
| |
| |
| import { useState } from "react"; |
| import { Link } from "wouter"; |
| import "./AuthPage.css"; |
| import CryptoJS from "crypto-js"; |
| |
| |
| function AuthPage() { |
| const [activeTab, setActiveTab] = useState("login"); |
| |
| // Login form state |
| const [loginData, setLoginData] = useState({ |
| username: "", |
| password: "", |
| rememberMe: false, |
| }); |
| |
| // Register form state |
| const [registerData, setRegisterData] = useState({ |
| username: "", |
| email: "", |
| password: "", |
| confirmPassword: "", |
| inviteCode: "", |
| agreeTerms: false, |
| }); |
| |
| // Form errors |
| const [errors, setErrors] = useState({ |
| login: {}, |
| register: {}, |
| }); |
| |
| const hashPassword = (password) => { |
| return CryptoJS.SHA256(password).toString(CryptoJS.enc.Hex); |
| }; |
| |
| // Handle login form submission |
| const handleLogin = async (e) => { |
| e.preventDefault(); |
| |
| // 客户端验证 |
| const newErrors = {}; |
| if (!loginData.username) { |
| newErrors.username = "请输入用户名或邮箱"; |
| } |
| if (!loginData.password) { |
| newErrors.password = "请输入密码"; |
| } |
| |
| if (Object.keys(newErrors).length > 0) { |
| setErrors((prev) => ({ ...prev, login: newErrors })); |
| return; |
| } |
| |
| // 加密密码 |
| const hashedPassword = hashPassword(loginData.password); |
| |
| try { |
| const response = await fetch(`/echo/user/login`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ |
| username: loginData.username, |
| password: hashedPassword, |
| }), |
| }); |
| |
| if (!response.ok) { |
| throw new Error('登录失败'); |
| } |
| |
| const data = await response.json(); |
| |
| if (data.code !== 0 || !data.result) { |
| throw new Error(data.msg || '登录失败'); |
| } |
| |
| console.log('登录成功:', data); |
| localStorage.setItem('token', data.rows.token); |
| localStorage.setItem('userId', data.rows.userId); |
| window.location.href = '/'; |
| } catch (error) { |
| console.error('登录错误:', error.message); |
| setErrors((prev) => ({ |
| ...prev, |
| login: { message: error.message }, |
| })); |
| throw error; |
| } |
| }; |
| |
| // Handle register form submission |
| const handleRegister = async (e) => { |
| e.preventDefault(); |
| |
| // 客户端验证 |
| const newErrors = {}; |
| if (!registerData.username) { |
| newErrors.username = "请输入用户名"; |
| } |
| if (!registerData.email) { |
| newErrors.email = "请输入邮箱"; |
| } else if (!/\S+@\S+\.\S+/.test(registerData.email)) { |
| newErrors.email = "邮箱格式不正确"; |
| } |
| if (!registerData.password) { |
| newErrors.password = "请输入密码"; |
| } else if (registerData.password.length < 6) { |
| newErrors.password = "密码长度至少为6位"; |
| } |
| if (registerData.password !== registerData.confirmPassword) { |
| newErrors.confirmPassword = "两次输入的密码不一致"; |
| } |
| if (!registerData.agreeTerms) { |
| newErrors.agreeTerms = "请同意用户协议和隐私政策"; |
| } |
| |
| if (Object.keys(newErrors).length > 0) { |
| setErrors({ ...errors, register: newErrors }); |
| return; |
| } |
| |
| // 加密密码 |
| const hashedPassword = hashPassword(registerData.password); |
| |
| try { |
| const response = await fetch(`/echo/user/register`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ |
| username: registerData.username, |
| email: registerData.email, |
| password: hashedPassword, |
| inviteCode: registerData.inviteCode, |
| }), |
| }); |
| |
| if (!response.ok) { |
| throw new Error('注册失败'); |
| } |
| |
| const data = await response.json(); |
| if (data.code !== 0 || !data.result) { |
| throw new Error(data.msg || '注册失败'); |
| } |
| |
| console.log('注册成功:', data); |
| setActiveTab('login'); |
| alert('注册成功,请登录!'); |
| } catch (error) { |
| console.error('注册错误:', error.message); |
| setErrors((prev) => ({ |
| ...prev, |
| register: { message: error.message }, |
| })); |
| } |
| }; |
| |
| // Update login form data |
| const updateLoginData = (field, value) => { |
| setLoginData({ |
| ...loginData, |
| [field]: value, |
| }); |
| }; |
| |
| // Update register form data |
| const updateRegisterData = (field, value) => { |
| setRegisterData({ |
| ...registerData, |
| [field]: value, |
| }); |
| }; |
| |
| return ( |
| <div className="auth-container"> |
| <div className="auth-card"> |
| <div className="auth-header"> |
| <div className={`auth-tab ${activeTab === "login" ? "active" : ""}`} onClick={() => setActiveTab("login")}> |
| 登录 |
| </div> |
| <div className={`auth-tab ${activeTab === "register" ? "active" : ""}`} onClick={() => setActiveTab("register")}> |
| 注册 |
| </div> |
| </div> |
| |
| <div className="auth-content"> |
| {activeTab === "login" ? ( |
| <form className="auth-form" onSubmit={handleLogin}> |
| {errors.login.message && <div className="error-message">{errors.login.message}</div>} |
| <div className="form-group"> |
| <label htmlFor="login-username">用户名/邮箱</label> |
| <input |
| type="text" |
| id="login-username" |
| value={loginData.username} |
| onChange={(e) => updateLoginData("username", e.target.value)} |
| placeholder="请输入用户名或邮箱" |
| required |
| /> |
| {errors.login.username && <div className="error-message">{errors.login.username}</div>} |
| </div> |
| |
| <div className="form-group"> |
| <label htmlFor="login-password">密码</label> |
| <input |
| type="password" |
| id="login-password" |
| value={loginData.password} |
| onChange={(e) => updateLoginData("password", e.target.value)} |
| placeholder="请输入密码" |
| required |
| /> |
| {errors.login.password && <div className="error-message">{errors.login.password}</div>} |
| </div> |
| |
| <div className="form-group-inline"> |
| <div className="checkbox-container"> |
| <input |
| type="checkbox" |
| id="remember-me" |
| checked={loginData.rememberMe} |
| onChange={(e) => updateLoginData("rememberMe", e.target.checked)} |
| /> |
| <label htmlFor="remember-me">记住我</label> |
| </div> |
| <Link to="/forgot-password" className="forgot-password"> |
| 忘记密码? |
| </Link> |
| </div> |
| |
| <button type="submit" className="auth-button"> |
| 登录 |
| </button> |
| </form> |
| ) : ( |
| <form className="auth-form" onSubmit={handleRegister}> |
| {errors.register.message && <div className="error-message">{errors.register.message}</div>} |
| <div className="form-group"> |
| <label htmlFor="register-username">用户名</label> |
| <input |
| type="text" |
| id="register-username" |
| value={registerData.username} |
| onChange={(e) => updateRegisterData("username", e.target.value)} |
| placeholder="请输入用户名" |
| required |
| /> |
| {errors.register.username && <div className="error-message">{errors.register.username}</div>} |
| </div> |
| |
| <div className="form-group"> |
| <label htmlFor="register-email">邮箱</label> |
| <input |
| type="email" |
| id="register-email" |
| value={registerData.email} |
| onChange={(e) => updateRegisterData("email", e.target.value)} |
| placeholder="请输入邮箱" |
| required |
| /> |
| {errors.register.email && <div className="error-message">{errors.register.email}</div>} |
| </div> |
| |
| <div className="form-group"> |
| <label htmlFor="register-password">密码</label> |
| <input |
| type="password" |
| id="register-password" |
| value={registerData.password} |
| onChange={(e) => updateRegisterData("password", e.target.value)} |
| placeholder="请输入密码" |
| required |
| /> |
| {errors.register.password && <div className="error-message">{errors.register.password}</div>} |
| </div> |
| |
| <div className="form-group"> |
| <label htmlFor="register-confirm-password">确认密码</label> |
| <input |
| type="password" |
| id="register-confirm-password" |
| value={registerData.confirmPassword} |
| onChange={(e) => updateRegisterData("confirmPassword", e.target.value)} |
| placeholder="请再次输入密码" |
| required |
| /> |
| {errors.register.confirmPassword && ( |
| <div className="error-message">{errors.register.confirmPassword}</div> |
| )} |
| </div> |
| |
| <div className="form-group"> |
| <label htmlFor="register-inviteCode">邀请码</label> |
| <input |
| type="text" |
| id="register-inviteCode" |
| value={registerData.inviteCode} |
| onChange={(e) => updateRegisterData("inviteCode", e.target.value)} |
| placeholder="请输入邀请码" |
| /> |
| {errors.register.inviteCode && <div className="error-message">{errors.register.inviteCode}</div>} |
| </div> |
| |
| <button type="submit" className="auth-button"> |
| 注册 |
| </button> |
| </form> |
| )} |
| </div> |
| </div> |
| </div> |
| ); |
| } |
| |
| export default AuthPage; |