File size: 3,967 Bytes
888cb3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d38ca8
888cb3b
1d38ca8
 
 
888cb3b
1d38ca8
888cb3b
1d38ca8
 
888cb3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { useState, useCallback } from "react";
import Dashboard from "./pages/Dashboard";
import RadarView3D from "./pages/RadarView3D"; 
import PatientForm from "./pages/PatientForm";
import AdminPanel from "./pages/AdminPanel";
import "./App.css";

const API = import.meta.env.PROD ? window.location.origin : "http://localhost:8000";

const TABS = [
  { id: "dashboard", label: "Overview" },
  { id: "map",       label: "Live simulation" },
  { id: "patient",   label: "Dispatch" },
  { id: "admin",     label: "System"   },
];

export default function App() {
  const [activeTab, setActiveTab] = useState("dashboard");
  const [simRunning, setSimRunning] = useState(false);

  // FIX 1: Optimistic UI Update for instant, smooth toggling
  const toggleSim = useCallback(async () => {
    const nextState = !simRunning;
    setSimRunning(nextState); // Update UI instantly
    
    try { 
      await fetch(`${API}/simulation/${nextState ? "start" : "stop"}`); 
    } catch (e) {
      console.warn("Backend unreached, reverting local sim state.", e);
      setSimRunning(!nextState); // Revert safely if it fails
    }
  }, [simRunning]);

  return (
    <div className="os-root dot-bg">
      {/* ── TOP MENU BAR ── */}
      <div className="menubar">
        <div className="menubar-left">
          <span className="app-name">Smart Routing System</span>
        </div>
        <div className="menubar-right">
          <button 
            onClick={toggleSim} 
            style={{
              background: simRunning ? 'var(--accent)' : 'transparent', 
              color: simRunning ? '#ffffff' : 'var(--text)', 
              border: `2px solid ${simRunning ? 'var(--accent)' : 'var(--text)'}`,
              fontFamily: 'var(--mono-font)', 
              textTransform: 'uppercase', 
              padding: '8px 20px', 
              borderRadius: '40px', 
              cursor: 'pointer',
              fontWeight: 'bold',
              transition: 'all 0.3s ease'
            }}>
            {simRunning ? "[ STOP ENGINE ]" : "[ IGNITE ENGINE ]"}
          </button>
          <div className="status-pill">
            <span className="pulse-dot" style={{background: simRunning ? "var(--accent)" : "var(--text)"}} />
            {simRunning ? "SYS.ACTIVE" : "SYS.IDLE"}
          </div>
        </div>
      </div>

      {/* ── MAIN WORKSPACE ── */}
      <div className="window-frame">
        {/* SIDEBAR NAVIGATION */}
        <div className="sidebar">
          <nav className="sidebar-nav">
            {TABS.map(tab => (
              <button 
                key={tab.id} 
                className={`sidebar-item ${activeTab === tab.id ? "active" : ""}`} 
                onClick={() => setActiveTab(tab.id)}
              >
                {tab.label}
              </button>
            ))}
          </nav>
        </div>

        {/* CONTENT AREA */}
        <div className="content-area">
          <div className="content-header">
            <div className="ch-breadcrumb">
              PATH <span className="ch-page">/{TABS.find(t => t.id === activeTab)?.label}</span>
            </div>
          </div>
          <div className="content-body">
            
            <div style={{ display: activeTab === "dashboard" ? "block" : "none" }}>
              <Dashboard simRunning={simRunning} onToggleSim={toggleSim} />
            </div>
            
            {/* The new 3D Interactive Map */}
            <div style={{ display: activeTab === "map" ? "block" : "none", height: "100%" }}>
              <RadarView3D isActive={activeTab === "map"} />
            </div>
            
            <div style={{ display: activeTab === "patient" ? "block" : "none" }}>
              <PatientForm />
            </div>
            
            <div style={{ display: activeTab === "admin" ? "block" : "none" }}>
              <AdminPanel />
            </div>

          </div>
        </div>
      </div>
    </div>
  );
}