// src/views/Community/components/MarketReviewCard.js // 市场复盘组件(左右布局:事件列表 | 事件详情) import React, { forwardRef, useState } from 'react'; import { Card, CardHeader, CardBody, Box, Flex, VStack, HStack, Heading, Text, Badge, Center, Spinner, useColorModeValue, Grid, GridItem, } from '@chakra-ui/react'; import { TimeIcon, InfoIcon } from '@chakra-ui/icons'; import dayjs from 'dayjs'; import CompactEventCard from './EventCard/CompactEventCard'; import EventHeader from './EventCard/EventHeader'; import EventStats from './EventCard/EventStats'; import EventFollowButton from './EventCard/EventFollowButton'; import EventPriceDisplay from './EventCard/EventPriceDisplay'; import EventDescription from './EventCard/EventDescription'; import { getImportanceConfig } from '../../../constants/importanceLevels'; /** * 市场复盘 - 左右布局卡片组件 * @param {Array} events - 事件列表 * @param {boolean} loading - 加载状态 * @param {Date} lastUpdateTime - 最后更新时间 * @param {Function} onEventClick - 事件点击回调 * @param {Function} onViewDetail - 查看详情回调 * @param {Function} onToggleFollow - 切换关注回调 * @param {Object} ref - 用于滚动的ref */ const MarketReviewCard = forwardRef(({ events, loading, lastUpdateTime, onEventClick, onViewDetail, onToggleFollow, ...rest }, ref) => { const cardBg = useColorModeValue('white', 'gray.800'); const borderColor = useColorModeValue('gray.200', 'gray.700'); const linkColor = useColorModeValue('blue.600', 'blue.400'); const mutedColor = useColorModeValue('gray.500', 'gray.400'); const textColor = useColorModeValue('gray.700', 'gray.200'); const selectedBg = useColorModeValue('blue.50', 'blue.900'); // 选中的事件 const [selectedEvent, setSelectedEvent] = useState(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', }; }; // 处理事件点击 const handleEventClick = (event) => { setSelectedEvent(event); if (onEventClick) { onEventClick(event); } }; // 渲染右侧事件详情 const renderEventDetail = () => { if (!selectedEvent) { return (
请从左侧选择事件查看详情
); } const importance = getImportanceConfig(selectedEvent.importance); return ( {/* 第一行:标题+优先级 | 统计+关注 */} {/* 左侧:标题 + 优先级标签 */} { e.preventDefault(); e.stopPropagation(); if (onViewDetail) { onViewDetail(e, selectedEvent.id); } }} linkColor={linkColor} compact={false} size="lg" /> {/* 右侧:统计数据 + 关注按钮 */} {/* 统计数据 */} {/* 关注按钮 */} onToggleFollow && onToggleFollow(selectedEvent.id)} size="sm" showCount={false} /> {/* 第二行:价格标签 | 时间+作者 */} {/* 左侧:价格标签 */} {/* 右侧:时间 + 作者 */} {dayjs(selectedEvent.created_at).format('YYYY-MM-DD HH:mm')} @{selectedEvent.creator?.username || 'Anonymous'} {/* 第三行:描述文字 */} ); }; return ( {/* 标题部分 */} 市场复盘 复盘 总结 完整 最后更新: {lastUpdateTime?.toLocaleTimeString() || '未知'} {/* 主体内容 */} {/* Loading 状态 */} {loading && (
正在加载复盘数据...
)} {/* Empty 状态 */} {!loading && (!events || events.length === 0) && (
暂无复盘数据
)} {/* 左右布局:事件列表 | 事件详情 */} {!loading && events && events.length > 0 && ( {/* 左侧:事件列表 (33.3%) */} {events.map((event, index) => ( handleEventClick(event)} cursor="pointer" bg={selectedEvent?.id === event.id ? selectedBg : 'transparent'} borderRadius="md" transition="all 0.2s" _hover={{ bg: selectedBg }} > handleEventClick(event)} onTitleClick={(e) => { e.preventDefault(); e.stopPropagation(); handleEventClick(event); }} onViewDetail={onViewDetail} onToggleFollow={() => {}} timelineStyle={getTimelineBoxStyle()} borderColor={borderColor} /> ))} {/* 右侧:事件详情 (66.7%) */} {renderEventDetail()} )}
); }); MarketReviewCard.displayName = 'MarketReviewCard'; export default MarketReviewCard;