Files
vf_react/src/views/Community/components/EventCard/CompactEventCard.js
zdl ff9f1fe2a1 feat: 创建组合组件(Molecules)
- EventHeader: 标题头部组件(100行)                                                                                             │ │
│ │ - CompactEventCard: 紧凑模式卡片(160行)                                                                                        │ │
│ │ - DetailedEventCard: 详细模式卡片(170行)                                                                                       │ │
│ │ - index.js: EventCard 统一入口(60行)
2025-10-30 12:15:03 +08:00

152 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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 (
<HStack align="stretch" spacing={3} w="full">
{/* 左侧时间轴 */}
<EventTimeline
createdAt={event.created_at}
timelineStyle={timelineStyle}
borderColor={borderColor}
minHeight="40px"
/>
{/* 右侧内容卡片 */}
<Card
flex="1"
bg={index % 2 === 0 ? cardBg : useColorModeValue('gray.50', 'gray.750')}
borderWidth="1px"
borderColor={borderColor}
borderRadius="md"
boxShadow="sm"
_hover={{
boxShadow: 'lg',
transform: 'translateY(-2px)',
borderColor: importance.color,
}}
transition="all 0.3s ease"
cursor="pointer"
onClick={() => onEventClick?.(event)}
mb={2}
>
<CardBody p={3}>
<VStack align="stretch" spacing={2}>
{/* 第一行标题2行+ 标签(内联)+ 按钮(右侧) */}
<Flex align="flex-start" gap={2}>
{/* 标题区域:标题+标签(内联) */}
<EventHeader
title={event.title}
importance={event.importance}
onTitleClick={(e) => onTitleClick?.(e, event)}
linkColor={linkColor}
compact={true}
avgChange={event.related_avg_chg}
size="md"
/>
{/* 操作按钮 - 固定右侧 */}
<HStack spacing={2} flexShrink={0}>
<Button
size="xs"
variant="ghost"
colorScheme="blue"
onClick={handleViewDetailClick}
>
详情
</Button>
<EventFollowButton
isFollowing={isFollowing}
followerCount={followerCount}
onToggle={() => onToggleFollow?.(event.id)}
size="xs"
showCount={true}
/>
</HStack>
</Flex>
{/* 第二行:统计数据(左) + 作者时间(右) */}
<Flex justify="space-between" align="center" fontSize="xs" color={mutedColor}>
{/* 左侧:统计数据 */}
<EventStats
viewCount={event.view_count}
postCount={event.post_count}
followerCount={followerCount}
size="sm"
spacing={3}
display={{ base: 'none', md: 'flex' }}
mutedColor={mutedColor}
/>
{/* 右侧:作者 + 时间 */}
<HStack spacing={2}>
<Text>@{event.creator?.username || 'Anonymous'}</Text>
<Text></Text>
<Text fontWeight="bold" color={linkColor}>
{moment(event.created_at).format('YYYY-MM-DD HH:mm')}
</Text>
</HStack>
</Flex>
</VStack>
</CardBody>
</Card>
</HStack>
);
};
export default CompactEventCard;