diff --git a/src/views/Community/components/EventCard/CompactEventCard.js b/src/views/Community/components/EventCard/CompactEventCard.js new file mode 100644 index 00000000..469f4a1b --- /dev/null +++ b/src/views/Community/components/EventCard/CompactEventCard.js @@ -0,0 +1,151 @@ +// src/views/Community/components/EventCard/CompactEventCard.js +import React from 'react'; +import { + HStack, + Card, + CardBody, + VStack, + Flex, + Box, + Button, + Text, + useColorModeValue, +} from '@chakra-ui/react'; +import moment from 'moment'; +import { getImportanceConfig } from '../../../../constants/importanceLevels'; + +// 导入子组件 +import EventTimeline from './EventTimeline'; +import EventHeader from './EventHeader'; +import EventStats from './EventStats'; +import EventFollowButton from './EventFollowButton'; + +/** + * 紧凑模式事件卡片组件 + * @param {Object} props + * @param {Object} props.event - 事件对象 + * @param {number} props.index - 事件索引 + * @param {boolean} props.isFollowing - 是否已关注 + * @param {number} props.followerCount - 关注数 + * @param {Function} props.onEventClick - 卡片点击事件 + * @param {Function} props.onTitleClick - 标题点击事件 + * @param {Function} props.onViewDetail - 查看详情事件 + * @param {Function} props.onToggleFollow - 切换关注事件 + * @param {Object} props.timelineStyle - 时间轴样式配置 + * @param {string} props.borderColor - 边框颜色 + */ +const CompactEventCard = ({ + event, + index, + isFollowing, + followerCount, + onEventClick, + onTitleClick, + onViewDetail, + onToggleFollow, + timelineStyle, + borderColor, +}) => { + const importance = getImportanceConfig(event.importance); + const cardBg = useColorModeValue('white', 'gray.800'); + const linkColor = useColorModeValue('blue.600', 'blue.400'); + const mutedColor = useColorModeValue('gray.500', 'gray.400'); + + const handleViewDetailClick = (e) => { + e.stopPropagation(); + onViewDetail?.(event.id); + }; + + return ( + + {/* 左侧时间轴 */} + + + {/* 右侧内容卡片 */} + onEventClick?.(event)} + mb={2} + > + + + {/* 第一行:标题(2行)+ 标签(内联)+ 按钮(右侧) */} + + {/* 标题区域:标题+标签(内联) */} + onTitleClick?.(e, event)} + linkColor={linkColor} + compact={true} + avgChange={event.related_avg_chg} + size="md" + /> + + {/* 操作按钮 - 固定右侧 */} + + + onToggleFollow?.(event.id)} + size="xs" + showCount={true} + /> + + + + {/* 第二行:统计数据(左) + 作者时间(右) */} + + {/* 左侧:统计数据 */} + + + {/* 右侧:作者 + 时间 */} + + @{event.creator?.username || 'Anonymous'} + + + {moment(event.created_at).format('YYYY-MM-DD HH:mm')} + + + + + + + + ); +}; + +export default CompactEventCard; diff --git a/src/views/Community/components/EventCard/DetailedEventCard.js b/src/views/Community/components/EventCard/DetailedEventCard.js new file mode 100644 index 00000000..080bfb3b --- /dev/null +++ b/src/views/Community/components/EventCard/DetailedEventCard.js @@ -0,0 +1,151 @@ +// src/views/Community/components/EventCard/DetailedEventCard.js +import React from 'react'; +import { + HStack, + Card, + CardBody, + VStack, + Flex, + Text, + useColorModeValue, +} from '@chakra-ui/react'; +import moment from 'moment'; +import { getImportanceConfig } from '../../../../constants/importanceLevels'; + +// 导入子组件 +import EventTimeline from './EventTimeline'; +import EventHeader from './EventHeader'; +import EventStats from './EventStats'; +import EventFollowButton from './EventFollowButton'; +import EventPriceDisplay from './EventPriceDisplay'; +import EventDescription from './EventDescription'; + +/** + * 详细模式事件卡片组件 + * @param {Object} props + * @param {Object} props.event - 事件对象 + * @param {boolean} props.isFollowing - 是否已关注 + * @param {number} props.followerCount - 关注数 + * @param {Function} props.onEventClick - 卡片点击事件 + * @param {Function} props.onTitleClick - 标题点击事件 + * @param {Function} props.onToggleFollow - 切换关注事件 + * @param {Object} props.timelineStyle - 时间轴样式配置 + * @param {string} props.borderColor - 边框颜色 + */ +const DetailedEventCard = ({ + event, + isFollowing, + followerCount, + onEventClick, + onTitleClick, + onToggleFollow, + timelineStyle, + borderColor, +}) => { + const importance = getImportanceConfig(event.importance); + const cardBg = useColorModeValue('white', 'gray.800'); + const linkColor = useColorModeValue('blue.600', 'blue.400'); + const mutedColor = useColorModeValue('gray.500', 'gray.400'); + const textColor = useColorModeValue('gray.700', 'gray.200'); + + return ( + + {/* 左侧时间轴 */} + + + {/* 事件卡片 */} + onEventClick?.(event)} + mb={3} + > + + + {/* 第一行:标题+优先级 | 统计+关注 */} + + {/* 左侧:标题 + 优先级标签 */} + onTitleClick?.(e, event)} + linkColor={linkColor} + compact={false} + size="md" + /> + + {/* 右侧:统计数据 + 关注按钮 */} + + {/* 统计数据 */} + + + {/* 关注按钮 */} + onToggleFollow?.(event.id)} + size="sm" + showCount={false} + /> + + + + {/* 第二行:价格标签 | 时间+作者 */} + + {/* 左侧:价格标签 */} + + + {/* 右侧:时间 + 作者 */} + + + {moment(event.created_at).format('YYYY-MM-DD HH:mm')} + + + @{event.creator?.username || 'Anonymous'} + + + + {/* 第三行:描述文字 + 展开/收起 */} + + + + + + ); +}; + +export default DetailedEventCard; diff --git a/src/views/Community/components/EventCard/EventHeader.js b/src/views/Community/components/EventCard/EventHeader.js new file mode 100644 index 00000000..d5573e9a --- /dev/null +++ b/src/views/Community/components/EventCard/EventHeader.js @@ -0,0 +1,100 @@ +// src/views/Community/components/EventCard/EventHeader.js +import React from 'react'; +import { Box, Text, Heading, Tooltip, HStack } from '@chakra-ui/react'; +import EventImportanceBadge from './EventImportanceBadge'; +import EventPriceDisplay from './EventPriceDisplay'; + +/** + * 事件标题头部组件 + * @param {Object} props + * @param {string} props.title - 事件标题 + * @param {string} props.importance - 重要性等级 + * @param {Function} props.onTitleClick - 标题点击事件 + * @param {string} props.linkColor - 链接颜色 + * @param {boolean} props.compact - 是否紧凑模式(默认 false) + * @param {number|null} props.avgChange - 平均涨跌幅(紧凑模式下使用) + * @param {string} props.size - 标题大小('sm' | 'md' | 'lg',默认 'md') + */ +const EventHeader = ({ + title, + importance, + onTitleClick, + linkColor, + compact = false, + avgChange = null, + size = 'md' +}) => { + const handleClick = (e) => { + e.preventDefault(); + e.stopPropagation(); + onTitleClick?.(e); + }; + + // 紧凑模式:标题 + 标签内联 + if (compact) { + return ( + + + {title} + + {' '} + {/* 重要性标签 - 内联 */} + + {' '} + {/* 价格标签 - 内联 */} + {avgChange != null && ( + + )} + + ); + } + + // 详细模式:标题 + 提示框的重要性标签 + return ( + + + + {title} + + + + + + ); +}; + +export default EventHeader; diff --git a/src/views/Community/components/EventCard/index.js b/src/views/Community/components/EventCard/index.js new file mode 100644 index 00000000..7c3efc00 --- /dev/null +++ b/src/views/Community/components/EventCard/index.js @@ -0,0 +1,67 @@ +// src/views/Community/components/EventCard/index.js +import React from 'react'; +import CompactEventCard from './CompactEventCard'; +import DetailedEventCard from './DetailedEventCard'; + +/** + * 事件卡片统一入口组件 + * 根据 isCompactMode 自动选择紧凑模式或详细模式 + * + * @param {Object} props + * @param {Object} props.event - 事件对象 + * @param {number} props.index - 事件索引(紧凑模式下用于交替背景色) + * @param {boolean} props.isCompactMode - 是否为紧凑模式 + * @param {boolean} props.isFollowing - 是否已关注 + * @param {number} props.followerCount - 关注数 + * @param {Function} props.onEventClick - 卡片点击事件 + * @param {Function} props.onTitleClick - 标题点击事件 + * @param {Function} props.onViewDetail - 查看详情事件(仅紧凑模式) + * @param {Function} props.onToggleFollow - 切换关注事件 + * @param {Object} props.timelineStyle - 时间轴样式配置 + * @param {string} props.borderColor - 边框颜色 + */ +const EventCard = ({ + event, + index, + isCompactMode, + isFollowing, + followerCount, + onEventClick, + onTitleClick, + onViewDetail, + onToggleFollow, + timelineStyle, + borderColor, +}) => { + if (isCompactMode) { + return ( + + ); + } + + return ( + + ); +}; + +export default EventCard;