feat(ui): Add C3BOX sidebar navigation to KISS theme

- Add shared navigation config in kiss-theme.js
- Add renderSidebar() method for reusable sidebar
- Add wrap() helper for full page with sidebar
- Update InterceptoR to use sidebar layout
- Responsive: collapses on mobile, icons-only on tablet

Other views can use: KissTheme.wrap([content], 'active/path')

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-02-11 12:03:33 +01:00
parent 03e90bb4af
commit 546da471f8
2 changed files with 229 additions and 20 deletions

View File

@ -24,6 +24,27 @@ var QUICK_LINKS = [
{ name: 'CrowdSec', path: 'admin/secubox/security/crowdsec/overview', icon: '🛡️' }
];
var C3_NAV = [
{ cat: 'Main', items: [
{ icon: '🏠', name: 'Home', path: 'admin/secubox-home' },
{ icon: '📊', name: 'System Hub', path: 'admin/secubox/system/system-hub' }
]},
{ cat: 'Security', items: [
{ icon: '🧙', name: 'InterceptoR', path: 'admin/secubox/interceptor/overview', active: true },
{ icon: '🛡️', name: 'CrowdSec', path: 'admin/secubox/security/crowdsec/overview' },
{ icon: '🔍', name: 'mitmproxy', path: 'admin/secubox/security/mitmproxy/status' },
{ icon: '🌐', name: 'DNS Guard', path: 'admin/secubox/security/dnsguard' }
]},
{ cat: 'Services', items: [
{ icon: '📡', name: 'IoT Guard', path: 'admin/secubox/services/iot-guard' },
{ icon: '💾', name: 'CDN Cache', path: 'admin/services/cdn-cache' },
{ icon: '🔗', name: 'HAProxy', path: 'admin/services/haproxy' }
]},
{ cat: 'Navigate', items: [
{ icon: '🌳', name: 'LuCI Tree', path: 'admin/secubox/luci-tree' }
]}
];
return view.extend({
load: function() {
return callGetStatus().catch(function() {
@ -50,12 +71,17 @@ return view.extend({
var score = summary.health_score || 0;
var pillarsActive = summary.pillars_active || 0;
return E('div', { 'class': 'kiss-root' }, [
// Header
E('div', { 'style': 'margin-bottom: 24px;' }, [
E('h2', { 'style': 'font-size: 24px; font-weight: 700; margin: 0 0 8px 0;' }, '🧙 InterceptoR'),
E('p', { 'style': 'color: var(--kiss-muted); margin: 0;' }, 'The Gandalf Proxy — Transparent traffic interception')
]),
return E('div', { 'class': 'kiss-root kiss-with-sidebar' }, [
// Sidebar
this.renderSidebar(),
// Main content
E('div', { 'class': 'kiss-main' }, [
// Header
E('div', { 'style': 'margin-bottom: 24px;' }, [
E('h2', { 'style': 'font-size: 24px; font-weight: 700; margin: 0 0 8px 0;' }, '🧙 InterceptoR'),
E('p', { 'style': 'color: var(--kiss-muted); margin: 0;' }, 'The Gandalf Proxy — Transparent traffic interception')
]),
// Health Score Card
E('div', { 'class': 'kiss-card', 'style': 'text-align: center; padding: 30px; margin-bottom: 20px;' }, [
@ -72,22 +98,56 @@ return view.extend({
})
),
// Quick Links
E('div', { 'class': 'kiss-card' }, [
E('div', { 'class': 'kiss-card-title' }, '🔗 Quick Links'),
E('div', { 'style': 'display: flex; flex-wrap: wrap; gap: 10px;' },
QUICK_LINKS.map(function(link) {
return E('a', {
'href': '/cgi-bin/luci/' + link.path,
'class': 'kiss-btn',
'style': 'text-decoration: none;'
}, link.icon + ' ' + link.name);
})
)
// Quick Links
E('div', { 'class': 'kiss-card' }, [
E('div', { 'class': 'kiss-card-title' }, '🔗 Quick Links'),
E('div', { 'style': 'display: flex; flex-wrap: wrap; gap: 10px;' },
QUICK_LINKS.map(function(link) {
return E('a', {
'href': '/cgi-bin/luci/' + link.path,
'class': 'kiss-btn',
'style': 'text-decoration: none;'
}, link.icon + ' ' + link.name);
})
)
])
])
]);
},
renderSidebar: function() {
var navItems = [];
C3_NAV.forEach(function(cat) {
navItems.push(E('div', { 'class': 'kiss-nav-section' }, cat.cat));
cat.items.forEach(function(item) {
navItems.push(E('a', {
'href': '/cgi-bin/luci/' + item.path,
'class': 'kiss-nav-item' + (item.active ? ' active' : '')
}, [
E('span', { 'class': 'kiss-nav-icon' }, item.icon),
item.name
]));
});
});
return E('nav', { 'class': 'kiss-sidebar' }, [
// Logo
E('div', { 'class': 'kiss-sidebar-logo' }, [
E('div', { 'class': 'kiss-logo-text' }, [
E('span', { 'style': 'color: var(--kiss-green);' }, 'C'),
E('span', { 'style': 'color: var(--kiss-red); font-size: 14px; vertical-align: super;' }, '3'),
E('span', { 'style': 'color: var(--kiss-blue);' }, 'B'),
E('span', { 'style': 'color: #37474F;' }, 'O'),
E('span', { 'style': 'color: var(--kiss-green);' }, 'X')
]),
E('div', { 'class': 'kiss-logo-sub' }, 'SECUBOX')
]),
// Nav
E('div', { 'class': 'kiss-nav' }, navItems)
]);
},
renderPillar: function(pillar, data) {
var enabled = data.enabled || false;
var running = data.running !== undefined ? data.running : enabled;
@ -148,8 +208,34 @@ return view.extend({
}
.kiss-root {
background: var(--kiss-bg); color: var(--kiss-text);
font-family: 'Segoe UI', sans-serif; min-height: 100vh; padding: 20px;
font-family: 'Segoe UI', sans-serif; min-height: 100vh;
}
.kiss-with-sidebar { display: flex; }
.kiss-sidebar {
position: fixed; left: 0; top: 0; bottom: 0; width: 200px;
background: linear-gradient(180deg, #0d1321 0%, var(--kiss-bg) 100%);
border-right: 1px solid var(--kiss-line); z-index: 100;
display: flex; flex-direction: column; overflow-y: auto;
}
.kiss-sidebar-logo {
padding: 16px; border-bottom: 1px solid var(--kiss-line); text-align: center;
}
.kiss-logo-text { font-weight: 900; font-size: 24px; letter-spacing: -1px; }
.kiss-logo-sub { font-size: 9px; color: var(--kiss-muted); letter-spacing: 2px; margin-top: 4px; }
.kiss-nav { flex: 1; padding: 8px 0; }
.kiss-nav-section {
padding: 8px 12px 4px; font-size: 9px; letter-spacing: 2px;
text-transform: uppercase; color: var(--kiss-muted);
}
.kiss-nav-item {
display: flex; align-items: center; gap: 10px; padding: 8px 16px;
text-decoration: none; font-size: 13px; color: var(--kiss-muted);
transition: all 0.2s; border-left: 2px solid transparent;
}
.kiss-nav-item:hover { background: rgba(255,255,255,0.03); color: var(--kiss-text); }
.kiss-nav-item.active { color: var(--kiss-green); background: rgba(0,200,83,0.05); border-left-color: var(--kiss-green); }
.kiss-nav-icon { font-size: 16px; width: 20px; text-align: center; }
.kiss-main { margin-left: 200px; padding: 20px; flex: 1; min-height: 100vh; }
.kiss-card {
background: var(--kiss-card); border: 1px solid var(--kiss-line);
border-radius: 12px; padding: 20px; margin-bottom: 16px;
@ -171,7 +257,19 @@ return view.extend({
display: flex; align-items: center; justify-content: center;
}
#kiss-toggle:hover { opacity: 1; transform: scale(1.1); }
@media (max-width: 600px) { .kiss-grid-auto { grid-template-columns: 1fr 1fr; } }
@media (max-width: 768px) {
.kiss-sidebar { width: 60px; }
.kiss-sidebar-logo, .kiss-nav-section { display: none; }
.kiss-nav-item { padding: 12px; justify-content: center; }
.kiss-nav-item span:last-child { display: none; }
.kiss-main { margin-left: 60px; }
.kiss-grid-auto { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
.kiss-sidebar { display: none; }
.kiss-main { margin-left: 0; }
.kiss-grid-auto { grid-template-columns: 1fr; }
}
`;
var style = document.createElement('style');
style.id = 'kiss-interceptor-css';

View File

@ -14,6 +14,29 @@
*/
window.KissTheme = window.KissTheme || {
// Navigation config - shared across all views
nav: [
{ cat: 'Main', items: [
{ icon: '🏠', name: 'Home', path: 'admin/secubox-home' },
{ icon: '📊', name: 'System Hub', path: 'admin/secubox/system/system-hub' }
]},
{ cat: 'Security', items: [
{ icon: '🧙', name: 'InterceptoR', path: 'admin/secubox/interceptor/overview' },
{ icon: '🛡️', name: 'CrowdSec', path: 'admin/secubox/security/crowdsec/overview' },
{ icon: '🔍', name: 'mitmproxy', path: 'admin/secubox/security/mitmproxy/status' },
{ icon: '🌐', name: 'DNS Guard', path: 'admin/secubox/security/dnsguard' }
]},
{ cat: 'Services', items: [
{ icon: '📡', name: 'IoT Guard', path: 'admin/secubox/services/iot-guard' },
{ icon: '💾', name: 'CDN Cache', path: 'admin/services/cdn-cache' },
{ icon: '🔗', name: 'HAProxy', path: 'admin/services/haproxy' },
{ icon: '🔒', name: 'WireGuard', path: 'admin/services/wireguard' }
]},
{ cat: 'Navigate', items: [
{ icon: '🌳', name: 'LuCI Tree', path: 'admin/secubox/luci-tree' }
]}
],
// Core palette
colors: {
bg: '#0a0e17',
@ -120,9 +143,53 @@ window.KissTheme = window.KissTheme || {
.kiss-panel-red { border-left: 3px solid var(--kiss-red); }
.kiss-panel-blue { border-left: 3px solid var(--kiss-blue); }
.kiss-panel-orange { border-left: 3px solid var(--kiss-orange); }
/* Sidebar layout */
.kiss-with-sidebar { display: flex; }
.kiss-sidebar {
position: fixed; left: 0; top: 0; bottom: 0; width: 200px;
background: linear-gradient(180deg, #0d1321 0%, var(--kiss-bg) 100%);
border-right: 1px solid var(--kiss-line); z-index: 100;
display: flex; flex-direction: column; overflow-y: auto;
}
.kiss-sidebar-logo {
padding: 16px; border-bottom: 1px solid var(--kiss-line); text-align: center;
}
.kiss-logo-text { font-weight: 900; font-size: 24px; letter-spacing: -1px; }
.kiss-logo-sub { font-size: 9px; color: var(--kiss-muted); letter-spacing: 2px; margin-top: 4px; }
.kiss-nav { flex: 1; padding: 8px 0; }
.kiss-nav-section {
padding: 8px 12px 4px; font-size: 9px; letter-spacing: 2px;
text-transform: uppercase; color: var(--kiss-muted);
}
.kiss-nav-item {
display: flex; align-items: center; gap: 10px; padding: 8px 16px;
text-decoration: none; font-size: 13px; color: var(--kiss-muted);
transition: all 0.2s; border-left: 2px solid transparent;
}
.kiss-nav-item:hover { background: rgba(255,255,255,0.03); color: var(--kiss-text); }
.kiss-nav-item.active { color: var(--kiss-green); background: rgba(0,200,83,0.05); border-left-color: var(--kiss-green); }
.kiss-nav-icon { font-size: 16px; width: 20px; text-align: center; }
.kiss-main { margin-left: 200px; padding: 20px; flex: 1; min-height: 100vh; }
/* Toggle */
#kiss-toggle {
position: fixed; top: 10px; right: 10px; z-index: 99999;
font-size: 32px; cursor: pointer; opacity: 0.7; transition: all 0.3s;
background: rgba(0,0,0,0.5); border-radius: 50%; width: 50px; height: 50px;
display: flex; align-items: center; justify-content: center;
}
#kiss-toggle:hover { opacity: 1; transform: scale(1.1); }
/* Responsive */
@media (max-width: 768px) {
.kiss-grid-2, .kiss-grid-3, .kiss-grid-4 { grid-template-columns: 1fr; }
.kiss-sidebar { width: 60px; }
.kiss-sidebar-logo, .kiss-nav-section { display: none; }
.kiss-nav-item { padding: 12px; justify-content: center; }
.kiss-nav-item span:last-child { display: none; }
.kiss-main { margin-left: 60px; }
}
@media (max-width: 480px) {
.kiss-sidebar { display: none; }
.kiss-main { margin-left: 0; }
}
`;
},
@ -283,6 +350,50 @@ window.KissTheme = window.KissTheme || {
'class': 'kiss-btn' + (type ? ' kiss-btn-' + type : ''),
'onClick': onClick
}, label);
},
// Render sidebar navigation
renderSidebar: function(activePath) {
var self = this;
var currentPath = activePath || window.location.pathname.replace('/cgi-bin/luci/', '');
var navItems = [];
this.nav.forEach(function(cat) {
navItems.push(self.E('div', { 'class': 'kiss-nav-section' }, cat.cat));
cat.items.forEach(function(item) {
var isActive = currentPath.indexOf(item.path) !== -1;
navItems.push(self.E('a', {
'href': '/cgi-bin/luci/' + item.path,
'class': 'kiss-nav-item' + (isActive ? ' active' : '')
}, [
self.E('span', { 'class': 'kiss-nav-icon' }, item.icon),
self.E('span', {}, item.name)
]));
});
});
return this.E('nav', { 'class': 'kiss-sidebar' }, [
this.E('div', { 'class': 'kiss-sidebar-logo' }, [
this.E('div', { 'class': 'kiss-logo-text' }, [
this.E('span', { 'style': 'color: var(--kiss-green);' }, 'C'),
this.E('span', { 'style': 'color: var(--kiss-red); font-size: 14px; vertical-align: super;' }, '3'),
this.E('span', { 'style': 'color: var(--kiss-blue);' }, 'B'),
this.E('span', { 'style': 'color: #37474F;' }, 'O'),
this.E('span', { 'style': 'color: var(--kiss-green);' }, 'X')
]),
this.E('div', { 'class': 'kiss-logo-sub' }, 'SECUBOX')
]),
this.E('div', { 'class': 'kiss-nav' }, navItems)
]);
},
// Create full page with sidebar
wrap: function(content, activePath) {
this.apply();
return this.E('div', { 'class': 'kiss-root kiss-with-sidebar' }, [
this.renderSidebar(activePath),
this.E('div', { 'class': 'kiss-main' }, Array.isArray(content) ? content : [content])
]);
}
};