syco.me Homelab Dashboard

This commit is contained in:
2026-05-10 21:23:42 +02:00
parent 933e492d15
commit 90de2c1674
45 changed files with 6666 additions and 0 deletions
+77
View File
@@ -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>
)
}