import { useState, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; // Aircraft category colors (matches AircraftLayer military fixed colors) const AC_CAT_COLORS: Record = { fighter: '#ff4444', military: '#ff6600', surveillance: '#ffcc00', tanker: '#00ccff', cargo: '#a78bfa', civilian: '#FFD700', unknown: '#7CFC00', }; // Altitude color legend (matches AircraftLayer gradient) const ALT_LEGEND: [string, string][] = [ ['Ground', '#555555'], ['< 2,000ft', '#00c000'], ['2,000ft', '#55EC55'], ['4,000ft', '#7CFC00'], ['6,000ft', '#BFFF00'], ['10,000ft', '#FFFF00'], ['20,000ft', '#FFD700'], ['30,000ft', '#FF8C00'], ['40,000ft', '#FF4500'], ['50,000ft+', '#BA55D3'], ]; // Military color legend const MIL_LEGEND: [string, string][] = [ ['Fighter', '#ff4444'], ['Military', '#ff6600'], ['ISR / Surveillance', '#ffcc00'], ['Tanker', '#00ccff'], ]; // Ship MT category color (matches ShipLayer MT_TYPE_COLORS) const MT_CAT_COLORS: Record = { cargo: 'var(--kcg-ship-cargo)', tanker: 'var(--kcg-ship-tanker)', passenger: 'var(--kcg-ship-passenger)', fishing: 'var(--kcg-ship-fishing)', military: 'var(--kcg-ship-military)', tug_special: 'var(--kcg-ship-tug)', high_speed: 'var(--kcg-ship-highspeed)', pleasure: 'var(--kcg-ship-pleasure)', other: 'var(--kcg-ship-other)', unspecified: 'var(--kcg-ship-unknown)', unknown: 'var(--kcg-ship-unknown)', }; // Ship type color legend (MarineTraffic style) const SHIP_TYPE_LEGEND: [string, string][] = [ ['cargo', 'var(--kcg-ship-cargo)'], ['tanker', 'var(--kcg-ship-tanker)'], ['passenger', 'var(--kcg-ship-passenger)'], ['fishing', 'var(--kcg-ship-fishing)'], ['pleasure', 'var(--kcg-ship-pleasure)'], ['military', 'var(--kcg-ship-military)'], ['tug_special', 'var(--kcg-ship-tug)'], ['other', 'var(--kcg-ship-other)'], ['unspecified', 'var(--kcg-ship-unknown)'], ]; const AC_CATEGORIES = ['fighter', 'military', 'surveillance', 'tanker', 'cargo', 'civilian', 'unknown'] as const; const MT_CATEGORIES = ['cargo', 'tanker', 'passenger', 'fishing', 'military', 'tug_special', 'high_speed', 'pleasure', 'other', 'unspecified'] as const; interface ExtraLayer { key: string; label: string; color: string; count?: number; } interface LayerPanelProps { layers: Record; onToggle: (key: string) => void; aircraftByCategory: Record; aircraftTotal: number; shipsByMtCategory: Record; shipTotal: number; satelliteCount: number; extraLayers?: ExtraLayer[]; hiddenAcCategories: Set; hiddenShipCategories: Set; onAcCategoryToggle: (cat: string) => void; onShipCategoryToggle: (cat: string) => void; } export function LayerPanel({ layers, onToggle, aircraftByCategory, aircraftTotal, shipsByMtCategory, shipTotal, satelliteCount, extraLayers, hiddenAcCategories, hiddenShipCategories, onAcCategoryToggle, onShipCategoryToggle, }: LayerPanelProps) { const { t } = useTranslation(['common', 'ships']); const [expanded, setExpanded] = useState>(new Set(['aircraft', 'ships'])); const [legendOpen, setLegendOpen] = useState>(new Set()); const toggleExpand = useCallback((key: string) => { setExpanded(prev => { const next = new Set(prev); if (next.has(key)) { next.delete(key); } else { next.add(key); } return next; }); }, []); const toggleLegend = useCallback((key: string) => { setLegendOpen(prev => { const next = new Set(prev); if (next.has(key)) { next.delete(key); } else { next.add(key); } return next; }); }, []); const militaryCount = Object.entries(aircraftByCategory) .filter(([cat]) => cat !== 'civilian' && cat !== 'unknown') .reduce((sum, [, c]) => sum + c, 0); return (

LAYERS

{/* Aircraft tree */} onToggle('aircraft')} onExpand={() => toggleExpand('aircraft')} /> {layers.aircraft && expanded.has('aircraft') && (
{AC_CATEGORIES.map(cat => { const count = aircraftByCategory[cat] || 0; if (count === 0) return null; return (
)} {/* Ships tree */} onToggle('ships')} onExpand={() => toggleExpand('ships')} /> {layers.ships && expanded.has('ships') && (
{MT_CATEGORIES.map(cat => { const count = shipsByMtCategory[cat] || 0; if (count === 0) return null; return (
)} {/* Satellites (simple toggle) */} onToggle('satellites')} /> {/* Extra layers (tab-specific) */} {extraLayers && extraLayers.map(el => ( onToggle(el.key)} /> ))}
{/* Military only filter */} onToggle('militaryOnly')} />
); } /* ── Sub-components ─────────────────────────────────── */ function LayerTreeItem({ layerKey, label, color, active, expandable, isExpanded, onToggle, onExpand, }: { layerKey: string; label: string; color: string; active: boolean; expandable?: boolean; isExpanded?: boolean; onToggle: () => void; onExpand?: () => void; }) { return (
{expandable ? ( { e.stopPropagation(); onExpand?.(); }} > {'\u25B6'} ) : ( )}
); } function CategoryToggle({ label, color, count, hidden, onClick, }: { label: string; color: string; count: number; hidden: boolean; onClick: () => void; }) { return (
{label} {count}
); }