add forum
This commit is contained in:
203
src/views/ValueForum/components/PostCard.js
Normal file
203
src/views/ValueForum/components/PostCard.js
Normal file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* 帖子卡片组件 - 类似小红书风格
|
||||
* 用于论坛主页的帖子展示
|
||||
*/
|
||||
|
||||
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;
|
||||
Reference in New Issue
Block a user