// src/views/Community/components/DynamicNewsCard/EventScrollList.js // 横向滚动事件列表组件 import React, { useRef } from 'react'; import { Box, Flex, Grid, IconButton, Button, ButtonGroup, Center, VStack, Spinner, Text, useColorModeValue } from '@chakra-ui/react'; import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons'; import DynamicNewsEventCard from '../EventCard/DynamicNewsEventCard'; import PaginationControl from './PaginationControl'; /** * 事件列表组件 - 支持两种展示模式 * @param {Array} events - 当前页的事件列表(服务端已分页) * @param {Object} selectedEvent - 当前选中的事件 * @param {Function} onEventSelect - 事件选择回调 * @param {string} borderColor - 边框颜色 * @param {number} currentPage - 当前页码 * @param {number} totalPages - 总页数(由服务端返回) * @param {Function} onPageChange - 页码改变回调 * @param {boolean} loading - 加载状态 * @param {string} mode - 展示模式:'carousel'(单排轮播)| 'grid'(双排网格) * @param {Function} onModeChange - 模式切换回调 * @param {boolean} hasMore - 是否还有更多数据 * @param {Object} eventFollowStatus - 事件关注状态 { [eventId]: { isFollowing, followerCount } } * @param {Function} onToggleFollow - 关注按钮回调 */ const EventScrollList = ({ events, selectedEvent, onEventSelect, borderColor, currentPage, totalPages, onPageChange, loading = false, mode = 'carousel', onModeChange, hasMore = true, eventFollowStatus = {}, onToggleFollow }) => { const scrollContainerRef = useRef(null); // 时间轴样式配置 const getTimelineBoxStyle = () => { return { bg: useColorModeValue('gray.50', 'gray.700'), borderColor: useColorModeValue('gray.400', 'gray.500'), borderWidth: '2px', textColor: useColorModeValue('blue.600', 'blue.400'), boxShadow: 'sm', }; }; return ( {/* 顶部控制栏:模式切换按钮(左)+ 分页控制器(右) */} {/* 模式切换按钮 */} {/* 分页控制器 */} {totalPages > 1 && ( )} {/* 横向滚动区域 */} {/* 左侧翻页按钮 - 上一页 */} {currentPage > 1 && ( } position="absolute" left="0" top="50%" transform="translateY(-50%)" zIndex={2} onClick={() => onPageChange(currentPage - 1)} variant="ghost" size="md" w="40px" h="40px" minW="40px" borderRadius="full" bg={useColorModeValue('rgba(255, 255, 255, 0.9)', 'rgba(0, 0, 0, 0.6)')} boxShadow="0 2px 8px rgba(0, 0, 0, 0.15)" _hover={{ bg: useColorModeValue('rgba(255, 255, 255, 1)', 'rgba(0, 0, 0, 0.8)'), boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2)', transform: 'translateY(-50%) scale(1.05)' }} aria-label="上一页" title="上一页" /> )} {/* 右侧翻页按钮 - 下一页 */} {currentPage < totalPages && hasMore && ( } position="absolute" right="0" top="50%" transform="translateY(-50%)" zIndex={2} onClick={() => onPageChange(currentPage + 1)} variant="ghost" size="md" w="40px" h="40px" minW="40px" borderRadius="full" bg={useColorModeValue('rgba(255, 255, 255, 0.9)', 'rgba(0, 0, 0, 0.6)')} boxShadow="0 2px 8px rgba(0, 0, 0, 0.15)" _hover={{ bg: useColorModeValue('rgba(255, 255, 255, 1)', 'rgba(0, 0, 0, 0.8)'), boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2)', transform: 'translateY(-50%) scale(1.05)' }} isDisabled={currentPage >= totalPages && !hasMore} aria-label="下一页" title="下一页" /> )} {/* 事件卡片容器 */} {/* 加载遮罩 */} {loading && (
加载中...
)} {/* 模式1: 单排轮播模式 */} {mode === 'carousel' && ( {events.map((event, index) => ( { onEventSelect(clickedEvent); }} onTitleClick={(e) => { e.preventDefault(); e.stopPropagation(); onEventSelect(event); }} onToggleFollow={() => onToggleFollow?.(event.id)} timelineStyle={getTimelineBoxStyle()} borderColor={borderColor} /> ))} )} {/* 模式2: 双排网格模式 */} {mode === 'grid' && ( {events.map((event, index) => ( { onEventSelect(clickedEvent); }} onTitleClick={(e) => { e.preventDefault(); e.stopPropagation(); onEventSelect(event); }} onToggleFollow={() => onToggleFollow?.(event.id)} timelineStyle={getTimelineBoxStyle()} borderColor={borderColor} /> ))} )}
); }; export default EventScrollList;