From c40589c8436f5307de7d46b6090c5a4e050d6e53 Mon Sep 17 00:00:00 2001 From: zyh Date: Tue, 22 Oct 2024 09:09:28 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=BB=A5=E6=94=AF=E6=8C=81=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E6=88=90=E5=8A=9F=E5=90=8E=E7=9A=84=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/auth/Login.tsx | 8 ++++- app/components/auth/LoginRegisterDialog.tsx | 39 +++++++++++++++++++++ app/components/auth/Register.tsx | 10 ++++-- app/components/auth/SubscriptionDialog.tsx | 18 +++++++--- 4 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 app/components/auth/LoginRegisterDialog.tsx diff --git a/app/components/auth/Login.tsx b/app/components/auth/Login.tsx index b6c94f9..05e6d1b 100644 --- a/app/components/auth/Login.tsx +++ b/app/components/auth/Login.tsx @@ -2,7 +2,12 @@ import React, { useState } from 'react'; import { useAuth } from '~/hooks/useAuth'; import type { LoginResponse } from '~/routes/api.auth.login'; -export function Login({ onClose }: { onClose: () => void }) { +interface LoginProps { + onClose: () => void; + onLoginSuccess: () => void; +} + +export function Login({ onClose, onLoginSuccess }: LoginProps) { const [phone, setPhone] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(null); @@ -24,6 +29,7 @@ export function Login({ onClose }: { onClose: () => void }) { if (response.ok && data.token && data.user) { login(data.token, data.user); onClose(); // 登录成功后关闭登录窗口 + onLoginSuccess(); } else { setError(data.error || '登录失败,请检查您的手机号和密码'); } diff --git a/app/components/auth/LoginRegisterDialog.tsx b/app/components/auth/LoginRegisterDialog.tsx new file mode 100644 index 0000000..0786334 --- /dev/null +++ b/app/components/auth/LoginRegisterDialog.tsx @@ -0,0 +1,39 @@ +import { useState } from 'react'; +import { Dialog, DialogTitle, DialogDescription, DialogRoot } from '~/components/ui/Dialog'; +import { Login } from './Login'; +import { Register } from './Register'; + +interface LoginRegisterDialogProps { + isOpen: boolean; + onClose: () => void; + onLoginSuccess: () => void; +} + +export function LoginRegisterDialog({ isOpen, onClose, onLoginSuccess }: LoginRegisterDialogProps) { + const [isLoginView, setIsLoginView] = useState(true); + + const toggleView = () => setIsLoginView(!isLoginView); + + return ( + + + {isLoginView ? '登录' : '注册'} + + {isLoginView ? ( + + ) : ( + + )} +
+ +
+
+
+
+ ); +} diff --git a/app/components/auth/Register.tsx b/app/components/auth/Register.tsx index 142b95a..3cbe6e4 100644 --- a/app/components/auth/Register.tsx +++ b/app/components/auth/Register.tsx @@ -3,7 +3,12 @@ import { useAuth } from '~/hooks/useAuth'; import type { RegisterResponse } from '~/routes/api.auth.register'; import { uploadToOSS } from '~/utils/uploadToOSS'; -export function Register() { +interface RegisterProps { + onClose: () => void; + onRegisterSuccess: () => void; +} + +export function Register({ onClose, onRegisterSuccess }: RegisterProps) { const [phone, setPhone] = useState(''); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); @@ -62,7 +67,8 @@ export function Register() { const data = await registerResponse.json() as RegisterResponse; if (registerResponse.ok && data.token && data.user) { login(data.token, data.user); - // 登录成功后,直接显示用户信息,不跳转 + onClose(); // 关闭注册窗口 + onRegisterSuccess(); // 调用注册成功的回调 } else { setError(data.error || '注册失败,请稍后再试'); } diff --git a/app/components/auth/SubscriptionDialog.tsx b/app/components/auth/SubscriptionDialog.tsx index 3dbe53b..380068b 100644 --- a/app/components/auth/SubscriptionDialog.tsx +++ b/app/components/auth/SubscriptionDialog.tsx @@ -3,6 +3,7 @@ import { useState, useEffect, useCallback } from 'react'; import { useAuth } from '~/hooks/useAuth'; import { toast } from 'react-toastify'; import { PaymentModal } from './PaymentModal'; +import { LoginRegisterDialog } from './LoginRegisterDialog'; import type { SubscriptionPlan } from '~/types/subscription'; import pkg from 'lodash'; const {toString} = pkg; @@ -46,6 +47,7 @@ export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps) const [isLoading, setIsLoading] = useState(true); const { user, token, isAuthenticated, login } = useAuth(); const [paymentData, setPaymentData] = useState(null); + const [isLoginRegisterOpen, setIsLoginRegisterOpen] = useState(false); useEffect(() => { if (isOpen) { @@ -94,10 +96,7 @@ export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps) const handlePurchase = async (planId: string) => { if (!isAuthenticated) { - // 如果用户未登录,提示用户登录 - toast.info('请先登录以继续购买'); - // 这里可以触发登录流程,例如打开登录对话框 - // openLoginDialog(); + setIsLoginRegisterOpen(true); return; } if (!token) { @@ -133,6 +132,12 @@ export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps) toast.success('订阅成功!'); }, [fetchUserSubscription]); + const handleLoginSuccess = useCallback(() => { + setIsLoginRegisterOpen(false); + fetchUserSubscription(); + toast.success('登录成功!'); + }, [fetchUserSubscription]); + if (isLoading) return null; return ( @@ -232,6 +237,11 @@ export function SubscriptionDialog({ isOpen, onClose }: SubscriptionDialogProps) onPaymentSuccess={handlePaymentSuccess} /> )} + setIsLoginRegisterOpen(false)} + onLoginSuccess={handleLoginSuccess} + /> ); }