Index: lan-frontend/src/App.jsx
===================================================================
--- lan-frontend/src/App.jsx	(revision d42aac31fe37e6e42a1b0515b54b86e8706d90a8)
+++ lan-frontend/src/App.jsx	(revision a762898ecd37a452c782821d4c2c4955c6ed2521)
@@ -1,4 +1,5 @@
-import React, { useEffect, useMemo, useState } from "react";
+import React, {useEffect, useMemo, useState} from "react";
 import "./styles/theme.css";
+import "./styles/netinel.css";
 
 import Login from "./components/Login";
@@ -7,270 +8,329 @@
 import ComputerDetailsModal from "./components/ComputerDetailsModal";
 import AIAssistantDrawer from "./components/AIAssistantDrawer";
+import NetIntelViz from "./components/NetIntelViz.jsx";
+import SideMenu from "./components/SideMenu";
+
 
 export default function App() {
-  const [stats, setStats] = useState(null);
-  const [computers, setComputers] = useState([]);
-  const [loading, setLoading] = useState(true);
-  const [lastUpdated, setLastUpdated] = useState(null);
-
-  const [query, setQuery] = useState("");
-  const [status, setStatus] = useState("");
-
-  const [selectedComputer, setSelectedComputer] = useState(null);
-  const [aiOpen, setAiOpen] = useState(false);
-  const [aiScope, setAiScope] = useState(null);
-  const [selectedEnv, setSelectedEnv] = useState("default");
-
-  const [me, setMe] = useState(null);
-  const [meLoading, setMeLoading] = useState(true);
-
-  // NEW: environment setting (switch)
-  const [saveProcHistory, setSaveProcHistory] = useState(false);
-
-  async function loadMe() {
-    setMeLoading(true);
-    try {
-      const r = await fetch("/api/me", { credentials: "include" });
-      if (r.ok) {
-        const data = await r.json();
-        setMe(data.user);
-      } else {
-        setMe(null);
-      }
-    } catch (e) {
-      console.error("loadMe error", e);
-      setMe(null);
-    } finally {
-      setMeLoading(false);
+    const [stats, setStats] = useState(null);
+    const [computers, setComputers] = useState([]);
+    const [loading, setLoading] = useState(true);
+    const [lastUpdated, setLastUpdated] = useState(null);
+
+    const [query, setQuery] = useState("");
+    const [status, setStatus] = useState("");
+
+    const [selectedComputer, setSelectedComputer] = useState(null);
+    const [aiOpen, setAiOpen] = useState(false);
+    const [aiScope, setAiScope] = useState(null);
+    const [selectedEnv, setSelectedEnv] = useState("default");
+
+    const [me, setMe] = useState(null);
+    const [meLoading, setMeLoading] = useState(true);
+
+    const [activeView, setActiveView] = useState("dashboard");
+// "dashboard" | "visualizations" | "account"
+
+
+    // NEW: environment setting (switch)
+    const [saveProcHistory, setSaveProcHistory] = useState(false);
+
+    async function loadMe() {
+        setMeLoading(true);
+        try {
+            const r = await fetch("/api/me", {credentials: "include"});
+            if (r.ok) {
+                const data = await r.json();
+                setMe(data.user);
+            } else {
+                setMe(null);
+            }
+        } catch (e) {
+            console.error("loadMe error", e);
+            setMe(null);
+        } finally {
+            setMeLoading(false);
+        }
     }
-  }
-
-  async function refresh() {
-    try {
-      setLoading(true);
-      const [s, c] = await Promise.all([
-        fetch("/api/stats", { credentials: "include" }).then((r) => r.json()),
-        fetch("/api/computers", {
-          credentials: "include",
-          headers: { "X-Env": selectedEnv },
-        }).then((r) => r.json()),
-      ]);
-
-      setStats(s);
-      setComputers(Array.isArray(c) ? c : []);
-      setLastUpdated(new Date().toISOString());
-    } catch (e) {
-      console.error("refresh error", e);
-    } finally {
-      setLoading(false);
+
+    async function refresh() {
+        try {
+            setLoading(true);
+            const [s, c] = await Promise.all([
+                fetch("/api/stats", {credentials: "include"}).then((r) => r.json()),
+                fetch("/api/computers", {
+                    credentials: "include",
+                    headers: {"X-Env": selectedEnv},
+                }).then((r) => r.json()),
+            ]);
+
+            setStats(s);
+            setComputers(Array.isArray(c) ? c : []);
+            setLastUpdated(new Date().toISOString());
+        } catch (e) {
+            console.error("refresh error", e);
+        } finally {
+            setLoading(false);
+        }
     }
-  }
-
-  // NEW: load env settings (switch state) for selected env
-  async function loadEnvSettings(env) {
-    try {
-      // само admin ќе има пристап (ако не си admin, ќе падне во else и ќе стане false)
-      const r = await fetch(`/api/admin/env-settings/${encodeURIComponent(env)}`, {
-        credentials: "include",
-      });
-
-      if (r.ok) {
-        const data = await r.json();
-        setSaveProcHistory(!!data.save_process_history);
-      } else {
-        setSaveProcHistory(false);
-      }
-    } catch (e) {
-      console.error("loadEnvSettings error", e);
-      setSaveProcHistory(false);
+
+    // NEW: load env settings (switch state) for selected env
+    async function loadEnvSettings(env) {
+        try {
+            // само admin ќе има пристап (ако не си admin, ќе падне во else и ќе стане false)
+            const r = await fetch(`/api/admin/env-settings/${encodeURIComponent(env)}`, {
+                credentials: "include",
+            });
+
+            if (r.ok) {
+                const data = await r.json();
+                setSaveProcHistory(!!data.save_process_history);
+            } else {
+                setSaveProcHistory(false);
+            }
+        } catch (e) {
+            console.error("loadEnvSettings error", e);
+            setSaveProcHistory(false);
+        }
     }
-  }
-
-  // NEW: set env setting (toggle)
-  async function setEnvProcessHistory(env, enabled) {
-    // optimistic UI
-    setSaveProcHistory(enabled);
-
-    try {
-      const r = await fetch(`/api/admin/env-settings/${encodeURIComponent(env)}`, {
-        method: "POST",
-        credentials: "include",
-        headers: { "Content-Type": "application/json" },
-        body: JSON.stringify({ save_process_history: enabled }),
-      });
-
-      if (r.ok) {
-        const data = await r.json();
-        setSaveProcHistory(!!data.save_process_history);
-      } else {
-        // rollback
-        setSaveProcHistory(!enabled);
-        console.error("setEnvProcessHistory failed", await r.text());
-      }
-    } catch (e) {
-      setSaveProcHistory(!enabled);
-      console.error("setEnvProcessHistory error", e);
+
+    // NEW: set env setting (toggle)
+    async function setEnvProcessHistory(env, enabled) {
+        // optimistic UI
+        setSaveProcHistory(enabled);
+
+        try {
+            const r = await fetch(`/api/admin/env-settings/${encodeURIComponent(env)}`, {
+                method: "POST",
+                credentials: "include",
+                headers: {"Content-Type": "application/json"},
+                body: JSON.stringify({save_process_history: enabled}),
+            });
+
+            if (r.ok) {
+                const data = await r.json();
+                setSaveProcHistory(!!data.save_process_history);
+            } else {
+                // rollback
+                setSaveProcHistory(!enabled);
+                console.error("setEnvProcessHistory failed", await r.text());
+            }
+        } catch (e) {
+            setSaveProcHistory(!enabled);
+            console.error("setEnvProcessHistory error", e);
+        }
     }
-  }
-
-  // on mount: check session
-  useEffect(() => {
-    loadMe();
-  }, []);
-
-  // when logged in OR env changed, refresh data + load env switch state
-  useEffect(() => {
-    if (!me) return;
-    loadEnvSettings(selectedEnv);
-    refresh();
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [me, selectedEnv]);
-
-  const filtered = useMemo(() => {
-    const q = query.trim().toLowerCase();
-    return (computers || [])
-      .filter((c) => (status ? c.status === status : true))
-      .filter((c) => {
-        if (!q) return true;
-        const hay = [c.name, c.user, c.ip, c.os, c.status]
-          .filter(Boolean)
-          .join(" ")
-          .toLowerCase();
-        return hay.includes(q);
-      });
-  }, [computers, query, status]);
-
-  // Gate UI
-  if (meLoading) return <div style={{ padding: 20 }}>Loading…</div>;
-  if (!me) return <Login onDone={loadMe} />;
-
-  return (
-    <div className="app-wrap">
-      <TopBar
-        onOpenAI={() => setAiOpen(true)}
-        onRefresh={refresh}
-        lastUpdated={lastUpdated}
-        onEnvChange={(env) => setSelectedEnv(env)}
-        selectedEnv={selectedEnv}
-        me={me}
-        onLoggedOut={loadMe}
-        // NEW props for switch:
-        saveProcHistory={saveProcHistory}
-        onToggleProcHistory={(enabled) => setEnvProcessHistory(selectedEnv, enabled)}
-      />
-
-      {/* STATS */}
-      <div className="stats-grid">
-        <div className="stat-card">
-          <div className="label">Total Computers</div>
-          <div className="value">{computers.length}</div>
-          <div className="sub">Monitored Systems</div>
+
+    // on mount: check session
+    useEffect(() => {
+        loadMe();
+    }, []);
+
+    // when logged in OR env changed, refresh data + load env switch state
+    useEffect(() => {
+        if (!me) return;
+        loadEnvSettings(selectedEnv);
+        refresh();
+        // eslint-disable-next-line react-hooks/exhaustive-deps
+    }, [me, selectedEnv]);
+
+    const filtered = useMemo(() => {
+        const q = query.trim().toLowerCase();
+        return (computers || [])
+            .filter((c) => (status ? c.status === status : true))
+            .filter((c) => {
+                if (!q) return true;
+                const hay = [c.name, c.user, c.ip, c.os, c.status]
+                    .filter(Boolean)
+                    .join(" ")
+                    .toLowerCase();
+                return hay.includes(q);
+            });
+    }, [computers, query, status]);
+
+    // Gate UI
+    if (meLoading) return <div style={{padding: 20}}>Loading…</div>;
+    if (!me) return <Login onDone={loadMe}/>;
+
+    return (
+        <div className="app-shell">
+            <div className="layout">
+                <SideMenu activeView={activeView} setActiveView={setActiveView}/>
+                <main className="content">
+                    {/* TopBar + pages */}
+                </main>
+            </div>
+
+            <div className="cont">
+                <TopBar
+                    onOpenAI={() => setAiOpen(true)}
+                    onRefresh={refresh}
+                    lastUpdated={lastUpdated}
+                    onEnvChange={(env) => setSelectedEnv(env)}
+                    selectedEnv={selectedEnv}
+                    me={me}
+                    onLoggedOut={loadMe}
+                    saveProcHistory={saveProcHistory}
+                    onToggleProcHistory={(enabled) => setEnvProcessHistory(selectedEnv, enabled)}
+                />
+
+                <div className="app-main">
+                    {/* ====== VIEW SWITCH ====== */}
+                    {activeView === "dashboard" && (
+                        <>
+                            {/* STATS */}
+                            <div className="stats-grid">
+                                <div className="stat-card">
+                                    <div className="label">Total Computers</div>
+                                    <div className="value">{computers.length}</div>
+                                    <div className="sub">Monitored Systems</div>
+                                </div>
+
+                                <div className="stat-card">
+                                    <div className="label">Sysmon Events (24h)</div>
+                                    <div className="value">{stats?.total_sysmon_events ?? "—"}</div>
+                                    <div className="sub">Security Events</div>
+                                </div>
+
+                                <div className="stat-card">
+                                    <div className="label">Network Connections (24h)</div>
+                                    <div className="value">{stats?.total_network_connections ?? "—"}</div>
+                                    <div className="sub">Captured Connections</div>
+                                </div>
+                            </div>
+
+                            {/* FILTERS */}
+                            <div className="panel" style={{marginBottom: 14}}>
+                                <div className="panel-head">
+                                    <div className="panel-title">Filters</div>
+                                    <div style={{color: "var(--dim)", fontSize: 12}}>
+                                        {loading ? "Refreshing…" : `${filtered.length} shown`}
+                                    </div>
+                                </div>
+                                <div className="panel-body">
+                                    <div className="filters">
+                                        <input
+                                            className="input"
+                                            value={query}
+                                            onChange={(e) => setQuery(e.target.value)}
+                                            placeholder="Search by name / user / ip / os…"
+                                        />
+
+                                        <select
+                                            className="select"
+                                            value={status}
+                                            onChange={(e) => setStatus(e.target.value)}
+                                        >
+                                            <option value="">All status</option>
+                                            <option value="online">Online</option>
+                                            <option value="idle">Idle</option>
+                                            <option value="offline">Offline</option>
+                                        </select>
+
+                                        <button className="btn primary" onClick={refresh}>
+                                            Refresh
+                                        </button>
+                                    </div>
+                                </div>
+                            </div>
+
+                            {/* COMPUTERS */}
+                            <div className="panel">
+                                <div className="panel-head">
+                                    <div className="panel-title">Connected Computers</div>
+                                    <div style={{display: "flex", gap: 10, alignItems: "center"}}>
+                                        <span className="pill">{filtered.length} computers</span>
+                                        <button
+                                            className="btn"
+                                            onClick={() => {
+                                                setQuery("");
+                                                setStatus("");
+                                            }}
+                                        >
+                                            Reset
+                                        </button>
+                                    </div>
+                                </div>
+                                <div className="panel-body">
+                                    <div className="computers-grid">
+                                        {filtered.map((c) => (
+                                            <ComputerCard
+                                                key={c.name}
+                                                c={c}
+                                                onOpen={(pc) => {
+                                                    setSelectedComputer(pc);
+                                                    setAiScope(pc.name);
+                                                }}
+                                            />
+                                        ))}
+                                        {filtered.length === 0 && (
+                                            <div style={{color: "var(--dim)"}}>
+                                                No computers match filter.
+                                            </div>
+                                        )}
+                                    </div>
+                                </div>
+                            </div>
+                        </>
+                    )}
+
+                    {activeView === "visualizations" && (
+                        <>
+                            <div className="panel" style={{marginBottom: 14}}>
+                                <div className="panel-head">
+                                    <div className="panel-title">Visualizations</div>
+                                    <div style={{color: "var(--dim)", fontSize: 12}}>
+                                        Network graphs / charts / tables
+                                    </div>
+                                </div>
+                                <div className="panel-body">
+                                    <NetIntelViz baseUrl="http://localhost:5555"/>
+                                </div>
+                            </div>
+                        </>
+                    )}
+
+                    {activeView === "account" && (
+                        <div className="panel">
+                            <div className="panel-head">
+                                <div className="panel-title">Account</div>
+                                <div style={{color: "var(--dim)", fontSize: 12}}>
+                                    Profile info
+                                </div>
+                            </div>
+                            <div className="panel-body">
+                                <div style={{display: "grid", gap: 10}}>
+                                    <div className="pill">Email: {me.email}</div>
+                                    <div className="pill">Role: {me.role}</div>
+                                    <div className="pill">Tenant ID: {me.tenant_id}</div>
+                                    <div className="pill">Name: {me.name || "—"}</div>
+                                </div>
+                            </div>
+                        </div>
+                    )}
+                </div>
+
+                {/* DETAILS MODAL */}
+                <ComputerDetailsModal
+                    open={!!selectedComputer}
+                    computer={selectedComputer}
+                    onClose={() => setSelectedComputer(null)}
+                    onAskAI={(name) => {
+                        setAiScope(name);
+                        setAiOpen(true);
+                    }}
+                />
+
+                {/* AI DRAWER */}
+                <AIAssistantDrawer
+                    open={aiOpen}
+                    onClose={() => setAiOpen(false)}
+                    computers={computers}
+                    scope={aiScope}
+                    setScope={setAiScope}
+                    apiBase={import.meta.env.VITE_API_BASE}
+                />
+            </div>
         </div>
-
-        <div className="stat-card">
-          <div className="label">Sysmon Events (24h)</div>
-          <div className="value">{stats?.total_sysmon_events ?? "—"}</div>
-          <div className="sub">Security Events</div>
-        </div>
-
-        <div className="stat-card">
-          <div className="label">Network Connections (24h)</div>
-          <div className="value">{stats?.total_network_connections ?? "—"}</div>
-          <div className="sub">Captured Connections</div>
-        </div>
-      </div>
-
-      {/* FILTERS */}
-      <div className="panel" style={{ marginBottom: 14 }}>
-        <div className="panel-head">
-          <div className="panel-title">Filters</div>
-          <div style={{ color: "var(--dim)", fontSize: 12 }}>
-            {loading ? "Refreshing…" : `${filtered.length} shown`}
-          </div>
-        </div>
-        <div className="panel-body">
-          <div className="filters">
-            <input
-              className="input"
-              value={query}
-              onChange={(e) => setQuery(e.target.value)}
-              placeholder="Search by name / user / ip / os…"
-            />
-
-            <select
-              className="select"
-              value={status}
-              onChange={(e) => setStatus(e.target.value)}
-            >
-              <option value="">All status</option>
-              <option value="online">Online</option>
-              <option value="idle">Idle</option>
-              <option value="offline">Offline</option>
-            </select>
-
-            <button className="btn primary" onClick={refresh}>
-              Refresh
-            </button>
-          </div>
-        </div>
-      </div>
-
-      {/* COMPUTERS */}
-      <div className="panel">
-        <div className="panel-head">
-          <div className="panel-title">Connected Computers</div>
-          <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
-            <span className="pill">{filtered.length} computers</span>
-            <button
-              className="btn"
-              onClick={() => {
-                setQuery("");
-                setStatus("");
-              }}
-            >
-              Reset
-            </button>
-          </div>
-        </div>
-        <div className="panel-body">
-          <div className="computers-grid">
-            {filtered.map((c) => (
-              <ComputerCard
-                key={c.name}
-                c={c}
-                onOpen={(pc) => {
-                  setSelectedComputer(pc);
-                  setAiScope(pc.name);
-                }}
-              />
-            ))}
-            {filtered.length === 0 && (
-              <div style={{ color: "var(--dim)" }}>No computers match filter.</div>
-            )}
-          </div>
-        </div>
-      </div>
-
-      {/* DETAILS MODAL */}
-      <ComputerDetailsModal
-        open={!!selectedComputer}
-        computer={selectedComputer}
-        onClose={() => setSelectedComputer(null)}
-        onAskAI={(name) => {
-          setAiScope(name);
-          setAiOpen(true);
-        }}
-      />
-
-      {/* AI DRAWER */}
-      <AIAssistantDrawer
-        open={aiOpen}
-        onClose={() => setAiOpen(false)}
-        computers={computers}
-        scope={aiScope}
-        setScope={setAiScope}
-        apiBase={import.meta.env.VITE_API_BASE}
-      />
-    </div>
-  );
+    );
 }
