Rebuilds the v1 map-centric experience in React: Layout: - 400px sidebar on left, interactive map on right (flex, 100vh) - Exact same proportions and dark theme as v1 Sidebar (top→bottom): - Header with active player count + Dashboard toggle button - Server status dot (Coldeve online/offline with pulse) - Aggregate counters: Rares (gold), Server KPH (blue glow), Kills (red) - 6 sort buttons (Name, KPH, S.Kills, S.Rares, T.Kills, KPR) - Player name filter - Scrollable player list with per-row: - Name + coordinates - HP/Stamina/Mana vital bars (red/orange/blue gradients) - Session kills, total kills, KPH - Session rares, total rares, VTank meta state pill - Online time, deaths, prismatic tapers - Color-coded left border per player Map: - dereth.png with CSS transform pan (drag) + zoom (wheel, 1.1x factor, max 20x) - Player dots (6px circles, color-matched to sidebar) - Hover tooltip (name, coords, kph, kills) - World coordinate display at cursor position - Fit-to-window on first load View toggle: Map View ↔ Dashboard with localStorage persistence. All v1 CSS ported under ml-* prefix, scoped via map-layout.css. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
24 lines
695 B
TypeScript
24 lines
695 B
TypeScript
import React from 'react';
|
|
import { PlayerRow } from './PlayerRow';
|
|
import type { TelemetrySnapshot, VitalsMessage } from '../../types';
|
|
|
|
interface Props {
|
|
players: TelemetrySnapshot[];
|
|
vitals: Map<string, VitalsMessage>;
|
|
getColor: (name: string) => string;
|
|
onSelect: (name: string) => void;
|
|
}
|
|
|
|
export const PlayerList: React.FC<Props> = ({ players, vitals, getColor, onSelect }) => (
|
|
<ul className="ml-player-list">
|
|
{players.map(p => (
|
|
<PlayerRow
|
|
key={p.character_name}
|
|
player={p}
|
|
vitals={vitals.get(p.character_name) ?? null}
|
|
color={getColor(p.character_name)}
|
|
onSelect={() => onSelect(p.character_name)}
|
|
/>
|
|
))}
|
|
</ul>
|
|
);
|