import type { RouteEndpoint, RouteInfo, InteractionMode } from '../types'; import { NODE_TYPE_LABELS, ROUTE_COLORS } from '../constants'; interface Props { endpoints: RouteEndpoint[]; source: string | null; target: string | null; onSourceChange: (id: string | null) => void; onTargetChange: (id: string | null) => void; onSwap: () => void; onClear: () => void; info: RouteInfo | null; mode: InteractionMode; onArmStart: () => void; onArmEnd: () => void; } function labelFor(endpoints: RouteEndpoint[], id: string | null): string { if (!id) return 'not set'; const ep = endpoints.find((e) => e.id === id); return ep ? ep.label : id; } function optionLabel(ep: RouteEndpoint): string { const typeLabel = NODE_TYPE_LABELS[ep.type] || ep.type; return ep.type === 'room' ? ep.label : `${ep.label} (${typeLabel})`; } export default function RoutePanel({ endpoints, source, target, onSourceChange, onTargetChange, onSwap, onClear, info, mode, onArmStart, onArmEnd, }: Props) { const hasRoute = !!source && !!target; return (

Navigation

Click Set Start, then click a node on the graph. Do the same for Set Destination. The shortest route is computed with A* search.

{labelFor(endpoints, source)}
{labelFor(endpoints, target)}
{hasRoute && info && (
{info.found ? ( <>
Path length {info.distance.toLocaleString()} px
Segments {info.segments}
{info.crossFloor && Crosses floors} ) : ( No route found between these points. )}
)}
Pick from list instead
); }