From 4d18edcffe28758f069c4706a9c0b88a8ae1a697 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Mon, 29 Dec 2025 19:49:37 +0100 Subject: [PATCH] Node status checking --- src/app/applications/page.tsx | 3 +- src/app/containers/page.tsx | 7 ++--- src/app/deployments/page.tsx | 7 ++--- src/app/monitoring/page.tsx | 4 +-- src/app/nodes/page.tsx | 33 ++++++++++++-------- src/app/overview/page.tsx | 21 +++++++------ src/components/dashboard/StatusIndicator.tsx | 33 -------------------- src/core/docker.ts | 21 +++++++++---- src/core/node.ts | 23 +++----------- src/lib/types.ts | 2 +- 10 files changed, 59 insertions(+), 95 deletions(-) delete mode 100644 src/components/dashboard/StatusIndicator.tsx diff --git a/src/app/applications/page.tsx b/src/app/applications/page.tsx index d983248..9ee1ebc 100644 --- a/src/app/applications/page.tsx +++ b/src/app/applications/page.tsx @@ -4,7 +4,6 @@ import { DashboardLayout } from "@/components/dashboard/DashboardLayout"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; -import { StatusIndicator } from "@/components/dashboard/StatusIndicator"; import { Play, Square, RotateCcw, MoreVertical, Plus } from "lucide-react"; import { Progress } from "@/components/ui/progress"; @@ -111,7 +110,7 @@ export default function ApplicationsPage() {
{/* Status & Name */}
- + {/* {app.status} */}
{app.name} diff --git a/src/app/containers/page.tsx b/src/app/containers/page.tsx index dc3542d..f930933 100644 --- a/src/app/containers/page.tsx +++ b/src/app/containers/page.tsx @@ -4,7 +4,6 @@ import { DashboardLayout } from "@/components/dashboard/DashboardLayout"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; -import { StatusIndicator } from "@/components/dashboard/StatusIndicator"; import { Terminal, MoreVertical, Play, Square, Trash2 } from "lucide-react"; const containers = [ @@ -184,9 +183,7 @@ export default function ContainersPage() { {container.node} - - - + {/* {container.status} */} {container.uptime} @@ -235,7 +232,7 @@ export default function ContainersPage() { {container.name}
- + {/* {container.status} */}
diff --git a/src/app/deployments/page.tsx b/src/app/deployments/page.tsx index 311fe46..0938bda 100644 --- a/src/app/deployments/page.tsx +++ b/src/app/deployments/page.tsx @@ -4,7 +4,6 @@ import { DashboardLayout } from "@/components/dashboard/DashboardLayout"; import { Card, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; -import { StatusIndicator } from "@/components/dashboard/StatusIndicator"; import { Rocket, RotateCcw, @@ -153,9 +152,7 @@ export default function DeploymentsPage() {
- - - + {dep.status} {dep.replicas} @@ -201,7 +198,7 @@ export default function DeploymentsPage() { {dep.app}
- + {dep.status}
diff --git a/src/app/monitoring/page.tsx b/src/app/monitoring/page.tsx index 2aa6d3e..ead99e9 100644 --- a/src/app/monitoring/page.tsx +++ b/src/app/monitoring/page.tsx @@ -56,8 +56,8 @@ export default function MonitoringPage() { const fetchNodes = async () => { const nodes = await getLiveNodes(); setLiveData({ - cpuUsage: average(nodes, (n) => n.liveData.cpu.usage), - ramUsage: average(nodes, (n) => n.liveData.memory.usage), + cpuUsage: average(nodes, (n) => n.liveData?.cpu.usage || 0), + ramUsage: average(nodes, (n) => n.liveData?.memory.usage || 0), }); }; fetchNodes(); diff --git a/src/app/nodes/page.tsx b/src/app/nodes/page.tsx index 7516e5f..28820b7 100644 --- a/src/app/nodes/page.tsx +++ b/src/app/nodes/page.tsx @@ -8,12 +8,15 @@ import { Server, Plus, Settings, Trash2 } from "lucide-react"; import { Progress } from "@/components/ui/progress"; import { Docker, Node, NodeLiveData } from "@/lib/types"; import { useEffect, useState } from "react"; -import { getDockerNode, getLiveNodes } from "@/core/node"; +import { getLiveNodes } from "@/core/node"; import { formatBytes } from "@/lib/format"; import { setNodes as updateNodes } from "@/core/node"; import AddNode from "@/components/dialogs/AddNode"; +import { getDocker } from "@/core/docker"; function DiskUsage({ liveData }: NodeLiveData) { + if (!liveData) return null; + const usage = (liveData.disk.used / liveData.disk.size) * 100; return ( @@ -44,7 +47,7 @@ export default function NodesPage() { useEffect(() => { const fetchDocker = async () => { - setDockerNodes(await Promise.all(nodes.map(getDockerNode))); + setDockerNodes(await getDocker(nodes)); }; fetchDocker(); }, [nodes]); @@ -54,9 +57,7 @@ export default function NodesPage() {
{nodes.length} nodes - - {/* {nodes.filter((n) => n.status === "running").length} online */} - + {nodes.filter((node) => node.liveData).length} online
- {/* */} {node.name} + {node.liveData ? ( + + ) : ( + + )}
{node.ip} • {node.ip} @@ -135,13 +140,13 @@ export default function NodesPage() { {/* CPU */}
- CPU ({node.liveData.cpu.cores} cores) + CPU ({node.liveData?.cpu.cores} cores)
- {node.liveData.cpu.usage.toFixed(0)}% + {node.liveData?.cpu.usage.toFixed(0)}%
@@ -152,15 +157,17 @@ export default function NodesPage() { Memory
- {node.liveData.memory.usage.toFixed(0)}% + {node.liveData?.memory.usage.toFixed(0)}%
- {formatBytes(node.liveData.memory.used)} /{" "} - {formatBytes(node.liveData.memory.total)} + {node.liveData && + formatBytes(node.liveData?.memory.used) + + "/" + + formatBytes(node.liveData?.memory.total)}
diff --git a/src/app/overview/page.tsx b/src/app/overview/page.tsx index 0bfa0d2..8f034b8 100644 --- a/src/app/overview/page.tsx +++ b/src/app/overview/page.tsx @@ -5,7 +5,6 @@ import { StatCard } from "@/components/dashboard/StatCard"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; -import { StatusIndicator } from "@/components/dashboard/StatusIndicator"; import { Box, Server, @@ -178,9 +177,7 @@ export default function OverviewPage() { {app.memory}%
-
- -
+
{app.status}
))} @@ -205,7 +202,7 @@ export default function OverviewPage() { className="flex flex-col sm:flex-row sm:items-center sm:justify-between py-2 border-b border-border last:border-0" >
- + {dep.status}
{dep.app}
@@ -235,7 +232,11 @@ export default function OverviewPage() {
- + {node.liveData ? ( + + ) : ( + + )} {node.name}
@@ -246,21 +247,21 @@ export default function OverviewPage() {
CPU - {node.liveData.cpu.usage.toFixed(0)}% + {node.liveData?.cpu.usage.toFixed(0)}%
Memory - {node.liveData.memory.usage.toFixed(0)}% + {node.liveData?.memory.usage.toFixed(0)}%
diff --git a/src/components/dashboard/StatusIndicator.tsx b/src/components/dashboard/StatusIndicator.tsx deleted file mode 100644 index 6f3b752..0000000 --- a/src/components/dashboard/StatusIndicator.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { cn } from "@/lib/utils"; - -interface StatusIndicatorProps { - status: "running" | "stopped" | "error" | "pending"; - showLabel?: boolean; - size?: "sm" | "md"; -} - -const statusConfig = { - running: { label: "Running", className: "status-running" }, - stopped: { label: "Stopped", className: "status-stopped" }, - error: { label: "Error", className: "status-error" }, - pending: { label: "Pending", className: "status-pending" }, -}; - -export function StatusIndicator({ status, showLabel = false, size = "md" }: StatusIndicatorProps) { - const config = statusConfig[status]; - - return ( -
-
- {showLabel && ( - {config.label} - )} -
- ); -} diff --git a/src/core/docker.ts b/src/core/docker.ts index 60103c8..6ee9137 100644 --- a/src/core/docker.ts +++ b/src/core/docker.ts @@ -1,12 +1,21 @@ "use server"; import axios from "axios"; -import { Node } from "@/lib/types"; +import { Docker, Node } from "@/lib/types"; +import { verifySession } from "./auth/session"; -export async function getDocker(node: Node): Promise<{ version: string }> { - return await ( - await axios.get(`http://${node.ip}:3000/api/get-docker`, { - headers: { Authorization: `ApiKey ${node.key}` }, +export async function getDocker(nodes: Node[]): Promise { + if (await verifySession()) return []; + + return await Promise.all( + nodes.map(async (node) => { + const data = await ( + await axios.get(`http://${node.ip}:3000/api/get-docker`, { + headers: { Authorization: `ApiKey ${node.key}` }, + }) + ).data; + + return { ...node, containers: data.containers, version: data.version }; }) - ).data; + ); } diff --git a/src/core/node.ts b/src/core/node.ts index a9cda4b..98ab7a6 100644 --- a/src/core/node.ts +++ b/src/core/node.ts @@ -1,12 +1,12 @@ "use server"; import { read, write } from "@/app/api/file"; -import { Docker, Node, NodeLiveData } from "@/lib/types"; +import { Node, NodeLiveData } from "@/lib/types"; import axios from "axios"; import { verifySession } from "./auth/session"; -export async function getNodes(): Promise { - if (await verifySession()) return; +export async function getNodes(): Promise { + if (await verifySession()) return []; return await read(() => [], "data", "nodes.json"); } @@ -17,10 +17,8 @@ export async function setNodes(nodes: Node[]) { await write(nodes, "data", "nodes.json"); } -export async function getLiveNodes(): Promise< - (NodeLiveData & Node)[] | undefined -> { - if (await verifySession()) return; +export async function getLiveNodes(): Promise<(NodeLiveData & Node)[]> { + if (await verifySession()) return []; const nodes: Node[] = await read(() => [], "data", "nodes.json"); @@ -36,17 +34,6 @@ export async function getLiveNodes(): Promise< ); } -export async function getDockerNode(node: Node): Promise { - if (await verifySession()) return; - - const data = await ( - await axios.get(`http://${node.ip}:3000/api/get-docker`, { - headers: { Authorization: `ApiKey ${node.key}` }, - }) - ).data; - return { ...node, containers: data.containers, version: data.version }; -} - export async function authNode(ip: string, key: string) { if (await verifySession()) return; diff --git a/src/lib/types.ts b/src/lib/types.ts index 6dbee52..1cca76c 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -11,7 +11,7 @@ export interface Node { } export interface NodeLiveData { - liveData: { + liveData?: { cpu: { manufacturer: string; brand: string;