feat(ForumCenter): 新增价值论坛/互动中心组件
- 我的预测卡片(看涨/看跌投票) - 社区动态卡片(我发布的/我参与的) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
// 社区动态卡片
|
||||
import React, { useState } from 'react';
|
||||
import { Box, Text, VStack, HStack, Icon, Button } from '@chakra-ui/react';
|
||||
import { Newspaper, Flame, MessageCircle } from 'lucide-react';
|
||||
|
||||
const CommunityFeedCard = ({
|
||||
myPosts = [
|
||||
{ id: 1, title: '关于新能源车下半场的思考', date: '2025/12/18', replies: 32, isHot: true },
|
||||
{ id: 2, title: '半导体行业深度分析', date: '2025/12/15', replies: 18, isHot: false },
|
||||
],
|
||||
participatedPosts = [
|
||||
{ id: 3, title: 'AI产业链投资机会分析', date: '2025/12/17', replies: 45, isHot: true },
|
||||
{ id: 4, title: '消费板块复苏节奏讨论', date: '2025/12/14', replies: 12, isHot: false },
|
||||
],
|
||||
onPostClick,
|
||||
}) => {
|
||||
const [activeTab, setActiveTab] = useState('my'); // 'my' | 'participated'
|
||||
|
||||
const currentPosts = activeTab === 'my' ? myPosts : participatedPosts;
|
||||
|
||||
return (
|
||||
<Box
|
||||
bg="rgba(26, 26, 46, 0.7)"
|
||||
borderRadius="lg"
|
||||
overflow="hidden"
|
||||
border="1px solid"
|
||||
borderColor="rgba(212, 175, 55, 0.15)"
|
||||
backdropFilter="blur(8px)"
|
||||
>
|
||||
{/* 标题栏 */}
|
||||
<HStack
|
||||
px={4}
|
||||
py={2}
|
||||
bg="rgba(15, 15, 26, 0.8)"
|
||||
borderBottom="1px solid"
|
||||
borderColor="rgba(212, 175, 55, 0.1)"
|
||||
>
|
||||
<Icon as={Newspaper} boxSize={4} color="#3B82F6" />
|
||||
<Text fontSize="sm" fontWeight="bold" color="rgba(255, 255, 255, 0.95)">
|
||||
社区动态
|
||||
</Text>
|
||||
</HStack>
|
||||
|
||||
{/* 内容区 */}
|
||||
<Box p={4}>
|
||||
<VStack spacing={3} align="stretch">
|
||||
{/* Tab 切换 */}
|
||||
<HStack spacing={4}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
color={activeTab === 'my' ? 'rgba(212, 175, 55, 0.9)' : 'rgba(255, 255, 255, 0.5)'}
|
||||
fontWeight={activeTab === 'my' ? 'bold' : 'normal'}
|
||||
_hover={{ color: 'rgba(212, 175, 55, 0.9)' }}
|
||||
onClick={() => setActiveTab('my')}
|
||||
px={2}
|
||||
>
|
||||
[我发布的]
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
color={activeTab === 'participated' ? 'rgba(212, 175, 55, 0.9)' : 'rgba(255, 255, 255, 0.5)'}
|
||||
fontWeight={activeTab === 'participated' ? 'bold' : 'normal'}
|
||||
_hover={{ color: 'rgba(212, 175, 55, 0.9)' }}
|
||||
onClick={() => setActiveTab('participated')}
|
||||
px={2}
|
||||
>
|
||||
[我参与的]
|
||||
</Button>
|
||||
</HStack>
|
||||
|
||||
{/* 帖子列表 */}
|
||||
<VStack spacing={3} align="stretch">
|
||||
{currentPosts.map((post) => (
|
||||
<Box
|
||||
key={post.id}
|
||||
p={3}
|
||||
bg="rgba(37, 37, 64, 0.5)"
|
||||
borderRadius="md"
|
||||
cursor="pointer"
|
||||
transition="all 0.2s"
|
||||
_hover={{
|
||||
bg: 'rgba(37, 37, 64, 0.8)',
|
||||
transform: 'translateX(4px)',
|
||||
}}
|
||||
onClick={() => onPostClick?.(post)}
|
||||
>
|
||||
<Text
|
||||
fontSize="sm"
|
||||
fontWeight="medium"
|
||||
color="rgba(255, 255, 255, 0.9)"
|
||||
noOfLines={1}
|
||||
mb={1}
|
||||
>
|
||||
{post.title}
|
||||
</Text>
|
||||
<HStack spacing={3} fontSize="xs" color="rgba(255, 255, 255, 0.5)">
|
||||
<Text>{post.date}</Text>
|
||||
<Text>·</Text>
|
||||
<HStack spacing={1}>
|
||||
{post.isHot ? (
|
||||
<Icon as={Flame} boxSize={3} color="#F97316" />
|
||||
) : (
|
||||
<Icon as={MessageCircle} boxSize={3} />
|
||||
)}
|
||||
<Text color={post.isHot ? '#F97316' : 'inherit'}>
|
||||
{post.replies}回复
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
))}
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommunityFeedCard;
|
||||
@@ -0,0 +1,169 @@
|
||||
// 我的预测卡片
|
||||
import React from 'react';
|
||||
import { Box, Text, VStack, HStack, Button, Icon } from '@chakra-ui/react';
|
||||
import { Zap, History, TrendingUp, TrendingDown } from 'lucide-react';
|
||||
|
||||
const PredictionCard = ({
|
||||
question = '大A 2025年收盘价?',
|
||||
myBet = { type: '看涨', points: 500 },
|
||||
winRate = 58,
|
||||
odds = 1.8,
|
||||
onBullish,
|
||||
onBearish,
|
||||
onViewHistory,
|
||||
}) => {
|
||||
return (
|
||||
<Box
|
||||
bg="rgba(26, 26, 46, 0.7)"
|
||||
borderRadius="lg"
|
||||
overflow="hidden"
|
||||
border="1px solid"
|
||||
borderColor="rgba(212, 175, 55, 0.15)"
|
||||
backdropFilter="blur(8px)"
|
||||
>
|
||||
{/* 标题栏 */}
|
||||
<HStack
|
||||
px={4}
|
||||
py={2}
|
||||
bg="rgba(15, 15, 26, 0.8)"
|
||||
borderBottom="1px solid"
|
||||
borderColor="rgba(212, 175, 55, 0.1)"
|
||||
>
|
||||
<Icon as={Zap} boxSize={4} color="#FBBF24" />
|
||||
<Text fontSize="sm" fontWeight="bold" color="rgba(255, 255, 255, 0.95)">
|
||||
我的预测
|
||||
</Text>
|
||||
</HStack>
|
||||
|
||||
{/* 内容区 */}
|
||||
<Box p={4}>
|
||||
<VStack spacing={4} align="stretch">
|
||||
{/* 预测问题 - 带渐变背景 */}
|
||||
<Box
|
||||
bg="linear-gradient(135deg, rgba(30, 30, 50, 0.9) 0%, rgba(20, 20, 35, 0.95) 100%)"
|
||||
borderRadius="lg"
|
||||
p={4}
|
||||
textAlign="center"
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
>
|
||||
{/* 装饰性弧线 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
transform="translate(-50%, -50%)"
|
||||
w="120px"
|
||||
h="60px"
|
||||
borderRadius="50%"
|
||||
border="2px solid"
|
||||
borderColor="rgba(212, 175, 55, 0.2)"
|
||||
borderBottomColor="transparent"
|
||||
borderLeftColor="transparent"
|
||||
/>
|
||||
|
||||
<Text
|
||||
fontSize="lg"
|
||||
fontWeight="bold"
|
||||
color="rgba(255, 255, 255, 0.95)"
|
||||
position="relative"
|
||||
zIndex={1}
|
||||
>
|
||||
{question}
|
||||
</Text>
|
||||
|
||||
{/* 看涨/看跌按钮 */}
|
||||
<HStack spacing={3} mt={4} justify="center">
|
||||
<Button
|
||||
flex={1}
|
||||
maxW="140px"
|
||||
h="40px"
|
||||
bg="linear-gradient(135deg, #DC2626 0%, #EF4444 100%)"
|
||||
color="white"
|
||||
fontWeight="bold"
|
||||
fontSize="md"
|
||||
borderRadius="full"
|
||||
_hover={{
|
||||
bg: 'linear-gradient(135deg, #B91C1C 0%, #DC2626 100%)',
|
||||
transform: 'scale(1.02)',
|
||||
}}
|
||||
_active={{ transform: 'scale(0.98)' }}
|
||||
leftIcon={<Icon as={TrendingUp} boxSize={4} />}
|
||||
onClick={onBullish}
|
||||
>
|
||||
看涨
|
||||
</Button>
|
||||
<Button
|
||||
flex={1}
|
||||
maxW="140px"
|
||||
h="40px"
|
||||
bg="linear-gradient(135deg, #16A34A 0%, #22C55E 100%)"
|
||||
color="white"
|
||||
fontWeight="bold"
|
||||
fontSize="md"
|
||||
borderRadius="full"
|
||||
_hover={{
|
||||
bg: 'linear-gradient(135deg, #15803D 0%, #16A34A 100%)',
|
||||
transform: 'scale(1.02)',
|
||||
}}
|
||||
_active={{ transform: 'scale(0.98)' }}
|
||||
leftIcon={<Icon as={TrendingDown} boxSize={4} />}
|
||||
onClick={onBearish}
|
||||
>
|
||||
看跌
|
||||
</Button>
|
||||
</HStack>
|
||||
</Box>
|
||||
|
||||
{/* 底部信息 */}
|
||||
<HStack justify="space-between" fontSize="xs" px={1}>
|
||||
<HStack spacing={4}>
|
||||
<HStack spacing={1}>
|
||||
<Text color="rgba(255, 255, 255, 0.5)">我的下注:</Text>
|
||||
<Text color="#EF4444" fontWeight="medium">
|
||||
{myBet.type}
|
||||
</Text>
|
||||
<Text color="rgba(212, 175, 55, 0.9)" fontWeight="medium">
|
||||
{myBet.points}积分
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</HStack>
|
||||
|
||||
<HStack justify="space-between" fontSize="xs" px={1}>
|
||||
<HStack spacing={4}>
|
||||
<HStack spacing={1}>
|
||||
<Text color="rgba(255, 255, 255, 0.5)">当前胜率:</Text>
|
||||
<Text color="rgba(255, 255, 255, 0.9)" fontWeight="medium">
|
||||
{winRate}%
|
||||
</Text>
|
||||
</HStack>
|
||||
<HStack spacing={1}>
|
||||
<Text color="rgba(255, 255, 255, 0.5)">赔率:</Text>
|
||||
<Text color="rgba(255, 255, 255, 0.9)" fontWeight="medium">
|
||||
{odds}
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
|
||||
<Button
|
||||
size="xs"
|
||||
variant="ghost"
|
||||
color="rgba(255, 255, 255, 0.6)"
|
||||
leftIcon={<Icon as={History} boxSize={3} />}
|
||||
_hover={{
|
||||
color: 'rgba(212, 175, 55, 0.9)',
|
||||
bg: 'rgba(212, 175, 55, 0.1)',
|
||||
}}
|
||||
onClick={onViewHistory}
|
||||
>
|
||||
历史战绩
|
||||
</Button>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default PredictionCard;
|
||||
@@ -0,0 +1,3 @@
|
||||
// 价值论坛子组件导出
|
||||
export { default as PredictionCard } from './PredictionCard';
|
||||
export { default as CommunityFeedCard } from './CommunityFeedCard';
|
||||
49
src/views/Profile/components/ForumCenter/index.js
Normal file
49
src/views/Profile/components/ForumCenter/index.js
Normal file
@@ -0,0 +1,49 @@
|
||||
// 价值论坛 / 互动中心组件 (Forum Center)
|
||||
import React from 'react';
|
||||
import { Box, Text, HStack, SimpleGrid, Icon } from '@chakra-ui/react';
|
||||
import { MessageCircle } from 'lucide-react';
|
||||
import GlassCard from '@components/GlassCard';
|
||||
import { PredictionCard, CommunityFeedCard } from './components';
|
||||
|
||||
const ForumCenter = () => {
|
||||
return (
|
||||
<GlassCard
|
||||
variant="transparent"
|
||||
rounded="2xl"
|
||||
padding="md"
|
||||
hoverable={false}
|
||||
cornerDecor
|
||||
>
|
||||
{/* 标题栏 */}
|
||||
<HStack mb={4} spacing={2}>
|
||||
<Icon
|
||||
as={MessageCircle}
|
||||
boxSize={5}
|
||||
color="rgba(212, 175, 55, 0.9)"
|
||||
/>
|
||||
<Text
|
||||
fontSize="lg"
|
||||
fontWeight="bold"
|
||||
color="rgba(255, 255, 255, 0.95)"
|
||||
letterSpacing="wide"
|
||||
>
|
||||
价值论坛 / 互动中心
|
||||
</Text>
|
||||
<Box
|
||||
h="1px"
|
||||
flex={1}
|
||||
bgGradient="linear(to-r, rgba(212, 175, 55, 0.4), transparent)"
|
||||
ml={2}
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
{/* 两列布局:预测卡片 + 社区动态 */}
|
||||
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}>
|
||||
<PredictionCard />
|
||||
<CommunityFeedCard />
|
||||
</SimpleGrid>
|
||||
</GlassCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForumCenter;
|
||||
Reference in New Issue
Block a user