From e20e9d6657ab1967295fe5ddfc2944d744acd422 Mon Sep 17 00:00:00 2001 From: Nurfog Date: Wed, 9 Sep 2026 09:44:58 -0300 Subject: [PATCH] feat: tablero por modulo funcional (estado+carga+funciones en sidebar) --- src/app/m/[name]/page.tsx | 219 ++++++++++++++++++++++---------------- 1 file changed, 130 insertions(+), 89 deletions(-) diff --git a/src/app/m/[name]/page.tsx b/src/app/m/[name]/page.tsx index 5978f67..9991975 100644 --- a/src/app/m/[name]/page.tsx +++ b/src/app/m/[name]/page.tsx @@ -1,67 +1,77 @@ "use client"; -import { useEffect, useMemo, useState, useSyncExternalStore } from "react"; -import { useParams } from "next/navigation"; import Link from "next/link"; import SamShell from "@/components/SamShell"; +import { useModules, useStats } from "@/lib/store"; +import { useParams } from "next/navigation"; import { displayName, + envOf, getModuleFunctions, + getStatusInfo, moduleUrl, - type ApiResponse, - type ModuleState, } from "@/lib/sam"; +import { + memUsed, + pct, + shortUptime, + statFor, +} from "@/lib/stats"; const API_URL = process.env.NEXT_PUBLIC_API_URL || "https://api.devops.norteamericano.cl"; -function subscribeHash(cb: () => void) { - window.addEventListener("hashchange", cb); - return () => window.removeEventListener("hashchange", cb); -} - -function snapshotHash() { - return window.location.hash.slice(1); +function Bar({ value, color }: { value: number; color: string }) { + return ( +
+
+
+ ); } +// Tablero funcional del módulo: estado + carga de trabajo + +// funciones API en el sidebar (plantilla SamShell). export default function ModuleBoard() { const params = useParams(); const name = Array.isArray(params.name) ? params.name[0] : params.name ?? ""; - const [data, setData] = useState(null); - const [loading, setLoading] = useState(true); - const hash = - useSyncExternalStore(subscribeHash, snapshotHash, () => "") || null; + const { data } = useModules(); + const stats = useStats(); + const loading = data === null; - useEffect(() => { - fetch("/api/modules", { cache: "no-store" }) - .then((r) => r.json()) - .then((j) => setData(j)) - .catch(() => setData(null)) - .finally(() => setLoading(false)); - }, []); - - const mod: ModuleState | undefined = useMemo( - () => data?.modules.find((m) => m.name.toLowerCase() === name.toLowerCase()), - [data, name] + const mod = data?.modules.find( + (m) => m.name.toLowerCase() === name.toLowerCase() ); - - const functions = useMemo(() => getModuleFunctions(name), [name]); - const activePath = hash || functions[0]?.path || null; - const activeFn = functions.find((f) => f.path === activePath) ?? functions[0]; + const functions = getModuleFunctions(name); + const stat = mod ? statFor(stats, `${mod.name}-frontend`) : undefined; + const status = mod ? getStatusInfo(mod) : null; + const env = mod ? envOf(mod.branch) : null; + const cpu = pct(stat?.cpu); + const mem = pct(stat?.memPerc); const title = mod ? displayName(mod.name) : displayName(name || "Módulo"); - const menu = functions.map((f) => ({ - label: f.label, - icon: f.icon, - href: `#${f.path}`, - })); + const menu = [ + { label: "Estado", icon: "bx-grid-alt", href: "#estado" }, + ...functions.map((f) => ({ + label: f.label, + icon: f.icon, + href: `/m/${name}#${f.path}`, + })), + { label: "Aplicaciones", icon: "bx-layer", href: "/" }, + ]; return ( )} - {!loading && mod && activeFn && ( + {!loading && mod && status && env && ( <> -
- - - {activeFn.label} - - {activeFn.desc} - - - - - GET {activeFn.path} - - - - API - - - - Abrir aplicación - - -
- -
+
-
- - Funciones disponibles de la API -
+
+
+ + Estado y carga de trabajo +
+ + + {status.label} + + {env.label} + + +
+
+
+ Uptime + {shortUptime(stat?.status ?? mod.container)} +
+
+ Puerto + :{mod.port} +
+
+ Rama + {mod.branch} +
+
+ Red + {stat?.netIO ?? "—"} +
+
+
+
+ CPU + {stat?.cpu ?? "—"} +
+ +
+
+
+ MEM {memUsed(stat)} + {stat?.memPerc ?? "—"} +
+ +
+ +
+
+
+ +
+ Funciones disponibles de la API +
+
+
+
{functions.map((f) => ( - + GET {f.path} + ))}
-

- Las funciones se consumen desde {API_URL}. Usa «Abrir - aplicación» para operar en {moduleUrl(mod)}. -

)} - ); }