gridloc / src /components /twin /LeftPanel.tsx
lassanmonster's picture
GridLoc: Bengaluru parking congestion digital twin
db3dbe1
Raw
History Blame Contribute Delete
1.87 kB
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>
)
}