50 lines
1.5 KiB
JavaScript
Executable File
50 lines
1.5 KiB
JavaScript
Executable File
// src/components/ProtectedRoute.js - 弹窗拦截版本
|
||
import React, { useEffect } from 'react';
|
||
import { Box, VStack, Spinner, Text } from '@chakra-ui/react';
|
||
import { useAuth } from '../contexts/AuthContext';
|
||
import { useAuthModal } from '../contexts/AuthModalContext';
|
||
|
||
const ProtectedRoute = ({ children }) => {
|
||
const { isAuthenticated, isLoading, user } = useAuth();
|
||
const { openAuthModal, isAuthModalOpen } = useAuthModal();
|
||
|
||
// 记录当前路径,登录成功后可以跳转回来
|
||
const currentPath = window.location.pathname + window.location.search;
|
||
|
||
// 未登录时自动弹出认证窗口
|
||
useEffect(() => {
|
||
if (!isLoading && !isAuthenticated && !user && !isAuthModalOpen) {
|
||
openAuthModal(currentPath);
|
||
}
|
||
}, [isAuthenticated, user, isLoading, isAuthModalOpen, currentPath, openAuthModal]);
|
||
|
||
// 显示加载状态
|
||
if (isLoading) {
|
||
return (
|
||
<Box
|
||
height="100vh"
|
||
display="flex"
|
||
alignItems="center"
|
||
justifyContent="center"
|
||
bg="gray.50"
|
||
>
|
||
<VStack spacing={4}>
|
||
<Spinner size="xl" color="blue.500" thickness="4px" />
|
||
<Text fontSize="lg" color="gray.600">正在验证登录状态...</Text>
|
||
</VStack>
|
||
</Box>
|
||
);
|
||
}
|
||
|
||
// 未登录时,渲染子组件 + 自动打开弹窗(通过 useEffect)
|
||
// 弹窗会在 useEffect 中自动触发,页面正常显示
|
||
if (!isAuthenticated || !user) {
|
||
return children;
|
||
}
|
||
|
||
// 已登录,渲染子组件
|
||
return children;
|
||
};
|
||
|
||
export default ProtectedRoute;
|