geoip and config editor online
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var el = {};
|
||||
var _resolve = null;
|
||||
var _busy = false;
|
||||
|
||||
function build() {
|
||||
el.overlay = document.createElement('div');
|
||||
el.overlay.id = 'app-modal';
|
||||
el.overlay.style.cssText = [
|
||||
'display:none', 'position:fixed', 'inset:0',
|
||||
'background:rgba(0,0,0,0.65)', 'z-index:9999',
|
||||
'align-items:center', 'justify-content:center'
|
||||
].join(';');
|
||||
|
||||
el.box = document.createElement('div');
|
||||
el.box.style.cssText = [
|
||||
'background:#0f1520', 'border:1px solid #1e2d45',
|
||||
'border-radius:8px', 'padding:24px 28px',
|
||||
'max-width:440px', 'width:calc(100% - 48px)',
|
||||
'box-shadow:0 16px 48px rgba(0,0,0,0.6)'
|
||||
].join(';');
|
||||
|
||||
el.msg = document.createElement('p');
|
||||
el.msg.style.cssText = 'margin:0 0 20px;color:#c9d1d9;font-size:14px;line-height:1.6;white-space:pre-wrap';
|
||||
|
||||
el.row = document.createElement('div');
|
||||
el.row.style.cssText = 'display:flex;gap:8px;justify-content:flex-end';
|
||||
|
||||
el.cancelBtn = document.createElement('button');
|
||||
el.cancelBtn.textContent = 'Cancel';
|
||||
el.cancelBtn.className = 'btn-ghost';
|
||||
|
||||
el.confirmBtn = document.createElement('button');
|
||||
el.confirmBtn.className = 'btn-danger';
|
||||
|
||||
el.row.appendChild(el.cancelBtn);
|
||||
el.row.appendChild(el.confirmBtn);
|
||||
el.box.appendChild(el.msg);
|
||||
el.box.appendChild(el.row);
|
||||
el.overlay.appendChild(el.box);
|
||||
document.body.appendChild(el.overlay);
|
||||
|
||||
el.cancelBtn.addEventListener('click', function () { close(false); });
|
||||
el.confirmBtn.addEventListener('click', function () { close(true); });
|
||||
el.overlay.addEventListener('click', function (e) {
|
||||
if (e.target === el.overlay) close(false);
|
||||
});
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (el.overlay && el.overlay.style.display !== 'none' && e.key === 'Escape') close(false);
|
||||
});
|
||||
}
|
||||
|
||||
function openModal(msg, confirmLabel, isDanger, showCancel) {
|
||||
if (!el.overlay) build();
|
||||
el.msg.textContent = msg;
|
||||
el.confirmBtn.textContent = confirmLabel || 'OK';
|
||||
el.confirmBtn.className = isDanger !== false ? 'btn-danger' : 'btn-primary';
|
||||
el.cancelBtn.style.display = showCancel === false ? 'none' : '';
|
||||
el.overlay.style.display = 'flex';
|
||||
el.confirmBtn.focus();
|
||||
return new Promise(function (res) { _resolve = res; });
|
||||
}
|
||||
|
||||
function close(result) {
|
||||
if (el.overlay) el.overlay.style.display = 'none';
|
||||
if (_resolve) { _resolve(result); _resolve = null; }
|
||||
}
|
||||
|
||||
window.appModal = {
|
||||
// Confirmation dialog — returns Promise<boolean>
|
||||
confirm: function (msg, label) {
|
||||
return openModal(msg, label || 'Confirm', true, true);
|
||||
},
|
||||
// Info/alert dialog — returns Promise<void>
|
||||
info: function (msg) {
|
||||
return openModal(msg, 'OK', false, false);
|
||||
}
|
||||
};
|
||||
|
||||
// Auto-intercept: buttons/links with data-confirm or data-confirm-fn attribute.
|
||||
document.addEventListener('click', function (e) {
|
||||
if (_busy) return;
|
||||
|
||||
var btn = e.target.closest('[data-confirm], [data-confirm-fn]');
|
||||
if (!btn) return;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
var msg;
|
||||
|
||||
if (btn.dataset.confirm) {
|
||||
msg = btn.dataset.confirm;
|
||||
} else {
|
||||
var fn = window[btn.dataset.confirmFn];
|
||||
if (typeof fn !== 'function') return;
|
||||
msg = fn(); // returns message string, or null/'' to abort (fn may show its own info modal)
|
||||
}
|
||||
|
||||
if (!msg) return;
|
||||
|
||||
var label = btn.dataset.confirmLabel || 'Confirm';
|
||||
window.appModal.confirm(msg, label).then(function (ok) {
|
||||
if (!ok) return;
|
||||
_busy = true;
|
||||
// requestSubmit includes button name/value and respects formaction
|
||||
if (btn.form && typeof btn.form.requestSubmit === 'function') {
|
||||
btn.form.requestSubmit(btn);
|
||||
} else if (btn.form) {
|
||||
btn.form.submit();
|
||||
} else {
|
||||
btn.click();
|
||||
}
|
||||
setTimeout(function () { _busy = false; }, 100);
|
||||
});
|
||||
}, true);
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user