import React, { useState, useEffect, useRef } from 'react'; const WS_BASE = (import.meta.env.VITE_API_URL || 'http://localhost:8000').replace('http', 'ws'); const STATUS_COLOR = { DELIVERING: 'var(--accent)', RETURNING: 'var(--warning)', IDLE: 'var(--on-surface-variant)' }; export default function RouteIntelligence() { const [dispatch, setDispatch] = useState(null); const [connected, setConnected] = useState(false); const [log, setLog] = useState([]); const wsRef = useRef(null); const logEndRef = useRef(null); useEffect(() => { connect(); return () => wsRef.current?.close(); }, []); useEffect(() => { logEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [log]); const connect = () => { try { const ws = new WebSocket(`${WS_BASE}/ws/dispatch`); wsRef.current = ws; ws.onopen = () => setConnected(true); ws.onclose = () => { setConnected(false); setTimeout(connect, 3000); // auto-reconnect }; ws.onmessage = (e) => { const data = JSON.parse(e.data); setDispatch(data); if (data.batch) { setLog(prev => [ ...prev.slice(-49), { ts: new Date().toTimeString().slice(0, 8), rider: data.batch.rider_id, orders: data.batch.orders, efficiency: data.batch.efficiency_score, saved: data.batch.saved_distance_km, }, ]); } }; } catch { setTimeout(connect, 3000); } }; const riders = dispatch?.riders || []; const delivering = riders.filter(r => r.status === 'DELIVERING').length; const idle = riders.filter(r => r.status === 'IDLE').length; return (