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>
36 lines
1.3 KiB
TypeScript
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>
|
|
);
|
|
};
|