feat: 添加导航激活状态检测功能
- 使用 React Router 的 useLocation 钩子检测当前路径 - 为顶级导航菜单添加激活状态样式(蓝色背景 + 底部边框) - 为下拉菜单项添加激活状态样式(蓝色背景 + 左侧边框) - 支持桌面端和移动端抽屉菜单 - 解决用户无法感知当前导航位置的 UX 问题 激活路由映射: - 高频跟踪: /community, /concepts - 行情复盘: /limit-analyse, /stocks 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -34,7 +34,7 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
import { ChevronDownIcon, HamburgerIcon, SunIcon, MoonIcon } from '@chakra-ui/icons';
|
||||
import { FiStar, FiCalendar } from 'react-icons/fi';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import { useAuthModal } from '../../contexts/AuthModalContext';
|
||||
|
||||
@@ -45,12 +45,28 @@ import { useAuthModal } from '../../contexts/AuthModalContext';
|
||||
*/
|
||||
const NavItems = ({ isAuthenticated, user }) => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
// 辅助函数:判断导航项是否激活
|
||||
const isActive = (paths) => {
|
||||
return paths.some(path => location.pathname.includes(path));
|
||||
};
|
||||
|
||||
if (isAuthenticated && user) {
|
||||
return (
|
||||
<HStack spacing={8}>
|
||||
<Menu>
|
||||
<MenuButton as={Button} variant="ghost" rightIcon={<ChevronDownIcon />}>
|
||||
<MenuButton
|
||||
as={Button}
|
||||
variant="ghost"
|
||||
rightIcon={<ChevronDownIcon />}
|
||||
bg={isActive(['/community', '/concepts']) ? 'blue.50' : 'transparent'}
|
||||
color={isActive(['/community', '/concepts']) ? 'blue.600' : 'inherit'}
|
||||
fontWeight={isActive(['/community', '/concepts']) ? 'bold' : 'normal'}
|
||||
borderBottom={isActive(['/community', '/concepts']) ? '2px solid' : 'none'}
|
||||
borderColor="blue.600"
|
||||
_hover={{ bg: isActive(['/community', '/concepts']) ? 'blue.100' : 'gray.50' }}
|
||||
>
|
||||
高频跟踪
|
||||
</MenuButton>
|
||||
<MenuList minW="260px" p={2}>
|
||||
@@ -62,6 +78,10 @@ const NavItems = ({ isAuthenticated, user }) => {
|
||||
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'}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text fontSize="sm">新闻催化分析</Text>
|
||||
@@ -78,6 +98,10 @@ const NavItems = ({ isAuthenticated, user }) => {
|
||||
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'}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text fontSize="sm">概念中心</Text>
|
||||
@@ -89,7 +113,17 @@ const NavItems = ({ isAuthenticated, user }) => {
|
||||
</Menu>
|
||||
|
||||
<Menu>
|
||||
<MenuButton as={Button} variant="ghost" rightIcon={<ChevronDownIcon />}>
|
||||
<MenuButton
|
||||
as={Button}
|
||||
variant="ghost"
|
||||
rightIcon={<ChevronDownIcon />}
|
||||
bg={isActive(['/limit-analyse', '/stocks']) ? 'blue.50' : 'transparent'}
|
||||
color={isActive(['/limit-analyse', '/stocks']) ? 'blue.600' : 'inherit'}
|
||||
fontWeight={isActive(['/limit-analyse', '/stocks']) ? 'bold' : 'normal'}
|
||||
borderBottom={isActive(['/limit-analyse', '/stocks']) ? '2px solid' : 'none'}
|
||||
borderColor="blue.600"
|
||||
_hover={{ bg: isActive(['/limit-analyse', '/stocks']) ? 'blue.100' : 'gray.50' }}
|
||||
>
|
||||
行情复盘
|
||||
</MenuButton>
|
||||
<MenuList minW="260px" p={2}>
|
||||
@@ -101,6 +135,10 @@ const NavItems = ({ isAuthenticated, user }) => {
|
||||
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'}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text fontSize="sm">涨停分析</Text>
|
||||
@@ -114,6 +152,10 @@ const NavItems = ({ isAuthenticated, user }) => {
|
||||
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'}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text fontSize="sm">个股中心</Text>
|
||||
@@ -809,6 +851,9 @@ export default function HomeNavbar() {
|
||||
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>
|
||||
@@ -826,6 +871,10 @@ export default function HomeNavbar() {
|
||||
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>
|
||||
@@ -845,6 +894,10 @@ export default function HomeNavbar() {
|
||||
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>
|
||||
@@ -867,6 +920,10 @@ export default function HomeNavbar() {
|
||||
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>
|
||||
@@ -883,6 +940,10 @@ export default function HomeNavbar() {
|
||||
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>
|
||||
|
||||
Reference in New Issue
Block a user