"use client"; import { AppSidebar } from "@/components/app-sidebar"; import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from "@/components/ui/breadcrumb"; import { Separator } from "@/components/ui/separator"; import { SidebarInset, SidebarProvider, SidebarTrigger, } from "@/components/ui/sidebar"; import { Button } from "@/components/ui/button"; import { Plus, Link, MonitorCog, FileDigit, Trash2, LayoutGrid, List, Pencil, Cpu, Microchip, MemoryStick, HardDrive, Server, } from "lucide-react"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "@/components/ui/pagination"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import Cookies from "js-cookie"; import { useState, useEffect } from "react"; import axios from "axios"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Checkbox } from "@/components/ui/checkbox"; import { Alert } from "@/components/ui/alert"; import { ScrollArea } from "@/components/ui/scroll-area"; interface Server { id: number; name: string; host: boolean; hostServer: number | null; os?: string; ip?: string; url?: string; cpu?: string; gpu?: string; ram?: string; disk?: string; hostedVMs: Server[]; } interface GetServersResponse { servers: Server[]; maxPage: number; } export default function Dashboard() { const [host, setHost] = useState(false); const [hostServer, setHostServer] = useState(0); const [name, setName] = useState(""); const [os, setOs] = useState(""); const [ip, setIp] = useState(""); const [url, setUrl] = useState(""); const [cpu, setCpu] = useState(""); const [gpu, setGpu] = useState(""); const [ram, setRam] = useState(""); const [disk, setDisk] = useState(""); const [currentPage, setCurrentPage] = useState(1); const [maxPage, setMaxPage] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(4); const [servers, setServers] = useState([]); const [isGridLayout, setIsGridLayout] = useState(false); const [loading, setLoading] = useState(true); const [editId, setEditId] = useState(null); const [editHost, setEditHost] = useState(false); const [editHostServer, setEditHostServer] = useState(0); const [editName, setEditName] = useState(""); const [editOs, setEditOs] = useState(""); const [editIp, setEditIp] = useState(""); const [editUrl, setEditUrl] = useState(""); const [editCpu, setEditCpu] = useState(""); const [editGpu, setEditGpu] = useState(""); const [editRam, setEditRam] = useState(""); const [editDisk, setEditDisk] = useState(""); const [searchTerm, setSearchTerm] = useState(""); const [isSearching, setIsSearching] = useState(false); const [hostServers, setHostServers] = useState([]); const [isAddDialogOpen, setIsAddDialogOpen] = useState(false); useEffect(() => { const savedLayout = Cookies.get("layoutPreference-servers"); const layout_bool = savedLayout === "grid"; setIsGridLayout(layout_bool); setItemsPerPage(layout_bool ? 6 : 4); }, []); const toggleLayout = () => { const newLayout = !isGridLayout; setIsGridLayout(newLayout); Cookies.set("layoutPreference-servers", newLayout ? "grid" : "standard", { expires: 365, path: "/", sameSite: "strict", }); setItemsPerPage(newLayout ? 6 : 4); }; const add = async () => { try { await axios.post("/api/servers/add", { host, hostServer, name, os, ip, url, cpu, gpu, ram, disk, }); setIsAddDialogOpen(false); setHost(false); setHostServer(0); setName(""); setOs(""); setIp(""); setUrl(""); setCpu(""); setGpu(""); setRam(""); setDisk(""); getServers(); } catch (error: any) { console.log(error.response.data); } }; const getServers = async () => { try { setLoading(true); const response = await axios.post( "/api/servers/get", { page: currentPage, ITEMS_PER_PAGE: itemsPerPage, } ); for (const server of response.data.servers) { console.log("Host Server:" + server.hostServer); console.log("ID:" + server.id); } setServers(response.data.servers); setMaxPage(response.data.maxPage); setLoading(false); } catch (error: any) { console.log(error.response); } }; useEffect(() => { getServers(); }, [currentPage, itemsPerPage]); const handlePrevious = () => { setCurrentPage((prev) => Math.max(1, prev - 1)); }; const handleNext = () => { setCurrentPage((prev) => Math.min(maxPage, prev + 1)); }; const deleteApplication = async (id: number) => { try { await axios.post("/api/servers/delete", { id }); getServers(); } catch (error: any) { console.log(error.response.data); } }; const openEditDialog = (server: Server) => { setEditId(server.id); setEditHost(server.host); setEditHostServer(server.hostServer || null); setEditName(server.name); setEditOs(server.os || ""); setEditIp(server.ip || ""); setEditUrl(server.url || ""); setEditCpu(server.cpu || ""); setEditGpu(server.gpu || ""); setEditRam(server.ram || ""); setEditDisk(server.disk || ""); }; const edit = async () => { if (!editId) return; try { await axios.put("/api/servers/edit", { id: editId, host: editHost, hostServer: editHostServer, name: editName, os: editOs, ip: editIp, url: editUrl, cpu: editCpu, gpu: editGpu, ram: editRam, disk: editDisk, }); getServers(); setEditId(null); } catch (error: any) { console.log(error.response.data); } }; const searchServers = async () => { try { setIsSearching(true); const response = await axios.post<{ results: Server[] }>( "/api/servers/search", { searchterm: searchTerm } ); setServers(response.data.results); setIsSearching(false); } catch (error: any) { console.error("Search error:", error.response?.data); setIsSearching(false); } }; useEffect(() => { const delayDebounce = setTimeout(() => { if (searchTerm.trim() === "") { getServers(); } else { searchServers(); } }, 300); return () => clearTimeout(delayDebounce); }, [searchTerm]); useEffect(() => { const fetchHostServers = async () => { try { const response = await axios.get<{ servers: Server[] }>( "/api/servers/hosts" ); setHostServers(response.data.servers); } catch (error) { console.error("Error fetching host servers:", error); } }; if (isAddDialogOpen || editId !== null) { fetchHostServers(); } }, [isAddDialogOpen, editId]); return (
/ My Infrastructure Servers
Your Servers
{isGridLayout ? "Switch to list view" : "Switch to grid view"} Add an server General Hardware Virtualization
setName(e.target.value)} />
setIp(e.target.value)} />
Link to a web interface (e.g. Proxmox or Portainer) with which the server can be managed setUrl(e.target.value)} />
setCpu(e.target.value)} />
setGpu(e.target.value)} />
setRam(e.target.value)} />
setDisk(e.target.value)} />
setHost(checked === true) } />
{!host && (
)}
Cancel Add
setSearchTerm(e.target.value)} />

