update ui

This commit is contained in:
2025-11-13 23:06:19 +08:00
parent 6113a3fefd
commit d3b980b3ca
2 changed files with 78 additions and 122 deletions

View File

@@ -146,7 +146,7 @@ const HorizontalDynamicNewsEventCard = ({
> >
<CardBody p={3} pb={2}> <CardBody p={3} pb={2}>
{/* 右上角:关注按钮 */} {/* 右上角:关注按钮 */}
<Box position="absolute" top={2} right={2} zIndex={1}> <Box position="absolute" top={2} right={2} zIndex={2}>
<EventFollowButton <EventFollowButton
isFollowing={isFollowing} isFollowing={isFollowing}
followerCount={followerCount} followerCount={followerCount}
@@ -156,6 +156,18 @@ const HorizontalDynamicNewsEventCard = ({
/> />
</Box> </Box>
{/* Keywords梦幻轮播 - 绝对定位在卡片右侧空白处 */}
{event.keywords && event.keywords.length > 0 && (
<KeywordsCarousel
keywords={event.keywords}
interval={4000}
onKeywordClick={(keyword) => {
console.log('Keyword clicked:', keyword);
// TODO: 实现关键词筛选功能
}}
/>
)}
<VStack align="stretch" spacing={1.5}> <VStack align="stretch" spacing={1.5}>
{/* 标题 - 最多两行hover 显示完整内容 */} {/* 标题 - 最多两行hover 显示完整内容 */}
<Tooltip <Tooltip
@@ -173,7 +185,7 @@ const HorizontalDynamicNewsEventCard = ({
cursor="pointer" cursor="pointer"
onClick={(e) => onTitleClick?.(e, event)} onClick={(e) => onTitleClick?.(e, event)}
mt={1} mt={1}
paddingRight="10px" paddingRight="120px"
> >
<Text <Text
fontSize="md" fontSize="md"
@@ -188,37 +200,13 @@ const HorizontalDynamicNewsEventCard = ({
</Box> </Box>
</Tooltip> </Tooltip>
{/* 第二行:涨跌幅数据 + Keywords轮播 */} {/* 第二行:涨跌幅数据 */}
<HStack spacing={3} align="center" justify="space-between" w="full"> <StockChangeIndicators
{/* 左侧:涨跌幅数据 */} avgChange={event.related_avg_chg}
<StockChangeIndicators maxChange={event.related_max_chg}
avgChange={event.related_avg_chg} weekChange={event.related_week_chg}
maxChange={event.related_max_chg} size={indicatorSize}
weekChange={event.related_week_chg} />
size={indicatorSize}
/>
{/* 右侧Keywords轮播半透明效果 */}
{event.keywords && event.keywords.length > 0 && (
<Box
flex="1"
minW={0}
opacity={0.85}
_hover={{ opacity: 1 }}
transition="opacity 0.2s"
>
<KeywordsCarousel
keywords={event.keywords}
displayCount={3}
interval={3500}
onKeywordClick={(keyword) => {
console.log('Keyword clicked:', keyword);
// TODO: 实现关键词筛选功能
}}
/>
</Box>
)}
</HStack>
</VStack> </VStack>
</CardBody> </CardBody>
</Card> </Card>

View File

@@ -1,31 +1,31 @@
// src/views/Community/components/EventCard/KeywordsCarousel.js // src/views/Community/components/EventCard/KeywordsCarousel.js
// Keywords标签轮播组件 // Keywords标签梦幻淡入淡出轮播组件
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Box, Tag, HStack, useColorModeValue, Tooltip } from '@chakra-ui/react'; import { Box, Text, useColorModeValue } from '@chakra-ui/react';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
const MotionBox = motion(Box); const MotionBox = motion(Box);
/** /**
* Keywords标签轮播组件 * Keywords标签梦幻轮播组件(单个显示,淡入淡出)
* @param {Array} keywords - 关键词数组 * @param {Array} keywords - 关键词数组
* @param {number} displayCount - 显示的标签数量默认3个 * @param {number} interval - 轮播间隔毫秒默认4000ms
* @param {number} interval - 轮播间隔毫秒默认3000ms
* @param {Function} onKeywordClick - 关键词点击回调 * @param {Function} onKeywordClick - 关键词点击回调
*/ */
const KeywordsCarousel = ({ const KeywordsCarousel = ({
keywords = [], keywords = [],
displayCount = 3, interval = 4000,
interval = 3000,
onKeywordClick onKeywordClick
}) => { }) => {
const [currentIndex, setCurrentIndex] = useState(0); const [currentIndex, setCurrentIndex] = useState(0);
const [isPaused, setIsPaused] = useState(false); const [isPaused, setIsPaused] = useState(false);
// 颜色配置 // 颜色配置 - 梦幻渐变效果
const tagBg = useColorModeValue('rgba(66, 153, 225, 0.1)', 'rgba(66, 153, 225, 0.2)'); const textColor = useColorModeValue(
const tagColor = useColorModeValue('blue.600', 'blue.300'); 'linear(to-r, purple.400, pink.400, blue.400)',
const tagBorder = useColorModeValue('blue.200', 'blue.600'); 'linear(to-r, purple.300, pink.300, blue.300)'
);
const hoverBg = useColorModeValue('rgba(159, 122, 234, 0.1)', 'rgba(159, 122, 234, 0.15)');
// 如果没有keywords不渲染 // 如果没有keywords不渲染
if (!keywords || keywords.length === 0) { if (!keywords || keywords.length === 0) {
@@ -34,98 +34,66 @@ const KeywordsCarousel = ({
// 自动轮播 // 自动轮播
useEffect(() => { useEffect(() => {
if (isPaused || keywords.length <= displayCount) return; if (isPaused || keywords.length <= 1) return;
const timer = setInterval(() => { const timer = setInterval(() => {
setCurrentIndex((prev) => (prev + 1) % keywords.length); setCurrentIndex((prev) => (prev + 1) % keywords.length);
}, interval); }, interval);
return () => clearInterval(timer); return () => clearInterval(timer);
}, [isPaused, keywords.length, displayCount, interval]); }, [isPaused, keywords.length, interval]);
// 获取当前显示的关键词 const currentKeyword = keywords[currentIndex];
const getVisibleKeywords = () => {
if (keywords.length <= displayCount) {
return keywords;
}
const visible = [];
for (let i = 0; i < displayCount; i++) {
const index = (currentIndex + i) % keywords.length;
visible.push(keywords[index]);
}
return visible;
};
const visibleKeywords = getVisibleKeywords();
return ( return (
<Box <Box
position="absolute"
right={4}
top="50%"
transform="translateY(-50%)"
onMouseEnter={() => setIsPaused(true)} onMouseEnter={() => setIsPaused(true)}
onMouseLeave={() => setIsPaused(false)} onMouseLeave={() => setIsPaused(false)}
position="relative" pointerEvents="auto"
zIndex={1}
> >
<HStack spacing={1.5} flexWrap="wrap"> <AnimatePresence mode="wait">
<AnimatePresence mode="wait"> <MotionBox
{visibleKeywords.map((keyword, index) => ( key={`keyword-${currentKeyword}-${currentIndex}`}
<MotionBox initial={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}
key={`${keyword}-${currentIndex}-${index}`} animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}
initial={{ opacity: 0, scale: 0.8 }} exit={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}
animate={{ opacity: 1, scale: 1 }} transition={{
exit={{ opacity: 0, scale: 0.8 }} duration: 0.8,
transition={{ duration: 0.3 }} ease: [0.4, 0, 0.2, 1]
> }}
<Tooltip cursor="pointer"
label={`点击筛选"${keyword}"`} onClick={(e) => {
placement="top" e.stopPropagation();
hasArrow onKeywordClick?.(currentKeyword);
> }}
<Tag px={3}
size="sm" py={1.5}
variant="subtle" borderRadius="full"
bg={tagBg} bg="transparent"
color={tagColor} _hover={{
borderWidth="1px" bg: hoverBg,
borderColor={tagBorder} transform: 'scale(1.05)',
cursor="pointer" }}
fontSize="10px" transition="background 0.3s, transform 0.2s"
fontWeight="medium"
px={2}
py={0.5}
borderRadius="full"
_hover={{
bg: useColorModeValue('blue.100', 'blue.700'),
transform: 'scale(1.05)',
boxShadow: 'md'
}}
transition="all 0.2s"
onClick={(e) => {
e.stopPropagation();
onKeywordClick?.(keyword);
}}
>
#{keyword}
</Tag>
</Tooltip>
</MotionBox>
))}
</AnimatePresence>
</HStack>
{/* 如果有更多关键词,显示指示器 */}
{keywords.length > displayCount && (
<Box
position="absolute"
right={-2}
top="50%"
transform="translateY(-50%)"
fontSize="10px"
color="gray.400"
fontWeight="bold"
> >
+{keywords.length - displayCount} <Text
</Box> bgGradient={textColor}
)} bgClip="text"
fontSize="md"
fontWeight="bold"
letterSpacing="wide"
whiteSpace="nowrap"
textShadow="0 0 20px rgba(159, 122, 234, 0.3)"
>
{currentKeyword}
</Text>
</MotionBox>
</AnimatePresence>
</Box> </Box>
); );
}; };