import { useEffect, useState } from 'react'; import { Server, Users, Gamepad2, Activity, Wifi, WifiOff } from 'lucide-react'; import { apiService, wsClient, type ServerStats } from '../api'; export default function Dashboard() { const [stats, setStats] = useState(null); const [health, setHealth] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { loadData(); const off = wsClient.on('status', (data: any) => { setStats(prev => prev ? { ...prev, node: { ...prev.node, rooms: data.rooms, players: data.players }, cluster: data.nodes || prev.cluster, } : prev); }); return () => off(); }, []); async function loadData() { try { setLoading(true); const [statsData, healthData] = await Promise.all([ apiService.getStats(), apiService.getHealth(), ]); setStats(statsData); setHealth(healthData); setError(''); } catch (err: any) { setError('无法连接到服务器: ' + (err.message || '未知错误')); } finally { setLoading(false); } } if (loading) { return (
); } if (error) { return (

连接失败

{error}

); } const statCards = [ { label: '在线房间', value: stats?.node.rooms || 0, max: stats?.node.maxRooms || 100, icon: Gamepad2, color: 'text-green-400', bg: 'bg-green-400/10', }, { label: '在线玩家', value: stats?.node.players || 0, icon: Users, color: 'text-blue-400', bg: 'bg-blue-400/10', }, { label: '集群节点', value: stats?.cluster?.onlineNodes || 1, max: stats?.cluster?.totalNodes || 1, icon: Server, color: 'text-purple-400', bg: 'bg-purple-400/10', }, { label: '服务状态', value: health?.status === 'ok' ? '正常' : '异常', icon: Activity, color: health?.status === 'ok' ? 'text-green-400' : 'text-red-400', bg: health?.status === 'ok' ? 'bg-green-400/10' : 'bg-red-400/10', }, ]; return (

仪表盘

FunMC 服务器运行状态总览

节点: {stats?.node.name || 'N/A'}
{/* Stats Cards */}
{statCards.map((card, i) => { const Icon = card.icon; return (

{card.label}

{card.value} {card.max !== undefined && ( /{card.max} )}

); })}
{/* Server Info */}

服务器信息

{stats?.cluster && (

集群状态

)}
{/* Quick Guide */}

快速入门

); } function InfoRow({ label, value }: { label: string; value: string }) { return (
{label} {value}
); } function StepCard({ step, title, desc }: { step: number; title: string; desc: string }) { return (
{step}

{title}

{desc}

); } function formatUptime(seconds: number): string { const h = Math.floor(seconds / 3600); const m = Math.floor((seconds % 3600) / 60); const s = Math.floor(seconds % 60); if (h > 0) return `${h}时${m}分${s}秒`; if (m > 0) return `${m}分${s}秒`; return `${s}秒`; }