{!loading ? (
{servers .filter((server) => server.hostServer === 0) .map((server) => (
{server.name}
OS: {server.os || "-"}
IP: {server.ip || "Not set"}
CPU: {server.cpu || "-"}
GPU: {server.gpu || "-"}
RAM: {server.ram || "-"}
Disk: {server.disk || "-"}
{server.url && ( )}
Edit Server General Hardware Virtualization
setEditName(e.target.value) } />
setEditIp(e.target.value) } />
setEditUrl(e.target.value) } />
setEditCpu(e.target.value) } />
setEditGpu(e.target.value) } />
setEditRam(e.target.value) } />
setEditDisk(e.target.value) } />
setEditHost(checked === true) } />
{!editHost && (
)}
Cancel
{server.hostedVMs.length > 0 && ( Hosted VMs {server.host && (
{server.hostedVMs?.map( (hostedVM) => (
{hostedVM.name}
Edit VM General Hardware Virtualization
setEditName( e .target .value ) } />
setEditIp( e .target .value ) } />
setEditUrl( e .target .value ) } />
setEditCpu( e .target .value ) } />
setEditGpu( e .target .value ) } />
setEditRam( e .target .value ) } />
setEditDisk( e .target .value ) } />
setEditHost( checked === true ) } />
{!editHost && (
)}
Cancel
OS:{" "} {hostedVM.os || "-"}
IP:{" "} {hostedVM.ip || "Not set"}
CPU:{" "} {hostedVM.cpu || "-"}
GPU:{" "} {hostedVM.gpu || "-"}
RAM:{" "} {hostedVM.ram || "-"}
Disk:{" "} {hostedVM.disk || "-"}
) )}
)}
Close
)}
))}
) : (
Loading...
)}
1} style={{ cursor: currentPage === 1 ? "not-allowed" : "pointer", }} /> {currentPage}
); }