Spaces:
Sleeping
Sleeping
Download frontend/src/api.js from REBELLION2002/traffix-live: direct link, hf CLI and curl.
- Browser
- Download file 2.4 kB
-
https://huggingface.co/spaces/REBELLION2002/traffix-live/resolve/main/frontend/src/api.js
- Command line
-
hf download hf://spaces/REBELLION2002/traffix-live/frontend/src/api.js
-
curl -L -o api.js https://huggingface.co/spaces/REBELLION2002/traffix-live/resolve/main/frontend/src/api.js
2.4 kB
| // All data comes from the Python backend (supermaster API). Nothing talks to SUMO directly. | |
| import { useEffect, useState } from "react"; | |
| export async function api(path, options = {}) { | |
| const headers = new Headers(options.headers || {}); | |
| try { | |
| const token = sessionStorage.getItem("traffix-operator-token"); | |
| if (token) headers.set("Authorization", `Bearer ${token}`); | |
| } catch { /* sessionStorage may be unavailable in private browser modes */ } | |
| if (options.body && !headers.has("Content-Type")) headers.set("Content-Type", "application/json"); | |
| const res = await fetch(`/api${path}`, { ...options, headers }); | |
| if (!res.ok) { | |
| const text = await res.text(); | |
| let detail = text; | |
| try { detail = JSON.parse(text).detail || text; } catch { /* not JSON */ } | |
| if (typeof detail !== "string") detail = JSON.stringify(detail); // FastAPI 422: a list of objects | |
| throw new Error(`${res.status} ${detail}`); | |
| } | |
| return res.json(); | |
| } | |
| // Polls the live snapshot once per second. | |
| export function useLive() { | |
| const [state, setState] = useState({ status: "idle" }); | |
| useEffect(() => { | |
| let alive = true; | |
| const tick = async () => { | |
| try { | |
| const s = await api("/state"); | |
| if (alive) setState(s); | |
| } catch { | |
| if (alive) setState({ status: "offline" }); | |
| } | |
| }; | |
| tick(); | |
| const id = setInterval(tick, 1000); | |
| return () => { alive = false; clearInterval(id); }; | |
| }, []); | |
| return state; | |
| } | |
| export function useOnce(path, deps = []) { | |
| const [data, setData] = useState(null); | |
| useEffect(() => { | |
| if (!path) { setData(null); return; } // nothing to fetch yet | |
| api(path).then(setData).catch(() => setData(null)); | |
| }, deps); | |
| return data; | |
| } | |
| export const PERSONAS = [ | |
| { id: "pedestrian", path: "/pedestrian", name: "Ferjani", role: "Pedestrian" }, | |
| { id: "car_driver", path: "/driver", name: "Faycel", role: "Car driver" }, | |
| { id: "bus_passenger", path: "/passenger", name: "Mamadou", role: "Bus passenger" }, | |
| { id: "bus_driver", path: "/bus-driver", name: "Hédi", role: "Bus driver" }, | |
| { id: "emergency_crew", path: "/emergency", name: "Touhami", role: "Ambulance crew" }, | |
| { id: "operator", path: "/operator", name: "Kamel", role: "Traffic operator" }, | |
| { id: "analyst", path: "/analyst", name: "Tahani", role: "Incident analyst" }, | |
| ]; | |