Fix panel

This commit is contained in:
2026-05-10 18:14:16 -03:00
parent 77a722d4ed
commit e00a7bd93c
4 changed files with 155 additions and 38 deletions

View File

@@ -9,6 +9,7 @@ let tlsForwardersState = [];
let editingXrayClientId = null;
let wzInbounds = [];
let dashboardCache = { sshUsers: [], xrayInbounds: [], me: null };
let currentTab = "dashboard";
// ─── DOM refs ─────────────────────────────────────────────────────────────────
const loginOverlay = document.getElementById("loginOverlay");
@@ -206,6 +207,7 @@ const tabTitles = {
};
function selectTab(tab) {
currentTab = tab;
const pane = document.getElementById("tab-" + tab);
const btn = document.querySelector(`.tab-btn[data-tab="${tab}"]`);
if (!pane || !btn) return;
@@ -311,14 +313,18 @@ function initAfterLogin() {
selectTab("dashboard");
if (currentRole === "superadmin") {
loadStats();
statsTimer = setInterval(loadStats, 2000);
loadDashboardStats();
statsTimer = setInterval(() => {
loadDashboardStats();
if (currentTab === "stats") loadStats();
}, 2000);
} else {
loadMe();
}
xrayTimer = setInterval(loadXrayStatus, 7000);
xrayTimer = setInterval(() => { loadXrayStatus(); if (currentTab === "xray") loadInbounds(); }, 7000);
loadUsers();
loadXrayStatus();
loadInbounds();
usersTimer = setInterval(() => loadUsersSilent(), 3000);
}
@@ -1072,6 +1078,22 @@ async function deleteReseller(username) {
// ─── Stats ────────────────────────────────────────────────────────────────────
document.querySelector("[data-tab='stats']")?.addEventListener("click", loadStats);
async function loadDashboardStats() {
try {
const res = await api("/api/stats");
if (!res.ok) throw new Error(await res.text());
const s = await res.json();
updateDashboardStats(s);
} catch (e) {
if (e.message === "auth") doAuthError();
else {
if (dashCpuVal) dashCpuVal.textContent = "erro";
if (dashRamVal) dashRamVal.textContent = "erro";
if (dashNetVal) dashNetVal.textContent = "erro";
}
}
}
function updateDashboardStats(s) {
if (!s) return;
const cpu = Number(s.cpu_percent ?? 0);
@@ -1101,28 +1123,33 @@ function updateDashboardStats(s) {
async function loadStats() {
try {
const res = await api("/api/stats");
if (!res.ok) throw new Error(await res.text());
const s = await res.json();
updateDashboardStats(s);
const cpu = s?.cpu_percent ?? 0;
cpuVal.textContent = fmtPct(cpu);
cpuBar.style.width = Math.min(100, Math.max(0, cpu)) + "%";
const mp = s?.mem_percent ?? null;
memVal.textContent = mp == null ? "--%" : fmtPct(mp);
memBar.style.width = mp == null ? "0%" : Math.min(100, Math.max(0, mp)) + "%";
const cpu = Number(s?.cpu_percent ?? 0);
if (cpuVal) cpuVal.textContent = fmtPct(cpu);
if (cpuBar) cpuBar.style.width = Math.min(100, Math.max(0, cpu)) + "%";
const mp = s?.mem_percent == null ? null : Number(s.mem_percent);
if (memVal) memVal.textContent = mp == null ? "--%" : fmtPct(mp);
if (memBar) memBar.style.width = mp == null ? "0%" : Math.min(100, Math.max(0, mp)) + "%";
const mu = s?.mem_used_bytes, mt = s?.mem_total_bytes;
memDetail.textContent = (mu != null && mt != null) ? `${fmtBytes(mu)} / ${fmtBytes(mt)}` : "";
if (memDetail) memDetail.textContent = (mu != null && mt != null) ? `${fmtBytes(mu)} / ${fmtBytes(mt)}` : "";
const ifaces = Array.isArray(s.interfaces) ? s.interfaces : [];
ifaceBody.innerHTML = "";
if (ifaceBody) ifaceBody.innerHTML = "";
let totRx = 0, totTx = 0;
ifaces.forEach(it => {
totRx += it.rx_bytes||0; totTx += it.tx_bytes||0;
totRx += Number(it.rx_bytes||0); totTx += Number(it.tx_bytes||0);
if (!ifaceBody) return;
const tr = document.createElement("tr");
tr.innerHTML = `<td>${it.name}</td><td>${fmtMbps(it.rx_mbps)}</td><td>${fmtMbps(it.tx_mbps)}</td><td>${fmtBytes(it.rx_bytes)}</td><td>${fmtBytes(it.tx_bytes)}</td>`;
ifaceBody.appendChild(tr);
});
ifaceSummary.textContent = `Total: ${fmtBytes(totRx)} rx / ${fmtBytes(totTx)} tx`;
statsUpdated.textContent = "Updated: " + new Date().toLocaleTimeString();
} catch (e) { if (e.message==="auth") doAuthError(); }
if (ifaceSummary) ifaceSummary.textContent = `Total: ${fmtBytes(totRx)} rx / ${fmtBytes(totTx)} tx`;
if (statsUpdated) statsUpdated.textContent = "Updated: " + new Date().toLocaleTimeString();
} catch (e) {
if (e.message==="auth") doAuthError();
else if (statsUpdated) statsUpdated.textContent = "Erro ao carregar stats.";
}
}
resetIfaceStatsBtn?.addEventListener("click", resetInterfaceStats);

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8"/>
<title>DragonCore Panel</title>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<link rel="stylesheet" href="assets/app.css"/>
<link rel="stylesheet" href="assets/app.css?v=20260510xraystats2"/>
</head>
<body>
<div class="app">
@@ -876,6 +876,6 @@
</div><!-- /shell -->
</div><!-- /app -->
<script defer src="assets/app.js"></script>
<script defer src="assets/app.js?v=20260510xraystats2"></script>
</body>
</html>