community增加事件详情

This commit is contained in:
2026-01-06 19:15:18 +08:00
parent ce0c7a6177
commit 5a133084ca
2 changed files with 194 additions and 97 deletions

View File

@@ -1,38 +1,27 @@
// src/components/EventDetailPanel/CompactMetaBar.js // src/components/EventDetailPanel/CompactMetaBar.js
// 精简信息栏组件(无头部模式下右上角显示) // 精简信息栏组件(无头部模式下右上角显示)- 现代化设计
import React from 'react'; import React from 'react';
import { import {
HStack, HStack,
Badge, Box,
Text, Text,
Icon, Icon,
IconButton,
Tooltip, Tooltip,
useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { EventFollowButton } from '@views/Community/components/EventCard/atoms'; import { EventFollowButton } from '@views/Community/components/EventCard/atoms';
import { Eye, ExternalLink } from 'lucide-react'; import { Eye, Share2, ExternalLink, CheckCircle, AlertTriangle, Flame, Zap } from 'lucide-react';
import ShareButton from '@components/ShareButton'; import ShareButton from '@components/ShareButton';
import { getEventDetailUrl } from '@utils/idEncoder'; import { getEventDetailUrl, encodeEventId } from '@utils/idEncoder';
/** /**
* 精简信息栏组件 * 精简信息栏组件
* 在无头部模式下,显示在 CardBody 右上角 * 在无头部模式下,显示在 CardBody 右上角
* 包含:重要性徽章、浏览次数、关注按钮 * 现代化毛玻璃设计风格
*
* @param {Object} props
* @param {Object} props.event - 事件对象
* @param {Object} props.importance - 重要性配置对象(包含 level, icon 等)
* @param {boolean} props.isFollowing - 是否已关注
* @param {number} props.followerCount - 关注数
* @param {Function} props.onToggleFollow - 切换关注回调
*/ */
const CompactMetaBar = ({ event, importance, isFollowing, followerCount, onToggleFollow }) => { const CompactMetaBar = ({ event, importance, isFollowing, followerCount, onToggleFollow }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const viewCountBg = useColorModeValue('white', 'gray.700');
const viewCountTextColor = useColorModeValue('gray.600', 'gray.300');
// 跳转到事件详情页 // 跳转到事件详情页
const handleViewDetail = () => { const handleViewDetail = () => {
@@ -41,62 +30,104 @@ const CompactMetaBar = ({ event, importance, isFollowing, followerCount, onToggl
} }
}; };
// 获取重要性文本 // 重要性配置
const getImportanceText = () => { const importanceConfig = {
const levelMap = { 'S': {
'S': '极高', label: '极高',
'A': '高', icon: Flame,
'B': '中', gradient: 'linear(to-r, #FF416C, #FF4B2B)',
'C': '低' glow: '0 0 20px rgba(255, 65, 108, 0.5)',
}; borderColor: 'rgba(255, 65, 108, 0.6)',
return levelMap[importance.level] || '中'; },
'A': {
label: '高',
icon: Zap,
gradient: 'linear(to-r, #F09819, #FF512F)',
glow: '0 0 15px rgba(240, 152, 25, 0.4)',
borderColor: 'rgba(240, 152, 25, 0.5)',
},
'B': {
label: '中',
icon: AlertTriangle,
gradient: 'linear(to-r, #4776E6, #8E54E9)',
glow: '0 0 12px rgba(71, 118, 230, 0.3)',
borderColor: 'rgba(71, 118, 230, 0.4)',
},
'C': {
label: '低',
icon: CheckCircle,
gradient: 'linear(to-r, #606c88, #3f4c6b)',
glow: 'none',
borderColor: 'rgba(96, 108, 136, 0.4)',
},
}; };
const config = importanceConfig[importance.level] || importanceConfig['C'];
return ( return (
<HStack <HStack
position="absolute" position="absolute"
top={3} top={3}
right={3} right={3}
spacing={3} spacing={2}
zIndex={1} zIndex={1}
> >
{/* 重要性徽章 - 与 EventHeaderInfo 样式一致,尺寸略小 - H5 隐藏 */} {/* 重要性徽章 - 发光效果 */}
<Badge <Tooltip label={`重要性:${config.label}`} hasArrow placement="bottom">
<Box
display={{ base: 'none', lg: 'flex' }}
alignItems="center"
gap={1.5}
px={3} px={3}
py={1.5} py={1.5}
borderRadius="full" borderRadius="full"
fontSize="sm" bgGradient={config.gradient}
fontWeight="bold" boxShadow={config.glow}
bgGradient={ border="1px solid"
importance.level === 'S' ? 'linear(to-r, red.500, red.700)' : borderColor={config.borderColor}
importance.level === 'A' ? 'linear(to-r, orange.500, orange.700)' : cursor="default"
importance.level === 'B' ? 'linear(to-r, blue.500, blue.700)' : transition="all 0.3s ease"
'linear(to-r, gray.500, gray.700)' _hover={{
} transform: 'scale(1.05)',
color="white" boxShadow: config.glow.replace('0.5', '0.7').replace('0.4', '0.6').replace('0.3', '0.5'),
boxShadow="lg" }}
display={{ base: 'none', lg: 'flex' }}
alignItems="center"
gap={1}
> >
<Icon as={importance.icon} boxSize={4} /> <Icon as={config.icon} boxSize={4} color="white" />
<Text>重要性{getImportanceText()}</Text> <Text fontSize="sm" fontWeight="bold" color="white" letterSpacing="wide">
</Badge> {config.label}
</Text>
</Box>
</Tooltip>
{/* 浏览次数 - 添加容器背景以提高可读性 */} {/* 统计信息容器 - 毛玻璃效果 */}
<HStack <HStack
spacing={1} spacing={0}
bg={viewCountBg} bg="rgba(0, 0, 0, 0.4)"
px={2} backdropFilter="blur(10px)"
py={1} borderRadius="full"
borderRadius="md" border="1px solid rgba(255, 255, 255, 0.1)"
boxShadow="sm" overflow="hidden"
boxShadow="0 4px 15px rgba(0, 0, 0, 0.2)"
> >
<Icon as={Eye} boxSize={4} color="gray.400" /> {/* 浏览量 */}
<Text fontSize="sm" color={viewCountTextColor} whiteSpace="nowrap"> <Tooltip label="浏览量" hasArrow placement="bottom">
<HStack
spacing={1.5}
px={3}
py={1.5}
cursor="default"
_hover={{ bg: 'rgba(255, 255, 255, 0.1)' }}
transition="all 0.2s"
>
<Icon as={Eye} boxSize={4} color="cyan.400" />
<Text fontSize="sm" fontWeight="semibold" color="white">
{(event.view_count || 0).toLocaleString()} {(event.view_count || 0).toLocaleString()}
</Text> </Text>
</HStack> </HStack>
</Tooltip>
{/* 分隔线 */}
<Box h="20px" w="1px" bg="rgba(255, 255, 255, 0.15)" />
{/* 关注按钮 */} {/* 关注按钮 */}
<EventFollowButton <EventFollowButton
@@ -105,35 +136,67 @@ const CompactMetaBar = ({ event, importance, isFollowing, followerCount, onToggl
onToggle={onToggleFollow} onToggle={onToggleFollow}
size="sm" size="sm"
showCount={true} showCount={true}
variant="minimal"
/> />
</HStack>
{/* 分享按钮 - 复制链接 */} {/* 操作按钮 - 毛玻璃效果 */}
<HStack
spacing={0}
bg="rgba(0, 0, 0, 0.4)"
backdropFilter="blur(10px)"
borderRadius="full"
border="1px solid rgba(255, 255, 255, 0.1)"
overflow="hidden"
boxShadow="0 4px 15px rgba(0, 0, 0, 0.2)"
>
{/* 分享按钮 */}
<ShareButton <ShareButton
title={event.title} title={event.title}
desc={event.description?.slice(0, 100) || ''} desc={event.description?.slice(0, 100) || ''}
link={`${window.location.origin}/community?event=${event.id}`} link={`${window.location.origin}/event-detail?id=${encodeEventId(event.id)}`}
imgUrl={`${window.location.origin}/logo192.png`} imgUrl={`${window.location.origin}/logo192.png`}
variant="icon" >
size="sm" <Tooltip label="分享事件" hasArrow placement="bottom">
colorScheme="teal" <HStack
/> spacing={1.5}
px={3}
py={1.5}
cursor="pointer"
_hover={{ bg: 'rgba(255, 255, 255, 0.1)' }}
transition="all 0.2s"
>
<Icon as={Share2} boxSize={4} color="teal.400" />
<Text fontSize="sm" fontWeight="medium" color="gray.300" display={{ base: 'none', md: 'block' }}>
分享
</Text>
</HStack>
</Tooltip>
</ShareButton>
{/* 分隔线 */}
<Box h="20px" w="1px" bg="rgba(255, 255, 255, 0.15)" />
{/* 查看详情按钮 */} {/* 查看详情按钮 */}
<Tooltip label="在新页面查看完整详情" hasArrow> <Tooltip label="在新页面查看完整详情" hasArrow placement="bottom">
<IconButton <HStack
icon={<Icon as={ExternalLink} boxSize={4} />} as="button"
aria-label="查看事件详情" spacing={1.5}
size="sm" px={3}
variant="ghost" py={1.5}
color="blue.300" cursor="pointer"
onClick={handleViewDetail} onClick={handleViewDetail}
_hover={{ _hover={{ bg: 'rgba(255, 255, 255, 0.1)' }}
bg: 'blue.500', transition="all 0.2s"
color: 'white', >
}} <Icon as={ExternalLink} boxSize={4} color="blue.400" />
/> <Text fontSize="sm" fontWeight="medium" color="gray.300" display={{ base: 'none', md: 'block' }}>
详情
</Text>
</HStack>
</Tooltip> </Tooltip>
</HStack> </HStack>
</HStack>
); );
}; };

View File

@@ -1,6 +1,6 @@
// src/views/Community/components/EventCard/atoms/EventFollowButton.js // src/views/Community/components/EventCard/atoms/EventFollowButton.js
import React from 'react'; import React from 'react';
import { IconButton, Box } from '@chakra-ui/react'; import { IconButton, Box, HStack, Text, Tooltip } from '@chakra-ui/react';
import { Star } from 'lucide-react'; import { Star } from 'lucide-react';
/** /**
@@ -11,13 +11,15 @@ import { Star } from 'lucide-react';
* @param {Function} props.onToggle - 切换关注状态的回调函数 * @param {Function} props.onToggle - 切换关注状态的回调函数
* @param {string} props.size - 按钮尺寸('xs' | 'sm' | 'md',默认 'sm' * @param {string} props.size - 按钮尺寸('xs' | 'sm' | 'md',默认 'sm'
* @param {boolean} props.showCount - 是否显示关注数(默认 true * @param {boolean} props.showCount - 是否显示关注数(默认 true
* @param {string} props.variant - 样式变体('default' | 'minimal',默认 'default'
*/ */
const EventFollowButton = ({ const EventFollowButton = ({
isFollowing, isFollowing,
followerCount = 0, followerCount = 0,
onToggle, onToggle,
size = 'sm', size = 'sm',
showCount = true showCount = true,
variant = 'default'
}) => { }) => {
const iconSize = size === 'xs' ? '16px' : size === 'sm' ? '18px' : '22px'; const iconSize = size === 'xs' ? '16px' : size === 'sm' ? '18px' : '22px';
@@ -26,6 +28,41 @@ const EventFollowButton = ({
onToggle?.(); onToggle?.();
}; };
// 最小样式 - 用于毛玻璃容器内
if (variant === 'minimal') {
return (
<Tooltip label={isFollowing ? '取消关注' : '关注事件'} hasArrow placement="bottom">
<HStack
as="button"
spacing={1.5}
px={3}
py={1.5}
cursor="pointer"
onClick={handleClick}
_hover={{ bg: 'rgba(255, 255, 255, 0.1)' }}
transition="all 0.2s"
>
<Star
size={iconSize}
color={isFollowing ? "#FFD700" : "#A0AEC0"}
fill={isFollowing ? "#FFD700" : "none"}
style={{ transition: 'all 0.2s' }}
/>
{showCount && (
<Text
fontSize="sm"
fontWeight="semibold"
color={isFollowing ? "yellow.400" : "white"}
>
{followerCount || 0}
</Text>
)}
</HStack>
</Tooltip>
);
}
// 默认样式
return ( return (
<Box display="inline-flex" alignItems="center" gap={1}> <Box display="inline-flex" alignItems="center" gap={1}>
<IconButton <IconButton
@@ -48,9 +85,6 @@ const EventFollowButton = ({
onClick={handleClick} onClick={handleClick}
aria-label={isFollowing ? '取消关注' : '关注'} aria-label={isFollowing ? '取消关注' : '关注'}
/> />
{/* <Box fontSize="xs" color="gray.500">
{followerCount || 0}
</Box> */}
</Box> </Box>
); );
}; };