diff --git a/src/pages/Login/Login.tsx b/src/pages/Login/Login.tsx index e69de29..90f04ca 100644 --- a/src/pages/Login/Login.tsx +++ b/src/pages/Login/Login.tsx @@ -0,0 +1,255 @@ +import { useState, useEffect } from 'react'; +import { useNavigate, useLocation } from 'react-router-dom'; +import { Icon } from '@iconify/react'; +import { motion } from 'framer-motion'; +import authService from '../../services/authService'; +import './Login.css'; + +interface LoginProps { + mode?: 'login' | 'register'; +} + +export default function Login({ mode = 'login' }: LoginProps) { + const navigate = useNavigate(); + const location = useLocation(); + const [isLogin, setIsLogin] = useState(mode === 'login'); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + + // Shared form data or separate? Let's use shared for email/password continuity + const [formData, setFormData] = useState({ + username: '', + email: '', + password: '', + }); + + // Redirect if authenticated + useEffect(() => { + if (authService.isAuthenticated()) { + const from = (location.state as { from?: { pathname: string } })?.from?.pathname || '/home'; + navigate(from, { replace: true }); + } + }, [navigate, location]); + + // Sync prop mode + useEffect(() => { + setIsLogin(mode === 'login'); + }, [mode]); + + const handleChange = (e: React.ChangeEvent) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + setError(''); + }; + + const handleRegister = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + setError(''); + try { + await authService.register({ + email: formData.email, + password: formData.password, + username: formData.username, + }); + navigate('/home'); + } catch (err: unknown) { + const errorMessage = err instanceof Error ? err.message : '注册失败,请重试'; + setError(errorMessage); + } finally { + setLoading(false); + } + }; + + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + setError(''); + try { + await authService.login({ + email: formData.email, + password: formData.password, + }); + navigate('/home'); + } catch (err: unknown) { + const errorMessage = err instanceof Error ? err.message : '登录失败,请重试'; + setError(errorMessage); + } finally { + setLoading(false); + } + }; + + const Particles = () => { + return ( +
+ {[...Array(15)].map((_, i) => ( + + ))} +
+ ); + }; + + return ( +
+ + +
+ {/* Sign Up Form */} +
+
+

创建账户

+ + 或使用邮箱注册 + +
+ +
+
+ +
+
+ +
+ + {error && !isLogin &&

{error}

} + + + +
+ setIsLogin(true)}>已有账户?去登录 +
+
+
+ + {/* Sign In Form */} +
+
+

欢迎回来

+ + 或使用账户登录 + +
+ +
+
+ +
+ +

忘记密码?

+ + {error && isLogin &&

{error}

} + + + +
+ setIsLogin(false)}>还没有账户?去注册 +
+
+
+ + {/* Overlay Container */} +
+
+
+

欢迎回来!

+

为了保持与我们的联系,请登录您的个人信息

+ +
+
+

你好,朋友!

+

输入您的个人详细信息并开始与我们一起管理旅程

+ +
+
+
+
+
+ ); +}