CoreControl/app/dashboard/Dashboard.tsx

230 lines
11 KiB
TypeScript
Raw Normal View History

2025-04-15 16:11:31 +02:00
"use client"
import { useEffect, useState } from "react"
import axios from "axios"
import Link from "next/link"
import { Activity, Layers, Network, Server } from "lucide-react"
import { AppSidebar } from "@/components/app-sidebar"
2025-04-11 14:48:12 +02:00
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
2025-04-15 16:11:31 +02:00
} from "@/components/ui/breadcrumb"
import { Separator } from "@/components/ui/separator"
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
2025-04-15 14:49:07 +02:00
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
2025-04-15 16:11:31 +02:00
import { Button } from "@/components/ui/button"
2025-04-13 21:10:17 +02:00
interface StatsResponse {
serverCountNoVMs: number
serverCountOnlyVMs: number
2025-04-15 16:11:31 +02:00
applicationCount: number
onlineApplicationsCount: number
2025-04-13 21:10:17 +02:00
}
2025-04-11 14:48:12 +02:00
2025-04-11 14:53:00 +02:00
export default function Dashboard() {
const [serverCountNoVMs, setServerCountNoVMs] = useState<number>(0)
const [serverCountOnlyVMs, setServerCountOnlyVMs] = useState<number>(0)
2025-04-15 16:11:31 +02:00
const [applicationCount, setApplicationCount] = useState<number>(0)
const [onlineApplicationsCount, setOnlineApplicationsCount] = useState<number>(0)
2025-04-12 19:34:20 +02:00
const getStats = async () => {
try {
2025-04-15 16:11:31 +02:00
const response = await axios.post<StatsResponse>("/api/dashboard/get", {})
setServerCountNoVMs(response.data.serverCountNoVMs)
setServerCountOnlyVMs(response.data.serverCountOnlyVMs)
2025-04-15 16:11:31 +02:00
setApplicationCount(response.data.applicationCount)
setOnlineApplicationsCount(response.data.onlineApplicationsCount)
2025-04-12 19:34:20 +02:00
} catch (error: any) {
2025-04-15 16:11:31 +02:00
console.log("Axios error:", error.response?.data)
2025-04-12 19:34:20 +02:00
}
2025-04-15 16:11:31 +02:00
}
2025-04-12 19:34:20 +02:00
useEffect(() => {
2025-04-15 16:11:31 +02:00
getStats()
}, [])
2025-04-12 19:34:20 +02:00
2025-04-11 14:48:12 +02:00
return (
<SidebarProvider>
<AppSidebar />
<SidebarInset>
2025-04-15 16:11:31 +02:00
<header className="flex h-16 shrink-0 items-center gap-2 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
2025-04-11 14:48:12 +02:00
<div className="flex items-center gap-2 px-4">
<SidebarTrigger className="-ml-1" />
<Separator orientation="vertical" className="mr-2 h-4" />
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem className="hidden md:block">
2025-04-15 16:11:31 +02:00
<BreadcrumbPage>/</BreadcrumbPage>
2025-04-11 14:48:12 +02:00
</BreadcrumbItem>
<BreadcrumbSeparator className="hidden md:block" />
<BreadcrumbItem>
<BreadcrumbPage>Dashboard</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</div>
</header>
2025-04-15 16:11:31 +02:00
<div className="p-6">
<h1 className="text-3xl font-bold tracking-tight mb-6">Dashboard</h1>
2025-04-15 14:49:07 +02:00
2025-04-15 16:11:31 +02:00
<div className="grid gap-6 md:grid-cols-1 lg:grid-cols-2">
2025-04-21 13:11:37 +02:00
<Card className="overflow-hidden border-t-4 border-t-rose-500 shadow-lg transition-all hover:shadow-xl hover:border-t-rose-600">
<CardHeader className="py-3 pb-1">
<div className="flex items-center justify-between">
<div>
2025-04-21 13:11:37 +02:00
<CardTitle className="text-2xl font-semibold">Servers</CardTitle>
<CardDescription className="mt-1">Physical and virtual servers overview</CardDescription>
</div>
2025-04-21 13:11:37 +02:00
<Server className="h-8 w-8 text-rose-500 p-1.5 rounded-lg" />
</div>
2025-04-21 13:11:37 +02:00
</CardHeader>
<CardContent className="pt-1 pb-2 min-h-[120px]">
<div className="grid grid-cols-2 gap-4">
{/* Physical Servers */}
<div className="flex items-center space-x-4 border border-gray-background p-4 rounded-lg">
<div className="bg-rose-100 p-2 rounded-full">
<Server className="h-6 w-6 text-rose-600" />
</div>
<div>
<div className="text-3xl font-bold">{serverCountNoVMs}</div>
<p className="text-sm text-muted-foreground">Physical Servers</p>
</div>
</div>
2025-04-21 13:11:37 +02:00
{/* Virtual Machines */}
<div className="flex items-center space-x-4 border border-gray-background p-4 rounded-lg">
<div className="bg-violet-100 p-2 rounded-full">
<Network className="h-6 w-6 text-violet-600" />
</div>
<div>
<div className="text-3xl font-bold">{serverCountOnlyVMs}</div>
<p className="text-sm text-muted-foreground">Virtual Servers</p>
</div>
</div>
</div>
2025-04-21 13:11:37 +02:00
</CardContent>
<CardFooter className="border-t bg-muted/10 py-2 px-4">
<Button
variant="outline"
size="default"
className="w-full font-semibold transition-colors border border-muted-foreground/20 hover:bg-primary hover:text-primary-foreground"
asChild
>
<Link href="/dashboard/servers" className="flex items-center justify-between">
<span>Manage Servers</span>
</Link>
</Button>
</CardFooter>
</Card>
2025-04-15 14:49:07 +02:00
2025-04-21 13:11:37 +02:00
<Card className="overflow-hidden border-t-4 border-t-amber-500 shadow-lg transition-all hover:shadow-xl hover:border-t-amber-600">
<CardHeader className="py-3 pb-1">
2025-04-15 14:49:07 +02:00
<div className="flex items-center justify-between">
2025-04-21 13:11:37 +02:00
<div>
<CardTitle className="text-2xl font-semibold">Applications</CardTitle>
<CardDescription className="mt-1">Manage your deployed applications</CardDescription>
</div>
<Layers className="h-8 w-8 text-amber-500 p-1.5 rounded-lg" />
2025-04-12 19:34:20 +02:00
</div>
</CardHeader>
2025-04-21 13:11:37 +02:00
<CardContent className="pt-1 pb-2 min-h-[120px]">
2025-04-15 16:11:31 +02:00
<div className="text-4xl font-bold">{applicationCount}</div>
<p className="text-sm text-muted-foreground mt-2">Running applications</p>
2025-04-15 14:49:07 +02:00
</CardContent>
2025-04-21 13:11:37 +02:00
<CardFooter className="border-t bg-muted/10 py-2 px-4">
<Button
variant="outline"
size="default"
className="w-full font-semibold transition-colors border border-muted-foreground/20 hover:bg-primary hover:text-primary-foreground"
asChild
>
<Link href="/dashboard/applications" className="flex items-center justify-between">
<span>View all applications</span>
</Link>
2025-04-15 14:49:07 +02:00
</Button>
</CardFooter>
2025-04-12 19:34:20 +02:00
</Card>
2025-04-15 14:49:07 +02:00
2025-04-21 13:11:37 +02:00
<Card className="overflow-hidden border-t-4 border-t-emerald-500 shadow-lg transition-all hover:shadow-xl hover:border-t-emerald-600">
<CardHeader className="py-3 pb-1">
2025-04-15 14:49:07 +02:00
<div className="flex items-center justify-between">
2025-04-21 13:11:37 +02:00
<div>
<CardTitle className="text-2xl font-semibold">Uptime</CardTitle>
<CardDescription className="mt-1">Monitor your service availability</CardDescription>
</div>
<Activity className="h-8 w-8 text-emerald-500 p-1.5 rounded-lg" />
2025-04-12 19:34:20 +02:00
</div>
</CardHeader>
2025-04-21 13:11:37 +02:00
<CardContent className="pt-1 pb-2 min-h-[120px]">
2025-04-15 16:11:31 +02:00
<div className="flex flex-col">
<div className="text-4xl font-bold flex items-center justify-between">
<span>
{onlineApplicationsCount}/{applicationCount}
</span>
<div className="flex items-center bg-emerald-100 text-emerald-700 px-2 py-1 rounded-md text-lg font-semibold">
{applicationCount > 0 ? Math.round((onlineApplicationsCount / applicationCount) * 100) : 0}%
</div>
</div>
<div className="w-full bg-gray-200 rounded-full h-2.5 mt-3">
<div
className="bg-emerald-500 h-2.5 rounded-full"
style={{
width: `${applicationCount > 0 ? Math.round((onlineApplicationsCount / applicationCount) * 100) : 0}%`,
}}
></div>
</div>
<p className="text-sm text-muted-foreground mt-2">Online applications</p>
</div>
2025-04-15 14:49:07 +02:00
</CardContent>
2025-04-21 13:11:37 +02:00
<CardFooter className="border-t bg-muted/10 py-2 px-4">
<Button
variant="outline"
size="default"
className="w-full font-semibold transition-colors border border-muted-foreground/20 hover:bg-primary hover:text-primary-foreground"
asChild
>
<Link href="/dashboard/uptime" className="flex items-center justify-between">
<span>View uptime metrics</span>
</Link>
2025-04-15 14:49:07 +02:00
</Button>
</CardFooter>
</Card>
2025-04-21 13:11:37 +02:00
<Card className="overflow-hidden border-t-4 border-t-sky-500 shadow-lg transition-all hover:shadow-xl hover:border-t-sky-600">
<CardHeader className="py-3 pb-1">
2025-04-15 14:49:07 +02:00
<div className="flex items-center justify-between">
2025-04-21 13:11:37 +02:00
<div>
<CardTitle className="text-2xl font-semibold">Network</CardTitle>
<CardDescription className="mt-1">Manage network configuration</CardDescription>
</div>
<Network className="h-8 w-8 text-sky-500 p-1.5 rounded-lg" />
2025-04-15 14:49:07 +02:00
</div>
</CardHeader>
2025-04-21 13:11:37 +02:00
<CardContent className="pt-1 pb-2 min-h-[120px]">
<div className="text-4xl font-bold">{serverCountNoVMs + serverCountOnlyVMs + applicationCount}</div>
2025-04-15 16:11:31 +02:00
<p className="text-sm text-muted-foreground mt-2">Active connections</p>
2025-04-15 14:49:07 +02:00
</CardContent>
2025-04-21 13:11:37 +02:00
<CardFooter className="border-t bg-muted/10 py-2 px-4">
<Button
variant="outline"
size="default"
className="w-full font-semibold transition-colors border border-muted-foreground/20 hover:bg-primary hover:text-primary-foreground"
asChild
>
<Link href="/dashboard/network" className="flex items-center justify-between">
<span>View network details</span>
</Link>
2025-04-15 14:49:07 +02:00
</Button>
</CardFooter>
2025-04-12 19:34:20 +02:00
</Card>
</div>
2025-04-15 16:11:31 +02:00
</div>
2025-04-11 14:48:12 +02:00
</SidebarInset>
</SidebarProvider>
2025-04-15 14:49:07 +02:00
)
}