import React, { useEffect, useMemo, useState } from "react"; import logo from "../assets/logo_image.png"; export default function TopBar({ onOpenAI, onRefresh, lastUpdated, onEnvChange, selectedEnv: selectedEnvProp, // optional (ако сакаш да го контролира App) me, onLoggedOut, // optional callback (App loadMe) // NEW: process history switch (controlled by App) saveProcHistory = false, onToggleProcHistory, // (enabled:boolean) => void }) { const [open, setOpen] = useState(false); // env + tokens const [envs, setEnvs] = useState(["default"]); const [selectedEnv, setSelectedEnv] = useState(selectedEnvProp || "default"); const [newEnvName, setNewEnvName] = useState(""); const [token, setToken] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); const isAdmin = (me?.role || "").toLowerCase() === "admin"; // keep in sync ако App праќа selectedEnv prop useEffect(() => { if (selectedEnvProp && selectedEnvProp !== selectedEnv) { setSelectedEnv(selectedEnvProp); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedEnvProp]); async function loadEnvironments() { const r = await fetch("/api/admin/environments", { credentials: "include", }); const data = await r.json(); if (!r.ok) throw new Error(data?.error || `HTTP ${r.status}`); const list = data.environments?.length ? data.environments : ["default"]; setEnvs(list); if (!list.includes(selectedEnv)) { setSelectedEnv(list[0]); onEnvChange?.(list[0]); } } async function createEnvironment() { setError(""); setToken(""); if (!newEnvName.trim()) { setError("Внеси име за environment."); return; } setBusy(true); try { const r = await fetch("/api/admin/environments", { method: "POST", headers: { "Content-Type": "application/json" }, credentials: "include", body: JSON.stringify({ name: newEnvName.trim() }), }); const data = await r.json(); if (!r.ok) throw new Error(data?.error || `HTTP ${r.status}`); await loadEnvironments(); setSelectedEnv(newEnvName.trim()); onEnvChange?.(newEnvName.trim()); setNewEnvName(""); } catch (e) { setError(String(e.message || e)); } finally { setBusy(false); } } async function generateToken() { setError(""); setToken(""); if (!selectedEnv) { setError("Избери environment."); return; } setBusy(true); try { const r = await fetch("/api/admin/tokens", { method: "POST", headers: { "Content-Type": "application/json" }, credentials: "include", body: JSON.stringify({ env: selectedEnv }), }); const data = await r.json(); if (!r.ok) throw new Error(data?.error || `HTTP ${r.status}`); setToken(data.token || ""); } catch (e) { setError(String(e.message || e)); } finally { setBusy(false); } } async function copyToken() { if (!token) return; await navigator.clipboard.writeText(token); } function changeEnv(val) { setSelectedEnv(val); setToken(""); onEnvChange?.(val); } async function logout() { try { await fetch("/api/auth/logout", { method: "POST", credentials: "include" }); } catch {} onLoggedOut?.(); // reset local admin modal state setOpen(false); setToken(""); setError(""); } const prettyTime = useMemo(() => { if (!lastUpdated) return "Loading…"; try { return `Updated ${new Date(lastUpdated).toLocaleTimeString()}`; } catch { return "Updated"; } }, [lastUpdated]); return ( <>