事件中心UI优化
This commit is contained in:
@@ -456,7 +456,7 @@ const [currentMode, setCurrentMode] = useState('vertical');
|
|||||||
top={isFixedMode ? `${TOTAL_NAV_HEIGHT}px` : 'auto'}
|
top={isFixedMode ? `${TOTAL_NAV_HEIGHT}px` : 'auto'}
|
||||||
left={isFixedMode ? 0 : 'auto'}
|
left={isFixedMode ? 0 : 'auto'}
|
||||||
right={isFixedMode ? 0 : 'auto'}
|
right={isFixedMode ? 0 : 'auto'}
|
||||||
maxW={isFixedMode ? 'container.xl' : '100%'}
|
maxW={isFixedMode ? '1600px' : '100%'}
|
||||||
mx={isFixedMode ? 'auto' : 0}
|
mx={isFixedMode ? 'auto' : 0}
|
||||||
px={isFixedMode ? { base: 3, md: 4 } : undefined}
|
px={isFixedMode ? { base: 3, md: 4 } : undefined}
|
||||||
zIndex={isFixedMode ? 999 : 1}
|
zIndex={isFixedMode ? 999 : 1}
|
||||||
@@ -502,7 +502,7 @@ const [currentMode, setCurrentMode] = useState('vertical');
|
|||||||
left={isFixedMode ? 0 : 'auto'}
|
left={isFixedMode ? 0 : 'auto'}
|
||||||
right={isFixedMode ? 0 : 'auto'}
|
right={isFixedMode ? 0 : 'auto'}
|
||||||
bottom={isFixedMode ? `${FOOTER_HEIGHT}px` : 'auto'}
|
bottom={isFixedMode ? `${FOOTER_HEIGHT}px` : 'auto'}
|
||||||
maxW={isFixedMode ? 'container.xl' : '100%'}
|
maxW={isFixedMode ? '1600px' : '100%'}
|
||||||
mx={isFixedMode ? 'auto' : 0}
|
mx={isFixedMode ? 'auto' : 0}
|
||||||
h={isFixedMode ? `calc(100vh - ${TOTAL_NAV_HEIGHT + headerHeight + FOOTER_HEIGHT}px)` : 'auto'}
|
h={isFixedMode ? `calc(100vh - ${TOTAL_NAV_HEIGHT + headerHeight + FOOTER_HEIGHT}px)` : 'auto'}
|
||||||
px={isFixedMode ? { base: 3, md: 4 } : undefined}
|
px={isFixedMode ? { base: 3, md: 4 } : undefined}
|
||||||
@@ -579,9 +579,9 @@ const [currentMode, setCurrentMode] = useState('vertical');
|
|||||||
|
|
||||||
{/* 四排模式详情弹窗 - 未打开时不渲染 */}
|
{/* 四排模式详情弹窗 - 未打开时不渲染 */}
|
||||||
{isModalOpen && (
|
{isModalOpen && (
|
||||||
<Modal isOpen={isModalOpen} onClose={onModalClose} size="6xl" scrollBehavior="inside">
|
<Modal isOpen={isModalOpen} onClose={onModalClose} size="full" scrollBehavior="inside">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent maxW="1600px" mx="auto" my={8}>
|
||||||
<ModalHeader>
|
<ModalHeader>
|
||||||
{modalEvent?.title || '事件详情'}
|
{modalEvent?.title || '事件详情'}
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
HStack,
|
HStack,
|
||||||
Heading,
|
Heading,
|
||||||
Text,
|
Text,
|
||||||
|
Badge,
|
||||||
|
Icon,
|
||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { ViewIcon } from '@chakra-ui/icons';
|
import { ViewIcon } from '@chakra-ui/icons';
|
||||||
@@ -100,7 +102,7 @@ const EventHeaderInfo = ({ event, importance, isFollowing, followerCount, onTogg
|
|||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
{/* 第三行:涨跌幅指标 + 重要性文本 */}
|
{/* 第三行:涨跌幅指标 + 重要性徽章 */}
|
||||||
<HStack spacing={3} align="center">
|
<HStack spacing={3} align="center">
|
||||||
<Box maxW="500px">
|
<Box maxW="500px">
|
||||||
<StockChangeIndicators
|
<StockChangeIndicators
|
||||||
@@ -110,19 +112,28 @@ const EventHeaderInfo = ({ event, importance, isFollowing, followerCount, onTogg
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* 重要性文本 */}
|
{/* 重要性徽章 - 使用渐变色和图标 */}
|
||||||
<Box
|
<Badge
|
||||||
bg={importance.bgColor}
|
px={4}
|
||||||
borderWidth="2px"
|
py={2}
|
||||||
borderColor={importance.badgeBg}
|
borderRadius="full"
|
||||||
px={2}
|
fontSize="md"
|
||||||
py={1}
|
fontWeight="bold"
|
||||||
borderRadius="md"
|
bgGradient={
|
||||||
|
importance.level === 'S' ? 'linear(to-r, red.500, red.700)' :
|
||||||
|
importance.level === 'A' ? 'linear(to-r, orange.500, orange.700)' :
|
||||||
|
importance.level === 'B' ? 'linear(to-r, blue.500, blue.700)' :
|
||||||
|
'linear(to-r, gray.500, gray.700)'
|
||||||
|
}
|
||||||
|
color="white"
|
||||||
|
boxShadow="lg"
|
||||||
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
|
gap={2}
|
||||||
>
|
>
|
||||||
<Text fontSize="sm" color={importance.badgeBg} whiteSpace="nowrap" fontWeight="medium">
|
<Icon as={importance.icon} boxSize={5} />
|
||||||
重要性:{getImportanceText()}
|
<Text>重要性:{getImportanceText()}</Text>
|
||||||
</Text>
|
</Badge>
|
||||||
</Box>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
SimpleGrid,
|
VStack,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import StockListItem from './StockListItem';
|
import StockListItem from './StockListItem';
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ const RelatedStocksSection = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={4}>
|
<VStack align="stretch" spacing={3}>
|
||||||
{stocks.map((stock, index) => (
|
{stocks.map((stock, index) => (
|
||||||
<StockListItem
|
<StockListItem
|
||||||
key={index}
|
key={index}
|
||||||
@@ -40,7 +40,7 @@ const RelatedStocksSection = ({
|
|||||||
onWatchlistToggle={onWatchlistToggle}
|
onWatchlistToggle={onWatchlistToggle}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</SimpleGrid>
|
</VStack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
IconButton,
|
IconButton,
|
||||||
Collapse,
|
Collapse,
|
||||||
|
Stat,
|
||||||
|
StatLabel,
|
||||||
|
StatNumber,
|
||||||
|
StatHelpText,
|
||||||
|
StatArrow,
|
||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { StarIcon } from '@chakra-ui/icons';
|
import { StarIcon } from '@chakra-ui/icons';
|
||||||
@@ -101,46 +106,56 @@ const StockListItem = ({
|
|||||||
<>
|
<>
|
||||||
<Box
|
<Box
|
||||||
bg={cardBg}
|
bg={cardBg}
|
||||||
borderWidth="1px"
|
borderWidth="2px"
|
||||||
borderColor={borderColor}
|
borderColor={borderColor}
|
||||||
borderRadius="md"
|
borderRadius="xl"
|
||||||
p={4}
|
p={5}
|
||||||
onClick={handleViewDetail}
|
onClick={handleViewDetail}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
_hover={{
|
position="relative"
|
||||||
boxShadow: 'md',
|
overflow="hidden"
|
||||||
borderColor: 'blue.300',
|
_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}>
|
{/* 横向布局:左侧基础信息 + 中间图表 + 右侧操作按钮 */}
|
||||||
{/* 顶部:股票代码 + 名称 + 操作按钮(上下两行布局) */}
|
<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}>
|
<VStack align="stretch" spacing={2}>
|
||||||
{/* 第一行:股票代码 + 涨跌幅 + 操作按钮 */}
|
<Flex align="center" gap={2}>
|
||||||
<Flex justify="space-between" align="center">
|
<Box
|
||||||
{/* 左侧:代码 + 涨跌幅 */}
|
bgGradient="linear(to-r, blue.400, blue.600)"
|
||||||
<Flex align="baseline" gap={2}>
|
px={3}
|
||||||
|
py={1}
|
||||||
|
borderRadius="md"
|
||||||
|
boxShadow="sm"
|
||||||
|
>
|
||||||
<Text
|
<Text
|
||||||
fontSize="md"
|
fontSize="md"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
color={codeColor}
|
color="white"
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={handleViewDetail}
|
onClick={handleViewDetail}
|
||||||
_hover={{ textDecoration: 'underline' }}
|
_hover={{ opacity: 0.8 }}
|
||||||
|
transition="opacity 0.2s"
|
||||||
>
|
>
|
||||||
{stock.stock_code}
|
{stock.stock_code}
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
</Box>
|
||||||
fontSize="sm"
|
|
||||||
fontWeight="semibold"
|
|
||||||
color={getChangeColor(change)}
|
|
||||||
>
|
|
||||||
{formatChange(change)}
|
|
||||||
</Text>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
{/* 右侧:操作按钮 */}
|
|
||||||
<Flex gap={2}>
|
|
||||||
{onWatchlistToggle && (
|
{onWatchlistToggle && (
|
||||||
<IconButton
|
<IconButton
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -150,43 +165,74 @@ const StockListItem = ({
|
|||||||
onClick={handleWatchlistClick}
|
onClick={handleWatchlistClick}
|
||||||
aria-label={isInWatchlist ? '已关注' : '加自选'}
|
aria-label={isInWatchlist ? '已关注' : '加自选'}
|
||||||
title={isInWatchlist ? '已关注' : '加自选'}
|
title={isInWatchlist ? '已关注' : '加自选'}
|
||||||
|
borderRadius="full"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
colorScheme="blue"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
handleViewDetail();
|
|
||||||
}}
|
|
||||||
display={{ base: 'inline-flex', lg: 'none' }}
|
|
||||||
>
|
|
||||||
查看
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
|
||||||
|
|
||||||
{/* 第二行:公司名称 + 分时图 + K线图 */}
|
|
||||||
<Flex align="center" gap={3}>
|
|
||||||
{/* 左侧:公司名称 */}
|
|
||||||
<Text
|
<Text
|
||||||
fontSize="sm"
|
fontSize="md"
|
||||||
fontWeight="medium"
|
fontWeight="semibold"
|
||||||
color={codeColor}
|
color={nameColor}
|
||||||
bg={useColorModeValue('blue.50', 'blue.900')}
|
noOfLines={1}
|
||||||
px={2}
|
|
||||||
py={0.5}
|
|
||||||
borderRadius="sm"
|
|
||||||
whiteSpace="nowrap"
|
|
||||||
flexShrink={0}
|
|
||||||
>
|
>
|
||||||
{stock.stock_name}
|
{stock.stock_name}
|
||||||
</Text>
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
|
||||||
{/* 右侧:分时图 + K线图 */}
|
{/* 涨跌幅 - 使用 Stat 组件 */}
|
||||||
<Flex gap={2} flex={1} onClick={(e) => e.stopPropagation()}>
|
<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线图) */}
|
||||||
|
<Flex flex={1} gap={3} onClick={(e) => e.stopPropagation()} minW={0}>
|
||||||
{/* 分时图 */}
|
{/* 分时图 */}
|
||||||
<Box flex={1} 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
|
<MiniTimelineChart
|
||||||
stockCode={stock.stock_code}
|
stockCode={stock.stock_code}
|
||||||
eventTime={eventTime}
|
eventTime={eventTime}
|
||||||
@@ -195,7 +241,30 @@ const StockListItem = ({
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* K线图 */}
|
{/* K线图 */}
|
||||||
<Box flex={1} minW={0}>
|
<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
|
<MiniKLineChart
|
||||||
stockCode={stock.stock_code}
|
stockCode={stock.stock_code}
|
||||||
eventTime={eventTime}
|
eventTime={eventTime}
|
||||||
@@ -203,62 +272,76 @@ const StockListItem = ({
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
|
||||||
</VStack>
|
|
||||||
|
|
||||||
{/* 分隔线 */}
|
{/* 右侧:操作按钮 */}
|
||||||
<Box borderTop="1px solid" borderColor={dividerColor} />
|
<Flex direction="column" gap={2} minW={{ base: 'auto', lg: '120px' }} justify="center">
|
||||||
|
<Button
|
||||||
{/* 关联描述 */}
|
size="md"
|
||||||
{relationText && relationText !== '--' && (
|
bgGradient="linear(to-r, blue.400, blue.600)"
|
||||||
<Box>
|
color="white"
|
||||||
<Text fontSize="xs" color={descColor} mb={1}>
|
_hover={{
|
||||||
关联描述:
|
bgGradient: "linear(to-r, blue.500, blue.700)",
|
||||||
</Text>
|
transform: "scale(1.05)",
|
||||||
<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 } : {}}
|
_active={{
|
||||||
|
bgGradient: "linear(to-r, blue.600, blue.800)",
|
||||||
|
}}
|
||||||
|
boxShadow="md"
|
||||||
|
borderRadius="lg"
|
||||||
|
fontWeight="bold"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleViewDetail();
|
||||||
|
}}
|
||||||
|
transition="all 0.2s"
|
||||||
>
|
>
|
||||||
{relationText}
|
查看详情 →
|
||||||
|
</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>
|
</Text>
|
||||||
</Collapse>
|
|
||||||
{needTruncate && (
|
{needTruncate && (
|
||||||
<Button
|
<Button
|
||||||
size="xs"
|
size="xs"
|
||||||
variant="link"
|
variant="ghost"
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setIsDescExpanded(!isDescExpanded);
|
setIsDescExpanded(!isDescExpanded);
|
||||||
}}
|
}}
|
||||||
mt={1}
|
|
||||||
>
|
>
|
||||||
{isDescExpanded ? '收起' : '展开'}
|
{isDescExpanded ? '收起 ▲' : '展开 ▼'}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
</Flex>
|
||||||
|
<Collapse in={isDescExpanded} startingHeight={needTruncate ? 40 : undefined}>
|
||||||
|
<Text
|
||||||
|
fontSize="sm"
|
||||||
|
color={nameColor}
|
||||||
|
lineHeight="1.8"
|
||||||
|
>
|
||||||
|
{relationText}
|
||||||
|
</Text>
|
||||||
|
</Collapse>
|
||||||
|
|
||||||
{/* 合规提示 */}
|
{/* 合规提示 */}
|
||||||
<Text
|
<Text
|
||||||
fontSize="xs"
|
fontSize="xs"
|
||||||
color="gray.500"
|
color="gray.500"
|
||||||
mt={2}
|
mt={3}
|
||||||
fontStyle="italic"
|
fontStyle="italic"
|
||||||
>
|
>
|
||||||
⚠️ 以上关联描述由AI生成,仅供参考,不构成投资建议
|
⚠️ 以上关联描述由AI生成,仅供参考,不构成投资建议
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</VStack>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* 股票详情弹窗 - 未打开时不渲染 */}
|
{/* 股票详情弹窗 - 未打开时不渲染 */}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ const Community = () => {
|
|||||||
return (
|
return (
|
||||||
<Box minH="100vh" bg={bgColor}>
|
<Box minH="100vh" bg={bgColor}>
|
||||||
{/* 主内容区域 */}
|
{/* 主内容区域 */}
|
||||||
<Container ref={containerRef} maxW="container.xl" pt={6} pb={8}>
|
<Container ref={containerRef} maxW="1600px" pt={6} pb={8}>
|
||||||
{/* 热点事件区域 */}
|
{/* 热点事件区域 */}
|
||||||
<HotEventsSection events={hotEvents} />
|
<HotEventsSection events={hotEvents} />
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user