From 1e450537280d93f4026d869ba44016260116bd7f Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Mon, 29 Dec 2025 09:27:52 +0100 Subject: [PATCH] SecuBox v0.5.0-A UI polish --- .claude/HISTORY.md | 5 ++ .claude/WIP.md | 4 ++ .codex/HISTORY.md | 3 + .codex/WIP.md | 6 +- luci-app-secubox/Makefile | 2 +- .../luci-static/resources/secubox/common.css | 41 ++++++++---- .../luci-static/resources/secubox/nav.js | 3 +- .../resources/view/secubox/alerts.js | 4 +- .../resources/view/secubox/help.js | 48 ++++---------- .../resources/view/secubox/modules.js | 34 ++++------ .../resources/view/secubox/monitoring.js | 64 ------------------- 11 files changed, 75 insertions(+), 139 deletions(-) diff --git a/.claude/HISTORY.md b/.claude/HISTORY.md index 1a30c53e..4d39c67a 100644 --- a/.claude/HISTORY.md +++ b/.claude/HISTORY.md @@ -23,3 +23,8 @@ _Last updated: 2025-12-28_ - Use `secubox-tools/deploy-secubox-dashboard.sh` for view-only pushes. - Use `secubox-tools/deploy-secubox-v0.1.2.sh` for RPCD/config updates. - Always clear `/tmp/luci-*` after copying UI assets. + +6. **SecuBox v0.5.0-A Polish (2025-12-29)** + - Monitoring and Modules views drop legacy hero/filter UIs; all tabs now use SecuNav styling. + - Help/Bonus page adopts the shared header, navbar entry, and chips. + - Alerts buttons use `sh-btn` components; nav + title chips inherit theme colors. diff --git a/.claude/WIP.md b/.claude/WIP.md index 1a05ec7a..c2ec7032 100644 --- a/.claude/WIP.md +++ b/.claude/WIP.md @@ -6,6 +6,10 @@ Status: ✅ COMPLETE (2025-12-28) Notes: All view tabs now respect theme colors; monitoring menu cleaned up. +- **SecuBox v0.5.0-A polish** + Status: ✅ COMPLETE (2025-12-29) + Notes: Monitoring/Modules/Alerts/Help views now share the same navbar + chip headers; Help tab added globally. + - **Backup/Restore UX Alignment** Status: ✅ COMPLETE Notes: System Hub header and restore flow updated; API now accepts `file_name`. diff --git a/.codex/HISTORY.md b/.codex/HISTORY.md index 43981c98..322a82e8 100644 --- a/.codex/HISTORY.md +++ b/.codex/HISTORY.md @@ -19,3 +19,6 @@ Navigation tabs respond to dark/light/cyberpunk palettes. Monitoring menu simplified (no `/overview` tab). CSS updated so chip headers stay on a single row (with responsive wrap). + +- **2025-12-29 – v0.5.0-A UI polish** + Monitoring hero + modules filter migrated to SecuNav styling, alerts buttons use `sh-btn`, Help page adopts shared header and navbar Bonus tab, and overall theme consistency is verified on router. diff --git a/.codex/WIP.md b/.codex/WIP.md index 24126e2a..7a585ca8 100644 --- a/.codex/WIP.md +++ b/.codex/WIP.md @@ -2,9 +2,9 @@ ## Completed Today -- Synced navigation styling with theme preferences (dark/light/cyberpunk). -- Ensured Monitoring view hides legacy LuCI tab bar and uses direct menu route. -- Added Theme.init call to Settings view. +- Unified Monitoring + Modules filters and Help view with SecuNav styling. +- Added Bonus tab to navbar, refreshed alerts action buttons, removed legacy hero blocks. +- Verified on router (scp + cache reset) and tagged release v0.5.0-A. ## In Progress diff --git a/luci-app-secubox/Makefile b/luci-app-secubox/Makefile index 75680d44..852d0f09 100644 --- a/luci-app-secubox/Makefile +++ b/luci-app-secubox/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-secubox PKG_VERSION:=0.4.6 -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_LICENSE:=Apache-2.0 PKG_MAINTAINER:=CyberMind diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/common.css b/luci-app-secubox/htdocs/luci-static/resources/secubox/common.css index 5a5f2697..8d6d346f 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/secubox/common.css +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/common.css @@ -237,6 +237,7 @@ pre { cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); font-size: 14px; + box-shadow: 0 8px 20px var(--sh-shadow); } .sh-btn-secondary:hover { @@ -476,8 +477,8 @@ pre { /* Slim header utility */ .sh-page-header-lite { - background: #f7f9fc; - border: 1px solid rgba(148, 163, 184, 0.35); + background: var(--sh-bg-secondary); + border: 1px solid var(--sh-border); border-radius: 18px; padding: 14px 20px; display: flex; @@ -486,7 +487,7 @@ pre { gap: 12px; flex-wrap: nowrap; overflow-x: auto; - box-shadow: 0 10px 24px rgba(15, 23, 42, 0.05); + box-shadow: 0 10px 24px var(--sh-shadow); } .sh-header-meta { @@ -502,11 +503,12 @@ pre { gap: 8px; padding: 6px 12px; border-radius: 999px; - background: #ffffff; - border: 1px solid rgba(148, 163, 184, 0.3); + background: var(--sh-bg-card); + border: 1px solid var(--sh-border); font-size: 13px; font-weight: 600; color: var(--sh-text-secondary); + box-shadow: 0 6px 16px var(--sh-shadow); } .sh-header-chip strong { @@ -532,20 +534,20 @@ pre { } .sh-header-chip.success { - background: rgba(34, 197, 94, 0.12); - border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.15); + border-color: rgba(34, 197, 94, 0.5); color: #15803d; } .sh-header-chip.danger { - background: rgba(239, 68, 68, 0.12); - border-color: rgba(239, 68, 68, 0.45); + background: rgba(239, 68, 68, 0.15); + border-color: rgba(239, 68, 68, 0.5); color: #b91c1c; } .sh-header-chip.warn { - background: rgba(245, 158, 11, 0.12); - border-color: rgba(245, 158, 11, 0.45); + background: rgba(245, 158, 11, 0.18); + border-color: rgba(245, 158, 11, 0.55); color: #b45309; } @@ -558,3 +560,20 @@ pre { flex-wrap: wrap; } } +.sh-btn-danger { + background: linear-gradient(135deg, #ef4444, #b91c1c); + color: #fff; + border: none; + padding: 10px 20px; + border-radius: 8px; + font-weight: 600; + box-shadow: 0 12px 25px rgba(239, 68, 68, 0.35); + cursor: pointer; + font-size: 14px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.sh-btn-danger:hover { + box-shadow: 0 14px 28px rgba(239, 68, 68, 0.5); + transform: translateY(-2px); +} diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/nav.js b/luci-app-secubox/htdocs/luci-static/resources/secubox/nav.js index b0c7f78b..0a6d1bdb 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/secubox/nav.js +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/nav.js @@ -6,7 +6,8 @@ var tabs = [ { id: 'modules', icon: '🧩', label: _('Modules'), path: ['admin', 'secubox', 'modules'] }, { id: 'monitoring', icon: '📡', label: _('Monitoring'), path: ['admin', 'secubox', 'monitoring'] }, { id: 'alerts', icon: '⚠️', label: _('Alerts'), path: ['admin', 'secubox', 'alerts'] }, - { id: 'settings', icon: '⚙️', label: _('Settings'), path: ['admin', 'secubox', 'settings'] } + { id: 'settings', icon: '⚙️', label: _('Settings'), path: ['admin', 'secubox', 'settings'] }, + { id: 'help', icon: '✨', label: _('Bonus'), path: ['admin', 'secubox', 'help'] } ]; return baseclass.extend({ diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/alerts.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/alerts.js index 4bbc09a8..5739b952 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/alerts.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/alerts.js @@ -88,13 +88,13 @@ return view.extend({ var self = this; return E('div', { 'class': 'secubox-header-actions' }, [ E('button', { - 'class': 'cbi-button cbi-button-action', + 'class': 'sh-btn sh-btn-danger', 'click': function() { self.clearAllAlerts(); } }, '🗑️ Clear All'), E('button', { - 'class': 'cbi-button cbi-button-neutral', + 'class': 'sh-btn sh-btn-secondary', 'click': function() { self.refreshData().then(function() { self.updateAlertsList(); diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/help.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/help.js index d392ebf0..d8c82acd 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/help.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/help.js @@ -34,52 +34,30 @@ return view.extend({ E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox/common.css') }), SecuNav.renderTabs('help'), this.renderHeader(data), - this.renderHero(data), this.renderHelpCatalog(helpPages), this.renderSupportSection(), this.renderFooter() ]); }, - renderHero: function(status) { - return E('div', { 'class': 'secubox-card secubox-help-hero' }, [ - E('div', { 'class': 'secubox-help-hero-text' }, [ - E('span', { 'class': 'secubox-help-eyebrow' }, _('Bonus Tab')), - E('h2', {}, _('Help à SecuBox')), - E('p', { 'class': 'secubox-help-subtitle' }, - _('Retrouvez la documentation, les guides et toutes les façons de soutenir la suite SecuBox.')), - E('div', { 'class': 'secubox-help-hero-stats' }, [ - this.renderHeroStat('📦', _('Modules Couvert•e•s'), Object.keys(Help.getAllHelpPages()).length), - this.renderHeroStat('⚙️', _('Version Actuelle'), status.version || 'v1.0.0'), - this.renderHeroStat('🌐', _('Site Officiel'), 'secubox.cybermood.eu') - ]) + renderHeader: function(status) { + return E('div', { 'class': 'sh-page-header sh-page-header-lite' }, [ + E('div', {}, [ + E('h2', { 'class': 'sh-page-title' }, [ + E('span', { 'class': 'sh-page-title-icon' }, '✨'), + _('SecuBox Help & Bonus') + ]), + E('p', { 'class': 'sh-page-subtitle' }, + _('Documentation, support et ressources officielles pour l’écosystème SecuBox.')) ]), - E('div', { 'class': 'secubox-help-hero-actions' }, [ - Help.createHelpButton('secubox', 'header', { - icon: '📚', - label: _('Ouvrir la knowledge base'), - modal: true - }), - E('a', { - 'class': 'sb-help-btn sb-help-header secubox-help-cta', - 'href': 'https://secubox.cybermood.eu/#contact', - 'target': '_blank' - }, [ - E('span', { 'class': 'sb-help-icon' }, '🤝'), - E('span', { 'class': 'sb-help-label' }, _('Contacter SecuBox')) - ]) + E('div', { 'class': 'sh-header-meta' }, [ + this.renderHeaderChip('🏷️', _('Version'), status.version || _('Unknown')), + this.renderHeaderChip('📘', _('Guides'), Object.keys(Help.getAllHelpPages()).length), + this.renderHeaderChip('🌐', _('Site vitrine'), 'secubox.cybermood.eu') ]) ]); }, - renderHeroStat: function(icon, label, value) { - return E('div', { 'class': 'secubox-help-hero-stat' }, [ - E('div', { 'class': 'secubox-help-hero-stat-icon' }, icon), - E('div', { 'class': 'secubox-help-hero-stat-value' }, value), - E('div', { 'class': 'secubox-help-hero-stat-label' }, label) - ]); - }, - renderHelpCatalog: function(pages) { var self = this; var entries = Object.keys(pages || {}); diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js index 021b5148..04c79b64 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/modules.js @@ -91,42 +91,32 @@ return view.extend({ renderFilterTabs: function() { var self = this; var tabs = [ - { id: 'all', label: 'All Modules', icon: '📦' }, - { id: 'security', label: 'Security', icon: '🛡️' }, - { id: 'monitoring', label: 'Monitoring', icon: '📊' }, - { id: 'network', label: 'Network', icon: '🌐' }, - { id: 'system', label: 'System', icon: '⚙️' } + { id: 'all', label: _('All Modules'), icon: '📦' }, + { id: 'security', label: _('Security'), icon: '🛡️' }, + { id: 'monitoring', label: _('Monitoring'), icon: '📊' }, + { id: 'network', label: _('Network'), icon: '🌐' }, + { id: 'system', label: _('System'), icon: '⚙️' } ]; var filterButtons = tabs.map(function(tab) { return E('button', { - 'class': 'cyber-tab cyber-tab--pill' + (tab.id === 'all' ? ' is-active' : ''), + 'class': 'sh-nav-tab secubox-module-tab' + (tab.id === 'all' ? ' active' : ''), 'data-filter': tab.id, 'type': 'button', 'click': function(ev) { - document.querySelectorAll('.secubox-filter-tabs .cyber-tab[data-filter]').forEach(function(el) { - el.classList.remove('is-active'); + document.querySelectorAll('.secubox-filter-tabs .sh-nav-tab[data-filter]').forEach(function(el) { + el.classList.remove('active'); }); - ev.currentTarget.classList.add('is-active'); + ev.currentTarget.classList.add('active'); self.filterModules(tab.id); } }, [ - E('span', { 'class': 'cyber-tab-icon' }, tab.icon), - E('span', { 'class': 'cyber-tab-label' }, tab.label) + E('span', { 'class': 'sh-tab-icon' }, tab.icon), + E('span', { 'class': 'sh-tab-label' }, tab.label) ]); }); - filterButtons.push( - E('button', { - 'class': 'cyber-tab cyber-tab--ghost', - 'type': 'button', - 'click': function() { - window.location.href = L.url('admin/secubox/help'); - } - }, '✨ ' + _('Bonus · Help à SecuBox')) - ); - - return E('div', { 'class': 'secubox-filter-tabs cyber-tablist cyber-tablist--filters' }, filterButtons); + return E('div', { 'class': 'secubox-filter-tabs sh-nav-tabs secubox-nav-tabs secubox-module-tabs' }, filterButtons); }, renderModuleCards: function(modules, filter) { diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/monitoring.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/monitoring.js index 124b485a..95ab15d8 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/monitoring.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/monitoring.js @@ -60,7 +60,6 @@ return view.extend({ E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox/monitoring.css') }), SecuNav.renderTabs('monitoring'), this.renderHeader(), - this.renderHero(), this.renderChartsGrid(), this.renderCurrentStatsCard() ]); @@ -114,44 +113,6 @@ return view.extend({ ]); }, - renderHero: function() { - var snapshot = this.getLatestSnapshot(); - - var badges = [ - this.renderHeroBadge('cpu', '🔥', _('CPU Usage'), snapshot.cpu.value.toFixed(1) + '%', snapshot.cpu.value), - this.renderHeroBadge('memory', '💾', _('Memory Usage'), snapshot.memory.value.toFixed(1) + '%', snapshot.memory.value), - this.renderHeroBadge('disk', '💿', _('Disk Usage'), snapshot.disk.value.toFixed(1) + '%', snapshot.disk.value), - this.renderHeroBadge('uptime', '⏱', _('Uptime'), API.formatUptime(snapshot.uptime || 0)) - ]; - - return E('section', { 'class': 'sb-card secubox-monitoring-hero' }, [ - E('div', { 'class': 'sb-card-header' }, [ - E('div', {}, [ - E('h2', {}, _('Advanced System Monitoring')), - E('p', { 'class': 'sb-card-subtitle' }, _('Live telemetry for CPU, memory, storage, and network throughput')) - ]), - E('span', { 'class': 'sb-badge sb-badge-ghost' }, _('Last update: ') + - (snapshot.timestamp ? new Date(snapshot.timestamp).toLocaleTimeString() : _('Initializing'))) - ]), - E('div', { 'class': 'secubox-monitoring-badges', 'id': 'secubox-monitoring-badges' }, badges) - ]); - }, - - renderHeroBadge: function(id, icon, label, value, percent) { - var color = typeof percent === 'number' ? this.getColorForValue(percent) : null; - return E('div', { 'class': 'secubox-hero-badge', 'data-metric': id }, [ - E('div', { 'class': 'secubox-hero-icon' }, icon), - E('div', { 'class': 'secubox-hero-meta' }, [ - E('span', { 'class': 'secubox-hero-label' }, label), - E('span', { - 'class': 'secubox-hero-value', - 'id': 'secubox-hero-' + id, - 'style': color ? 'color:' + color : '' - }, value) - ]) - ]); - }, - renderChartsGrid: function() { return E('section', { 'class': 'secubox-charts-grid' }, [ this.renderChartCard('cpu', _('CPU Usage'), '%', '#6366f1'), @@ -314,34 +275,9 @@ return view.extend({ dom.content(statsContainer, this.renderStatsTable()); var snapshot = this.getLatestSnapshot(); - this.updateHeroBadges(snapshot); this.updateHeaderChips(snapshot); }, - updateHeroBadges: function(snapshot) { - var badges = document.querySelectorAll('.secubox-hero-badge'); - if (!badges.length) - return; - - var values = { - cpu: snapshot.cpu.value.toFixed(1) + '%', - memory: snapshot.memory.value.toFixed(1) + '%', - disk: snapshot.disk.value.toFixed(1) + '%', - uptime: API.formatUptime(snapshot.uptime || 0) - }; - - Object.keys(values).forEach(function(key) { - var target = document.getElementById('secubox-hero-' + key); - if (target) { - target.textContent = values[key]; - if (key !== 'uptime') { - var numeric = snapshot[key] && snapshot[key].value || 0; - target.style.color = this.getColorForValue(numeric); - } - } - }, this); - }, - updateHeaderChips: function(snapshot) { this.setHeaderChipValue('cpu', snapshot.cpu.value.toFixed(1) + '%', snapshot.cpu.value); this.setHeaderChipValue('memory', snapshot.memory.value.toFixed(1) + '%', snapshot.memory.value);