update pay ui
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 热点概览组件
|
||||
* 热点概览组件 - 科技感设计
|
||||
* 展示大盘分时走势 + 概念异动标注
|
||||
*
|
||||
* 模块化结构:
|
||||
@@ -12,8 +12,6 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Card,
|
||||
CardBody,
|
||||
Heading,
|
||||
Text,
|
||||
HStack,
|
||||
@@ -27,16 +25,36 @@ import {
|
||||
useColorModeValue,
|
||||
Grid,
|
||||
GridItem,
|
||||
Divider,
|
||||
IconButton,
|
||||
Collapse,
|
||||
keyframes,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaFire, FaList, FaChartArea, FaChevronDown, FaChevronUp } from 'react-icons/fa';
|
||||
import { InfoIcon } from '@chakra-ui/icons';
|
||||
import {
|
||||
Flame,
|
||||
List,
|
||||
LineChart,
|
||||
ChevronDown,
|
||||
ChevronUp,
|
||||
Info,
|
||||
Zap,
|
||||
AlertCircle,
|
||||
} from 'lucide-react';
|
||||
|
||||
import { useHotspotData } from './hooks';
|
||||
import { IndexMinuteChart, ConceptAlertList, AlertSummary } from './components';
|
||||
|
||||
// 动画效果
|
||||
const gradientShift = keyframes`
|
||||
0% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
`;
|
||||
|
||||
const pulseGlow = keyframes`
|
||||
0%, 100% { opacity: 0.5; }
|
||||
50% { opacity: 1; }
|
||||
`;
|
||||
|
||||
/**
|
||||
* 热点概览主组件
|
||||
* @param {Object} props
|
||||
@@ -50,46 +68,102 @@ const HotspotOverview = ({ selectedDate }) => {
|
||||
const { loading, error, data } = useHotspotData(selectedDate);
|
||||
|
||||
// 颜色主题
|
||||
const cardBg = useColorModeValue('white', '#1a1a1a');
|
||||
const borderColor = useColorModeValue('gray.200', '#333333');
|
||||
const cardBg = useColorModeValue('white', '#0a0a0a');
|
||||
const borderColor = useColorModeValue('gray.200', '#1f1f1f');
|
||||
const textColor = useColorModeValue('gray.800', 'white');
|
||||
const subTextColor = useColorModeValue('gray.600', 'gray.400');
|
||||
const headerGradient = useColorModeValue(
|
||||
'linear(to-r, orange.500, red.500)',
|
||||
'linear(to-r, orange.400, red.400)'
|
||||
);
|
||||
|
||||
// 点击异动标注
|
||||
const handleAlertClick = useCallback((alert) => {
|
||||
setSelectedAlert(alert);
|
||||
// 可以在这里添加滚动到对应位置的逻辑
|
||||
}, []);
|
||||
|
||||
// 渲染加载状态
|
||||
if (loading) {
|
||||
return (
|
||||
<Card bg={cardBg} borderWidth="1px" borderColor={borderColor}>
|
||||
<CardBody>
|
||||
<Center h="400px">
|
||||
<VStack spacing={4}>
|
||||
<Spinner size="xl" color="purple.500" thickness="4px" />
|
||||
<Text color={subTextColor}>加载热点概览数据...</Text>
|
||||
<Box
|
||||
bg={cardBg}
|
||||
borderRadius="2xl"
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor}
|
||||
overflow="hidden"
|
||||
>
|
||||
{/* 顶部装饰条 */}
|
||||
<Box
|
||||
h="4px"
|
||||
bgGradient="linear(to-r, orange.400, red.500, pink.500)"
|
||||
backgroundSize="200% 200%"
|
||||
animation={`${gradientShift} 3s ease infinite`}
|
||||
/>
|
||||
|
||||
<Center h="400px" p={6}>
|
||||
<VStack spacing={4}>
|
||||
<Box position="relative">
|
||||
<Spinner
|
||||
size="xl"
|
||||
color="orange.400"
|
||||
thickness="3px"
|
||||
speed="0.8s"
|
||||
/>
|
||||
<Box
|
||||
position="absolute"
|
||||
inset={0}
|
||||
borderRadius="full"
|
||||
animation={`${pulseGlow} 2s ease-in-out infinite`}
|
||||
boxShadow="0 0 30px rgba(251, 146, 60, 0.3)"
|
||||
/>
|
||||
</Box>
|
||||
<VStack spacing={1}>
|
||||
<Text color={textColor} fontWeight="medium">
|
||||
加载热点概览数据
|
||||
</Text>
|
||||
<Text color={subTextColor} fontSize="sm">
|
||||
正在获取市场异动信息...
|
||||
</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</VStack>
|
||||
</Center>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// 渲染错误状态
|
||||
if (error) {
|
||||
return (
|
||||
<Card bg={cardBg} borderWidth="1px" borderColor={borderColor}>
|
||||
<CardBody>
|
||||
<Center h="400px">
|
||||
<VStack spacing={4}>
|
||||
<Icon as={InfoIcon} boxSize={10} color="red.400" />
|
||||
<Text color="red.500">{error}</Text>
|
||||
<Box
|
||||
bg={cardBg}
|
||||
borderRadius="2xl"
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor}
|
||||
overflow="hidden"
|
||||
>
|
||||
<Box h="4px" bg="red.500" />
|
||||
|
||||
<Center h="400px" p={6}>
|
||||
<VStack spacing={4}>
|
||||
<Box
|
||||
p={4}
|
||||
borderRadius="full"
|
||||
bg="red.500"
|
||||
bgOpacity={0.1}
|
||||
>
|
||||
<Icon as={AlertCircle} boxSize={10} color="red.400" />
|
||||
</Box>
|
||||
<VStack spacing={1}>
|
||||
<Text color="red.400" fontWeight="medium">
|
||||
数据加载失败
|
||||
</Text>
|
||||
<Text color={subTextColor} fontSize="sm" textAlign="center">
|
||||
{error}
|
||||
</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</VStack>
|
||||
</Center>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -101,53 +175,131 @@ const HotspotOverview = ({ selectedDate }) => {
|
||||
const { index, alerts, alert_summary } = data;
|
||||
|
||||
return (
|
||||
<Card bg={cardBg} borderWidth="1px" borderColor={borderColor}>
|
||||
<CardBody>
|
||||
<Box
|
||||
bg={cardBg}
|
||||
borderRadius="2xl"
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor}
|
||||
overflow="hidden"
|
||||
transition="all 0.3s"
|
||||
_hover={{
|
||||
boxShadow: useColorModeValue(
|
||||
'0 4px 20px rgba(0,0,0,0.08)',
|
||||
'0 4px 20px rgba(0,0,0,0.4)'
|
||||
),
|
||||
}}
|
||||
>
|
||||
{/* 顶部装饰条 */}
|
||||
<Box
|
||||
h="4px"
|
||||
bgGradient="linear(to-r, orange.400, red.500, pink.500)"
|
||||
backgroundSize="200% 200%"
|
||||
animation={`${gradientShift} 3s ease infinite`}
|
||||
/>
|
||||
|
||||
<Box p={5}>
|
||||
{/* 头部 */}
|
||||
<Flex align="center" mb={4}>
|
||||
<Flex align="center" mb={5}>
|
||||
<HStack spacing={3}>
|
||||
<Icon as={FaFire} boxSize={6} color="orange.500" />
|
||||
<Heading size="md" color={textColor}>
|
||||
热点概览
|
||||
</Heading>
|
||||
<Box
|
||||
p={2}
|
||||
borderRadius="xl"
|
||||
bgGradient="linear(to-br, orange.400, red.500)"
|
||||
boxShadow="0 4px 15px rgba(251, 146, 60, 0.4)"
|
||||
>
|
||||
<Icon as={Flame} boxSize={5} color="white" />
|
||||
</Box>
|
||||
<VStack align="flex-start" spacing={0}>
|
||||
<Heading size="md" color={textColor} fontWeight="bold">
|
||||
热点概览
|
||||
</Heading>
|
||||
<Text fontSize="xs" color={subTextColor}>
|
||||
实时概念异动监控
|
||||
</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
<Spacer />
|
||||
<HStack spacing={2}>
|
||||
<Tooltip label={showAlertList ? '收起异动列表' : '展开异动列表'}>
|
||||
{/* 异动数量徽章 */}
|
||||
{alerts.length > 0 && (
|
||||
<HStack
|
||||
spacing={1}
|
||||
px={3}
|
||||
py={1.5}
|
||||
borderRadius="full"
|
||||
bg="orange.500"
|
||||
bgOpacity={0.15}
|
||||
>
|
||||
<Icon as={Zap} boxSize={3.5} color="orange.400" />
|
||||
<Text fontSize="sm" fontWeight="bold" color="orange.400">
|
||||
{alerts.length}
|
||||
</Text>
|
||||
</HStack>
|
||||
)}
|
||||
|
||||
{/* 切换按钮 */}
|
||||
<Tooltip label={showAlertList ? '收起异动列表' : '展开异动列表'} hasArrow>
|
||||
<IconButton
|
||||
icon={showAlertList ? <FaChevronUp /> : <FaList />}
|
||||
icon={<Icon as={showAlertList ? ChevronUp : List} boxSize={4} />}
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
borderRadius="lg"
|
||||
onClick={() => setShowAlertList(!showAlertList)}
|
||||
aria-label="切换异动列表"
|
||||
_hover={{
|
||||
bg: useColorModeValue('gray.100', 'gray.800'),
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip label="展示大盘走势与概念异动的关联">
|
||||
<Icon as={InfoIcon} color={subTextColor} />
|
||||
|
||||
{/* 信息提示 */}
|
||||
<Tooltip
|
||||
label="展示大盘走势与概念异动的关联,帮助发现市场热点"
|
||||
hasArrow
|
||||
maxW="200px"
|
||||
>
|
||||
<Box cursor="help">
|
||||
<Icon as={Info} color={subTextColor} boxSize={4} />
|
||||
</Box>
|
||||
</Tooltip>
|
||||
</HStack>
|
||||
</Flex>
|
||||
|
||||
{/* 统计摘要 */}
|
||||
<Box mb={4}>
|
||||
<Box mb={5}>
|
||||
<AlertSummary indexData={index} alerts={alerts} alertSummary={alert_summary} />
|
||||
</Box>
|
||||
|
||||
<Divider mb={4} />
|
||||
|
||||
{/* 主体内容:图表 + 异动列表 */}
|
||||
<Grid
|
||||
templateColumns={{ base: '1fr', lg: showAlertList ? '1fr 300px' : '1fr' }}
|
||||
gap={4}
|
||||
templateColumns={{ base: '1fr', lg: showAlertList ? '1fr 320px' : '1fr' }}
|
||||
gap={5}
|
||||
>
|
||||
{/* 分时图 */}
|
||||
<GridItem>
|
||||
<Box>
|
||||
<HStack spacing={2} mb={2}>
|
||||
<Icon as={FaChartArea} color="purple.500" boxSize={4} />
|
||||
<Text fontSize="sm" fontWeight="medium" color={textColor}>
|
||||
<Box
|
||||
bg={useColorModeValue('gray.50', '#0d0d0d')}
|
||||
borderRadius="xl"
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor}
|
||||
p={4}
|
||||
transition="all 0.2s"
|
||||
>
|
||||
<HStack spacing={2} mb={3}>
|
||||
<Box
|
||||
p={1.5}
|
||||
borderRadius="lg"
|
||||
bg="purple.500"
|
||||
bgOpacity={0.15}
|
||||
>
|
||||
<Icon as={LineChart} boxSize={4} color="purple.400" />
|
||||
</Box>
|
||||
<Text fontSize="sm" fontWeight="bold" color={textColor}>
|
||||
大盘分时走势
|
||||
</Text>
|
||||
<Tooltip label="图表上的标记点表示概念异动时刻" hasArrow>
|
||||
<Icon as={Info} boxSize={3} color={subTextColor} cursor="help" />
|
||||
</Tooltip>
|
||||
</HStack>
|
||||
<IndexMinuteChart
|
||||
indexData={index}
|
||||
@@ -159,12 +311,26 @@ const HotspotOverview = ({ selectedDate }) => {
|
||||
</GridItem>
|
||||
|
||||
{/* 异动列表(可收起) */}
|
||||
<Collapse in={showAlertList} animateOpacity>
|
||||
<Collapse in={showAlertList} animateOpacity style={{ overflow: 'visible' }}>
|
||||
<GridItem>
|
||||
<Box>
|
||||
<HStack spacing={2} mb={2}>
|
||||
<Icon as={FaList} color="orange.500" boxSize={4} />
|
||||
<Text fontSize="sm" fontWeight="medium" color={textColor}>
|
||||
<Box
|
||||
bg={useColorModeValue('gray.50', '#0d0d0d')}
|
||||
borderRadius="xl"
|
||||
borderWidth="1px"
|
||||
borderColor={borderColor}
|
||||
p={4}
|
||||
h="100%"
|
||||
>
|
||||
<HStack spacing={2} mb={3}>
|
||||
<Box
|
||||
p={1.5}
|
||||
borderRadius="lg"
|
||||
bg="orange.500"
|
||||
bgOpacity={0.15}
|
||||
>
|
||||
<Icon as={List} boxSize={4} color="orange.400" />
|
||||
</Box>
|
||||
<Text fontSize="sm" fontWeight="bold" color={textColor}>
|
||||
异动记录
|
||||
</Text>
|
||||
<Text fontSize="xs" color={subTextColor}>
|
||||
@@ -175,7 +341,7 @@ const HotspotOverview = ({ selectedDate }) => {
|
||||
alerts={alerts}
|
||||
onAlertClick={handleAlertClick}
|
||||
selectedAlert={selectedAlert}
|
||||
maxHeight="350px"
|
||||
maxHeight="380px"
|
||||
/>
|
||||
</Box>
|
||||
</GridItem>
|
||||
@@ -184,14 +350,22 @@ const HotspotOverview = ({ selectedDate }) => {
|
||||
|
||||
{/* 无异动提示 */}
|
||||
{alerts.length === 0 && (
|
||||
<Center py={4}>
|
||||
<Text color={subTextColor} fontSize="sm">
|
||||
当日暂无概念异动数据
|
||||
</Text>
|
||||
<Center
|
||||
py={8}
|
||||
mt={4}
|
||||
bg={useColorModeValue('gray.50', '#0d0d0d')}
|
||||
borderRadius="xl"
|
||||
>
|
||||
<VStack spacing={2}>
|
||||
<Icon as={Zap} boxSize={8} color={subTextColor} opacity={0.5} />
|
||||
<Text color={subTextColor} fontSize="sm">
|
||||
当日暂无概念异动数据
|
||||
</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user