// src/views/Community/index.js import React, { useEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useSelector, useDispatch } from 'react-redux'; import { fetchPopularKeywords, fetchHotEvents } from '../../store/slices/communityDataSlice'; import { Box, Container, useColorModeValue, Alert, AlertIcon, AlertTitle, AlertDescription, Button, CloseButton, HStack, VStack, Text, } from '@chakra-ui/react'; // 导入组件 import DynamicNewsCard from './components/DynamicNewsCard'; import HotEventsSection from './components/HotEventsSection'; // 导入自定义 Hooks import { useEventData } from './hooks/useEventData'; import { useEventFilters } from './hooks/useEventFilters'; import { useCommunityEvents } from './hooks/useCommunityEvents'; import { logger } from '../../utils/logger'; import { useNotification } from '../../contexts/NotificationContext'; // 导航栏已由 MainLayout 提供,无需在此导入 const Community = () => { const navigate = useNavigate(); const dispatch = useDispatch(); // Redux状态 const { popularKeywords, hotEvents } = useSelector(state => state.communityData); // Chakra UI hooks const bgColor = useColorModeValue('gray.50', 'gray.900'); const alertBgColor = useColorModeValue('blue.50', 'blue.900'); const alertBorderColor = useColorModeValue('blue.200', 'blue.700'); // Ref:用于首次滚动到内容区域 const containerRef = useRef(null); // ⚡ 通知权限引导 const { browserPermission, requestBrowserPermission } = useNotification(); // 通知横幅显示状态 const [showNotificationBanner, setShowNotificationBanner] = useState(false); // 🎯 初始化Community埋点Hook const communityEvents = useCommunityEvents({ navigate }); // 自定义 Hooks const { filters, updateFilters, handlePageChange, handleEventClick, handleViewDetail } = useEventFilters({ navigate }); const { events, pagination, loading, lastUpdateTime } = useEventData(filters); // 加载热门关键词和热点事件(动态新闻由 DynamicNewsCard 内部管理) useEffect(() => { dispatch(fetchPopularKeywords()); dispatch(fetchHotEvents()); }, [dispatch]); // 🎯 追踪新闻列表查看(当事件列表加载完成后) useEffect(() => { if (events && events.length > 0 && !loading) { communityEvents.trackNewsListViewed({ totalCount: pagination?.total || events.length, sortBy: filters.sort, importance: filters.importance, dateRange: filters.date_range, industryFilter: filters.industry_code, }); } }, [events, loading, pagination, filters]); // ⚡ 检查通知权限状态,显示横幅提示 useEffect(() => { // 延迟3秒显示,让用户先浏览页面 const timer = setTimeout(() => { // 如果未授权或未请求过权限,显示横幅 if (browserPermission !== 'granted') { const hasClosedBanner = localStorage.getItem('notification_banner_closed'); if (!hasClosedBanner) { setShowNotificationBanner(true); logger.info('Community', '显示通知权限横幅'); } } }, 3000); return () => clearTimeout(timer); }, [browserPermission]); // 处理开启通知 const handleEnableNotifications = async () => { const permission = await requestBrowserPermission(); if (permission === 'granted') { setShowNotificationBanner(false); logger.info('Community', '通知权限已授予'); } }; // 处理关闭横幅 const handleCloseBanner = () => { setShowNotificationBanner(false); localStorage.setItem('notification_banner_closed', 'true'); logger.info('Community', '通知横幅已关闭'); }; // ⚡ 首次进入页面时滚动到内容区域(考虑导航栏高度) useEffect(() => { // 延迟执行,确保DOM已完全渲染 const timer = setTimeout(() => { if (containerRef.current) { // 滚动到容器顶部,自动考虑导航栏的高度 containerRef.current.scrollIntoView({ behavior: 'auto', block: 'start', inline: 'nearest' }); } }, 0); return () => clearTimeout(timer); }, []); // 空依赖数组,只在组件挂载时执行一次 return ( {/* 主内容区域 */} {/* 通知权限提示横幅 */} {showNotificationBanner && ( 开启桌面通知,不错过重要事件 即使浏览器最小化,也能第一时间接收新事件推送通知 )} {/* 热点事件区域 */} {/* 实时要闻·动态追踪 - 横向滚动 */} ); }; export default Community;