(function () { // ── Status section collapse toggle ──────────────────────────────── var toggleBtn = document.getElementById('sys-status-toggle'); var statusBody = document.getElementById('sys-status-body'); if (toggleBtn && statusBody) { toggleBtn.addEventListener('click', function () { var collapsed = statusBody.hidden; statusBody.hidden = !collapsed; toggleBtn.setAttribute('aria-expanded', collapsed ? 'true' : 'false'); toggleBtn.textContent = collapsed ? '▲ Réduire' : '▼ Développer'; try { localStorage.setItem('sys_status_collapsed', collapsed ? '0' : '1'); } catch(e) {} }); try { if (localStorage.getItem('sys_status_collapsed') === '1') { statusBody.hidden = true; toggleBtn.setAttribute('aria-expanded', 'false'); toggleBtn.textContent = '▼ Développer'; } } catch(e) {} } // ── fetch()-based tab panel loading ─────────────────────────────── var panel = document.getElementById('sys-tab-panel'); var tabNav = document.querySelector('.sys-tabs'); if (!panel || !tabNav || !window.fetch) return; var currentTab = panel.dataset.tab; var currentN = panel.dataset.n; function loadPanel(tab, n, pushState) { var url = new URL(window.location.href); var fragUrl = new URL('/admin/system-fragment.php', window.location.origin); fragUrl.searchParams.set('tab', tab); fragUrl.searchParams.set('n', n); // Mark the panel as loading panel.classList.add('sys-panel-loading'); fetch(fragUrl.toString(), { credentials: 'same-origin' }) .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); }) .then(function (html) { panel.innerHTML = html; panel.dataset.tab = tab; panel.dataset.n = n; currentTab = tab; currentN = n; panel.classList.remove('sys-panel-loading'); // Update active tab indicators tabNav.querySelectorAll('.sys-tab').forEach(function (a) { var isActive = a.dataset.tab === tab; a.classList.toggle('active', isActive); if (isActive) { a.setAttribute('aria-current', 'page'); } else { a.removeAttribute('aria-current'); } }); // Re-bind inner controls (lines-select, copy btn) bindPanelControls(); // Update browser URL without reloading if (pushState) { url.searchParams.set('tab', tab); url.searchParams.set('n', n); history.pushState({ tab: tab, n: n }, '', url.toString()); } }) .catch(function () { // Graceful degradation: fall back to full page load panel.classList.remove('sys-panel-loading'); url.searchParams.set('tab', tab); url.searchParams.set('n', n); window.location.href = url.toString(); }); } // Wire tab links tabNav.querySelectorAll('.sys-tab').forEach(function (a) { a.addEventListener('click', function (e) { e.preventDefault(); var tab = a.dataset.tab; if (tab && tab !== currentTab) { loadPanel(tab, currentN, true); } }); }); // Handle browser back/forward window.addEventListener('popstate', function (e) { if (e.state && e.state.tab) { loadPanel(e.state.tab, e.state.n || 100, false); } }); function bindPanelControls() { // Lines-select var sel = panel.querySelector('#lines-select'); if (sel) { sel.addEventListener('change', function () { loadPanel(currentTab, parseInt(this.value, 10), true); }); } // Copy button var copyBtn = panel.querySelector('#log-copy-btn'); var logOut = panel.querySelector('#log-output'); if (copyBtn && logOut) { copyBtn.addEventListener('click', function () { var text = Array.from(logOut.querySelectorAll('.log-line')) .map(function (el) { return el.textContent; }) .join('\n'); if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(function () { copyBtn.textContent = '✓ Copié'; copyBtn.classList.add('copied'); setTimeout(function () { copyBtn.textContent = 'Copier'; copyBtn.classList.remove('copied'); }, 2000); }).catch(function () { fallbackCopy(text); }); } else { fallbackCopy(text); } }); } } // Bind controls already present on first load bindPanelControls(); function fallbackCopy(text) { var ta = document.createElement('textarea'); ta.value = text; ta.style.cssText = 'position:fixed;opacity:0;top:0;left:0'; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); } catch (e) {} document.body.removeChild(ta); } })();