204 lines
5.4 KiB
JavaScript
204 lines
5.4 KiB
JavaScript
/**
|
||
* 帖子卡片组件 - 类似小红书风格
|
||
* 用于论坛主页的帖子展示
|
||
*/
|
||
|
||
import React from 'react';
|
||
import {
|
||
Box,
|
||
Image,
|
||
Text,
|
||
HStack,
|
||
VStack,
|
||
Avatar,
|
||
Badge,
|
||
IconButton,
|
||
Flex,
|
||
useColorModeValue,
|
||
} from '@chakra-ui/react';
|
||
import { motion } from 'framer-motion';
|
||
import { Heart, MessageCircle, Eye, TrendingUp } from 'lucide-react';
|
||
import { useNavigate } from 'react-router-dom';
|
||
import { forumColors } from '@theme/forumTheme';
|
||
|
||
const MotionBox = motion(Box);
|
||
|
||
const PostCard = ({ post }) => {
|
||
const navigate = useNavigate();
|
||
|
||
// 处理卡片点击
|
||
const handleCardClick = () => {
|
||
navigate(`/value-forum/post/${post.id}`);
|
||
};
|
||
|
||
// 格式化数字(1000 -> 1k)
|
||
const formatNumber = (num) => {
|
||
if (num >= 1000000) return `${(num / 1000000).toFixed(1)}M`;
|
||
if (num >= 1000) return `${(num / 1000).toFixed(1)}K`;
|
||
return num;
|
||
};
|
||
|
||
// 格式化时间
|
||
const formatTime = (dateString) => {
|
||
const date = new Date(dateString);
|
||
const now = new Date();
|
||
const diff = now - date;
|
||
|
||
const minutes = Math.floor(diff / 60000);
|
||
const hours = Math.floor(diff / 3600000);
|
||
const days = Math.floor(diff / 86400000);
|
||
|
||
if (minutes < 1) return '刚刚';
|
||
if (minutes < 60) return `${minutes}分钟前`;
|
||
if (hours < 24) return `${hours}小时前`;
|
||
if (days < 7) return `${days}天前`;
|
||
|
||
return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' });
|
||
};
|
||
|
||
return (
|
||
<MotionBox
|
||
bg={forumColors.background.card}
|
||
borderRadius="xl"
|
||
overflow="hidden"
|
||
border="1px solid"
|
||
borderColor={forumColors.border.default}
|
||
cursor="pointer"
|
||
onClick={handleCardClick}
|
||
whileHover={{ y: -8, scale: 1.02 }}
|
||
transition={{ duration: 0.3 }}
|
||
_hover={{
|
||
borderColor: forumColors.border.gold,
|
||
boxShadow: forumColors.shadows.gold,
|
||
}}
|
||
>
|
||
{/* 封面图片区域 */}
|
||
{post.images && post.images.length > 0 && (
|
||
<Box position="relative" overflow="hidden" h="200px">
|
||
<Image
|
||
src={post.images[0]}
|
||
alt={post.title}
|
||
w="100%"
|
||
h="100%"
|
||
objectFit="cover"
|
||
transition="transform 0.3s"
|
||
_groupHover={{ transform: 'scale(1.1)' }}
|
||
/>
|
||
|
||
{/* 置顶标签 */}
|
||
{post.is_pinned && (
|
||
<Badge
|
||
position="absolute"
|
||
top="12px"
|
||
right="12px"
|
||
bg={forumColors.gradients.goldPrimary}
|
||
color={forumColors.background.main}
|
||
px="3"
|
||
py="1"
|
||
borderRadius="full"
|
||
fontWeight="bold"
|
||
fontSize="xs"
|
||
display="flex"
|
||
alignItems="center"
|
||
gap="1"
|
||
>
|
||
<TrendingUp size={12} />
|
||
置顶
|
||
</Badge>
|
||
)}
|
||
</Box>
|
||
)}
|
||
|
||
{/* 内容区域 */}
|
||
<VStack align="stretch" p="4" spacing="3">
|
||
{/* 标题 */}
|
||
<Text
|
||
fontSize="md"
|
||
fontWeight="600"
|
||
color={forumColors.text.primary}
|
||
noOfLines={2}
|
||
lineHeight="1.4"
|
||
>
|
||
{post.title}
|
||
</Text>
|
||
|
||
{/* 内容预览 */}
|
||
{post.content && (
|
||
<Text
|
||
fontSize="sm"
|
||
color={forumColors.text.secondary}
|
||
noOfLines={2}
|
||
lineHeight="1.6"
|
||
>
|
||
{post.content}
|
||
</Text>
|
||
)}
|
||
|
||
{/* 标签 */}
|
||
{post.tags && post.tags.length > 0 && (
|
||
<HStack spacing="2" flexWrap="wrap">
|
||
{post.tags.slice(0, 3).map((tag, index) => (
|
||
<Badge
|
||
key={index}
|
||
bg={forumColors.gradients.goldSubtle}
|
||
color={forumColors.primary[500]}
|
||
border="1px solid"
|
||
borderColor={forumColors.border.gold}
|
||
borderRadius="full"
|
||
px="3"
|
||
py="1"
|
||
fontSize="xs"
|
||
fontWeight="500"
|
||
>
|
||
#{tag}
|
||
</Badge>
|
||
))}
|
||
</HStack>
|
||
)}
|
||
|
||
{/* 底部信息栏 */}
|
||
<Flex justify="space-between" align="center" pt="2">
|
||
{/* 作者信息 */}
|
||
<HStack spacing="2">
|
||
<Avatar
|
||
size="xs"
|
||
name={post.author_name}
|
||
src={post.author_avatar}
|
||
bg={forumColors.gradients.goldPrimary}
|
||
color={forumColors.background.main}
|
||
/>
|
||
<Text fontSize="xs" color={forumColors.text.tertiary}>
|
||
{post.author_name}
|
||
</Text>
|
||
</HStack>
|
||
|
||
{/* 互动数据 */}
|
||
<HStack spacing="4" fontSize="xs" color={forumColors.text.tertiary}>
|
||
<HStack spacing="1">
|
||
<Heart size={14} />
|
||
<Text>{formatNumber(post.likes_count || 0)}</Text>
|
||
</HStack>
|
||
|
||
<HStack spacing="1">
|
||
<MessageCircle size={14} />
|
||
<Text>{formatNumber(post.comments_count || 0)}</Text>
|
||
</HStack>
|
||
|
||
<HStack spacing="1">
|
||
<Eye size={14} />
|
||
<Text>{formatNumber(post.views_count || 0)}</Text>
|
||
</HStack>
|
||
</HStack>
|
||
</Flex>
|
||
|
||
{/* 时间 */}
|
||
<Text fontSize="xs" color={forumColors.text.muted} textAlign="right">
|
||
{formatTime(post.created_at)}
|
||
</Text>
|
||
</VStack>
|
||
</MotionBox>
|
||
);
|
||
};
|
||
|
||
export default PostCard;
|