74 lines
2.6 KiB
JavaScript
74 lines
2.6 KiB
JavaScript
// ====== Theme toggle =======================================================
|
|
(function () {
|
|
const btn = document.getElementById('theme-toggle');
|
|
if (!btn) return;
|
|
btn.addEventListener('click', () => {
|
|
const root = document.documentElement;
|
|
const next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
|
|
root.setAttribute('data-theme', next);
|
|
try { localStorage.setItem('alerthub-theme', next); } catch (_) {}
|
|
});
|
|
})();
|
|
|
|
// ====== Countdown timer ====================================================
|
|
// Each .countdown element has data-expires="YYYY-MM-DD" and renders 4 cells
|
|
// for days / hours / minutes / seconds. Updates every second.
|
|
(function () {
|
|
const els = document.querySelectorAll('.countdown[data-expires]');
|
|
if (!els.length) return;
|
|
|
|
function pad(n) { return n < 10 ? '0' + n : '' + n; }
|
|
|
|
function render() {
|
|
const now = new Date();
|
|
els.forEach((el) => {
|
|
const target = new Date(el.dataset.expires + 'T23:59:59');
|
|
let diff = (target.getTime() - now.getTime()) / 1000;
|
|
const card = el.closest('.alert-card');
|
|
const negative = diff < 0;
|
|
diff = Math.abs(diff);
|
|
|
|
const days = Math.floor(diff / 86400);
|
|
const hours = Math.floor((diff % 86400) / 3600);
|
|
const minutes = Math.floor((diff % 3600) / 60);
|
|
const seconds = Math.floor(diff % 60);
|
|
|
|
const segs = el.querySelectorAll('.countdown-value');
|
|
if (segs.length === 4) {
|
|
segs[0].textContent = days;
|
|
segs[1].textContent = pad(hours);
|
|
segs[2].textContent = pad(minutes);
|
|
segs[3].textContent = pad(seconds);
|
|
}
|
|
|
|
if (card) {
|
|
card.classList.remove('is-warning', 'is-critical', 'is-expired');
|
|
if (negative) {
|
|
card.classList.add('is-expired');
|
|
} else if (days < 7) {
|
|
card.classList.add('is-critical');
|
|
} else if (days < 30) {
|
|
card.classList.add('is-warning');
|
|
}
|
|
}
|
|
|
|
const dotLabel = el.parentElement && el.parentElement.querySelector('.alert-state-text');
|
|
if (dotLabel) {
|
|
if (negative) dotLabel.textContent = 'EXPIRED';
|
|
else if (days < 7) dotLabel.textContent = 'CRITICAL';
|
|
else if (days < 30) dotLabel.textContent = 'WARNING';
|
|
else dotLabel.textContent = 'NOMINAL';
|
|
}
|
|
});
|
|
}
|
|
render();
|
|
setInterval(render, 1000);
|
|
})();
|
|
|
|
// ====== Confirm-on-click for destructive actions ===========================
|
|
document.querySelectorAll('form[data-confirm]').forEach((form) => {
|
|
form.addEventListener('submit', (e) => {
|
|
if (!window.confirm(form.dataset.confirm)) e.preventDefault();
|
|
});
|
|
});
|