"use client"; import { DashboardLayout } from "@/components/dashboard/DashboardLayout"; 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 { Box, Server, Container, ArrowRight, Rocket } from "lucide-react"; import { Progress } from "@/components/ui/progress"; import Link from "next/link"; import { getLiveNodes } from "@/lib/dockship/node"; import { useMemo } from "react"; import { getDocker } from "@/lib/dockship/docker"; import { getApps } from "@/lib/dockship/application"; import { cn } from "@/lib/utils"; import { getDeployments } from "@/lib/dockship/deploy"; import { useAsync, useAsyncInterval } from "@/hooks/use-async"; export default function OverviewPage() { const { value: nodes } = useAsyncInterval( "liveNodes", [], getLiveNodes, 3000, ); const { value: dockerNodes } = useAsync( "docker", [], async () => getDocker(nodes), [nodes], ); const { value: apps } = useAsyncInterval("apps", [], getApps, 3000); const { value: deployments } = useAsyncInterval( "deployments", [], async () => (await getDeployments()).filter((d) => d !== null), 3000, ); const appNameByContainer = useMemo(() => { const map = new Map(); for (const app of apps) { for (const container of app.deployments) { map.set(container, app.name); } } return map; }, [apps]); return ( {/* Stats Grid */}
app.deployments.length > 0).length } Deployed`} icon={} /> d.status === "running").length} running`} icon={} /> n.liveData).length} subtitle="online" icon={} /> sum + n.containers.filter((c) => c.State === "running").length, 0, )} subtitle="running" icon={} />
{/* Applications & Deployments */}
{/* Applications Table */} Applications
{/* Header */}
Name
Deployments
Node
{/* Rows */} {apps.slice(-5).length === 0 ? (
No applications yet
) : ( apps.slice(-5).map((app) => (
{app.name}
{app.deployments.length}
)) )}
{/* Recent Deployments */} Recent Deployments
{deployments.slice(-5).map((dep) => (
{dep.name} @{" "} {appNameByContainer.get(dep.container) ?? "Unknown app"}
{dep.image.slice(7, 19)}
{/* {dep.time} */}
))}
{/* Nodes */} Cluster Nodes {nodes.length} nodes
{nodes.map((node, i) => (
{node.liveData ? ( ) : ( )} {node.name}
{node.ip}
CPU {node.liveData?.cpu.usage.toFixed(0)}%
Memory {node.liveData?.memory.usage.toFixed(0)}%
Containers {6}
))}
); }