// public/views/cards/host_perf.js import { el, mount } from '../../dom.js'; import { api } from '../../api.js'; let body, timer, prev; const GB = 1024 ** 3; function bar(pct) { return el('div', { class: 'sv-bar' }, el('i', { style: { width: Math.min(100, pct) + '%' } })); } async function load() { if (!body) return; try { const h = await api.get('/api/host'); let rate = ''; if (prev) { const dt = (h.at - prev.at) / 1000 || 1; const dn = (b) => ((b) / dt / 1e6).toFixed(1); rate = `โ†“${dn(h.net.rx_bytes - prev.net.rx_bytes)} โ†‘${dn(h.net.tx_bytes - prev.net.tx_bytes)} MB/s`; } prev = h; mount(body, el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'CPU'), el('span', {}, h.cpu_pct + '%')), bar(h.cpu_pct), el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'RAM'), el('span', {}, `${(h.mem.used / GB).toFixed(1)} / ${(h.mem.total / GB).toFixed(0)} GB`)), bar(h.mem.pct), el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'DISK'), el('span', {}, h.disk.pct + '%')), bar(h.disk.pct), el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'NET'), el('span', {}, rate || 'โ€”')) ); } catch { mount(body, el('span', { class: 'muted' }, 'Host unavailable')); } } export default { id: 'host-perf', title: 'Host Perf ยท CT 311', size: 'm', mount(el_) { body = el_; prev = null; load(); }, start() { timer = setInterval(load, 30000); }, stop() { clearInterval(timer); body = null; } };