/** * 预测市场频道组件 - HeroUI 深色风格 * Polymarket 风格的预测市场 */ import React, { useState, useEffect, useCallback } from 'react'; import { Box, Flex, Text, Button, Icon, IconButton, HStack, VStack, Select, Spinner, useDisclosure, Badge, Tooltip, SimpleGrid, } from '@chakra-ui/react'; import { motion, AnimatePresence } from 'framer-motion'; import { Plus, TrendingUp, Filter, Zap, Trophy, HelpCircle, Coins, RefreshCw, } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { Channel } from '../../../types'; import { GLASS_BLUR } from '@/constants/glassConfig'; import { useAuth } from '@/contexts/AuthContext'; import { getTopics, getUserAccount } from '@services/predictionMarketService.api'; // 导入原有组件 import CreatePredictionModal from '@views/ValueForum/components/CreatePredictionModal'; import PredictionGuideModal from '@views/ValueForum/components/PredictionGuideModal'; import PredictionTopicCardDark from './PredictionTopicCardDark'; interface PredictionChannelProps { channel: Channel; } type SortOption = 'latest' | 'hot' | 'ending_soon' | 'highest_pool'; type FilterOption = 'all' | 'active' | 'settled'; const PredictionChannel: React.FC = ({ channel }) => { const navigate = useNavigate(); const { user, isAuthenticated } = useAuth(); const [topics, setTopics] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [sortBy, setSortBy] = useState('latest'); const [filterBy, setFilterBy] = useState('active'); const [userAccount, setUserAccount] = useState(null); const { isOpen: isCreateOpen, onOpen: onCreateOpen, onClose: onCreateClose, } = useDisclosure(); const { isOpen: isGuideOpen, onOpen: onGuideOpen, onClose: onGuideClose, } = useDisclosure(); // 加载话题列表 const loadTopics = useCallback(async (showRefreshing = false) => { try { if (showRefreshing) { setRefreshing(true); } else { setLoading(true); } const response = await getTopics({ status: filterBy === 'all' ? undefined : filterBy, sort: sortBy, page: 1, pageSize: 20, }); if (response.success) { setTopics(response.data.items || []); } } catch (error) { console.error('加载预测话题失败:', error); } finally { setLoading(false); setRefreshing(false); } }, [sortBy, filterBy]); // 加载用户账户 const loadUserAccount = useCallback(async () => { if (!isAuthenticated) return; try { const response = await getUserAccount(); if (response.success) { setUserAccount(response.data); } } catch (error) { console.error('加载用户账户失败:', error); } }, [isAuthenticated]); useEffect(() => { loadTopics(); }, [loadTopics]); useEffect(() => { loadUserAccount(); }, [loadUserAccount]); // 创建成功回调 const handleTopicCreated = (newTopic: any) => { setTopics(prev => [newTopic, ...prev]); onCreateClose(); loadUserAccount(); // 刷新余额 }; // 点击话题卡片 const handleTopicClick = (topicId: string) => { navigate(`/value-forum/prediction/${topicId}`); }; return ( {/* 频道头部 */} {channel.name} 预测市场 类似 Polymarket 的预测交易市场 {/* 用户积分 */} {isAuthenticated && userAccount && ( {userAccount.balance?.toLocaleString()} )} {/* 玩法说明 */} } variant="ghost" size="sm" color="gray.400" _hover={{ bg: 'whiteAlpha.100', color: 'white' }} onClick={onGuideOpen} /> {/* 排行榜入口 */} } variant="ghost" size="sm" color="gray.400" _hover={{ bg: 'whiteAlpha.100', color: 'yellow.400' }} onClick={() => navigate('/value-forum/my-points')} /> {/* 工具栏 */} {/* 刷新按钮 */} } variant="ghost" size="sm" color="gray.400" _hover={{ bg: 'whiteAlpha.100', color: 'white' }} onClick={() => loadTopics(true)} isDisabled={refreshing} /> {/* 状态筛选 */} {/* 排序 */} {/* 话题列表 */} {loading ? ( 加载预测话题中... ) : topics.length === 0 ? ( 暂无预测话题 成为第一个发起预测的人! ) : ( {topics.map((topic, index) => ( handleTopicClick(topic.id)} /> ))} )} {/* 创建话题弹窗 */} {/* 玩法说明弹窗 */} ); }; export default PredictionChannel;