| import { useState } from "react"; |
| import { Link } from "wouter"; |
| import "./AuthPage.css"; |
| // import logo from '../../assets/logo.png'; |
| import { ReactComponent as LogoIcon } from '../../assets/logo.svg'; |
| // import backgroundImage from '../../assets/b.png'; |
| |
| 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: "", |
| }); |
| |
| // Form errors |
| const [errors, setErrors] = useState({ |
| login: {}, |
| register: {}, |
| }); |
| |
| // 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; |
| } |
| |
| try { |
| const response = await fetch("/echo/user/login", { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ |
| username: loginData.username, |
| password: loginData.password, |
| }), |
| }); |
| |
| const data = await response.json(); |
| |
| if (data.msg === "登录成功" && data.user) { |
| // 保存用户信息到 localStorage |
| localStorage.setItem("user", JSON.stringify(data.user)); |
| localStorage.setItem("userId", data.user.userId); // 如果有 id 字段 |
| window.location.href = '/forum'; |
| } else { |
| throw new Error(data.msg || "登录失败"); |
| } |
| } catch (error) { |
| console.error('登录错误:', error.message); |
| setErrors((prev) => ({ |
| ...prev, |
| login: { message: error.message }, |
| })); |
| } |
| }; |
| |
| |
| // 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 (Object.keys(newErrors).length > 0) { |
| setErrors((prev) => ({ ...prev, register: newErrors })); |
| return; |
| } |
| |
| 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: registerData.password, // 原始密码 |
| role: "user", |
| inviteCode: registerData.inviteCode, |
| }), |
| }); |
| |
| const data = await response.json(); |
| |
| if (data.msg === "注册成功") { |
| alert("注册成功,请登录!"); |
| setActiveTab("login"); |
| } else { |
| throw new Error(data.msg || "注册失败"); |
| } |
| } 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="logo-container"> |
| <LogoIcon className="site-logo" /> |
| </div> |
| |
| {/* <div className="auth-card"> */} |
| <div className="glass-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; |