Overview patches

This commit is contained in:
2026-01-02 13:47:45 +01:00
parent 05fb078903
commit a26a12f684
+36 -75
View File
@@ -12,16 +12,16 @@ import {
Activity, Activity,
ArrowRight, ArrowRight,
Clock, Clock,
Rocket,
} from "lucide-react"; } from "lucide-react";
import { Progress } from "@/components/ui/progress"; import { Progress } from "@/components/ui/progress";
import Link from "next/link"; import Link from "next/link";
import { getLiveNodes } from "@/core/node"; import { getLiveNodes } from "@/core/node";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Docker, Node, NodeLiveData } from "@/lib/types"; import { Application, Docker, Node, NodeLiveData } from "@/lib/types";
import axios from "axios";
import Cookies from "js-cookie";
import { getSession } from "@/core/auth/session";
import { getDocker } from "@/core/docker"; import { getDocker } from "@/core/docker";
import { getApplications } from "@/core/application";
import { cn } from "@/lib/utils";
const recentDeployments = [ const recentDeployments = [
{ {
@@ -54,53 +54,17 @@ const recentDeployments = [
}, },
]; ];
const applications = [
{
name: "api-gateway",
containers: 3,
cpu: 45,
memory: 62,
status: "running" as const,
},
{
name: "auth-service",
containers: 2,
cpu: 28,
memory: 45,
status: "running" as const,
},
{
name: "postgres-db",
containers: 1,
cpu: 65,
memory: 78,
status: "running" as const,
},
{
name: "redis-cache",
containers: 1,
cpu: 12,
memory: 34,
status: "running" as const,
},
{
name: "worker-queue",
containers: 4,
cpu: 55,
memory: 48,
status: "pending" as const,
},
].slice(-5);
export default function OverviewPage() { export default function OverviewPage() {
const [nodes, setNodes] = useState<(NodeLiveData & Node)[]>([]); const [nodes, setNodes] = useState<(NodeLiveData & Node)[]>([]);
const [dockerNodes, setDockerNodes] = useState<Docker[]>([]); const [dockerNodes, setDockerNodes] = useState<Docker[]>([]);
const [apps, setApplications] = useState<Application[]>([]);
useEffect(() => { useEffect(() => {
const fetchNodes = async () => { const fetchNodes = async () => {
const nodes = await getLiveNodes(); const nodes = await getLiveNodes();
setNodes(nodes); setNodes(nodes);
setDockerNodes(await getDocker(nodes)); setDockerNodes(await getDocker(nodes));
setApplications(await getApplications());
}; };
fetchNodes(); fetchNodes();
const interval = setInterval(fetchNodes, 3000); const interval = setInterval(fetchNodes, 3000);
@@ -114,10 +78,24 @@ export default function OverviewPage() {
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4 mb-6"> <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4 mb-6">
<StatCard <StatCard
title="Applications" title="Applications"
value="12" value={apps.length}
subtitle="3 pending" subtitle={`${
apps.filter((app) => app.deployments.length > 0).length
} Deployed`}
icon={<Box className="w-4 h-4" />} icon={<Box className="w-4 h-4" />}
/> />
<StatCard
title="Deployments"
value="0"
subtitle="0 running"
icon={<Rocket className="w-4 h-4" />}
/>
<StatCard
title="Nodes"
value={nodes.filter((n) => n.liveData).length}
subtitle="online"
icon={<Server className="w-4 h-4" />}
/>
<StatCard <StatCard
title="Containers" title="Containers"
value={dockerNodes.reduce( value={dockerNodes.reduce(
@@ -128,18 +106,6 @@ export default function OverviewPage() {
subtitle="running" subtitle="running"
icon={<Container className="w-4 h-4" />} icon={<Container className="w-4 h-4" />}
/> />
<StatCard
title="Nodes"
value={nodes.filter((n) => n.liveData).length}
subtitle="online"
icon={<Server className="w-4 h-4" />}
/>
<StatCard
title="Uptime"
value="99.9%"
trend={{ value: 0.2, isPositive: true }}
icon={<Activity className="w-4 h-4" />}
/>
</div> </div>
{/* Applications & Deployments */} {/* Applications & Deployments */}
@@ -158,33 +124,21 @@ export default function OverviewPage() {
<div className="space-y-0 min-w-125"> <div className="space-y-0 min-w-125">
<div className="grid grid-cols-12 gap-4 text-xs text-muted-foreground uppercase tracking-wider py-2 border-b border-border"> <div className="grid grid-cols-12 gap-4 text-xs text-muted-foreground uppercase tracking-wider py-2 border-b border-border">
<div className="col-span-4">Name</div> <div className="col-span-4">Name</div>
<div className="col-span-2">Containers</div> <div className="col-span-2">Deployments</div>
<div className="col-span-2">CPU</div> <div className="col-span-2">Node</div>
<div className="col-span-2">Memory</div>
<div className="col-span-2">Status</div>
</div> </div>
{applications.map((app) => ( {apps.slice(-5).map((app) => (
<div <div
key={app.name} key={app.name}
className="grid grid-cols-12 gap-4 py-3 items-center data-table-row" className="grid grid-cols-12 gap-4 py-3 items-center data-table-row"
> >
<div className="col-span-4 font-mono text-sm">{app.name}</div> <div className="col-span-4 font-mono text-sm">{app.name}</div>
<div className="col-span-2 text-sm text-muted-foreground"> <div className="col-span-2 text-sm text-muted-foreground">
{app.containers} {app.deployments.length}
</div> </div>
<div className="col-span-2 flex items-center gap-2"> <div className="col-span-2">
<Progress value={app.cpu} className="w-full" /> {nodes.find((node) => node.node_id === app.nodeId)?.name}
<span className="text-xs text-muted-foreground font-mono w-8">
{app.cpu}%
</span>
</div> </div>
<div className="col-span-2 flex items-center gap-2">
<Progress value={app.memory} className="w-full" />
<span className="text-xs text-muted-foreground font-mono w-8">
{app.memory}%
</span>
</div>
<div className="col-span-2">{app.status}</div>
</div> </div>
))} ))}
</div> </div>
@@ -209,7 +163,14 @@ 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" className="flex flex-col sm:flex-row sm:items-center sm:justify-between py-2 border-b border-border last:border-0"
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
{dep.status} <span
className={cn(
"size-2 rounded-full",
(dep.status === "running" && "bg-chart-2") ||
(dep.status === "pending" && "bg-chart-1") ||
"bg-slate-400 dark:bg-slate-600"
)}
/>
<div> <div>
<div className="font-mono text-sm">{dep.app}</div> <div className="font-mono text-sm">{dep.app}</div>
<div className="text-xs text-muted-foreground"> <div className="text-xs text-muted-foreground">