// Panel formatters
export function fmtBytes(value) {
if (!value && value !== 0) return '—'
const units = ['B', 'KB', 'MB', 'GB', 'TB']
let v = value
let i = 0
while (v >= 1024 && i < units.length - 1) {
v /= 1024
i++
}
const digits = v >= 100 ? 0 : v >= 10 ? 1 : 2
return `${v.toFixed(digits)} ${units[i]}`
}
export function fmtGiB(bytes) {
if (!bytes && bytes !== 0) return '—'
return (bytes / 2 ** 30).toFixed(1) + ' GiB'
}
export function fmtPercent(value) {
if (value === null || value === undefined) return '—'
return `${Math.round(value * 10) / 10}%`
}
export function fmtMbs(value) {
if (value === null || value === undefined) return '—'
if (value < 0.01) return '0 MB/s'
if (value < 1) return `${Math.round(value * 100) / 100} MB/s`
return `${Math.round(value * 10) / 10} MB/s`
}
export function fmtUptime(seconds) {
if (!seconds && seconds !== 0) return '—'
const days = Math.floor(seconds / 86400)
const hours = Math.floor((seconds % 86400) / 3600)
if (days > 0) return `${days}d ${hours}h`
const minutes = Math.floor((seconds % 3600) / 60)
if (hours > 0) return `${hours}h ${minutes}m`
return `${minutes}m ${Math.floor(seconds % 60)}s`
}
export function fmtAgo(iso) {
if (!iso) return 'never'
const seconds = Math.floor((Date.now() - new Date(iso).getTime()) / 1000)
if (seconds < 5) return 'just now'
if (seconds < 60) return `${seconds}s ago`
if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`
return `${Math.floor(seconds / 86400)}d ago`
}
export function ramPercent(metrics) {
if (!metrics || !metrics.ram || !metrics.ram.total) return null
return (metrics.ram.used / metrics.ram.total) * 100
}