事件中心UI优化
This commit is contained in:
@@ -10,6 +10,11 @@ import {
|
||||
Button,
|
||||
IconButton,
|
||||
Collapse,
|
||||
Stat,
|
||||
StatLabel,
|
||||
StatNumber,
|
||||
StatHelpText,
|
||||
StatArrow,
|
||||
useColorModeValue,
|
||||
} from '@chakra-ui/react';
|
||||
import { StarIcon } from '@chakra-ui/icons';
|
||||
@@ -101,46 +106,56 @@ const StockListItem = ({
|
||||
<>
|
||||
<Box
|
||||
bg={cardBg}
|
||||
borderWidth="1px"
|
||||
borderWidth="2px"
|
||||
borderColor={borderColor}
|
||||
borderRadius="md"
|
||||
p={4}
|
||||
borderRadius="xl"
|
||||
p={5}
|
||||
onClick={handleViewDetail}
|
||||
cursor="pointer"
|
||||
_hover={{
|
||||
boxShadow: 'md',
|
||||
borderColor: 'blue.300',
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
_before={{
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: '4px',
|
||||
bgGradient: 'linear(to-r, blue.400, purple.500, pink.500)',
|
||||
}}
|
||||
transition="all 0.2s"
|
||||
_hover={{
|
||||
boxShadow: '2xl',
|
||||
borderColor: 'blue.400',
|
||||
transform: 'translateY(-4px)',
|
||||
}}
|
||||
transition="all 0.3s ease-in-out"
|
||||
>
|
||||
<VStack align="stretch" spacing={3}>
|
||||
{/* 顶部:股票代码 + 名称 + 操作按钮(上下两行布局) */}
|
||||
<VStack align="stretch" spacing={2}>
|
||||
{/* 第一行:股票代码 + 涨跌幅 + 操作按钮 */}
|
||||
<Flex justify="space-between" align="center">
|
||||
{/* 左侧:代码 + 涨跌幅 */}
|
||||
<Flex align="baseline" gap={2}>
|
||||
<Text
|
||||
fontSize="md"
|
||||
fontWeight="bold"
|
||||
color={codeColor}
|
||||
cursor="pointer"
|
||||
onClick={handleViewDetail}
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
{/* 横向布局:左侧基础信息 + 中间图表 + 右侧操作按钮 */}
|
||||
<Flex direction={{ base: 'column', lg: 'row' }} gap={4} align="stretch">
|
||||
{/* 左侧:基础信息区(股票代码、名称、涨跌幅) */}
|
||||
<Flex direction="column" minW={{ base: 'auto', lg: '200px' }} maxW={{ base: 'auto', lg: '240px' }} gap={2}>
|
||||
{/* 股票代码和名称 */}
|
||||
<VStack align="stretch" spacing={2}>
|
||||
<Flex align="center" gap={2}>
|
||||
<Box
|
||||
bgGradient="linear(to-r, blue.400, blue.600)"
|
||||
px={3}
|
||||
py={1}
|
||||
borderRadius="md"
|
||||
boxShadow="sm"
|
||||
>
|
||||
{stock.stock_code}
|
||||
</Text>
|
||||
<Text
|
||||
fontSize="sm"
|
||||
fontWeight="semibold"
|
||||
color={getChangeColor(change)}
|
||||
>
|
||||
{formatChange(change)}
|
||||
</Text>
|
||||
</Flex>
|
||||
|
||||
{/* 右侧:操作按钮 */}
|
||||
<Flex gap={2}>
|
||||
<Text
|
||||
fontSize="md"
|
||||
fontWeight="bold"
|
||||
color="white"
|
||||
cursor="pointer"
|
||||
onClick={handleViewDetail}
|
||||
_hover={{ opacity: 0.8 }}
|
||||
transition="opacity 0.2s"
|
||||
>
|
||||
{stock.stock_code}
|
||||
</Text>
|
||||
</Box>
|
||||
{onWatchlistToggle && (
|
||||
<IconButton
|
||||
size="sm"
|
||||
@@ -150,115 +165,183 @@ const StockListItem = ({
|
||||
onClick={handleWatchlistClick}
|
||||
aria-label={isInWatchlist ? '已关注' : '加自选'}
|
||||
title={isInWatchlist ? '已关注' : '加自选'}
|
||||
borderRadius="full"
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
size="sm"
|
||||
colorScheme="blue"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleViewDetail();
|
||||
}}
|
||||
display={{ base: 'inline-flex', lg: 'none' }}
|
||||
>
|
||||
查看
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
{/* 第二行:公司名称 + 分时图 + K线图 */}
|
||||
<Flex align="center" gap={3}>
|
||||
{/* 左侧:公司名称 */}
|
||||
<Text
|
||||
fontSize="sm"
|
||||
fontWeight="medium"
|
||||
color={codeColor}
|
||||
bg={useColorModeValue('blue.50', 'blue.900')}
|
||||
px={2}
|
||||
py={0.5}
|
||||
borderRadius="sm"
|
||||
whiteSpace="nowrap"
|
||||
flexShrink={0}
|
||||
fontSize="md"
|
||||
fontWeight="semibold"
|
||||
color={nameColor}
|
||||
noOfLines={1}
|
||||
>
|
||||
{stock.stock_name}
|
||||
</Text>
|
||||
</VStack>
|
||||
|
||||
{/* 右侧:分时图 + K线图 */}
|
||||
<Flex gap={2} flex={1} onClick={(e) => e.stopPropagation()}>
|
||||
{/* 分时图 */}
|
||||
<Box flex={1} minW={0}>
|
||||
<MiniTimelineChart
|
||||
stockCode={stock.stock_code}
|
||||
eventTime={eventTime}
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
/>
|
||||
</Box>
|
||||
{/* 涨跌幅 - 使用 Stat 组件 */}
|
||||
<Stat
|
||||
bg={useColorModeValue('gray.50', 'gray.700')}
|
||||
px={3}
|
||||
py={2}
|
||||
borderRadius="lg"
|
||||
boxShadow="sm"
|
||||
>
|
||||
<StatLabel fontSize="xs" color={descColor}>
|
||||
涨跌幅
|
||||
</StatLabel>
|
||||
<StatNumber
|
||||
fontSize="2xl"
|
||||
fontWeight="bold"
|
||||
color={getChangeColor(change)}
|
||||
>
|
||||
{formatChange(change)}
|
||||
</StatNumber>
|
||||
{change !== null && change !== undefined && !isNaN(change) && (
|
||||
<StatHelpText mb={0}>
|
||||
<StatArrow type={change >= 0 ? 'increase' : 'decrease'} />
|
||||
{Math.abs(change).toFixed(2)}%
|
||||
</StatHelpText>
|
||||
)}
|
||||
</Stat>
|
||||
</Flex>
|
||||
|
||||
{/* K线图 */}
|
||||
<Box flex={1} minW={0}>
|
||||
<MiniKLineChart
|
||||
stockCode={stock.stock_code}
|
||||
eventTime={eventTime}
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</VStack>
|
||||
|
||||
{/* 分隔线 */}
|
||||
<Box borderTop="1px solid" borderColor={dividerColor} />
|
||||
|
||||
{/* 关联描述 */}
|
||||
{relationText && relationText !== '--' && (
|
||||
<Box>
|
||||
<Text fontSize="xs" color={descColor} mb={1}>
|
||||
关联描述:
|
||||
{/* 中间:图表区(分时图 + K线图) */}
|
||||
<Flex flex={1} gap={3} onClick={(e) => e.stopPropagation()} minW={0}>
|
||||
{/* 分时图 */}
|
||||
<Box
|
||||
flex={1}
|
||||
minW={0}
|
||||
borderWidth="1px"
|
||||
borderColor={useColorModeValue('blue.100', 'blue.700')}
|
||||
borderRadius="lg"
|
||||
p={3}
|
||||
bg={useColorModeValue('blue.50', 'blue.900')}
|
||||
transition="all 0.2s"
|
||||
_hover={{
|
||||
borderColor: useColorModeValue('blue.300', 'blue.500'),
|
||||
boxShadow: 'md'
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
fontSize="xs"
|
||||
color={useColorModeValue('blue.700', 'blue.200')}
|
||||
mb={2}
|
||||
fontWeight="bold"
|
||||
textTransform="uppercase"
|
||||
letterSpacing="wide"
|
||||
>
|
||||
📈 分时走势
|
||||
</Text>
|
||||
<MiniTimelineChart
|
||||
stockCode={stock.stock_code}
|
||||
eventTime={eventTime}
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* K线图 */}
|
||||
<Box
|
||||
flex={1}
|
||||
minW={0}
|
||||
borderWidth="1px"
|
||||
borderColor={useColorModeValue('purple.100', 'purple.700')}
|
||||
borderRadius="lg"
|
||||
p={3}
|
||||
bg={useColorModeValue('purple.50', 'purple.900')}
|
||||
transition="all 0.2s"
|
||||
_hover={{
|
||||
borderColor: useColorModeValue('purple.300', 'purple.500'),
|
||||
boxShadow: 'md'
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
fontSize="xs"
|
||||
color={useColorModeValue('purple.700', 'purple.200')}
|
||||
mb={2}
|
||||
fontWeight="bold"
|
||||
textTransform="uppercase"
|
||||
letterSpacing="wide"
|
||||
>
|
||||
📊 K线走势
|
||||
</Text>
|
||||
<MiniKLineChart
|
||||
stockCode={stock.stock_code}
|
||||
eventTime={eventTime}
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
{/* 右侧:操作按钮 */}
|
||||
<Flex direction="column" gap={2} minW={{ base: 'auto', lg: '120px' }} justify="center">
|
||||
<Button
|
||||
size="md"
|
||||
bgGradient="linear(to-r, blue.400, blue.600)"
|
||||
color="white"
|
||||
_hover={{
|
||||
bgGradient: "linear(to-r, blue.500, blue.700)",
|
||||
transform: "scale(1.05)",
|
||||
}}
|
||||
_active={{
|
||||
bgGradient: "linear(to-r, blue.600, blue.800)",
|
||||
}}
|
||||
boxShadow="md"
|
||||
borderRadius="lg"
|
||||
fontWeight="bold"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleViewDetail();
|
||||
}}
|
||||
transition="all 0.2s"
|
||||
>
|
||||
查看详情 →
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
{/* 关联描述(折叠区域) */}
|
||||
{relationText && relationText !== '--' && (
|
||||
<Box mt={4} pt={4} borderTop="1px solid" borderColor={dividerColor}>
|
||||
<Flex justify="space-between" align="center" mb={2}>
|
||||
<Text fontSize="sm" fontWeight="semibold" color={descColor}>
|
||||
关联描述
|
||||
</Text>
|
||||
<Collapse in={isDescExpanded} startingHeight={40}>
|
||||
<Text
|
||||
fontSize="sm"
|
||||
color={nameColor}
|
||||
lineHeight="1.6"
|
||||
cursor={needTruncate ? "pointer" : "default"}
|
||||
onClick={(e) => {
|
||||
if (needTruncate) {
|
||||
e.stopPropagation();
|
||||
setIsDescExpanded(!isDescExpanded);
|
||||
}
|
||||
}}
|
||||
_hover={needTruncate ? { opacity: 0.8 } : {}}
|
||||
>
|
||||
{relationText}
|
||||
</Text>
|
||||
</Collapse>
|
||||
{needTruncate && (
|
||||
<Button
|
||||
size="xs"
|
||||
variant="link"
|
||||
variant="ghost"
|
||||
colorScheme="blue"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsDescExpanded(!isDescExpanded);
|
||||
}}
|
||||
mt={1}
|
||||
>
|
||||
{isDescExpanded ? '收起' : '展开'}
|
||||
{isDescExpanded ? '收起 ▲' : '展开 ▼'}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* 合规提示 */}
|
||||
</Flex>
|
||||
<Collapse in={isDescExpanded} startingHeight={needTruncate ? 40 : undefined}>
|
||||
<Text
|
||||
fontSize="xs"
|
||||
color="gray.500"
|
||||
mt={2}
|
||||
fontStyle="italic"
|
||||
fontSize="sm"
|
||||
color={nameColor}
|
||||
lineHeight="1.8"
|
||||
>
|
||||
⚠️ 以上关联描述由AI生成,仅供参考,不构成投资建议
|
||||
{relationText}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</VStack>
|
||||
</Collapse>
|
||||
|
||||
{/* 合规提示 */}
|
||||
<Text
|
||||
fontSize="xs"
|
||||
color="gray.500"
|
||||
mt={3}
|
||||
fontStyle="italic"
|
||||
>
|
||||
⚠️ 以上关联描述由AI生成,仅供参考,不构成投资建议
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* 股票详情弹窗 - 未打开时不渲染 */}
|
||||
|
||||
Reference in New Issue
Block a user