feat: 创建原子组件(Atoms) - EventTimeline: 时间轴显示(60行) │ │

│ │ - EventImportanceBadge: 重要性等级标签(100行)                                                                                  │ │
│ │ - EventStats: 统计信息组件(60行)                                                                                               │ │
│ │ - EventFollowButton: 关注按钮(40行)                                                                                            │ │
│ │ - EventPriceDisplay: 价格变动显示(130行)                                                                                       │ │
│ │ - EventDescription: 描述文本组件(60行)
This commit is contained in:
zdl
2025-10-30 12:14:27 +08:00
parent 57a7d3b9e7
commit a39d57f9de
6 changed files with 436 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
// src/views/Community/components/EventCard/EventPriceDisplay.js
import React from 'react';
import { HStack, Badge, Text, Tooltip } from '@chakra-ui/react';
import { PriceArrow } from '../../../../utils/priceFormatters';
/**
* 事件价格变动显示组件
* @param {Object} props
* @param {number|null} props.avgChange - 平均涨跌幅
* @param {number|null} props.maxChange - 最大涨跌幅
* @param {number|null} props.weekChange - 周涨跌幅
* @param {boolean} props.compact - 是否为紧凑模式(只显示平均值,默认 false
* @param {boolean} props.inline - 是否内联显示(默认 false
*/
const EventPriceDisplay = ({
avgChange,
maxChange,
weekChange,
compact = false,
inline = false
}) => {
// 获取颜色方案
const getColorScheme = (value) => {
if (value == null) return 'gray';
return value > 0 ? 'red' : value < 0 ? 'green' : 'gray';
};
// 格式化百分比
const formatPercent = (value) => {
if (value == null) return '--';
return `${value > 0 ? '+' : ''}${value.toFixed(2)}%`;
};
// 紧凑模式:只显示平均值,内联在标题后
if (compact && avgChange != null) {
return (
<Tooltip label="平均" placement="top">
<Badge
colorScheme={getColorScheme(avgChange)}
fontSize="xs"
px={2}
py={1}
borderRadius="md"
fontWeight="bold"
display={inline ? "inline-flex" : "flex"}
alignItems="center"
gap={1}
verticalAlign="middle"
>
<PriceArrow value={avgChange} />
{formatPercent(avgChange)}
</Badge>
</Tooltip>
);
}
// 详细模式:显示所有价格变动
return (
<HStack spacing={2} flexWrap="wrap">
{/* 平均涨幅 - 始终显示,无数据时显示 -- */}
<Badge
colorScheme={getColorScheme(avgChange)}
fontSize="xs"
px={2}
py={0.5}
borderRadius="md"
cursor="pointer"
_hover={{ transform: 'scale(1.05)', boxShadow: 'md' }}
transition="all 0.2s"
>
<HStack spacing={1}>
<Text fontSize="xs" opacity={0.8}>平均</Text>
<Text fontWeight="bold">
{formatPercent(avgChange)}
</Text>
</HStack>
</Badge>
{/* 最大涨幅 - 始终显示,无数据时显示 -- */}
<Badge
colorScheme={getColorScheme(maxChange)}
fontSize="xs"
px={2}
py={0.5}
borderRadius="md"
cursor="pointer"
_hover={{ transform: 'scale(1.05)', boxShadow: 'md' }}
transition="all 0.2s"
>
<HStack spacing={1}>
<Text fontSize="xs" opacity={0.8}>最大</Text>
<Text fontWeight="bold">
{formatPercent(maxChange)}
</Text>
</HStack>
</Badge>
{/* 周涨幅 - 始终显示,无数据时显示 -- */}
<Badge
colorScheme={getColorScheme(weekChange)}
fontSize="xs"
px={2}
py={0.5}
borderRadius="md"
cursor="pointer"
_hover={{ transform: 'scale(1.05)', boxShadow: 'md' }}
transition="all 0.2s"
>
<HStack spacing={1}>
<Text fontSize="xs" opacity={0.8}></Text>
{weekChange != null && <PriceArrow value={weekChange} />}
<Text fontWeight="bold">
{formatPercent(weekChange)}
</Text>
</HStack>
</Badge>
</HStack>
);
};
export default EventPriceDisplay;