diff --git a/src/components/Navbars/HomeNavbar.js b/src/components/Navbars/HomeNavbar.js index 0fea6d3c..504a9822 100644 --- a/src/components/Navbars/HomeNavbar.js +++ b/src/components/Navbars/HomeNavbar.js @@ -6,37 +6,20 @@ import { Button, Container, useDisclosure, - Drawer, - DrawerBody, - DrawerHeader, - DrawerOverlay, - DrawerContent, - DrawerCloseButton, - VStack, HStack, Icon, Menu, MenuButton, MenuList, MenuItem, - MenuDivider, Badge, Grid, IconButton, useBreakpointValue, - Link, - Divider, - Avatar, Spinner, useColorMode, useColorModeValue, useToast, - Modal, - ModalOverlay, - ModalContent, - ModalHeader, - ModalBody, - ModalCloseButton, } from '@chakra-ui/react'; import { ChevronDownIcon, HamburgerIcon, SunIcon, MoonIcon } from '@chakra-ui/icons'; import { FiStar, FiCalendar, FiUser, FiSettings, FiHome, FiLogOut } from 'react-icons/fi'; @@ -63,6 +46,9 @@ import { DesktopUserMenu, TabletUserMenu } from './components/UserMenu'; // Phase 4 优化: 提取的导航菜单组件 import { DesktopNav, MoreMenu, PersonalCenterMenu } from './components/Navigation'; +// Phase 5 优化: 提取的移动端抽屉菜单组件 +import { MobileDrawer } from './components/MobileDrawer'; + /** 二级导航栏组件 - 显示当前一级菜单下的所有二级菜单项 */ const SecondaryNav = ({ showCompletenessAlert }) => { const navigate = useNavigate(); @@ -810,251 +796,15 @@ export default function HomeNavbar() { - {/* 移动端抽屉菜单 */} - - - - - - - 菜单 - {isAuthenticated && user && ( - 已登录 - )} - - - - - {/* 移动端:日夜模式切换 */} - - {/* 移动端用户信息 */} - {isAuthenticated && user && ( - <> - - - - - {getDisplayName()} - {user.email} - - - - - - )} - - {/* 首页链接 */} - { - 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" - > - 🏠 首页 - - - - 高频跟踪 - - { - 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'} - > - - 事件中心 - - HOT - NEW - - - - { - 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'} - > - - 概念中心 - NEW - - - - - - - 行情复盘 - - { - 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'} - > - - 涨停分析 - FREE - - - { - 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'} - > - - 个股中心 - HOT - - - { - 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'} - > - - 模拟盘 - NEW - - - - - - - - AGENT社群 - - - 今日热议 - - - 个股社区 - - - - - - 联系我们 - 敬请期待 - - - {/* 移动端登录/登出按钮 */} - - {isAuthenticated && user ? ( - - ) : ( - - )} - - - - + {/* 移动端抽屉菜单 (Phase 5 优化) */} + {/* 二级导航栏 - 显示当前页面所属的二级菜单 */} diff --git a/src/components/Navbars/components/MobileDrawer/MobileDrawer.js b/src/components/Navbars/components/MobileDrawer/MobileDrawer.js new file mode 100644 index 00000000..1649deff --- /dev/null +++ b/src/components/Navbars/components/MobileDrawer/MobileDrawer.js @@ -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 ( + + + + + + + 菜单 + {isAuthenticated && user && ( + 已登录 + )} + + + + + {/* 移动端:日夜模式切换 */} + + + {/* 移动端用户信息 */} + {isAuthenticated && user && ( + <> + + + + + {getDisplayName()} + {user.email} + + + + + + )} + + {/* 首页链接 */} + 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" + > + 🏠 首页 + + + + + {/* 高频跟踪 */} + + 高频跟踪 + + 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'} + > + + 事件中心 + + HOT + NEW + + + + 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'} + > + + 概念中心 + NEW + + + + + + + + {/* 行情复盘 */} + + 行情复盘 + + 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'} + > + + 涨停分析 + FREE + + + 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'} + > + + 个股中心 + HOT + + + 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'} + > + + 模拟盘 + NEW + + + + + + + + {/* AGENT社群 */} + + AGENT社群 + + + 今日热议 + + + 个股社区 + + + + + + + {/* 联系我们 */} + + 联系我们 + 敬请期待 + + + {/* 移动端登录/登出按钮 */} + + {isAuthenticated && user ? ( + + ) : ( + + )} + + + + + ); +}); + +MobileDrawer.displayName = 'MobileDrawer'; + +export default MobileDrawer; diff --git a/src/components/Navbars/components/MobileDrawer/index.js b/src/components/Navbars/components/MobileDrawer/index.js new file mode 100644 index 00000000..e18835e7 --- /dev/null +++ b/src/components/Navbars/components/MobileDrawer/index.js @@ -0,0 +1,4 @@ +// src/components/Navbars/components/MobileDrawer/index.js +// 移动端抽屉菜单组件统一导出 + +export { default as MobileDrawer } from './MobileDrawer';