MosswartOverlord/frontend/src/components/windows/StatsWindow.tsx
Erik b77450b6eb fix(v2): comprehensive bug fix round — all reported issues
1. Server stats: now shows player count, latency (rounded), uptime hours
2. Rares/Kills counters: fixed API response fields (all_time/total)
3. Chat send: wired socket.send with v1 envelope { player_name, command }
4. Stats button: opens Grafana iframe grid (4 panels, time range selector)
5. Char button: opens character window with attributes/skills/vitals from
   /character-stats/{name} API, structured display with sections
6. Inventory button: full inventory window with equipment table (material,
   set, imbue, AL, dmg, work, tink) + pack contents pill grid + filter
7. Radar button: opens radar window, sends start/stop commands via socket
8. Sidebar links: added Inventory Search, Suitbuilder, Player Debug
9. Color palette: expanded from 30 to 60 distinct colors matching v1
10. Window types properly routed: stats- prefix → Grafana, char- → character
    data, inv- → inventory, radar- → radar with socket commands

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

54 lines
1.6 KiB
TypeScript

import React, { useState } from 'react';
import { DraggableWindow } from './DraggableWindow';
interface Props { id: string; charName: string; zIndex: number; }
const PANELS = [
{ title: 'Kills per Hour', id: 1 },
{ title: 'Memory (MB)', id: 2 },
{ title: 'CPU (%)', id: 3 },
{ title: 'Mem Handles', id: 4 },
];
const TIME_RANGES = [
{ label: '1H', value: 'now-1h' },
{ label: '6H', value: 'now-6h' },
{ label: '24H', value: 'now-24h' },
{ label: '7D', value: 'now-7d' },
];
export const StatsWindow: React.FC<Props> = ({ id, charName, zIndex }) => {
const [timeRange, setTimeRange] = useState('now-24h');
const iframeUrl = (panelId: number) =>
`/grafana/d-solo/dereth-tracker/dereth-tracker-dashboard?panelId=${panelId}&var-character=${encodeURIComponent(charName)}&from=${timeRange}&to=now&theme=light`;
return (
<DraggableWindow id={id} title={`Stats: ${charName}`} zIndex={zIndex} width={750} height={480}>
<div className="ml-stats-controls">
{TIME_RANGES.map(r => (
<button
key={r.value}
className={`ml-stats-range-btn ${timeRange === r.value ? 'active' : ''}`}
onClick={() => setTimeRange(r.value)}
>
{r.label}
</button>
))}
</div>
<div className="ml-stats-grid">
{PANELS.map(p => (
<div key={p.id} className="ml-stats-panel">
<iframe
src={iframeUrl(p.id)}
width="100%"
height="100%"
frameBorder="0"
title={p.title}
/>
</div>
))}
</div>
</DraggableWindow>
);
};