diff --git a/TODO.md b/TODO.md index 5b419f8..3c49f1a 100644 --- a/TODO.md +++ b/TODO.md @@ -11,6 +11,9 @@ Pending tasks have been split into topic files under [`todo/`](todo/README.md): ## Recently completed (this session) +- [x] `admin/system.php` + `assets/js/system.js` + `assets/css/system.css` — extracted the large `$extraJsInline` heredoc (≈130 lines) into a static `public/assets/js/system.js` loaded via `$extraJs`; replaced 4 inline `style=` attributes with named CSS modifier classes (`srv-section-title--compact`, `srv-section-title--sub`, `php-grid--flush`, `log-toolbar label` rule); only the dynamic `--disk-pct`/`--disk-color` CSS custom properties remain inline because they carry PHP runtime values + + - [x] `src/App.php` — removed dead legacy flash key fallback chains from `consumeFlash()`: the `error`, `admin_error`, `edit_error`, `form_error`, `success`, `admin_success`, `edit_success` session keys were never written by any code; all callers already use `App::flash()` → `_flash_error` / `_flash_success`. Method is now 4 lines instead of 18. - [x] `admin/import.php` + `admin.css` — extracted all 4 remaining inline `style=` attributes from `import.php` into named CSS classes (`admin-error-list`, `admin-file-hint`, `admin-import-results`, `admin-import-results__title`) in the Import page section of `admin.css`. No more inline styles in `import.php`. diff --git a/public/admin/system.php b/public/admin/system.php index 01105bf..f37287a 100644 --- a/public/admin/system.php +++ b/public/admin/system.php @@ -360,154 +360,7 @@ if ($activeTab === 'nginx_config') { $isAdmin = true; $bodyClass = 'admin-body'; $extraCss = ['/assets/css/system.css']; -$extraJsInline = <<<'JS' -(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); - } - -})(); -JS; +$extraJs = ['/assets/js/system.js']; require_once APP_ROOT . '/templates/head.php'; ?> @@ -528,7 +381,7 @@ require_once APP_ROOT . '/templates/head.php'; ════════════════════════════════════════════════════════════════════ -->
-

Statut +

Statut ⚡ Cache — il y a s @@ -562,8 +415,8 @@ require_once APP_ROOT . '/templates/head.php';
-

Environnement PHP

-
+

Environnement PHP

+
$val): ?>
@@ -573,7 +426,7 @@ require_once APP_ROOT . '/templates/head.php';
-

Espace disque

+

Espace disque

85 ? '#e05555' : ($diskPct > 70 ? '#ffc107' : '#4caf50'); ?>
@@ -669,9 +522,7 @@ require_once APP_ROOT . '/templates/head.php';
- +