"use client" import { useState, useEffect } from "react" import { Card, CardContent, CardHeader, CardTitle } from "./ui/card" import { Badge } from "./ui/badge" import { Progress } from "./ui/progress" import { Server, Play, Square, Monitor, Cpu, MemoryStick, AlertCircle } from "lucide-react" interface VMData { vmid: number name: string status: string cpu: number mem: number maxmem: number disk: number maxdisk: number uptime: number } const fetchVMData = async (): Promise => { try { console.log("[v0] Fetching VM data from Flask server...") const response = await fetch("/api/vms", { method: "GET", headers: { "Content-Type": "application/json", }, signal: AbortSignal.timeout(5000), }) if (!response.ok) { throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() console.log("[v0] Successfully fetched VM data from Flask:", data) return Array.isArray(data) ? data : [] } catch (error) { console.error("[v0] Failed to fetch VM data from Flask server:", error) throw error } } export function VirtualMachines() { const [vmData, setVmData] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { const fetchData = async () => { try { setLoading(true) setError(null) const result = await fetchVMData() setVmData(result) } catch (err) { setError("Flask server not available. Please ensure the server is running.") } finally { setLoading(false) } } fetchData() const interval = setInterval(fetchData, 30000) return () => clearInterval(interval) }, []) if (loading) { return (
Loading VM data...
) } if (error) { return (
Flask Server Not Available
{error || "Unable to connect to the Flask server. Please ensure the server is running and try again."}
) } const runningVMs = vmData.filter((vm) => vm.status === "running").length const stoppedVMs = vmData.filter((vm) => vm.status === "stopped").length const totalCPU = vmData.reduce((sum, vm) => sum + (vm.cpu || 0), 0) const totalMemory = vmData.reduce((sum, vm) => sum + (vm.maxmem || 0), 0) const getStatusColor = (status: string) => { switch (status) { case "running": return "bg-green-500/10 text-green-500 border-green-500/20" case "stopped": return "bg-red-500/10 text-red-500 border-red-500/20" default: return "bg-yellow-500/10 text-yellow-500 border-yellow-500/20" } } const getStatusIcon = (status: string) => { switch (status) { case "running": return case "stopped": return default: return null } } const formatUptime = (seconds: number) => { const days = Math.floor(seconds / 86400) const hours = Math.floor((seconds % 86400) / 3600) const minutes = Math.floor((seconds % 3600) / 60) return `${days}d ${hours}h ${minutes}m` } return (
{/* VM Overview Cards */}
Total VMs
{vmData.length}
{runningVMs} Running {stoppedVMs} Stopped

Virtual machines configured

Total CPU
{(totalCPU * 100).toFixed(0)}%

Allocated CPU usage

Total Memory
{(totalMemory / 1024 ** 3).toFixed(1)} GB

Allocated RAM

Average Load
{runningVMs > 0 ? ((totalCPU / runningVMs) * 100).toFixed(0) : 0}%

Average resource utilization

{/* Virtual Machines List */} Virtual Machines {vmData.length === 0 ? (
No virtual machines found
) : (
{vmData.map((vm) => { const cpuPercent = (vm.cpu * 100).toFixed(1) const memPercent = vm.maxmem > 0 ? ((vm.mem / vm.maxmem) * 100).toFixed(1) : "0" const memGB = (vm.mem / 1024 ** 3).toFixed(1) const maxMemGB = (vm.maxmem / 1024 ** 3).toFixed(1) return (
{vm.name} VM
ID: {vm.vmid}
{getStatusIcon(vm.status)} {vm.status.toUpperCase()}
CPU Usage
{cpuPercent}%
Memory Usage
{memGB} GB / {maxMemGB} GB
Uptime
{formatUptime(vm.uptime)}
) })}
)}
) }