MosswartOverlord/frontend/src/components/GlobalStats.tsx
Erik e58c05c895 feat: v2 dashboard — React + Vite parallel implementation
New modern dashboard at /v2 running alongside the existing UI at /.
Same backend, same APIs, same WebSocket — zero backend changes.

Stack: React 19 + Vite + TypeScript + Recharts
Source: frontend/ — build output: static/v2/

Phase 1 delivers:
- Character overview cards in a responsive CSS Grid
  - Live HP/Stamina/Mana bars via WebSocket vitals
  - Kills/hr, total kills, deaths, session uptime
  - VTank state badge (Combat/Nav/Idle)
  - Location coordinates
  - Click to expand: combat stats, prismatic count, CPU/RAM
- Global stats header: active chars, total kills, total rares, server health
- WebSocket hook with auto-reconnect
- HTTP poll fallback for initial load + server health
- Mobile responsive (single column on narrow screens)
- Dark theme matching the MosswartOverlord palette

Build: cd frontend && npm run build
Access: /v2 (served by existing NoCacheStaticFiles mount)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:07:11 +02:00

36 lines
1.3 KiB
TypeScript

import React from 'react';
import type { ServerHealth } from '../types';
interface Props {
activeChars: number;
totalKills: number;
totalRares: number;
serverHealth: ServerHealth | null;
}
export const GlobalStats: React.FC<Props> = ({ activeChars, totalKills, totalRares, serverHealth }) => {
const serverStatus = serverHealth?.status?.toLowerCase() ?? 'unknown';
const isOnline = serverStatus === 'online' || serverStatus === 'up';
return (
<div className="global-stats">
<div className="global-stat">
<span className="global-value">{activeChars}</span>
<span className="global-label">Active Characters</span>
</div>
<div className="global-stat">
<span className="global-value">{totalKills.toLocaleString()}</span>
<span className="global-label">Total Kills</span>
</div>
<div className="global-stat">
<span className="global-value">{totalRares}</span>
<span className="global-label">Total Rares</span>
</div>
<div className="global-stat">
<span className={`server-dot ${isOnline ? 'online' : 'offline'}`} />
<span className="global-value">{serverHealth?.latency_ms ?? '--'}ms</span>
<span className="global-label">Coldeve</span>
</div>
</div>
);
};