Index: lan-frontend/src/components/ComputerDetailsModal.jsx
===================================================================
--- lan-frontend/src/components/ComputerDetailsModal.jsx	(revision 2058e5c694bb6097866a5fe6503c519e8f74970f)
+++ lan-frontend/src/components/ComputerDetailsModal.jsx	(revision 2058e5c694bb6097866a5fe6503c519e8f74970f)
@@ -0,0 +1,384 @@
+import React, { useEffect, useMemo, useState } from "react";
+
+function severityForEventId(eventId) {
+  const id = parseInt(eventId, 10);
+  const high = new Set([1, 3, 8, 10]);
+  const med = new Set([5, 6, 7, 11, 22]);
+  if (high.has(id)) return "high";
+  if (med.has(id)) return "medium";
+  return "low";
+}
+
+export default function ComputerDetailsModal({ open, computer, onClose, onAskAI }) {
+  const [tab, setTab] = useState("overview");
+  const [loading, setLoading] = useState(false);
+  const [details, setDetails] = useState(null);
+  const [search, setSearch] = useState("");
+
+  // JSON viewer state
+  const [jsonOpen, setJsonOpen] = useState(false);
+  const [jsonTitle, setJsonTitle] = useState("");
+  const [jsonData, setJsonData] = useState(null);
+
+  useEffect(() => {
+    if (!open || !computer?.name) return;
+    let cancelled = false;
+
+    async function load() {
+      try {
+        setLoading(true);
+        const r = await fetch(`/api/computer/${encodeURIComponent(computer.name)}`);
+        const d = await r.json();
+        if (!cancelled) setDetails(d);
+      } catch (e) {
+        console.error("details error", e);
+      } finally {
+        if (!cancelled) setLoading(false);
+      }
+    }
+
+    load();
+    return () => {
+      cancelled = true;
+    };
+  }, [open, computer?.name]);
+
+  const filteredSysmon = useMemo(() => {
+    const list = details?.sysmon_events || [];
+    const q = search.trim().toLowerCase();
+    if (!q) return list;
+    return list.filter((ev) => {
+      const msg = (ev.message || "").toLowerCase();
+      const type = (ev.event_type || "").toLowerCase();
+      const id = String(ev.event_id ?? "");
+      return msg.includes(q) || type.includes(q) || id.includes(q);
+    });
+  }, [details, search]);
+
+  function openJson(ev) {
+    // server ти враќа: { event_id, event_type, message, timestamp, details }
+    setJsonTitle(`Sysmon Event ${ev?.event_id ?? ""} • ${ev?.event_type ?? ""}`);
+    setJsonData(ev?.details ?? ev); // ако нема details, покажи цел event
+    setJsonOpen(true);
+  }
+
+  function closeJson() {
+    setJsonOpen(false);
+    setJsonTitle("");
+    setJsonData(null);
+  }
+
+  if (!open) return null;
+
+  return (
+    <>
+      <div className="backdrop" onMouseDown={onClose}>
+        <div className="modal" onMouseDown={(e) => e.stopPropagation()}>
+          <div className="modal-head">
+            <div>
+              <div className="modal-title">{computer.name}</div>
+              <div className="modal-sub">
+                {computer.ip || "—"} • {computer.user || "—"} • {computer.status || "—"}
+              </div>
+            </div>
+
+            <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
+              <div className="tabs">
+                <button className={`tab ${tab === "overview" ? "active" : ""}`} onClick={() => setTab("overview")}>
+                  Overview
+                </button>
+                <button className={`tab ${tab === "sysmon" ? "active" : ""}`} onClick={() => setTab("sysmon")}>
+                  Sysmon
+                </button>
+                <button className={`tab ${tab === "processes" ? "active" : ""}`} onClick={() => setTab("processes")}>
+                  Processes
+                </button>
+                <button className={`tab ${tab === "network" ? "active" : ""}`} onClick={() => setTab("network")}>
+                  Network
+                </button>
+              </div>
+              <button className="btn" onClick={onClose}>
+                Close
+              </button>
+            </div>
+          </div>
+
+          <div style={{ padding: 16 }}>
+            {loading && <div style={{ color: "#94a3b8" }}>Loading…</div>}
+
+            {!loading && details && tab === "overview" && (
+              <div className="panel">
+                <div className="panel-head">
+                  <div className="panel-title">System Overview</div>
+                  <button className="btn primary" onClick={() => onAskAI(computer.name)}>
+                    Ask AI about this PC
+                  </button>
+                </div>
+                <div className="panel-body" style={{ display: "grid", gap: 10 }}>
+                  <div>
+                    <b>User:</b> {details.computer?.user}
+                  </div>
+                  <div>
+                    <b>IP:</b> {details.computer?.ip}
+                  </div>
+                  <div>
+                    <b>OS:</b> {details.computer?.os}
+                  </div>
+                  <div>
+                    <b>First seen:</b> {details.computer?.first_seen}
+                  </div>
+                  <div>
+                    <b>Last seen:</b> {details.computer?.last_seen}
+                  </div>
+                  <div>
+                    <b>Total logs:</b> {details.computer?.total_logs}
+                  </div>
+                </div>
+              </div>
+            )}
+
+            {!loading && details && tab === "sysmon" && (
+              <div className="panel">
+                <div className="panel-head" style={{ alignItems: "center" }}>
+                  <div className="panel-title">Sysmon Events</div>
+                  <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
+                    <span className="pill">{filteredSysmon.length} events</span>
+                    <input
+                      className="input"
+                      style={{ maxWidth: 380 }}
+                      placeholder="Search by id / type / message…"
+                      value={search}
+                      onChange={(e) => setSearch(e.target.value)}
+                    />
+                  </div>
+                </div>
+
+                <div className="panel-body">
+                  <div className="table-wrap">
+                    <table>
+                      <thead>
+                        <tr>
+                          <th style={{ width: 90 }}>Time</th>
+                          <th style={{ width: 70 }}>ID</th>
+                          <th style={{ width: 170 }}>Type</th>
+                          <th style={{ width: 110 }}>Severity</th>
+                          <th>Message</th>
+                          <th style={{ width: 90 }}>View</th>
+                        </tr>
+                      </thead>
+                      <tbody>
+                        {filteredSysmon.slice(0, 200).map((ev, idx) => {
+                          const sev = severityForEventId(ev.event_id);
+                          return (
+                            <tr key={idx}>
+                              <td>{ev.timestamp ? new Date(ev.timestamp).toLocaleTimeString() : "—"}</td>
+                              <td>
+                                <b>{ev.event_id}</b>
+                              </td>
+                              <td>{ev.event_type}</td>
+                              <td>
+                                <span className={`badge ${sev}`}>{sev.toUpperCase()}</span>
+                              </td>
+                              <td
+                                style={{
+                                  fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
+                                  fontSize: 12,
+                                }}
+                              >
+                                {(ev.message || "").slice(0, 140)}
+                              </td>
+                              <td>
+                                <button className="btn" onClick={() => openJson(ev)}>
+                                  View
+                                </button>
+                              </td>
+                            </tr>
+                          );
+                        })}
+
+                        {filteredSysmon.length === 0 && (
+                          <tr>
+                            <td colSpan="6" style={{ color: "#94a3b8" }}>
+                              No sysmon events.
+                            </td>
+                          </tr>
+                        )}
+                      </tbody>
+                    </table>
+                  </div>
+
+                  {filteredSysmon.length > 200 && (
+                    <div style={{ marginTop: 10, color: "#94a3b8", fontSize: 12 }}>
+                      Showing first 200 (for speed).
+                    </div>
+                  )}
+                </div>
+              </div>
+            )}
+
+            {!loading && details && tab === "processes" && (
+              <div className="panel">
+                <div className="panel-head">
+                  <div className="panel-title">Recent Processes</div>
+                </div>
+                <div className="panel-body">
+                  <div className="table-wrap">
+                    <table>
+                      <thead>
+                        <tr>
+                          <th>Time</th>
+                          <th>PID</th>
+                          <th>Name</th>
+                          <th>User</th>
+                          <th>CPU%</th>
+                          <th>RAM MB</th>
+                          <th>Cmdline</th>
+                        </tr>
+                      </thead>
+                      <tbody>
+                        {(details.recent_processes || []).slice(0, 150).map((p, idx) => (
+                          <tr key={idx}>
+                            <td>{p.timestamp ? new Date(p.timestamp).toLocaleTimeString() : "—"}</td>
+                            <td>
+                              <b>{p.pid}</b>
+                            </td>
+                            <td>{p.name}</td>
+                            <td>{p.username || "—"}</td>
+                            <td>{p.cpu_percent ?? 0}</td>
+                            <td>{p.memory_mb ?? 0}</td>
+                            <td
+                              style={{
+                                fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
+                                fontSize: 12,
+                              }}
+                            >
+                              {(p.cmdline || "").slice(0, 120)}
+                            </td>
+                          </tr>
+                        ))}
+                        {(details.recent_processes || []).length === 0 && (
+                          <tr>
+                            <td colSpan="7" style={{ color: "#94a3b8" }}>
+                              No process data.
+                            </td>
+                          </tr>
+                        )}
+                      </tbody>
+                    </table>
+                  </div>
+                </div>
+              </div>
+            )}
+
+            {!loading && details && tab === "network" && (
+              <div className="panel">
+                <div className="panel-head">
+                  <div className="panel-title">Network Connections</div>
+                </div>
+                <div className="panel-body">
+                  <div className="table-wrap">
+                    <table>
+                      <thead>
+                        <tr>
+                          <th>Time</th>
+                          <th>PID</th>
+                          <th>Process</th>
+                          <th>Local</th>
+                          <th>Remote</th>
+                          <th>Status</th>
+                        </tr>
+                      </thead>
+                      <tbody>
+                        {(details.network_connections || []).slice(0, 150).map((n, idx) => (
+                          <tr key={idx}>
+                            <td>{n.timestamp ? new Date(n.timestamp).toLocaleTimeString() : "—"}</td>
+                            <td>
+                              <b>{n.pid}</b>
+                            </td>
+                            <td>{n.process_name || "—"}</td>
+                            <td
+                              style={{
+                                fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
+                                fontSize: 12,
+                              }}
+                            >
+                              {n.local_address || "—"}
+                            </td>
+                            <td
+                              style={{
+                                fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
+                                fontSize: 12,
+                              }}
+                            >
+                              {n.remote_address || "—"}
+                            </td>
+                            <td>{n.status || "—"}</td>
+                          </tr>
+                        ))}
+                        {(details.network_connections || []).length === 0 && (
+                          <tr>
+                            <td colSpan="6" style={{ color: "#94a3b8" }}>
+                              No network data.
+                            </td>
+                          </tr>
+                        )}
+                      </tbody>
+                    </table>
+                  </div>
+                </div>
+              </div>
+            )}
+
+            {!loading && !details && <div style={{ color: "#94a3b8" }}>No details.</div>}
+          </div>
+        </div>
+      </div>
+
+      {/* JSON VIEWER MODAL */}
+      {jsonOpen && (
+        <div className="backdrop" onMouseDown={closeJson}>
+          <div className="modal" onMouseDown={(e) => e.stopPropagation()} style={{ width: "min(900px, 96vw)" }}>
+            <div className="modal-head">
+              <div>
+                <div className="modal-title">View JSON</div>
+                <div className="modal-sub">{jsonTitle}</div>
+              </div>
+              <div style={{ display: "flex", gap: 10 }}>
+                <button
+                  className="btn"
+                  onClick={() => {
+                    const txt = JSON.stringify(jsonData ?? {}, null, 2);
+                    navigator.clipboard.writeText(txt);
+                  }}
+                >
+                  Copy
+                </button>
+                <button className="btn" onClick={closeJson}>
+                  Close
+                </button>
+              </div>
+            </div>
+            <div style={{ padding: 16 }}>
+              <pre
+                style={{
+                  margin: 0,
+                  maxHeight: "70vh",
+                  overflow: "auto",
+                  padding: 14,
+                  borderRadius: 12,
+                  border: "1px solid rgba(148,163,184,0.25)",
+                  background: "rgba(2,6,23,0.35)",
+                  color: "rgba(226,232,240,0.95)",
+                  fontSize: 12,
+                  lineHeight: 1.5,
+                }}
+              >
+                {JSON.stringify(jsonData ?? {}, null, 2)}
+              </pre>
+            </div>
+          </div>
+        </div>
+      )}
+    </>
+  );
+}
