Spaces:
Running
Running
| import { useTwinStore } from '../../lib/twin/store' | |
| import type { LeftView } from '../../lib/twin/store' | |
| import { ZonePanel } from './ZonePanel' | |
| import { MapPanel } from './MapPanel' | |
| const VIEWS: Array<{ id: LeftView; label: string }> = [ | |
| { id: 'zones', label: 'Zones' }, | |
| { id: 'map', label: 'Map' }, | |
| ] | |
| /** | |
| * Column B of the left dashboard panel. A top segmented toggle switches between | |
| * the Zones view (Patrol/Check/Calm ranked list) and the Map view (basemap | |
| * styles + layer visibility toggles). | |
| */ | |
| export function LeftPanel() { | |
| const leftView = useTwinStore((s) => s.leftView) | |
| const setLeftView = useTwinStore((s) => s.setLeftView) | |
| return ( | |
| <div className="flex min-h-0 min-w-0 flex-1 flex-col"> | |
| {/* Top segmented toggle */} | |
| <div | |
| className="flex flex-none items-center gap-1 p-1.5 m-3 mb-0 rounded-lg" | |
| style={{ background: 'var(--tw-hover)', border: '1px solid var(--tw-border)' }} | |
| role="tablist" | |
| aria-label="Left panel view" | |
| > | |
| {VIEWS.map((v) => { | |
| const active = v.id === leftView | |
| return ( | |
| <button | |
| key={v.id} | |
| role="tab" | |
| aria-selected={active} | |
| onClick={() => setLeftView(v.id)} | |
| className="flex-1 rounded-md px-3 py-1.5 text-[11px] uppercase transition-colors" | |
| style={{ | |
| fontFamily: 'var(--font-mono)', | |
| letterSpacing: '0.1em', | |
| fontWeight: 600, | |
| color: active ? '#0a0a0a' : 'var(--tw-muted)', | |
| background: active ? '#f5efe6' : 'transparent', | |
| cursor: 'pointer', | |
| }} | |
| > | |
| {v.label} | |
| </button> | |
| ) | |
| })} | |
| </div> | |
| {/* Active view */} | |
| {leftView === 'zones' ? <ZonePanel /> : <MapPanel />} | |
| </div> | |
| ) | |
| } | |