import { useEffect, useMemo, useState } from "react"; import { api } from "../api.js"; function time(value) { if (typeof value !== "number") return ""; return new Date(value * 1000).toLocaleTimeString(); } export default function EventInjector({ live }) { const [options, setOptions] = useState([]); const [edgeId, setEdgeId] = useState(""); const [laneIndex, setLaneIndex] = useState(0); const [duration, setDuration] = useState(180); const [busy, setBusy] = useState(false); const [message, setMessage] = useState(""); const [failure, setFailure] = useState(""); const events = live.world_events || []; const active = live.status === "running"; useEffect(() => { if (!active) { setOptions([]); return; } let alive = true; api("/event-options").then((result) => { if (!alive) return; setOptions(result.edges || []); setEdgeId((current) => current || result.edges?.[0]?.edge_id || ""); }).catch((error) => { if (alive) setFailure(error.message); }); return () => { alive = false; }; }, [active]); const edge = useMemo(() => options.find((item) => item.edge_id === edgeId), [options, edgeId]); useEffect(() => { if (edge && !edge.lanes.includes(laneIndex)) setLaneIndex(edge.lanes[0]); }, [edge, laneIndex]); async function inject(e) { e.preventDefault(); setBusy(true); setFailure(""); setMessage(""); try { const result = await api("/events", { method: "POST", body: JSON.stringify({ request_id: crypto.randomUUID(), edge_id: edgeId, lane_index: Number(laneIndex), duration_seconds: Number(duration), }) }); setMessage(`Incident ${result.event_id.slice(0, 8)} queued.`); } catch (error) { setFailure(error.message); } finally { setBusy(false); } } return (

Live event injection

Add a simulated stalled vehicle while the run is active. The live map marks injected vehicles in red.

{!active && Start a simulation to enable event controls.} {message && {message}} {failure && {failure}}

Event timeline

{events.length === 0 ?

No operator-injected events in this run.

: (
{[...events].reverse().map((event) => (
{event.status} Stalled vehicle · {event.edge_id} · lane {event.lane_index + 1} {event.applied_at != null ? `applied ${Math.round(event.applied_at)}s` : `queued ${time(event.queued_at)}`} {event.detected_at != null && detector observed at {Math.round(event.detected_at)}s} {event.error && {event.error}}
))}
)}

Injected events and agent detections are recorded separately. Detection may take time and is not guaranteed.

); }