feat: 创建组合组件(Molecules)
- EventHeader: 标题头部组件(100行) │ │ │ │ - CompactEventCard: 紧凑模式卡片(160行) │ │ │ │ - DetailedEventCard: 详细模式卡片(170行) │ │ │ │ - index.js: EventCard 统一入口(60行)
This commit is contained in:
151
src/views/Community/components/EventCard/DetailedEventCard.js
Normal file
151
src/views/Community/components/EventCard/DetailedEventCard.js
Normal file
@@ -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 (
|
||||
<HStack align="stretch" spacing={3} w="full">
|
||||
{/* 左侧时间轴 */}
|
||||
<EventTimeline
|
||||
createdAt={event.created_at}
|
||||
timelineStyle={timelineStyle}
|
||||
borderColor={borderColor}
|
||||
minHeight="80px"
|
||||
/>
|
||||
|
||||
{/* 事件卡片 */}
|
||||
<Card
|
||||
flex="1"
|
||||
bg={cardBg}
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor}
|
||||
borderRadius="md"
|
||||
boxShadow="sm"
|
||||
_hover={{
|
||||
boxShadow: 'xl',
|
||||
transform: 'translateY(-3px)',
|
||||
borderColor: importance.color,
|
||||
}}
|
||||
transition="all 0.3s ease"
|
||||
cursor="pointer"
|
||||
onClick={() => onEventClick?.(event)}
|
||||
mb={3}
|
||||
>
|
||||
<CardBody p={4}>
|
||||
<VStack align="stretch" spacing={2.5}>
|
||||
{/* 第一行:标题+优先级 | 统计+关注 */}
|
||||
<Flex align="center" justify="space-between" gap={3}>
|
||||
{/* 左侧:标题 + 优先级标签 */}
|
||||
<EventHeader
|
||||
title={event.title}
|
||||
importance={event.importance}
|
||||
onTitleClick={(e) => onTitleClick?.(e, event)}
|
||||
linkColor={linkColor}
|
||||
compact={false}
|
||||
size="md"
|
||||
/>
|
||||
|
||||
{/* 右侧:统计数据 + 关注按钮 */}
|
||||
<HStack spacing={4} flexShrink={0}>
|
||||
{/* 统计数据 */}
|
||||
<EventStats
|
||||
viewCount={event.view_count}
|
||||
postCount={event.post_count}
|
||||
followerCount={followerCount}
|
||||
size="md"
|
||||
spacing={4}
|
||||
display="flex"
|
||||
mutedColor={mutedColor}
|
||||
/>
|
||||
|
||||
{/* 关注按钮 */}
|
||||
<EventFollowButton
|
||||
isFollowing={isFollowing}
|
||||
followerCount={followerCount}
|
||||
onToggle={() => onToggleFollow?.(event.id)}
|
||||
size="sm"
|
||||
showCount={false}
|
||||
/>
|
||||
</HStack>
|
||||
</Flex>
|
||||
|
||||
{/* 第二行:价格标签 | 时间+作者 */}
|
||||
<Flex justify="space-between" align="center" wrap="wrap" gap={3}>
|
||||
{/* 左侧:价格标签 */}
|
||||
<EventPriceDisplay
|
||||
avgChange={event.related_avg_chg}
|
||||
maxChange={event.related_max_chg}
|
||||
weekChange={event.related_week_chg}
|
||||
compact={false}
|
||||
/>
|
||||
|
||||
{/* 右侧:时间 + 作者 */}
|
||||
<HStack spacing={2} fontSize="sm" flexShrink={0}>
|
||||
<Text fontWeight="bold" color={linkColor}>
|
||||
{moment(event.created_at).format('YYYY-MM-DD HH:mm')}
|
||||
</Text>
|
||||
<Text color={mutedColor}>•</Text>
|
||||
<Text color={mutedColor}>@{event.creator?.username || 'Anonymous'}</Text>
|
||||
</HStack>
|
||||
</Flex>
|
||||
|
||||
{/* 第三行:描述文字 + 展开/收起 */}
|
||||
<EventDescription
|
||||
description={event.description}
|
||||
textColor={textColor}
|
||||
minLength={120}
|
||||
noOfLines={3}
|
||||
/>
|
||||
</VStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default DetailedEventCard;
|
||||
Reference in New Issue
Block a user