import { useEffect, useRef, useState } from 'react'; import { TrendingUp, TrendingDown, Activity, DollarSign, BarChart3, Zap } from 'lucide-react'; import type { MarketOverview } from '@/types'; interface MarketOverviewProps { data: MarketOverview; } function AnimatedNumber({ value, decimals = 1, suffix = '' }: { value: number; decimals?: number; suffix?: string }) { const [displayValue, setDisplayValue] = useState(0); const startTime = useRef(null); const duration = 1000; useEffect(() => { const animate = (timestamp: number) => { if (!startTime.current) startTime.current = timestamp; const progress = Math.min((timestamp - startTime.current) / duration, 1); const easeOut = 1 - Math.pow(1 - progress, 3); setDisplayValue(value * easeOut); if (progress < 1) { requestAnimationFrame(animate); } }; requestAnimationFrame(animate); return () => { startTime.current = null; }; }, [value]); return ( {displayValue.toFixed(decimals)}{suffix} ); } function MiniChart({ isUp }: { isUp: boolean }) { const points = isUp ? '0,30 10,25 20,28 30,20 40,22 50,15 60,18 70,10 80,12 90,5 100,8' : '0,10 10,15 20,12 30,20 40,18 50,25 60,22 70,30 80,28 90,35 100,32'; return ( ); } export function MarketOverviewPanel({ data }: MarketOverviewProps) { const cards = [ { title: '市场热度指数', value: data.heatIndex, change: data.heatChange, suffix: '', decimals: 1, icon: Activity, isUp: data.heatChange > 0, description: data.heatChange > 0 ? '多头情绪高涨' : '市场情绪偏冷', }, { title: '涨跌分布', value: data.upCount, change: data.downCount, suffix: '', decimals: 0, icon: BarChart3, isUp: true, description: `涨: ${data.upCount} | 跌: ${data.downCount}`, isDistribution: true, }, { title: '资金流向', value: data.capitalFlow, change: 0, suffix: '亿', decimals: 1, icon: DollarSign, isUp: data.capitalFlow > 0, description: data.capitalFlow > 0 ? '资金净流入' : '资金净流出', }, { title: '波动率指数', value: data.volatilityIndex, change: data.volatilityChange, suffix: '', decimals: 1, icon: Zap, isUp: data.volatilityChange > 0, description: data.volatilityChange > 0 ? '波动扩大' : '波动收窄', }, ]; return (
{cards.map((card, index) => (
{card.title}
{!card.isDistribution && card.change !== 0 && (
0 ? 'text-semantic-green' : 'text-semantic-red'}`}> {card.change > 0 ? : } {card.change > 0 ? '+' : ''}{card.change}%
)}
{card.isDistribution ? ( {data.upCount} / {data.downCount} ) : ( <> )}
{card.description}
))}
); }