Overview patches
This commit is contained in:
+36
-75
@@ -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">
|
||||||
|
|||||||
Reference in New Issue
Block a user