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';
|
} 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 } from 'react-icons/fi';
|
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 { useAuth } from '../../contexts/AuthContext';
|
||||||
import { useAuthModal } from '../../contexts/AuthModalContext';
|
import { useAuthModal } from '../../contexts/AuthModalContext';
|
||||||
|
|
||||||
@@ -45,12 +45,28 @@ import { useAuthModal } from '../../contexts/AuthModalContext';
|
|||||||
*/
|
*/
|
||||||
const NavItems = ({ isAuthenticated, user }) => {
|
const NavItems = ({ isAuthenticated, user }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
// 辅助函数:判断导航项是否激活
|
||||||
|
const isActive = (paths) => {
|
||||||
|
return paths.some(path => location.pathname.includes(path));
|
||||||
|
};
|
||||||
|
|
||||||
if (isAuthenticated && user) {
|
if (isAuthenticated && user) {
|
||||||
return (
|
return (
|
||||||
<HStack spacing={8}>
|
<HStack spacing={8}>
|
||||||
<Menu>
|
<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>
|
</MenuButton>
|
||||||
<MenuList minW="260px" p={2}>
|
<MenuList minW="260px" p={2}>
|
||||||
@@ -62,6 +78,10 @@ const NavItems = ({ isAuthenticated, user }) => {
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
_hover={{ bg: 'gray.100' }}
|
_hover={{ bg: 'gray.100' }}
|
||||||
cursor="pointer"
|
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">
|
<Flex justify="space-between" align="center">
|
||||||
<Text fontSize="sm">新闻催化分析</Text>
|
<Text fontSize="sm">新闻催化分析</Text>
|
||||||
@@ -78,6 +98,10 @@ const NavItems = ({ isAuthenticated, user }) => {
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
_hover={{ bg: 'gray.100' }}
|
_hover={{ bg: 'gray.100' }}
|
||||||
cursor="pointer"
|
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">
|
<Flex justify="space-between" align="center">
|
||||||
<Text fontSize="sm">概念中心</Text>
|
<Text fontSize="sm">概念中心</Text>
|
||||||
@@ -89,7 +113,17 @@ const NavItems = ({ isAuthenticated, user }) => {
|
|||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
<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>
|
</MenuButton>
|
||||||
<MenuList minW="260px" p={2}>
|
<MenuList minW="260px" p={2}>
|
||||||
@@ -101,6 +135,10 @@ const NavItems = ({ isAuthenticated, user }) => {
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
_hover={{ bg: 'gray.100' }}
|
_hover={{ bg: 'gray.100' }}
|
||||||
cursor="pointer"
|
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">
|
<Flex justify="space-between" align="center">
|
||||||
<Text fontSize="sm">涨停分析</Text>
|
<Text fontSize="sm">涨停分析</Text>
|
||||||
@@ -114,6 +152,10 @@ const NavItems = ({ isAuthenticated, user }) => {
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
_hover={{ bg: 'gray.100' }}
|
_hover={{ bg: 'gray.100' }}
|
||||||
cursor="pointer"
|
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">
|
<Flex justify="space-between" align="center">
|
||||||
<Text fontSize="sm">个股中心</Text>
|
<Text fontSize="sm">个股中心</Text>
|
||||||
@@ -809,6 +851,9 @@ export default function HomeNavbar() {
|
|||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
|
bg={location.pathname === '/home' ? 'blue.50' : 'transparent'}
|
||||||
|
borderLeft={location.pathname === '/home' ? '3px solid' : 'none'}
|
||||||
|
borderColor="blue.600"
|
||||||
>
|
>
|
||||||
<Text fontSize="md">🏠 首页</Text>
|
<Text fontSize="md">🏠 首页</Text>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -826,6 +871,10 @@ export default function HomeNavbar() {
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
_hover={{ bg: 'gray.100' }}
|
_hover={{ bg: 'gray.100' }}
|
||||||
cursor="pointer"
|
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">
|
<HStack justify="space-between">
|
||||||
<Text fontSize="sm">新闻催化分析</Text>
|
<Text fontSize="sm">新闻催化分析</Text>
|
||||||
@@ -845,6 +894,10 @@ export default function HomeNavbar() {
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
_hover={{ bg: 'gray.100' }}
|
_hover={{ bg: 'gray.100' }}
|
||||||
cursor="pointer"
|
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">
|
<HStack justify="space-between">
|
||||||
<Text fontSize="sm">概念中心</Text>
|
<Text fontSize="sm">概念中心</Text>
|
||||||
@@ -867,6 +920,10 @@ export default function HomeNavbar() {
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
_hover={{ bg: 'gray.100' }}
|
_hover={{ bg: 'gray.100' }}
|
||||||
cursor="pointer"
|
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">
|
<HStack justify="space-between">
|
||||||
<Text fontSize="sm">涨停分析</Text>
|
<Text fontSize="sm">涨停分析</Text>
|
||||||
@@ -883,6 +940,10 @@ export default function HomeNavbar() {
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
_hover={{ bg: 'gray.100' }}
|
_hover={{ bg: 'gray.100' }}
|
||||||
cursor="pointer"
|
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">
|
<HStack justify="space-between">
|
||||||
<Text fontSize="sm">个股中心</Text>
|
<Text fontSize="sm">个股中心</Text>
|
||||||
|
|||||||
Reference in New Issue
Block a user