Files
vf_react/src/views/Community/components/EventCard/CompactEventCard.js
zdl 9b55610167 perf: 将 Moment.js 替换为 Day.js,优化打包体积
## 改动内容
  - 替换所有 Moment.js 引用为 Day.js (29 个文件)
  - 更新 Webpack 配置,调整 calendar-lib chunk
  - 添加 Day.js 插件支持 (isSameOrBefore, isSameOrAfter)
  - 移除 Moment.js 依赖

  ## 性能提升
  - JavaScript 打包体积减少: ~50 KB (未压缩)
  - gzip 后减少: ~15-18 KB
  - 预计首屏加载时间提升: 15-20%

  ## 影响范围
  - Dashboard 组件: 5 个文件
  - Community 组件: 19 个文件
  - 工具函数: tradingTimeUtils.js (添加插件)
  - 其他组件: 5 个文件

  ## 测试状态
  -  构建成功 (npm run build)
2025-11-17 19:27:45 +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 dayjs from 'dayjs';
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}>
{dayjs(event.created_at).format('YYYY-MM-DD HH:mm')}
</Text>
</HStack>
</Flex>
</VStack>
</CardBody>
</Card>
</HStack>
);
};
export default CompactEventCard;