refactor(HomeNavbar): Phase 5 - 提取移动端抽屉菜单组件
**背景**
继 Phase 1-4 后,进一步优化 HomeNavbar 的移动端菜单结构
**重构内容**
1. **新增组件目录** `src/components/Navbars/components/MobileDrawer/`
- MobileDrawer.js (314行) - 移动端完整抽屉菜单
* 用户信息展示
* 日夜模式切换
* 完整导航菜单(高频跟踪、行情复盘、AGENT社群、联系我们)
* 登录/退出登录按钮
- index.js - 统一导出
2. **HomeNavbar.js 优化**
- 删除 ~262 行移动端 Drawer JSX 代码
- 精简 Chakra UI 导入(移除 Drawer、DrawerBody、DrawerHeader 等 12 个组件)
- 替换为 MobileDrawer 组件调用
- 1065 → 815 行 (-250行, -23%)
**技术亮点**
- React.memo 优化渲染性能
- 封装导航点击逻辑(handleNavigate)
- 独立管理主题切换状态
- 响应式颜色模式(useColorModeValue)
- 完整的用户状态判断和 UI 展示
**累计成果** (Phase 1-5)
- 原始: 1623 行
- 当前: 815 行
- 减少: 808 行 (-50%)
- 提取: 11 个组件
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6,37 +6,20 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Container,
|
Container,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
Drawer,
|
|
||||||
DrawerBody,
|
|
||||||
DrawerHeader,
|
|
||||||
DrawerOverlay,
|
|
||||||
DrawerContent,
|
|
||||||
DrawerCloseButton,
|
|
||||||
VStack,
|
|
||||||
HStack,
|
HStack,
|
||||||
Icon,
|
Icon,
|
||||||
Menu,
|
Menu,
|
||||||
MenuButton,
|
MenuButton,
|
||||||
MenuList,
|
MenuList,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
MenuDivider,
|
|
||||||
Badge,
|
Badge,
|
||||||
Grid,
|
Grid,
|
||||||
IconButton,
|
IconButton,
|
||||||
useBreakpointValue,
|
useBreakpointValue,
|
||||||
Link,
|
|
||||||
Divider,
|
|
||||||
Avatar,
|
|
||||||
Spinner,
|
Spinner,
|
||||||
useColorMode,
|
useColorMode,
|
||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
useToast,
|
useToast,
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalHeader,
|
|
||||||
ModalBody,
|
|
||||||
ModalCloseButton,
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { ChevronDownIcon, HamburgerIcon, SunIcon, MoonIcon } from '@chakra-ui/icons';
|
import { ChevronDownIcon, HamburgerIcon, SunIcon, MoonIcon } from '@chakra-ui/icons';
|
||||||
import { FiStar, FiCalendar, FiUser, FiSettings, FiHome, FiLogOut } from 'react-icons/fi';
|
import { FiStar, FiCalendar, FiUser, FiSettings, FiHome, FiLogOut } from 'react-icons/fi';
|
||||||
@@ -63,6 +46,9 @@ import { DesktopUserMenu, TabletUserMenu } from './components/UserMenu';
|
|||||||
// Phase 4 优化: 提取的导航菜单组件
|
// Phase 4 优化: 提取的导航菜单组件
|
||||||
import { DesktopNav, MoreMenu, PersonalCenterMenu } from './components/Navigation';
|
import { DesktopNav, MoreMenu, PersonalCenterMenu } from './components/Navigation';
|
||||||
|
|
||||||
|
// Phase 5 优化: 提取的移动端抽屉菜单组件
|
||||||
|
import { MobileDrawer } from './components/MobileDrawer';
|
||||||
|
|
||||||
/** 二级导航栏组件 - 显示当前一级菜单下的所有二级菜单项 */
|
/** 二级导航栏组件 - 显示当前一级菜单下的所有二级菜单项 */
|
||||||
const SecondaryNav = ({ showCompletenessAlert }) => {
|
const SecondaryNav = ({ showCompletenessAlert }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -810,251 +796,15 @@ export default function HomeNavbar() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
{/* 移动端抽屉菜单 */}
|
{/* 移动端抽屉菜单 (Phase 5 优化) */}
|
||||||
<Drawer isOpen={isOpen} placement="right" onClose={onClose}>
|
<MobileDrawer
|
||||||
<DrawerOverlay />
|
isOpen={isOpen}
|
||||||
<DrawerContent>
|
onClose={onClose}
|
||||||
<DrawerCloseButton />
|
isAuthenticated={isAuthenticated}
|
||||||
<DrawerHeader>
|
user={user}
|
||||||
<HStack>
|
handleLogout={handleLogout}
|
||||||
<Text>菜单</Text>
|
openAuthModal={openAuthModal}
|
||||||
{isAuthenticated && user && (
|
|
||||||
<Badge colorScheme="green" ml={2}>已登录</Badge>
|
|
||||||
)}
|
|
||||||
</HStack>
|
|
||||||
</DrawerHeader>
|
|
||||||
<DrawerBody>
|
|
||||||
<VStack spacing={4} align="stretch">
|
|
||||||
{/* 移动端:日夜模式切换 */}
|
|
||||||
<Button
|
|
||||||
leftIcon={colorMode === 'light' ? <MoonIcon /> : <SunIcon />}
|
|
||||||
variant="ghost"
|
|
||||||
justifyContent="flex-start"
|
|
||||||
onClick={toggleColorMode}
|
|
||||||
size="sm"
|
|
||||||
>
|
|
||||||
切换到{colorMode === 'light' ? '深色' : '浅色'}模式
|
|
||||||
</Button>
|
|
||||||
{/* 移动端用户信息 */}
|
|
||||||
{isAuthenticated && user && (
|
|
||||||
<>
|
|
||||||
<Box p={3} bg={useColorModeValue('gray.50', 'whiteAlpha.100')} borderRadius="md">
|
|
||||||
<HStack>
|
|
||||||
<Avatar
|
|
||||||
size="sm"
|
|
||||||
name={getDisplayName()}
|
|
||||||
src={user.avatar_url}
|
|
||||||
bg="blue.500"
|
|
||||||
/>
|
/>
|
||||||
<Box>
|
|
||||||
<Text fontSize="sm" fontWeight="bold">{getDisplayName()}</Text>
|
|
||||||
<Text fontSize="xs" color={useColorModeValue('gray.500', 'gray.300')}>{user.email}</Text>
|
|
||||||
</Box>
|
|
||||||
</HStack>
|
|
||||||
</Box>
|
|
||||||
<Divider />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 首页链接 */}
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/home');
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
py={2}
|
|
||||||
px={3}
|
|
||||||
borderRadius="md"
|
|
||||||
_hover={{ bg: 'gray.100' }}
|
|
||||||
cursor="pointer"
|
|
||||||
color="blue.500"
|
|
||||||
fontWeight="bold"
|
|
||||||
bg={location.pathname === '/home' ? 'blue.50' : 'transparent'}
|
|
||||||
borderLeft={location.pathname === '/home' ? '3px solid' : 'none'}
|
|
||||||
borderColor="blue.600"
|
|
||||||
>
|
|
||||||
<Text fontSize="md">🏠 首页</Text>
|
|
||||||
</Link>
|
|
||||||
<Divider />
|
|
||||||
<Box>
|
|
||||||
<Text fontWeight="bold" mb={2}>高频跟踪</Text>
|
|
||||||
<VStack spacing={2} align="stretch">
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/community');
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
py={1}
|
|
||||||
px={3}
|
|
||||||
borderRadius="md"
|
|
||||||
_hover={{ bg: 'gray.100' }}
|
|
||||||
cursor="pointer"
|
|
||||||
bg={location.pathname.includes('/community') ? 'blue.50' : 'transparent'}
|
|
||||||
borderLeft={location.pathname.includes('/community') ? '3px solid' : 'none'}
|
|
||||||
borderColor="blue.600"
|
|
||||||
fontWeight={location.pathname.includes('/community') ? 'bold' : 'normal'}
|
|
||||||
>
|
|
||||||
<HStack justify="space-between">
|
|
||||||
<Text fontSize="sm">事件中心</Text>
|
|
||||||
<HStack spacing={1}>
|
|
||||||
<Badge size="xs" colorScheme="green">HOT</Badge>
|
|
||||||
<Badge size="xs" colorScheme="red">NEW</Badge>
|
|
||||||
</HStack>
|
|
||||||
</HStack>
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/concepts');
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
py={1}
|
|
||||||
px={3}
|
|
||||||
borderRadius="md"
|
|
||||||
_hover={{ bg: 'gray.100' }}
|
|
||||||
cursor="pointer"
|
|
||||||
bg={location.pathname.includes('/concepts') ? 'blue.50' : 'transparent'}
|
|
||||||
borderLeft={location.pathname.includes('/concepts') ? '3px solid' : 'none'}
|
|
||||||
borderColor="blue.600"
|
|
||||||
fontWeight={location.pathname.includes('/concepts') ? 'bold' : 'normal'}
|
|
||||||
>
|
|
||||||
<HStack justify="space-between">
|
|
||||||
<Text fontSize="sm">概念中心</Text>
|
|
||||||
<Badge size="xs" colorScheme="red">NEW</Badge>
|
|
||||||
</HStack>
|
|
||||||
</Link>
|
|
||||||
</VStack>
|
|
||||||
</Box>
|
|
||||||
<Divider />
|
|
||||||
<Box>
|
|
||||||
<Text fontWeight="bold" mb={2}>行情复盘</Text>
|
|
||||||
<VStack spacing={2} align="stretch">
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/limit-analyse');
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
py={1}
|
|
||||||
px={3}
|
|
||||||
borderRadius="md"
|
|
||||||
_hover={{ bg: 'gray.100' }}
|
|
||||||
cursor="pointer"
|
|
||||||
bg={location.pathname.includes('/limit-analyse') ? 'blue.50' : 'transparent'}
|
|
||||||
borderLeft={location.pathname.includes('/limit-analyse') ? '3px solid' : 'none'}
|
|
||||||
borderColor="blue.600"
|
|
||||||
fontWeight={location.pathname.includes('/limit-analyse') ? 'bold' : 'normal'}
|
|
||||||
>
|
|
||||||
<HStack justify="space-between">
|
|
||||||
<Text fontSize="sm">涨停分析</Text>
|
|
||||||
<Badge size="xs" colorScheme="blue">FREE</Badge>
|
|
||||||
</HStack>
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/stocks');
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
py={1}
|
|
||||||
px={3}
|
|
||||||
borderRadius="md"
|
|
||||||
_hover={{ bg: 'gray.100' }}
|
|
||||||
cursor="pointer"
|
|
||||||
bg={location.pathname.includes('/stocks') ? 'blue.50' : 'transparent'}
|
|
||||||
borderLeft={location.pathname.includes('/stocks') ? '3px solid' : 'none'}
|
|
||||||
borderColor="blue.600"
|
|
||||||
fontWeight={location.pathname.includes('/stocks') ? 'bold' : 'normal'}
|
|
||||||
>
|
|
||||||
<HStack justify="space-between">
|
|
||||||
<Text fontSize="sm">个股中心</Text>
|
|
||||||
<Badge size="xs" colorScheme="green">HOT</Badge>
|
|
||||||
</HStack>
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/trading-simulation');
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
py={1}
|
|
||||||
px={3}
|
|
||||||
borderRadius="md"
|
|
||||||
_hover={{ bg: 'gray.100' }}
|
|
||||||
cursor="pointer"
|
|
||||||
bg={location.pathname.includes('/trading-simulation') ? 'blue.50' : 'transparent'}
|
|
||||||
borderLeft={location.pathname.includes('/trading-simulation') ? '3px solid' : 'none'}
|
|
||||||
borderColor="blue.600"
|
|
||||||
fontWeight={location.pathname.includes('/trading-simulation') ? 'bold' : 'normal'}
|
|
||||||
>
|
|
||||||
<HStack justify="space-between">
|
|
||||||
<Text fontSize="sm">模拟盘</Text>
|
|
||||||
<Badge size="xs" colorScheme="red">NEW</Badge>
|
|
||||||
</HStack>
|
|
||||||
</Link>
|
|
||||||
</VStack>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Divider />
|
|
||||||
<Box>
|
|
||||||
<Text fontWeight="bold" mb={2}>AGENT社群</Text>
|
|
||||||
<VStack spacing={2} align="stretch">
|
|
||||||
<Link
|
|
||||||
py={1}
|
|
||||||
px={3}
|
|
||||||
borderRadius="md"
|
|
||||||
_hover={{}}
|
|
||||||
cursor="not-allowed"
|
|
||||||
color="gray.400"
|
|
||||||
pointerEvents="none"
|
|
||||||
>
|
|
||||||
<Text fontSize="sm" color="gray.400">今日热议</Text>
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
py={1}
|
|
||||||
px={3}
|
|
||||||
borderRadius="md"
|
|
||||||
_hover={{}}
|
|
||||||
cursor="not-allowed"
|
|
||||||
color="gray.400"
|
|
||||||
pointerEvents="none"
|
|
||||||
>
|
|
||||||
<Text fontSize="sm" color="gray.400">个股社区</Text>
|
|
||||||
</Link>
|
|
||||||
</VStack>
|
|
||||||
</Box>
|
|
||||||
<Divider />
|
|
||||||
<Box>
|
|
||||||
<Text fontWeight="bold" mb={2}>联系我们</Text>
|
|
||||||
<Text fontSize="sm" color={useColorModeValue('gray.500', 'gray.300')}>敬请期待</Text>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 移动端登录/登出按钮 */}
|
|
||||||
<Divider />
|
|
||||||
{isAuthenticated && user ? (
|
|
||||||
<Button
|
|
||||||
colorScheme="red"
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
handleLogout();
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
🚪 退出登录
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Button
|
|
||||||
colorScheme="blue"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
openAuthModal();
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
🔐 登录 / 注册
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</VStack>
|
|
||||||
</DrawerBody>
|
|
||||||
</DrawerContent>
|
|
||||||
</Drawer>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* 二级导航栏 - 显示当前页面所属的二级菜单 */}
|
{/* 二级导航栏 - 显示当前页面所属的二级菜单 */}
|
||||||
|
|||||||
314
src/components/Navbars/components/MobileDrawer/MobileDrawer.js
Normal file
314
src/components/Navbars/components/MobileDrawer/MobileDrawer.js
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
// src/components/Navbars/components/MobileDrawer/MobileDrawer.js
|
||||||
|
// 移动端抽屉菜单组件
|
||||||
|
|
||||||
|
import React, { memo } from 'react';
|
||||||
|
import {
|
||||||
|
Drawer,
|
||||||
|
DrawerOverlay,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerCloseButton,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerBody,
|
||||||
|
VStack,
|
||||||
|
HStack,
|
||||||
|
Box,
|
||||||
|
Text,
|
||||||
|
Button,
|
||||||
|
Badge,
|
||||||
|
Link,
|
||||||
|
Divider,
|
||||||
|
Avatar,
|
||||||
|
useColorMode,
|
||||||
|
useColorModeValue
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { SunIcon, MoonIcon } from '@chakra-ui/icons';
|
||||||
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动端抽屉菜单组件
|
||||||
|
* 包含完整的导航菜单和用户功能
|
||||||
|
*
|
||||||
|
* @param {Object} props
|
||||||
|
* @param {boolean} props.isOpen - Drawer 是否打开
|
||||||
|
* @param {Function} props.onClose - 关闭 Drawer 的回调
|
||||||
|
* @param {boolean} props.isAuthenticated - 用户是否已登录
|
||||||
|
* @param {Object} props.user - 用户信息
|
||||||
|
* @param {Function} props.handleLogout - 退出登录回调
|
||||||
|
* @param {Function} props.openAuthModal - 打开登录弹窗回调
|
||||||
|
*/
|
||||||
|
const MobileDrawer = memo(({
|
||||||
|
isOpen,
|
||||||
|
onClose,
|
||||||
|
isAuthenticated,
|
||||||
|
user,
|
||||||
|
handleLogout,
|
||||||
|
openAuthModal
|
||||||
|
}) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
|
const { colorMode, toggleColorMode } = useColorMode();
|
||||||
|
const userBgColor = useColorModeValue('gray.50', 'whiteAlpha.100');
|
||||||
|
const contactTextColor = useColorModeValue('gray.500', 'gray.300');
|
||||||
|
const emailTextColor = useColorModeValue('gray.500', 'gray.300');
|
||||||
|
|
||||||
|
// 获取显示名称
|
||||||
|
const getDisplayName = () => {
|
||||||
|
if (!user) return '用户';
|
||||||
|
if (user.nickname) return user.nickname;
|
||||||
|
if (user.username) return user.username;
|
||||||
|
if (user.email) return user.email.split('@')[0];
|
||||||
|
if (user.phone) return user.phone;
|
||||||
|
return '用户';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 导航点击处理
|
||||||
|
const handleNavigate = (path) => {
|
||||||
|
navigate(path);
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Drawer isOpen={isOpen} placement="right" onClose={onClose}>
|
||||||
|
<DrawerOverlay />
|
||||||
|
<DrawerContent>
|
||||||
|
<DrawerCloseButton />
|
||||||
|
<DrawerHeader>
|
||||||
|
<HStack>
|
||||||
|
<Text>菜单</Text>
|
||||||
|
{isAuthenticated && user && (
|
||||||
|
<Badge colorScheme="green" ml={2}>已登录</Badge>
|
||||||
|
)}
|
||||||
|
</HStack>
|
||||||
|
</DrawerHeader>
|
||||||
|
<DrawerBody>
|
||||||
|
<VStack spacing={4} align="stretch">
|
||||||
|
{/* 移动端:日夜模式切换 */}
|
||||||
|
<Button
|
||||||
|
leftIcon={colorMode === 'light' ? <MoonIcon /> : <SunIcon />}
|
||||||
|
variant="ghost"
|
||||||
|
justifyContent="flex-start"
|
||||||
|
onClick={toggleColorMode}
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
切换到{colorMode === 'light' ? '深色' : '浅色'}模式
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
{/* 移动端用户信息 */}
|
||||||
|
{isAuthenticated && user && (
|
||||||
|
<>
|
||||||
|
<Box p={3} bg={userBgColor} borderRadius="md">
|
||||||
|
<HStack>
|
||||||
|
<Avatar
|
||||||
|
size="sm"
|
||||||
|
name={getDisplayName()}
|
||||||
|
src={user.avatar_url}
|
||||||
|
bg="blue.500"
|
||||||
|
/>
|
||||||
|
<Box>
|
||||||
|
<Text fontSize="sm" fontWeight="bold">{getDisplayName()}</Text>
|
||||||
|
<Text fontSize="xs" color={emailTextColor}>{user.email}</Text>
|
||||||
|
</Box>
|
||||||
|
</HStack>
|
||||||
|
</Box>
|
||||||
|
<Divider />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 首页链接 */}
|
||||||
|
<Link
|
||||||
|
onClick={() => handleNavigate('/home')}
|
||||||
|
py={2}
|
||||||
|
px={3}
|
||||||
|
borderRadius="md"
|
||||||
|
_hover={{ bg: 'gray.100' }}
|
||||||
|
cursor="pointer"
|
||||||
|
color="blue.500"
|
||||||
|
fontWeight="bold"
|
||||||
|
bg={location.pathname === '/home' ? 'blue.50' : 'transparent'}
|
||||||
|
borderLeft={location.pathname === '/home' ? '3px solid' : 'none'}
|
||||||
|
borderColor="blue.600"
|
||||||
|
>
|
||||||
|
<Text fontSize="md">🏠 首页</Text>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
{/* 高频跟踪 */}
|
||||||
|
<Box>
|
||||||
|
<Text fontWeight="bold" mb={2}>高频跟踪</Text>
|
||||||
|
<VStack spacing={2} align="stretch">
|
||||||
|
<Link
|
||||||
|
onClick={() => handleNavigate('/community')}
|
||||||
|
py={1}
|
||||||
|
px={3}
|
||||||
|
borderRadius="md"
|
||||||
|
_hover={{ bg: 'gray.100' }}
|
||||||
|
cursor="pointer"
|
||||||
|
bg={location.pathname.includes('/community') ? 'blue.50' : 'transparent'}
|
||||||
|
borderLeft={location.pathname.includes('/community') ? '3px solid' : 'none'}
|
||||||
|
borderColor="blue.600"
|
||||||
|
fontWeight={location.pathname.includes('/community') ? 'bold' : 'normal'}
|
||||||
|
>
|
||||||
|
<HStack justify="space-between">
|
||||||
|
<Text fontSize="sm">事件中心</Text>
|
||||||
|
<HStack spacing={1}>
|
||||||
|
<Badge size="xs" colorScheme="green">HOT</Badge>
|
||||||
|
<Badge size="xs" colorScheme="red">NEW</Badge>
|
||||||
|
</HStack>
|
||||||
|
</HStack>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
onClick={() => handleNavigate('/concepts')}
|
||||||
|
py={1}
|
||||||
|
px={3}
|
||||||
|
borderRadius="md"
|
||||||
|
_hover={{ bg: 'gray.100' }}
|
||||||
|
cursor="pointer"
|
||||||
|
bg={location.pathname.includes('/concepts') ? 'blue.50' : 'transparent'}
|
||||||
|
borderLeft={location.pathname.includes('/concepts') ? '3px solid' : 'none'}
|
||||||
|
borderColor="blue.600"
|
||||||
|
fontWeight={location.pathname.includes('/concepts') ? 'bold' : 'normal'}
|
||||||
|
>
|
||||||
|
<HStack justify="space-between">
|
||||||
|
<Text fontSize="sm">概念中心</Text>
|
||||||
|
<Badge size="xs" colorScheme="red">NEW</Badge>
|
||||||
|
</HStack>
|
||||||
|
</Link>
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
{/* 行情复盘 */}
|
||||||
|
<Box>
|
||||||
|
<Text fontWeight="bold" mb={2}>行情复盘</Text>
|
||||||
|
<VStack spacing={2} align="stretch">
|
||||||
|
<Link
|
||||||
|
onClick={() => handleNavigate('/limit-analyse')}
|
||||||
|
py={1}
|
||||||
|
px={3}
|
||||||
|
borderRadius="md"
|
||||||
|
_hover={{ bg: 'gray.100' }}
|
||||||
|
cursor="pointer"
|
||||||
|
bg={location.pathname.includes('/limit-analyse') ? 'blue.50' : 'transparent'}
|
||||||
|
borderLeft={location.pathname.includes('/limit-analyse') ? '3px solid' : 'none'}
|
||||||
|
borderColor="blue.600"
|
||||||
|
fontWeight={location.pathname.includes('/limit-analyse') ? 'bold' : 'normal'}
|
||||||
|
>
|
||||||
|
<HStack justify="space-between">
|
||||||
|
<Text fontSize="sm">涨停分析</Text>
|
||||||
|
<Badge size="xs" colorScheme="blue">FREE</Badge>
|
||||||
|
</HStack>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
onClick={() => handleNavigate('/stocks')}
|
||||||
|
py={1}
|
||||||
|
px={3}
|
||||||
|
borderRadius="md"
|
||||||
|
_hover={{ bg: 'gray.100' }}
|
||||||
|
cursor="pointer"
|
||||||
|
bg={location.pathname.includes('/stocks') ? 'blue.50' : 'transparent'}
|
||||||
|
borderLeft={location.pathname.includes('/stocks') ? '3px solid' : 'none'}
|
||||||
|
borderColor="blue.600"
|
||||||
|
fontWeight={location.pathname.includes('/stocks') ? 'bold' : 'normal'}
|
||||||
|
>
|
||||||
|
<HStack justify="space-between">
|
||||||
|
<Text fontSize="sm">个股中心</Text>
|
||||||
|
<Badge size="xs" colorScheme="green">HOT</Badge>
|
||||||
|
</HStack>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
onClick={() => handleNavigate('/trading-simulation')}
|
||||||
|
py={1}
|
||||||
|
px={3}
|
||||||
|
borderRadius="md"
|
||||||
|
_hover={{ bg: 'gray.100' }}
|
||||||
|
cursor="pointer"
|
||||||
|
bg={location.pathname.includes('/trading-simulation') ? 'blue.50' : 'transparent'}
|
||||||
|
borderLeft={location.pathname.includes('/trading-simulation') ? '3px solid' : 'none'}
|
||||||
|
borderColor="blue.600"
|
||||||
|
fontWeight={location.pathname.includes('/trading-simulation') ? 'bold' : 'normal'}
|
||||||
|
>
|
||||||
|
<HStack justify="space-between">
|
||||||
|
<Text fontSize="sm">模拟盘</Text>
|
||||||
|
<Badge size="xs" colorScheme="red">NEW</Badge>
|
||||||
|
</HStack>
|
||||||
|
</Link>
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
{/* AGENT社群 */}
|
||||||
|
<Box>
|
||||||
|
<Text fontWeight="bold" mb={2}>AGENT社群</Text>
|
||||||
|
<VStack spacing={2} align="stretch">
|
||||||
|
<Link
|
||||||
|
py={1}
|
||||||
|
px={3}
|
||||||
|
borderRadius="md"
|
||||||
|
_hover={{}}
|
||||||
|
cursor="not-allowed"
|
||||||
|
color="gray.400"
|
||||||
|
pointerEvents="none"
|
||||||
|
>
|
||||||
|
<Text fontSize="sm" color="gray.400">今日热议</Text>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
py={1}
|
||||||
|
px={3}
|
||||||
|
borderRadius="md"
|
||||||
|
_hover={{}}
|
||||||
|
cursor="not-allowed"
|
||||||
|
color="gray.400"
|
||||||
|
pointerEvents="none"
|
||||||
|
>
|
||||||
|
<Text fontSize="sm" color="gray.400">个股社区</Text>
|
||||||
|
</Link>
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
{/* 联系我们 */}
|
||||||
|
<Box>
|
||||||
|
<Text fontWeight="bold" mb={2}>联系我们</Text>
|
||||||
|
<Text fontSize="sm" color={contactTextColor}>敬请期待</Text>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 移动端登录/登出按钮 */}
|
||||||
|
<Divider />
|
||||||
|
{isAuthenticated && user ? (
|
||||||
|
<Button
|
||||||
|
colorScheme="red"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
handleLogout();
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
🚪 退出登录
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
colorScheme="blue"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
openAuthModal();
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
🔐 登录 / 注册
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</VStack>
|
||||||
|
</DrawerBody>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
MobileDrawer.displayName = 'MobileDrawer';
|
||||||
|
|
||||||
|
export default MobileDrawer;
|
||||||
4
src/components/Navbars/components/MobileDrawer/index.js
Normal file
4
src/components/Navbars/components/MobileDrawer/index.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// src/components/Navbars/components/MobileDrawer/index.js
|
||||||
|
// 移动端抽屉菜单组件统一导出
|
||||||
|
|
||||||
|
export { default as MobileDrawer } from './MobileDrawer';
|
||||||
Reference in New Issue
Block a user