(() => { const REFRESH_INTERVAL = 5000; const root = document.querySelector('[data-board-root]'); const statusEl = document.querySelector('[data-refresh-status]'); const errorEl = document.querySelector('[data-refresh-error]'); const clockEl = document.querySelector('[data-board-clock]'); if (!root) { return; } const formatTime = (date) => date.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit', second: '2-digit', }); const setError = (message) => { if (!errorEl) return; if (message) { errorEl.textContent = message; errorEl.setAttribute('aria-hidden', 'false'); } else { errorEl.textContent = ''; errorEl.setAttribute('aria-hidden', 'true'); } }; const updateStatus = (timestamp) => { if (!statusEl) return; if (timestamp) { const parsed = new Date(timestamp); if (!Number.isNaN(parsed.getTime())) { statusEl.textContent = formatTime(parsed); return; } } statusEl.textContent = formatTime(new Date()); }; const updateClock = () => { if (!clockEl) return; clockEl.textContent = new Date().toLocaleString([], { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', second: '2-digit', }); }; const refresh = async () => { try { const response = await fetch('data/main.php', { cache: 'no-store', headers: { 'X-Requested-With': 'XMLHttpRequest' }, }); if (!response.ok) { throw new Error(`Request failed: ${response.status}`); } const html = await response.text(); root.innerHTML = html; const generatedAt = root.querySelector('[data-generated-at]'); if (generatedAt) { updateStatus(generatedAt.getAttribute('data-generated-at')); } else { updateStatus(); } setError(''); root.removeAttribute('data-refresh-error'); } catch (error) { console.error('Failed to refresh overview data', error); setError('Connection lost — retrying'); root.setAttribute('data-refresh-error', 'true'); } }; refresh(); updateClock(); setInterval(refresh, REFRESH_INTERVAL); setInterval(updateClock, 1000); document.addEventListener('visibilitychange', () => { if (!document.hidden) { refresh(); } }); })();