diff --git a/hbd/server/templates/plugins.html b/hbd/server/templates/plugins.html index a74de89..d295beb 100644 --- a/hbd/server/templates/plugins.html +++ b/hbd/server/templates/plugins.html @@ -152,6 +152,31 @@ } .host-action-btn.delete-btn:hover { background: #ffcdd2; } + /* ── Action result toast ───────────────────────────────────── */ + #action-toast { + position: fixed; + bottom: 24px; + left: 50%; + transform: translateX(-50%) translateY(20px); + background: #323232; + color: #fff; + padding: 12px 22px; + border-radius: 6px; + font-size: 0.9em; + max-width: 480px; + text-align: center; + opacity: 0; + pointer-events: none; + transition: opacity 0.25s, transform 0.25s; + z-index: 9000; + white-space: pre-wrap; + } + #action-toast.show { + opacity: 1; + transform: translateX(-50%) translateY(0); + } + #action-toast.error { background: #c62828; } + /* ── Host body ──────────────────────────────────────────────── */ .host-body { @@ -401,12 +426,10 @@ {% endif %} {% if host.is_owner %} - Update - Delete + + {% endif %} @@ -1204,6 +1227,49 @@ fetchHostGlance(first.dataset.hostname); } }); + // ── Host action helpers ────────────────────────────────────── + + let _toastTimer = null; + function showToast(msg, isError) { + const t = document.getElementById('action-toast'); + t.textContent = msg; + t.classList.toggle('error', !!isError); + t.classList.add('show'); + clearTimeout(_toastTimer); + _toastTimer = setTimeout(() => t.classList.remove('show'), 4000); + } + + async function hostAction(btn, url) { + btn.disabled = true; + try { + const res = await fetch(url); + const text = await res.text(); + showToast(text, !res.ok); + } catch (e) { + showToast('Request failed: ' + e.message, true); + } finally { + btn.disabled = false; + } + } + + async function hostDelete(btn, hostname) { + if (!confirm('Delete host ' + hostname + '?')) return; + btn.disabled = true; + try { + const res = await fetch('/d?h=' + encodeURIComponent(hostname)); + const text = await res.text(); + showToast(text, !res.ok); + if (res.ok) { + const card = document.querySelector(`.host-card[data-hostname="${hostname}"]`); + if (card) card.remove(); + } + } catch (e) { + showToast('Request failed: ' + e.message, true); + btn.disabled = false; + } + } + +