import { useState, useEffect } from 'react'; import './StatsPanel.css'; const StatsPanel = ({ selectedTurtle, apiUrl }) => { const [miningStats, setMiningStats] = useState([]); const [topMiners, setTopMiners] = useState([]); const [timeFilter, setTimeFilter] = useState(7); // days const [loading, setLoading] = useState(false); useEffect(() => { loadMiningStats(); loadTopMiners(); // Refresh stats every 30 seconds const interval = setInterval(() => { loadMiningStats(); loadTopMiners(); }, 30000); return () => clearInterval(interval); }, [selectedTurtle, timeFilter]); const loadMiningStats = async () => { setLoading(true); try { const url = selectedTurtle ? `${apiUrl}/api/stats/mining/${selectedTurtle.turtleID}?days=${timeFilter}` : `${apiUrl}/api/stats/mining?days=${timeFilter}`; const response = await fetch(url); if (response.ok) { const data = await response.json(); // Response is either a single object (per turtle) or an array (all turtles) setMiningStats(Array.isArray(data) ? data : [data]); } } catch (error) { console.error('Failed to load mining stats:', error); } finally { setLoading(false); } }; const loadTopMiners = async () => { try { const response = await fetch(`${apiUrl}/api/stats/top-miners?limit=10`); if (response.ok) { const data = await response.json(); // Response is now a flat array of {turtleId, totalBlocks, uniqueTypes} setTopMiners(Array.isArray(data) ? data : (data.topMiners || [])); } } catch (error) { console.error('Failed to load top miners:', error); } }; const getTotalBlocks = (stats) => { if (!stats || !stats.blocks) return 0; return stats.blocks.reduce((sum, block) => sum + block.count, 0); }; const getBlockEmoji = (blockType) => { if (!blockType) return '📦'; const lower = blockType.toLowerCase(); if (lower.includes('diamond')) return '💎'; if (lower.includes('gold')) return '🟡'; if (lower.includes('iron')) return '⚪'; if (lower.includes('coal')) return '⚫'; if (lower.includes('emerald')) return '🟢'; if (lower.includes('redstone')) return '🔴'; if (lower.includes('lapis')) return '🔵'; if (lower.includes('copper')) return '🟠'; if (lower.includes('stone')) return '🗿'; if (lower.includes('dirt')) return '🟤'; if (lower.includes('cobble')) return '🪨'; if (lower.includes('wood') || lower.includes('log')) return '🪵'; return '📦'; }; const formatBlockType = (blockType) => { if (!blockType) return 'Unknown'; return blockType.replace('minecraft:', '').replace(/_/g, ' ') .split(' ') .map(word => word.charAt(0).toUpperCase() + word.slice(1)) .join(' '); }; return (

📊 Mining Statistics

{loading &&
Loading statistics...
} {/* Individual Turtle Stats */} {selectedTurtle && miningStats.length > 0 && (

🐢 {selectedTurtle.name || `Turtle ${selectedTurtle.turtleID}`}

{miningStats.map((stat) => (
{getTotalBlocks(stat)}
Total Blocks Mined
{stat.blocks && stat.blocks.length > 0 && (
{stat.blocks.map((block, idx) => (
{getBlockEmoji(block.blockType)}
{formatBlockType(block.blockType)}
{block.count} blocks
))}
)}
))}
)} {/* Top Miners Leaderboard */}

🏆 Top Miners

{topMiners.length === 0 && (
No mining data yet. Start mining!
)} {topMiners.map((miner, idx) => (
{idx === 0 && '🥇'} {idx === 1 && '🥈'} {idx === 2 && '🥉'} {idx > 2 && `#${idx + 1}`}
Turtle {miner.turtleId}
{miner.totalBlocks} blocks • {miner.uniqueTypes} types
{miner.totalBlocks}
))}
{/* All Turtles Summary */} {!selectedTurtle && miningStats.length > 0 && (

📈 All Turtles Overview

{miningStats.map((stat) => (
🐢 Turtle {stat.turtleId} {getTotalBlocks(stat)}
{stat.blocks && stat.blocks.length > 0 && (
{stat.blocks.slice(0, 3).map((block, idx) => (
{getBlockEmoji(block.blockType)} {block.count}
))}
)}
))}
)} {/* Empty State */} {!loading && miningStats.length === 0 && topMiners.length === 0 && (
⛏️
No Mining Data Yet
Start mining with your turtles to see statistics here!
)}
); }; export default StatsPanel;