+ {/* ── Total Storage (preview restyle: headline + stacked bar Local·Remote·Free) ── */}
+ {(() => {
+ const totalGB = (totalLocalCapacity || 0) + (totalRemoteCapacity || 0)
+ const localPct = totalGB > 0 ? (totalLocalUsed / totalGB) * 100 : 0
+ const remotePct = totalGB > 0 ? (totalRemoteUsed / totalGB) * 100 : 0
+ const freeGB = Math.max(0, totalGB - totalLocalUsed - totalRemoteUsed)
+ return (
+
+
+ Storage Used
+
+
+
+ {(() => {
+ const totalUsed = totalLocalUsed + totalRemoteUsed
+ const usedStr = formatStorage(totalUsed)
+ return (
+
+
+ {usedStr.split(' ')[0]}
+ {usedStr.split(' ')[1]}
+
+
{storageData.disk_count} disks
+
+ )
+ })()}
+
+
+
+ Local
+ {formatStorage(totalLocalUsed)}
+
+
+ Remote
+ {formatStorage(totalRemoteUsed)}
+
+
+ Free
+ {formatStorage(freeGB)}
+
+
+
+
+ )
+ })()}
-
-
- Local Used
-
-
-
- {formatStorage(totalLocalUsed)}
-
- {localUsagePercent}%
- of
- {formatStorage(totalLocalCapacity)}
-
-
-
+ {/* ── Local Used (preview restyle: donut + mini-bars Used/Free) ── */}
+ {(() => {
+ const pct = Number.parseFloat(localUsagePercent)
+ const freeGB = Math.max(0, totalLocalCapacity - totalLocalUsed)
+ const stroke = pct >= 90 ? '#ef4444' : pct >= 75 ? '#f59e0b' : '#22c55e'
+ return (
+
+
+ Local Used
+
+
+
+
+
+
+
+
+ Used
+ {formatStorage(totalLocalUsed)}
+
+
+
+
+
+ Free
+ {formatStorage(freeGB)}
+
+
+
+
+ Total
+ {formatStorage(totalLocalCapacity)}
+
+
+
+
+
+ )
+ })()}
-
-
- Remote Used
-
-
-
-
- {remoteStorageCount > 0 ? formatStorage(totalRemoteUsed) : "None"}
-
-
- {remoteStorageCount > 0 ? (
- <>
- {remoteUsagePercent}%
- of
- {formatStorage(totalRemoteCapacity)}
- >
- ) : (
- No remote storage
- )}
-
-
-
+ {/* ── Remote Used (preview restyle: donut + mini-bars Used/Free) ── */}
+ {(() => {
+ const has = remoteStorageCount > 0
+ const pct = has ? Number.parseFloat(remoteUsagePercent) : 0
+ const freeGB = has ? Math.max(0, totalRemoteCapacity - totalRemoteUsed) : 0
+ const stroke = pct >= 90 ? '#ef4444' : pct >= 75 ? '#f59e0b' : '#22c55e'
+ return (
+
+
+ Remote Used
+
+
+
+ {has ? (
+
+
+
+
+
+ Used
+ {formatStorage(totalRemoteUsed)}
+
+
+
+
+
+ Free
+ {formatStorage(freeGB)}
+
+
+
+
+ Total
+ {formatStorage(totalRemoteCapacity)}
+
+
+
+ ) : (
+
+
None
+
No remote storage
+
+ )}
+
+
+ )
+ })()}
-
-
- Physical Disks
-
-
-
- {storageData.disk_count} disks
-
-
- {diskTypesBreakdown.nvme > 0 && {diskTypesBreakdown.nvme} NVMe}
- {diskTypesBreakdown.ssd > 0 && (
- <>
- {diskTypesBreakdown.nvme > 0 && ", "}
- {diskTypesBreakdown.ssd} SSD
- >
- )}
- {diskTypesBreakdown.hdd > 0 && (
- <>
- {(diskTypesBreakdown.nvme > 0 || diskTypesBreakdown.ssd > 0) && ", "}
- {diskTypesBreakdown.hdd} HDD
- >
- )}
- {diskTypesBreakdown.usb > 0 && (
- <>
- {(diskTypesBreakdown.nvme > 0 || diskTypesBreakdown.ssd > 0 || diskTypesBreakdown.hdd > 0) && ", "}
- {diskTypesBreakdown.usb} USB
- >
- )}
-
-
- {diskHealthBreakdown.normal} normal
- {diskHealthBreakdown.warning > 0 && (
- <>
- {", "}
- {diskHealthBreakdown.warning} warning
- >
- )}
- {diskHealthBreakdown.critical > 0 && (
- <>
- {", "}
- {diskHealthBreakdown.critical} critical
- >
- )}
-
-
-
-
+ {/* ── Physical Disks (preview restyle: headline + type strip + health badge) ── */}
+ {(() => {
+ const total = Math.max(1, storageData.disk_count || 0)
+ const seg = 100 / total
+ const allHealthy = diskHealthBreakdown.warning === 0 && diskHealthBreakdown.critical === 0
+ const healthBadge = allHealthy
+ ?
✓ all healthy
+ : diskHealthBreakdown.critical > 0
+ ?
{diskHealthBreakdown.critical} critical
+ :
{diskHealthBreakdown.warning} warning
+ const seg_purple = '#a855f7'
+ const seg_cyan = '#06b6d4'
+ const seg_blue = '#3b82f6'
+ const seg_orange = '#f97316'
+ const segments: Array<{ color: string }> = []
+ for (let i = 0; i < diskTypesBreakdown.nvme; i++) segments.push({ color: seg_purple })
+ for (let i = 0; i < diskTypesBreakdown.ssd; i++) segments.push({ color: seg_cyan })
+ for (let i = 0; i < diskTypesBreakdown.hdd; i++) segments.push({ color: seg_blue })
+ for (let i = 0; i < diskTypesBreakdown.usb; i++) segments.push({ color: seg_orange })
+ return (
+
+
+ Physical Disks
+
+
+
+
+
+ {storageData.disk_count}
+ disks
+
+ {healthBadge}
+
+
+ {segments.map((s, i) => (
+
+ ))}
+
+
+ {diskTypesBreakdown.nvme > 0 && {diskTypesBreakdown.nvme} NVMe}
+ {diskTypesBreakdown.ssd > 0 && {diskTypesBreakdown.ssd} SSD}
+ {diskTypesBreakdown.hdd > 0 && {diskTypesBreakdown.hdd} HDD}
+ {diskTypesBreakdown.usb > 0 && {diskTypesBreakdown.usb} USB}
+
+
+
+ )
+ })()}
{proxmoxStorage && proxmoxStorage.storage && proxmoxStorage.storage.length > 0 && (
@@ -1477,7 +1587,7 @@ export function StorageOverview() {