// src/contexts/AuthModalContext.js import { createContext, useContext, useState, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from './AuthContext'; import { logger } from '../utils/logger'; const AuthModalContext = createContext(); /** * 自定义Hook:获取弹窗上下文 */ export const useAuthModal = () => { const context = useContext(AuthModalContext); if (!context) { throw new Error('useAuthModal must be used within AuthModalProvider'); } return context; }; /** * 认证弹窗提供者组件 * 管理统一的认证弹窗状态(登录/注册合并) */ export const AuthModalProvider = ({ children }) => { const navigate = useNavigate(); const { isAuthenticated } = useAuth(); // 弹窗状态(统一的认证弹窗) const [isAuthModalOpen, setIsAuthModalOpen] = useState(false); // 重定向URL(认证成功后跳转) const [redirectUrl, setRedirectUrl] = useState(null); // 成功回调函数 const [onSuccessCallback, setOnSuccessCallback] = useState(null); /** * 打开认证弹窗(统一的登录/注册入口) * @param {string} url - 认证成功后的重定向URL(可选) * @param {function} callback - 认证成功后的回调函数(可选) */ const openAuthModal = useCallback((url = null, callback = null) => { setRedirectUrl(url); setOnSuccessCallback(() => callback); setIsAuthModalOpen(true); }, []); /** * 关闭认证弹窗 * 如果用户未登录,跳转到首页 */ const closeModal = useCallback(() => { setIsAuthModalOpen(false); setRedirectUrl(null); setOnSuccessCallback(null); // ⭐ 如果用户关闭弹窗时仍未登录,跳转到首页 if (!isAuthenticated) { navigate('/home'); } }, [isAuthenticated, navigate]); /** * 登录/注册成功处理 * @param {object} user - 用户信息 */ const handleLoginSuccess = useCallback((user) => { // 执行自定义回调(如果有) if (onSuccessCallback) { try { onSuccessCallback(user); } catch (error) { logger.error('AuthModalContext', 'handleLoginSuccess', error, { userId: user?.id, hasCallback: !!onSuccessCallback }); } } // ⭐ 登录成功后,只关闭弹窗,留在当前页面(不跳转) // 移除了原有的 redirectUrl 跳转逻辑 setIsAuthModalOpen(false); setRedirectUrl(null); setOnSuccessCallback(null); }, [onSuccessCallback]); /** * 提供给子组件的上下文值 */ const value = { // 状态 isAuthModalOpen, redirectUrl, // 打开弹窗方法 openAuthModal, // 关闭弹窗方法 closeModal, // 成功处理方法 handleLoginSuccess, }; return ( {children} ); };