/** * EventDetailCard - 事件详情卡片组件 * 用于日历视图中展示单个事件的详细信息 */ import React, { useState, useRef, useEffect } from 'react'; import { Box, Badge, Flex, HStack, Text, Tag, TagLabel, TagLeftIcon, Button, useColorModeValue, } from '@chakra-ui/react'; import { FiTrendingUp, FiChevronDown, FiChevronUp, } from 'react-icons/fi'; import type { InvestmentEvent } from '@/types'; /** * EventDetailCard Props */ export interface EventDetailCardProps { /** 事件数据 */ event: InvestmentEvent; /** 边框颜色 */ borderColor?: string; /** 次要文字颜色 */ secondaryText?: string; } /** * 最大显示行数 */ const MAX_LINES = 3; /** * EventDetailCard 组件 */ export const EventDetailCard: React.FC = ({ event, borderColor: borderColorProp, secondaryText: secondaryTextProp, }) => { const [isExpanded, setIsExpanded] = useState(false); const [isOverflow, setIsOverflow] = useState(false); const descriptionRef = useRef(null); // 默认颜色 const defaultBorderColor = useColorModeValue('gray.200', 'gray.600'); const defaultSecondaryText = useColorModeValue('gray.600', 'gray.400'); const borderColor = borderColorProp || defaultBorderColor; const secondaryText = secondaryTextProp || defaultSecondaryText; // 检测内容是否溢出 useEffect(() => { const el = descriptionRef.current; if (el) { // 计算行高和最大高度 const lineHeight = parseInt(getComputedStyle(el).lineHeight) || 20; const maxHeight = lineHeight * MAX_LINES; setIsOverflow(el.scrollHeight > maxHeight + 5); // 5px 容差 } }, [event.description]); // 获取事件类型标签 const getEventBadge = () => { if (event.source === 'future') { return 系统事件; } else if (event.type === 'plan') { return 我的计划; } else if (event.type === 'review') { return 我的复盘; } return null; }; return ( {/* 标题和标签 */} {event.title} {getEventBadge()} {/* 描述内容 - 支持展开/收起 */} {event.description && ( {event.description} {isOverflow && ( )} )} {/* 相关股票 */} {event.stocks && event.stocks.length > 0 && ( 相关股票: {event.stocks.map((stock, i) => ( {stock} ))} )} ); }; export default EventDetailCard;