diff --git a/AppImage/components/system-overview.tsx b/AppImage/components/system-overview.tsx index 6c11a6d..ab853f9 100644 --- a/AppImage/components/system-overview.tsx +++ b/AppImage/components/system-overview.tsx @@ -40,6 +40,7 @@ interface StorageData { total: number used: number available: number + disk_count: number disks: Array<{ name: string mountpoint: string @@ -64,6 +65,18 @@ interface NetworkData { } } +interface ProxmoxStorageData { + storage: Array<{ + name: string + type: string + status: string + total: number + used: number + available: number + percent: number + }> +} + const fetchSystemData = async (): Promise => { try { const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" @@ -166,10 +179,37 @@ const fetchNetworkData = async (): Promise => { } } +const fetchProxmoxStorageData = async (): Promise => { + try { + const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" + const apiUrl = `${baseUrl}/api/proxmox-storage` + + const response = await fetch(apiUrl, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + cache: "no-store", + }) + + if (!response.ok) { + console.log("[v0] Proxmox storage API not available") + return null + } + + const data = await response.json() + return data + } catch (error) { + console.log("[v0] Proxmox storage data unavailable:", error instanceof Error ? error.message : "Unknown error") + return null + } +} + export function SystemOverview() { const [systemData, setSystemData] = useState(null) const [vmData, setVmData] = useState([]) const [storageData, setStorageData] = useState(null) + const [proxmoxStorageData, setProxmoxStorageData] = useState(null) const [networkData, setNetworkData] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) @@ -228,6 +268,9 @@ export function SystemOverview() { const fetchStorage = async () => { const storageResult = await fetchStorageData() setStorageData(storageResult) + + const proxmoxStorageResult = await fetchProxmoxStorageData() + setProxmoxStorageData(proxmoxStorageResult) } fetchStorage() @@ -310,8 +353,27 @@ export function SystemOverview() { return { status: "Hot", color: "bg-red-500/10 text-red-500 border-red-500/20" } } + const formatUptime = (seconds: number) => { + if (!seconds || seconds === 0) return "Stopped" + const days = Math.floor(seconds / 86400) + const hours = Math.floor((seconds % 86400) / 3600) + const minutes = Math.floor((seconds % 3600) / 60) + + if (days > 0) return `${days}d ${hours}h` + if (hours > 0) return `${hours}h ${minutes}m` + return `${minutes}m` + } + + const formatBytes = (bytes: number) => { + return (bytes / 1024 ** 3).toFixed(2) + } + const tempStatus = getTemperatureStatus(systemData.temperature) + const localStorage = proxmoxStorageData?.storage.find( + (s) => s.name === "local-lvm" || s.name === "local-zfs" || s.name === "local", + ) + return (
{/* Key Metrics Cards */} @@ -399,22 +461,52 @@ export function SystemOverview() { {storageData ? (
-
- Total Storage: - {storageData.total} GB +
+ Total Capacity: + {storageData.total} TB
-
- Used: - {storageData.used} GB -
-
- Available: - {storageData.available} GB -
- + + {localStorage ? ( + <> +
+
System Storage ({localStorage.name})
+
+ Used: + {localStorage.used} GB +
+
+ Available: + {localStorage.available} GB +
+ +
+ + {localStorage.used} / {localStorage.total} GB + + {localStorage.percent.toFixed(1)}% +
+
+ + ) : ( + <> +
+ Used: + {storageData.used} GB +
+
+ Available: + {storageData.available} GB +
+ + + )} +

- {storageData.disks.length} disk{storageData.disks.length !== 1 ? "s" : ""} configured + {storageData.disk_count} physical disk{storageData.disk_count !== 1 ? "s" : ""} configured

@@ -545,6 +637,85 @@ export function SystemOverview() {
+ + {vmData.length > 0 && ( + + + +
+ + Virtual Machines & Containers +
+ + {vmData.length} Total + +
+
+ +
+ {vmData.map((vm) => ( + + +
+
+
{vm.name}
+
+ {vm.type === "lxc" ? "LXC" : "VM"} #{vm.vmid} +
+
+ + {vm.status} + +
+ +
+
+
+ CPU + {(vm.cpu * 100).toFixed(1)}% +
+ +
+ +
+
+ Memory + + {formatBytes(vm.mem)} / {formatBytes(vm.maxmem)} GB + +
+ +
+ +
+
+ Disk + + {formatBytes(vm.disk)} / {formatBytes(vm.maxdisk)} GB + +
+ +
+ +
+ Uptime + {formatUptime(vm.uptime)} +
+
+
+
+ ))} +
+
+
+ )}
) }