diff --git a/src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js b/src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js index cb5a180f..2faf7c86 100644 --- a/src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js +++ b/src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js @@ -2,10 +2,25 @@ // 纵向分栏模式布局组件 import React, { useState } from 'react'; -import { Box, VStack, Flex, Center, Text, useBreakpointValue } from '@chakra-ui/react'; +import { + Box, + VStack, + Flex, + Center, + Text, + useBreakpointValue, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalBody, + ModalCloseButton, + useDisclosure +} from '@chakra-ui/react'; import { InfoIcon } from '@chakra-ui/icons'; import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard'; import EventDetailScrollPanel from './EventDetailScrollPanel'; +import DynamicNewsDetailPanel from '../../DynamicNewsDetail/DynamicNewsDetailPanel'; /** * 纵向分栏模式布局 @@ -38,6 +53,20 @@ const VerticalModeLayout = ({ const flexDirection = useBreakpointValue({ base: 'column', lg: 'row' }); const gap = useBreakpointValue({ base: 3, lg: 6 }); + // 移动端模态框控制 + const { isOpen: isMobileModalOpen, onOpen: onMobileModalOpen, onClose: onMobileModalClose } = useDisclosure(); + const [mobileSelectedEvent, setMobileSelectedEvent] = useState(null); + + // 处理移动端事件点击 + const handleMobileEventClick = (event) => { + if (isMobile) { + setMobileSelectedEvent(event); + onMobileModalOpen(); + } else { + onEventSelect(event); + } + }; + // 固定布局比例:左侧(4),右侧(6)- 平衡布局,确保左侧有足够空间显示内容 const leftFlex = '4'; const rightFlex = '6'; @@ -89,7 +118,7 @@ const VerticalModeLayout = ({ key={event.id} event={event} isSelected={selectedEvent?.id === event.id} - onEventClick={() => onEventSelect(event)} + onEventClick={() => handleMobileEventClick(event)} isFollowing={eventFollowStatus[event.id]?.isFollowing} followerCount={eventFollowStatus[event.id]?.followerCount} onToggleFollow={onToggleFollow} @@ -133,6 +162,24 @@ const VerticalModeLayout = ({ /> )} + + {/* 移动端详情弹窗 */} + {isMobile && ( + + + + + {mobileSelectedEvent?.title || '事件详情'} + + + + {mobileSelectedEvent && ( + + )} + + + + )} ); }; diff --git a/src/views/Community/components/DynamicNewsCard/VirtualizedFourRowGrid.js b/src/views/Community/components/DynamicNewsCard/VirtualizedFourRowGrid.js index 8b1df47a..1aa32b5a 100644 --- a/src/views/Community/components/DynamicNewsCard/VirtualizedFourRowGrid.js +++ b/src/views/Community/components/DynamicNewsCard/VirtualizedFourRowGrid.js @@ -3,7 +3,7 @@ import React, { useRef, useMemo, useEffect } from 'react'; import { useVirtualizer } from '@tanstack/react-virtual'; -import { Box, Grid, Spinner, Text, VStack, Center, HStack, IconButton } from '@chakra-ui/react'; +import { Box, Grid, Spinner, Text, VStack, Center, HStack, IconButton, useBreakpointValue } from '@chakra-ui/react'; import { RepeatIcon } from '@chakra-ui/icons'; import { useColorModeValue } from '@chakra-ui/react'; import DynamicNewsEventCard from '../EventCard/DynamicNewsEventCard'; @@ -52,14 +52,26 @@ const VirtualizedFourRowGrid = ({ const scrollbarThumbBg = useColorModeValue('#888', '#4A5568'); const scrollbarThumbHoverBg = useColorModeValue('#555', '#718096'); - // 将事件按 columnsPerRow 个一组分成行 + // 响应式列数 + const responsiveColumns = useBreakpointValue({ + base: 1, // 移动端:单列 + sm: 2, // 小屏:2列 + md: 2, // 中屏:2列 + lg: 3, // 大屏:3列 + xl: 4, // 超大屏:4列 + }); + + // 使用响应式列数或传入的列数 + const actualColumnsPerRow = responsiveColumns || columnsPerRow; + + // 将事件按 actualColumnsPerRow 个一组分成行 const rows = useMemo(() => { const r = []; - for (let i = 0; i < events.length; i += columnsPerRow) { - r.push(events.slice(i, i + columnsPerRow)); + for (let i = 0; i < events.length; i += actualColumnsPerRow) { + r.push(events.slice(i, i + actualColumnsPerRow)); } return r; - }, [events, columnsPerRow]); + }, [events, actualColumnsPerRow]); // 配置虚拟滚动器(纵向滚动 + 动态高度测量) const rowVirtualizer = useVirtualizer({ @@ -301,17 +313,17 @@ const VirtualizedFourRowGrid = ({ w="100%" transform={`translateY(${virtualRow.start}px)`} > - {/* 使用 Grid 横向排列卡片(列数由 columnsPerRow 决定) */} + {/* 使用 Grid 横向排列卡片(列数由 actualColumnsPerRow 决定) */} {rowEvents.map((event, colIndex) => ( { - const sectionBg = useColorModeValue('gray.50', 'gray.750'); + const sectionBg = PROFESSIONAL_COLORS.background.secondary; // 模式状态:'detailed' | 'simple' const [displayMode, setDisplayMode] = useState(defaultMode); diff --git a/src/views/Community/components/DynamicNewsDetail/EventDescriptionSection.js b/src/views/Community/components/DynamicNewsDetail/EventDescriptionSection.js index 6260e985..353b5c2f 100644 --- a/src/views/Community/components/DynamicNewsDetail/EventDescriptionSection.js +++ b/src/views/Community/components/DynamicNewsDetail/EventDescriptionSection.js @@ -8,6 +8,7 @@ import { Text, useColorModeValue, } from '@chakra-ui/react'; +import { PROFESSIONAL_COLORS } from '../../../../constants/professionalTheme'; /** * 事件描述区组件 @@ -15,9 +16,9 @@ import { * @param {string} props.description - 事件描述文本 */ const EventDescriptionSection = ({ description }) => { - const sectionBg = useColorModeValue('gray.50', 'gray.750'); - const headingColor = useColorModeValue('gray.700', 'gray.200'); - const textColor = useColorModeValue('gray.600', 'gray.400'); + const sectionBg = PROFESSIONAL_COLORS.background.secondary; + const headingColor = PROFESSIONAL_COLORS.text.primary; + const textColor = PROFESSIONAL_COLORS.text.secondary; // 如果没有描述,不渲染 if (!description) {