diff --git a/app/sovran_systemsos_web/static/css/buttons.css b/app/sovran_systemsos_web/static/css/buttons.css index c90487d..2276dcd 100644 --- a/app/sovran_systemsos_web/static/css/buttons.css +++ b/app/sovran_systemsos_web/static/css/buttons.css @@ -62,22 +62,23 @@ button:disabled { background: rgba(255, 255, 255, 0.04); } -/* Amber — destructive-ish confirmations (restart, reboot, retry) */ +/* Blue — restart / retry actions (amber reads as an error) */ .btn-amber, .btn-reboot, .btn-restart-amber, .btn-warning { - background: rgba(233, 182, 74, 0.10); - border-color: rgba(233, 182, 74, 0.32); - color: #f2c45e; + background: rgba(120, 174, 237, 0.10); + border-color: rgba(120, 174, 237, 0.35); + color: #a5cbf2; } .btn-amber:hover:not(:disabled), .btn-reboot:hover:not(:disabled), .btn-restart-amber:hover:not(:disabled), .btn-warning:hover:not(:disabled) { - background: rgba(233, 182, 74, 0.18); - border-color: rgba(233, 182, 74, 0.5); + background: rgba(120, 174, 237, 0.18); + border-color: rgba(120, 174, 237, 0.55); + color: #c2dcf8; } .btn-danger { @@ -96,9 +97,9 @@ button:disabled { /* ── Header / topbar buttons ────────────────────────────────────── */ .btn-header-reboot { - background: rgba(233, 182, 74, 0.10); - border: 1px solid rgba(233, 182, 74, 0.32); - color: #f2c45e; + background: rgba(120, 174, 237, 0.10); + border: 1px solid rgba(120, 174, 237, 0.35); + color: #a5cbf2; font-size: 0.77rem; font-weight: 700; padding: 6px 14px; @@ -106,8 +107,8 @@ button:disabled { } .btn-header-reboot:hover:not(:disabled) { - background: rgba(233, 182, 74, 0.18); - border-color: rgba(233, 182, 74, 0.5); + background: rgba(120, 174, 237, 0.18); + border-color: rgba(120, 174, 237, 0.55); } .btn-logout { diff --git a/app/sovran_systemsos_web/static/js/dashboard.js b/app/sovran_systemsos_web/static/js/dashboard.js index fa397fc..803317e 100644 --- a/app/sovran_systemsos_web/static/js/dashboard.js +++ b/app/sovran_systemsos_web/static/js/dashboard.js @@ -208,12 +208,6 @@ /* ── Systems Operational modal ───────────────────────────────── */ - function internalIp() { - var el = document.getElementById("ip-internal"); - var v = el ? el.textContent.trim() : ""; - return (v && v !== "…" && v !== "—") ? v : ""; - } - function step(n, title, sub, value) { return '
' + n + '
' + '
' + title + (sub ? ' · ' + sub + '' : '') + '
' + @@ -250,9 +244,6 @@ else running++; }); - var ip = internalIp(); - var fwd = ip ? ('\u2192 ' + escHtml(ip)) : "forward to this computer"; - var html = ""; /* System status */ @@ -263,32 +254,23 @@ step(3, "Turned off", "", off ? escHtml(offNames.join(", ")) : "None") + '
'; - /* Router ports — repo wording (domain-prereqs.js / server.py). - Node-only role: ports matter only once BTCPay Server or Lightning - Wallet Connections (LNURL) is turned on — until then, no router task. */ + /* Router — a simple open / not-open verdict. How to open the ports is + covered during onboarding, so the modal does not repeat instructions. + Node-only role: ports only matter once BTCPay Server or Lightning + Wallet Connections (LNURL) is turned on. */ if (isNodeRole() && !hasEnabledDomainService(services)) { html += '
' + '
' + icon("g-wifi") + 'Router
' + '
' + icon("g-check") + 'No router setup needed yet
' + - '
Ports 80 and 443 only need to be forwarded on your router if you turn on BTCPay Server or Lightning Wallet Connections (LNURL). If you enable one of them, come back here — this card will show exactly what to do.
' + + '
Ports 80 and 443 only need to be forwarded on your router if you turn on BTCPay Server or Lightning Wallet Connections (LNURL). If you enable one of them, come back here to check your ports.
' + '
'; } else { - html += '
' + - '
' + icon("g-wifi") + 'Router — Ports to Forward
' + - step(1, "Port 80", "TCP — HTTP (redirect to HTTPS)", fwd) + - step(2, "Port 443", "TCP — HTTPS", fwd) + - '
' + icon("g-alert") + 'One router task
' + - '
Set the internal and external port to the same number. You only need to do this once — all your services share these two ports.
' + + html += ''; } - /* Live domain diagnostics (sequential checklist from the backend — - same data the domain-service modals show) */ - html += ''; - /* Who uses these ports (redundant on a Node install with no domain services on — the router note above already covers it) */ if (!isNodeRole() || hasEnabledDomainService(services)) { @@ -300,33 +282,32 @@ $sysBody.innerHTML = html; $sysModal.classList.add("open"); - /* Poll the first configured domain service for its live checklist */ - var checkCard = document.getElementById("sys-check-card"); - var stepsEl = document.getElementById("sys-check-steps"); + /* Poll the first configured domain service and reduce its diagnostics + to one verdict: the ports are open or they are not. */ + var portsCard = document.getElementById("sys-ports-card"); + var portsEl = document.getElementById("sys-ports-status"); var units = DOMAIN_UNITS.filter(function (u) { return services.some(function (s) { return s.unit === u && s.enabled; }); }); - if (!units.length || !checkCard || !stepsEl) return; - checkCard.style.display = ""; + if (!units.length || !portsCard || !portsEl) return; + portsCard.style.display = ""; apiFetch("/api/service-detail/" + encodeURIComponent(units[0])) .then(function (data) { var steps = (data && data.domain_check_steps) || []; - if (!steps.length) { checkCard.style.display = "none"; return; } - var mark = { ok: "\u2705", error: "\u274c", warning: "\u26a0\ufe0f", skipped: "\u23ed\ufe0f" }; - var html2 = ""; - steps.forEach(function (st) { - var m = mark[st.status] || "\u2014"; - var detail = escHtml(st.detail || "").replace(/\n/g, "
"); - html2 += '
' + st.step + '
' + - '
' + m + " " + escHtml(st.label || "") + '
' + - (detail ? '
' + detail + '
' : '') + - '
'; + var portsStep = null; + steps.forEach(function (s) { + if (Number(s.step) === 3 || /ports?\s*80/i.test(s.label || "")) portsStep = s; }); - stepsEl.innerHTML = html2; + if (!portsStep) { portsCard.style.display = "none"; return; } + if (portsStep.status === "ok") { + portsEl.innerHTML = '
Ports 80 and 443 are open
'; + } else { + portsEl.innerHTML = '
Ports 80 and 443 are not open
'; + } }) .catch(function () { - checkCard.style.display = "none"; + portsCard.style.display = "none"; }); } diff --git a/app/sovran_systemsos_web/static/js/service-detail.js b/app/sovran_systemsos_web/static/js/service-detail.js index 41e4551..7f8b1a8 100644 --- a/app/sovran_systemsos_web/static/js/service-detail.js +++ b/app/sovran_systemsos_web/static/js/service-detail.js @@ -725,16 +725,20 @@ async function openServiceDetailModal(unit, name, icon) { }); var stepsHtml = ""; steps.forEach(function(step) { - var iconLabel = "—"; - if (step.status === "ok") iconLabel = "✅"; - else if (step.status === "error") iconLabel = "❌"; - else if (step.status === "warning") iconLabel = "⚠️"; - else if (step.status === "skipped") iconLabel = "⏭️"; var detail = escHtml(step.detail || "").replace(/\n/g, "
"); - stepsHtml += '
' + - '' + iconLabel + ' Step ' + escHtml(String(step.step)) + ': ' + escHtml(step.label || "") + '' + - (detail ? '
' + detail + '
' : '') + - '
'; + if (step.status === "ok") { + // Not a checklist anymore — just note that the domain works. + stepsHtml += '
Domain is active
' + + (detail ? '
' + detail + '
' : ''); + } else { + var iconLabel = "❌"; + if (step.status === "warning") iconLabel = "⚠️"; + else if (step.status === "skipped") iconLabel = "⏭️"; + stepsHtml += '
' + + '' + iconLabel + ' ' + escHtml(step.label || "Domain not configured") + '' + + (detail ? '
' + detail + '
' : '') + + '
'; + } }); var domainActionHtml = ""; @@ -746,7 +750,7 @@ async function openServiceDetailModal(unit, name, icon) { } addSetup('
' + - '
Domain Diagnostic Checklist
' + + '
Domain Status
' + stepsHtml + domainActionHtml + '
');