"use client" import { useState, useEffect } from "react" import { Card, CardContent, CardHeader, CardTitle } from "./ui/card" import { Progress } from "./ui/progress" import { Badge } from "./ui/badge" import { Cpu, MemoryStick, Thermometer, Server, Zap, AlertCircle, HardDrive, Network } from "lucide-react" interface SystemData { cpu_usage: number memory_usage: number memory_total: number memory_used: number temperature: number uptime: string load_average: number[] hostname: string node_id: string timestamp: string cpu_cores?: number proxmox_version?: string kernel_version?: string available_updates?: number } interface VMData { vmid: number name: string status: string cpu: number mem: number maxmem: number disk: number maxdisk: number uptime: number type?: string } interface StorageData { total: number used: number available: number disks: Array<{ name: string mountpoint: string total: number used: number available: number usage_percent: number }> } interface NetworkData { interfaces: Array<{ name: string status: string addresses: Array<{ ip: string; netmask: string }> }> traffic: { bytes_sent: number bytes_recv: number packets_sent: number packets_recv: number } } const fetchSystemData = async (): Promise => { try { const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" const apiUrl = `${baseUrl}/api/system` const response = await fetch(apiUrl, { method: "GET", headers: { "Content-Type": "application/json", }, cache: "no-store", }) if (!response.ok) { throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() return data } catch (error) { console.error("[v0] Failed to fetch system data:", error) return null } } const fetchVMData = async (): Promise => { try { const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" const apiUrl = `${baseUrl}/api/vms` const response = await fetch(apiUrl, { method: "GET", headers: { "Content-Type": "application/json", }, cache: "no-store", }) if (!response.ok) { throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() return Array.isArray(data) ? data : data.vms || [] } catch (error) { console.error("[v0] Failed to fetch VM data:", error) return [] } } const fetchStorageData = async (): Promise => { try { const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" const apiUrl = `${baseUrl}/api/storage` const response = await fetch(apiUrl, { method: "GET", headers: { "Content-Type": "application/json", }, cache: "no-store", }) if (!response.ok) { throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() return data } catch (error) { console.error("[v0] Failed to fetch storage data:", error) return null } } const fetchNetworkData = async (): Promise => { try { const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" const apiUrl = `${baseUrl}/api/network` const response = await fetch(apiUrl, { method: "GET", headers: { "Content-Type": "application/json", }, cache: "no-store", }) if (!response.ok) { throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() return data } catch (error) { console.error("[v0] Failed to fetch network data:", error) return null } } export function SystemOverview() { const [systemData, setSystemData] = useState(null) const [vmData, setVmData] = useState([]) const [storageData, setStorageData] = useState(null) const [networkData, setNetworkData] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { const fetchData = async () => { try { setLoading(true) setError(null) const [systemResult, vmResult, storageResult, networkResult] = await Promise.all([ fetchSystemData(), fetchVMData(), fetchStorageData(), fetchNetworkData(), ]) if (!systemResult) { setError("Flask server not available. Please ensure the server is running.") setLoading(false) return } setSystemData(systemResult) setVmData(vmResult) setStorageData(storageResult) setNetworkData(networkResult) } catch (err) { console.error("[v0] Error fetching data:", err) setError("Failed to connect to Flask server. Please check your connection.") } finally { setLoading(false) } } fetchData() const interval = setInterval(() => { fetchData() }, 60000) // Update every 60 seconds instead of 30 return () => { clearInterval(interval) } }, []) if (loading) { return (
Connecting to ProxMenux Monitor...
Fetching real-time system data
{[...Array(4)].map((_, i) => (
))}
) } if (error || !systemData) { return (
Flask Server Not Available
{error || "Unable to connect to the Flask server. Please ensure the server is running and try again."}
) } const vmStats = { total: vmData.length, running: vmData.filter((vm) => vm.status === "running").length, stopped: vmData.filter((vm) => vm.status === "stopped").length, lxc: vmData.filter((vm) => vm.type === "lxc").length, vms: vmData.filter((vm) => vm.type === "qemu" || !vm.type).length, } const getTemperatureStatus = (temp: number) => { if (temp === 0) return { status: "N/A", color: "bg-gray-500/10 text-gray-500 border-gray-500/20" } if (temp < 60) return { status: "Normal", color: "bg-green-500/10 text-green-500 border-green-500/20" } if (temp < 75) return { status: "Warm", color: "bg-yellow-500/10 text-yellow-500 border-yellow-500/20" } return { status: "Hot", color: "bg-red-500/10 text-red-500 border-red-500/20" } } const tempStatus = getTemperatureStatus(systemData.temperature) return (
{/* Key Metrics Cards */}
CPU Usage
{systemData.cpu_usage}%

Real-time data from Flask server

Memory Usage
{systemData.memory_used.toFixed(1)} GB

{systemData.memory_usage.toFixed(1)}% of {systemData.memory_total} GB

Temperature
{systemData.temperature === 0 ? "N/A" : `${systemData.temperature}°C`}
{tempStatus.status}

{systemData.temperature === 0 ? "No sensor available" : "Live temperature reading"}

Active VM & LXC
{vmStats.running}
{vmStats.running} Running {vmStats.stopped > 0 && ( {vmStats.stopped} Stopped )}

Total: {vmStats.vms} VMs, {vmStats.lxc} LXC

{/* Storage Summary */} Storage Overview {storageData ? (
Total Storage: {storageData.total} GB
Used: {storageData.used} GB
Available: {storageData.available} GB

{storageData.disks.length} disk{storageData.disks.length !== 1 ? "s" : ""} configured

) : (
Storage data not available
)}
{/* Network Summary */} Network Overview {networkData ? (
Active Interfaces: {networkData.interfaces.filter((i) => i.status === "up").length}
Data Sent: {(networkData.traffic.bytes_sent / 1024 ** 3).toFixed(2)} GB
Data Received: {(networkData.traffic.bytes_recv / 1024 ** 3).toFixed(2)} GB
{networkData.interfaces.slice(0, 3).map((iface) => (
{iface.name}: {iface.status}
))}
) : (
Network data not available
)}
{/* System Information */}
System Information
Uptime: {systemData.uptime}
Proxmox Version: {systemData.proxmox_version || "N/A"}
Kernel: {systemData.kernel_version || "Linux"}
{systemData.available_updates !== undefined && systemData.available_updates > 0 && (
Available Updates: {systemData.available_updates} packages
)}
Performance Metrics
Load Average: (1m, 5m, 15m)
{systemData.load_average.map((avg) => avg.toFixed(2)).join(", ")}
Total Memory: {systemData.memory_total} GB
Available Memory: {(systemData.memory_total - systemData.memory_used).toFixed(1)} GB
CPU Cores: {systemData.cpu_cores || "N/A"}
) }