From 14ba3b03c7fcd1a154f78bca73eae973fce16dde Mon Sep 17 00:00:00 2001 From: librelad Date: Sat, 23 May 2026 00:07:38 +0100 Subject: [PATCH] feat(backup): make config-backup warning stand out and dismissible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a large amber alert-triangle icon to the 'keep your config backed up offline' banner and a close (x) button in its top-right. Dismissal is stored in localStorage (libreportal:backup-config-warning-dismissed) — a per-browser UI nudge, not server config — and hides both the banner and its divider until cleared. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- .../libreportal/frontend/css/backup.css | 25 +++++++++++++++ .../js/components/backup/backup-page.js | 31 ++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/containers/libreportal/frontend/css/backup.css b/containers/libreportal/frontend/css/backup.css index fe042c8..94be310 100755 --- a/containers/libreportal/frontend/css/backup.css +++ b/containers/libreportal/frontend/css/backup.css @@ -840,6 +840,31 @@ min-width: 0; } +/* Big amber alert icon so the warning reads at a glance. */ +.backup-warning-banner-icon { + flex-shrink: 0; + color: #f59e0b; +} + +/* Dismiss (×) in the banner's top-right corner. */ +.backup-warning-banner-close { + flex-shrink: 0; + align-self: flex-start; + background: transparent; + border: none; + color: var(--text-secondary, rgba(var(--text-rgb), 0.6)); + cursor: pointer; + padding: 2px; + border-radius: 6px; + line-height: 0; + transition: background 0.15s ease, color 0.15s ease; +} + +.backup-warning-banner-close:hover { + background: rgba(var(--text-rgb), 0.1); + color: var(--text-primary); +} + .backup-warning-banner [data-action="export-passwords"] { flex-shrink: 0; white-space: nowrap; diff --git a/containers/libreportal/frontend/js/components/backup/backup-page.js b/containers/libreportal/frontend/js/components/backup/backup-page.js index 668094f..cb528da 100644 --- a/containers/libreportal/frontend/js/components/backup/backup-page.js +++ b/containers/libreportal/frontend/js/components/backup/backup-page.js @@ -203,6 +203,16 @@ class BackupPage { const exportBtn = e.target.closest('[data-action="export-passwords"]'); if (exportBtn) { this.exportRepositoryPasswords(exportBtn); return; } + const dismissWarn = e.target.closest('[data-action="dismiss-config-warning"]'); + if (dismissWarn) { + localStorage.setItem('libreportal:backup-config-warning-dismissed', '1'); + const banner = dismissWarn.closest('.backup-warning-banner'); + const divider = banner?.nextElementSibling; + if (divider && divider.classList.contains('config-divider')) divider.remove(); + banner?.remove(); + return; + } + const saveBtn = e.target.closest('[data-backup-save]'); if (saveBtn) { this.saveSection(saveBtn.dataset.backupSave); @@ -783,8 +793,17 @@ class BackupPage { const body = document.getElementById('backup-configuration-body'); if (!body) return; - body.innerHTML = ` + // The warning is a dismissible nudge, so its dismissed state lives in + // localStorage (per-browser) rather than server config. Banner + its + // divider are omitted entirely once dismissed. + const warningDismissed = localStorage.getItem('libreportal:backup-config-warning-dismissed') === '1'; + const warningHTML = warningDismissed ? '' : `
+
Keep your LibrePortal config backed up offline. Repository passwords live inside the config directory. Without that backup, snapshots cannot be decrypted by anyone — including you. @@ -797,8 +816,18 @@ class BackupPage { Export Repository Passwords +
+ `; + + body.innerHTML = ` + ${warningHTML}
`;