syco.me Homelab Dashboard
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import { useApi } from '../../hooks/useApi'
|
||||
import { ProxmoxData } from '../../types'
|
||||
import { formatBytes, formatUptime, pct, barColor } from '../../utils'
|
||||
|
||||
function ProgressBar({ label, value, total, color, valueLabel }: {
|
||||
label: string; value: number; total: number; color: string; valueLabel?: string
|
||||
}) {
|
||||
const p = pct(value, total)
|
||||
return (
|
||||
<div>
|
||||
<div className="progress-header">
|
||||
<span className="progress-name">{label}</span>
|
||||
<span className="progress-val">{valueLabel ?? `${p}% · ${formatBytes(value)} / ${formatBytes(total)}`}</span>
|
||||
</div>
|
||||
<div className="progress-track">
|
||||
<div className={`progress-fill ${color}`} style={{ width: `${p}%` }} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function ProxmoxWidget() {
|
||||
const { data, loading, error } = useApi<ProxmoxData>('/api/proxmox/status')
|
||||
|
||||
return (
|
||||
<div className="card">
|
||||
<div className="widget-header">
|
||||
<div className="widget-title">
|
||||
<span className="dot" style={{ background: 'var(--accent)' }} />
|
||||
Proxmox VE
|
||||
</div>
|
||||
<div className="widget-badge">M920q</div>
|
||||
</div>
|
||||
|
||||
{loading && <div className="widget-loading">Connecting…</div>}
|
||||
{error && <div className="widget-error">⚠ {error}</div>}
|
||||
|
||||
{data && (
|
||||
<>
|
||||
<div className="node-name">{data.node}</div>
|
||||
<div className="node-uptime">↑ {formatUptime(data.uptime)}</div>
|
||||
|
||||
<div className="progress-group">
|
||||
<ProgressBar
|
||||
label="CPU"
|
||||
value={data.cpu}
|
||||
total={1}
|
||||
color={barColor(Math.round(data.cpu * 100))}
|
||||
valueLabel={`${Math.round(data.cpu * 100)}%`}
|
||||
/>
|
||||
<ProgressBar label="RAM" value={data.memory.used} total={data.memory.total} color={barColor(pct(data.memory.used, data.memory.total))} />
|
||||
{data.storages.map(st => (
|
||||
<ProgressBar
|
||||
key={st.name}
|
||||
label={st.name}
|
||||
value={st.used}
|
||||
total={st.total}
|
||||
color={barColor(pct(st.used, st.total))}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="stat-row" style={{ marginTop: 14 }}>
|
||||
<div className="stat-item">
|
||||
<div className="stat-value accent">{data.lxcCount}</div>
|
||||
<div className="stat-label">LXC running</div>
|
||||
</div>
|
||||
<div className="stat-item">
|
||||
<div className="stat-value">{data.vmCount}</div>
|
||||
<div className="stat-label">VMs</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user