feat: HistoricalEvents UI 布局优化
- 从网格布局(SimpleGrid 3列)改为单列纵向布局(VStack) - 卡片样式优化:添加顶部渐变条装饰(蓝-紫-粉渐变) - 卡片内部从垂直布局改为横向布局(HStack) - 优化间距和边距,提升视觉层次感 - 调整卡片padding和borderRadius 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,7 @@ import {
|
||||
} from 'react-icons/fa';
|
||||
import { stockService } from '../../../services/eventService';
|
||||
import { logger } from '../../../utils/logger';
|
||||
import CitedContent from '../../../components/Citation/CitedContent';
|
||||
|
||||
const HistoricalEvents = ({
|
||||
events = [],
|
||||
@@ -224,8 +225,8 @@ const HistoricalEvents = ({
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* 历史事件卡片网格 */}
|
||||
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={4}>
|
||||
{/* 历史事件卡片列表 - 混合布局 */}
|
||||
<VStack spacing={3} align="stretch">
|
||||
{events.map((event) => {
|
||||
const importanceColor = getImportanceColor(event.importance);
|
||||
|
||||
@@ -235,92 +236,126 @@ const HistoricalEvents = ({
|
||||
bg={cardBg}
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor}
|
||||
borderRadius="md"
|
||||
p={4}
|
||||
borderRadius="lg"
|
||||
position="relative"
|
||||
overflow="visible"
|
||||
cursor="pointer"
|
||||
onClick={() => handleCardClick(event)}
|
||||
_before={{
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: '3px',
|
||||
bgGradient: 'linear(to-r, blue.400, purple.500, pink.500)',
|
||||
borderTopLeftRadius: 'lg',
|
||||
borderTopRightRadius: 'lg',
|
||||
}}
|
||||
_hover={{
|
||||
boxShadow: 'lg',
|
||||
borderColor: 'blue.400',
|
||||
transform: 'translateY(-2px)',
|
||||
}}
|
||||
transition="all 0.2s"
|
||||
>
|
||||
<VStack align="stretch" spacing={3}>
|
||||
{/* 事件名称 */}
|
||||
<Text
|
||||
fontSize="md"
|
||||
fontWeight="bold"
|
||||
color={useColorModeValue('blue.600', 'blue.400')}
|
||||
noOfLines={2}
|
||||
lineHeight="1.4"
|
||||
cursor="pointer"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleCardClick(event);
|
||||
}}
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
>
|
||||
{event.title || '未命名事件'}
|
||||
</Text>
|
||||
|
||||
{/* 日期 + Badges */}
|
||||
<HStack spacing={2} flexWrap="wrap">
|
||||
<Text fontSize="sm" color={textSecondary}>
|
||||
{formatDate(getEventDate(event))}
|
||||
</Text>
|
||||
<Text fontSize="sm" color={textSecondary}>
|
||||
({getRelativeTime(getEventDate(event))})
|
||||
</Text>
|
||||
{event.relevance && (
|
||||
<Badge colorScheme="blue" size="sm">
|
||||
相关度: {event.relevance}
|
||||
</Badge>
|
||||
)}
|
||||
{event.importance && (
|
||||
<Badge colorScheme={importanceColor} size="sm">
|
||||
重要性: {event.importance}
|
||||
</Badge>
|
||||
)}
|
||||
{event.avg_change_pct !== undefined && event.avg_change_pct !== null && (
|
||||
<Badge
|
||||
colorScheme={event.avg_change_pct > 0 ? 'red' : event.avg_change_pct < 0 ? 'green' : 'gray'}
|
||||
size="sm"
|
||||
<VStack align="stretch" spacing={2} p={3}>
|
||||
{/* 顶部区域:左侧(标题+时间) + 右侧(按钮) */}
|
||||
<HStack align="flex-start" spacing={3}>
|
||||
{/* 左侧:标题 + 时间信息(允许折行) */}
|
||||
<VStack flex="1" align="flex-start" spacing={1}>
|
||||
{/* 标题 */}
|
||||
<Text
|
||||
fontSize="md"
|
||||
fontWeight="bold"
|
||||
color={useColorModeValue('blue.600', 'blue.400')}
|
||||
lineHeight="1.4"
|
||||
cursor="pointer"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleCardClick(event);
|
||||
}}
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
>
|
||||
涨幅: {event.avg_change_pct > 0 ? '+' : ''}{event.avg_change_pct.toFixed(2)}%
|
||||
</Badge>
|
||||
)}
|
||||
{event.title || '未命名事件'}
|
||||
</Text>
|
||||
|
||||
{/* 时间 + Badges(允许折行) */}
|
||||
<HStack spacing={2} flexWrap="wrap">
|
||||
<Text fontSize="sm" color={textSecondary}>
|
||||
{formatDate(getEventDate(event))}
|
||||
</Text>
|
||||
<Text fontSize="sm" color={textSecondary}>
|
||||
({getRelativeTime(getEventDate(event))})
|
||||
</Text>
|
||||
{event.importance && (
|
||||
<Badge colorScheme={importanceColor} size="sm">
|
||||
重要性: {event.importance}
|
||||
</Badge>
|
||||
)}
|
||||
{event.avg_change_pct !== undefined && event.avg_change_pct !== null && (
|
||||
<Badge
|
||||
colorScheme={event.avg_change_pct > 0 ? 'red' : event.avg_change_pct < 0 ? 'green' : 'gray'}
|
||||
size="sm"
|
||||
>
|
||||
涨幅: {event.avg_change_pct > 0 ? '+' : ''}{event.avg_change_pct.toFixed(2)}%
|
||||
</Badge>
|
||||
)}
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
||||
{/* 右侧:相关股票按钮 */}
|
||||
<Button
|
||||
size="sm"
|
||||
leftIcon={<Icon as={FaChartLine} />}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleViewStocks(event);
|
||||
}}
|
||||
colorScheme="blue"
|
||||
variant="outline"
|
||||
flexShrink={0}
|
||||
>
|
||||
相关股票
|
||||
</Button>
|
||||
</HStack>
|
||||
|
||||
{/* 事件描述 */}
|
||||
<Text
|
||||
fontSize="sm"
|
||||
color={nameColor}
|
||||
lineHeight="1.6"
|
||||
noOfLines={4}
|
||||
>
|
||||
{getEventContent(event) ? `${getEventContent(event)}(AI合成)` : '暂无内容'}
|
||||
</Text>
|
||||
|
||||
{/* 相关股票按钮 */}
|
||||
<Button
|
||||
size="sm"
|
||||
leftIcon={<Icon as={FaChartLine} />}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleViewStocks(event);
|
||||
}}
|
||||
colorScheme="blue"
|
||||
variant="outline"
|
||||
width="full"
|
||||
>
|
||||
相关股票
|
||||
</Button>
|
||||
{/* 底部:描述(独占整行)- 升级和降级处理 */}
|
||||
<Box>
|
||||
{(() => {
|
||||
const content = getEventContent(event);
|
||||
// 检查是否有 data 结构(升级版本)
|
||||
if (content && typeof content === 'object' && content.data) {
|
||||
return (
|
||||
<CitedContent
|
||||
data={content}
|
||||
title=""
|
||||
showAIBadge={true}
|
||||
containerStyle={{
|
||||
backgroundColor: useColorModeValue('#f7fafc', 'rgba(45, 55, 72, 0.6)'),
|
||||
borderRadius: '8px',
|
||||
padding: '0',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
// 降级版本:纯文本
|
||||
return (
|
||||
<Text
|
||||
fontSize="sm"
|
||||
color={nameColor}
|
||||
lineHeight="1.6"
|
||||
noOfLines={2}
|
||||
>
|
||||
{content ? `${content}(AI合成)` : '暂无内容'}
|
||||
</Text>
|
||||
);
|
||||
})()}
|
||||
</Box>
|
||||
</VStack>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</SimpleGrid>
|
||||
</VStack>
|
||||
|
||||
{/* 相关股票 Modal - 条件渲染 */}
|
||||
{stocksModalOpen && (
|
||||
|
||||
Reference in New Issue
Block a user