diff --git a/src/components/Navbars/HomeNavbar.js b/src/components/Navbars/HomeNavbar.js index 81045a90..9641ec04 100644 --- a/src/components/Navbars/HomeNavbar.js +++ b/src/components/Navbars/HomeNavbar.js @@ -50,9 +50,13 @@ import { getApiBase } from '../../utils/apiConfig'; import SubscriptionButton from '../Subscription/SubscriptionButton'; import SubscriptionModal from '../Subscription/SubscriptionModal'; import { CrownIcon, TooltipContent } from '../Subscription/CrownTooltip'; -import InvestmentCalendar from '../../views/Community/components/InvestmentCalendar'; import { useNavigationEvents } from '../../hooks/useNavigationEvents'; +// Phase 1 优化: 提取的子组件 +import BrandLogo from './components/BrandLogo'; +import LoginButton from './components/LoginButton'; +import CalendarButton from './components/CalendarButton'; + /** 二级导航栏组件 - 显示当前一级菜单下的所有二级菜单项 */ const SecondaryNav = ({ showCompletenessAlert }) => { const navigate = useNavigate(); @@ -560,8 +564,8 @@ export default function HomeNavbar() { const WATCHLIST_PAGE_SIZE = 10; const EVENTS_PAGE_SIZE = 8; - // 投资日历 Modal 状态 - const [calendarModalOpen, setCalendarModalOpen] = useState(false); + // 投资日历 Modal 状态 - 已移至 CalendarButton 组件内部管理 + // const [calendarModalOpen, setCalendarModalOpen] = useState(false); // 用户信息完整性状态 const [profileCompleteness, setProfileCompleteness] = useState(null); @@ -897,24 +901,7 @@ export default function HomeNavbar() { {/* Logo - 价小前投研 */} - - { - // 🎯 追踪Logo点击 - navEvents.trackLogoClicked(); - navigate('/home'); - }} - style={{ minWidth: isMobile ? '100px' : '140px' }} - noOfLines={1} - > - 价小前投研 - - + {/* 中间导航区域 - 响应式 */} {isMobile ? ( @@ -958,18 +945,7 @@ export default function HomeNavbar() { // 已登录状态 - 用户菜单 + 功能菜单排列 {/* 投资日历 - 仅大屏显示 */} - {isDesktop && ( - - )} + {isDesktop && } {/* 自选股 - 仅大屏显示 */} {isDesktop && ( @@ -1336,19 +1312,7 @@ export default function HomeNavbar() { ) : ( // 未登录状态 - 单一按钮 - + )} @@ -1604,21 +1568,7 @@ export default function HomeNavbar() { {/* 二级导航栏 - 显示当前页面所属的二级菜单 */} {!isMobile && } - {/* 投资日历 Modal */} - setCalendarModalOpen(false)} - size="6xl" - > - - - 投资日历 - - - - - - + {/* 投资日历 Modal - 已移至 CalendarButton 组件内部 */} ); } \ No newline at end of file diff --git a/src/components/Navbars/components/BrandLogo.js b/src/components/Navbars/components/BrandLogo.js new file mode 100644 index 00000000..0ee1820b --- /dev/null +++ b/src/components/Navbars/components/BrandLogo.js @@ -0,0 +1,51 @@ +// src/components/Navbars/components/BrandLogo.js +import React, { memo } from 'react'; +import { HStack, Text, useColorModeValue, useBreakpointValue } from '@chakra-ui/react'; +import { useNavigate } from 'react-router-dom'; +import { useNavigationEvents } from '../../../hooks/useNavigationEvents'; + +/** + * 品牌 Logo 组件 + * + * 性能优化: + * - 使用 memo 避免父组件重新渲染时的不必要更新 + * - 没有外部 props,完全自包含 + * + * @returns {JSX.Element} + */ +const BrandLogo = memo(() => { + const navigate = useNavigate(); + const isMobile = useBreakpointValue({ base: true, md: false }); + const brandText = useColorModeValue('gray.800', 'white'); + const brandHover = useColorModeValue('blue.600', 'blue.300'); + + // 🎯 初始化导航埋点Hook + const navEvents = useNavigationEvents({ component: 'brand_logo' }); + + const handleClick = () => { + // 🎯 追踪Logo点击 + navEvents.trackLogoClicked(); + navigate('/home'); + }; + + return ( + + + 价小前投研 + + + ); +}); + +BrandLogo.displayName = 'BrandLogo'; + +export default BrandLogo; diff --git a/src/components/Navbars/components/CalendarButton.js b/src/components/Navbars/components/CalendarButton.js new file mode 100644 index 00000000..90da16d0 --- /dev/null +++ b/src/components/Navbars/components/CalendarButton.js @@ -0,0 +1,65 @@ +// src/components/Navbars/components/CalendarButton.js +import React, { memo, useState } from 'react'; +import { + Button, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalBody, + ModalCloseButton +} from '@chakra-ui/react'; +import { FiCalendar } from 'react-icons/fi'; +import InvestmentCalendar from '../../../views/Community/components/InvestmentCalendar'; + +/** + * 投资日历按钮组件 + * + * 功能: + * - 显示投资日历按钮 + * - 点击打开 Modal 显示日历内容 + * + * 性能优化: + * - 使用 memo 避免父组件重新渲染时的不必要更新 + * - Modal 状态内部管理,不影响父组件 + * + * @returns {JSX.Element} + */ +const CalendarButton = memo(() => { + const [isModalOpen, setIsModalOpen] = useState(false); + + return ( + <> + + + {/* 投资日历 Modal */} + setIsModalOpen(false)} + size="6xl" + > + + + 投资日历 + + + + + + + + ); +}); + +CalendarButton.displayName = 'CalendarButton'; + +export default CalendarButton; diff --git a/src/components/Navbars/components/LoginButton.js b/src/components/Navbars/components/LoginButton.js new file mode 100644 index 00000000..2e4732fc --- /dev/null +++ b/src/components/Navbars/components/LoginButton.js @@ -0,0 +1,37 @@ +// src/components/Navbars/components/LoginButton.js +import React, { memo } from 'react'; +import { Button } from '@chakra-ui/react'; +import { useAuthModal } from '../../../hooks/useAuthModal'; + +/** + * 登录/注册按钮组件 + * + * 性能优化: + * - 使用 memo 避免父组件重新渲染时的不必要更新 + * - 纯展示组件,无复杂逻辑 + * + * @returns {JSX.Element} + */ +const LoginButton = memo(() => { + const { openAuthModal } = useAuthModal(); + + return ( + + ); +}); + +LoginButton.displayName = 'LoginButton'; + +export default LoginButton;