feat: Add Apps section to SecuBox portal navigation
- Add "Apps" tab to header navigation for extended applications - Create apps.js view showing app categories: Administration, Services, IoT - Include SecuBox Admin, Cyber Dashboard, vHost Manager, Zigbee2MQTT, MagicMirror, and MQTT Bridge - Move ndpid and netifyd detection to Monitoring section - Add menu entry for /admin/secubox/apps Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
20619fd241
commit
fec4b5a128
@ -227,7 +227,8 @@ var sections = [
|
|||||||
{ id: 'security', name: 'Security', icon: '\ud83d\udee1\ufe0f', path: 'admin/secubox/security' },
|
{ id: 'security', name: 'Security', icon: '\ud83d\udee1\ufe0f', path: 'admin/secubox/security' },
|
||||||
{ id: 'network', name: 'Network', icon: '\ud83c\udf10', path: 'admin/secubox/network' },
|
{ id: 'network', name: 'Network', icon: '\ud83c\udf10', path: 'admin/secubox/network' },
|
||||||
{ id: 'monitoring', name: 'Monitoring', icon: '\ud83d\udcca', path: 'admin/secubox/monitoring' },
|
{ id: 'monitoring', name: 'Monitoring', icon: '\ud83d\udcca', path: 'admin/secubox/monitoring' },
|
||||||
{ id: 'system', name: 'System', icon: '\u2699\ufe0f', path: 'admin/secubox/system' }
|
{ id: 'system', name: 'System', icon: '\u2699\ufe0f', path: 'admin/secubox/system' },
|
||||||
|
{ id: 'apps', name: 'Apps', icon: '\ud83d\udce6', path: 'admin/secubox/apps' }
|
||||||
];
|
];
|
||||||
|
|
||||||
function injectCSS() {
|
function injectCSS() {
|
||||||
@ -278,7 +279,14 @@ function detectActiveSection() {
|
|||||||
if (path.indexOf('/secubox/security') !== -1) return 'security';
|
if (path.indexOf('/secubox/security') !== -1) return 'security';
|
||||||
if (path.indexOf('/secubox/network') !== -1) return 'network';
|
if (path.indexOf('/secubox/network') !== -1) return 'network';
|
||||||
if (path.indexOf('/secubox/monitoring') !== -1) return 'monitoring';
|
if (path.indexOf('/secubox/monitoring') !== -1) return 'monitoring';
|
||||||
|
if (path.indexOf('/secubox/ndpid') !== -1) return 'monitoring';
|
||||||
|
if (path.indexOf('/secubox/netifyd') !== -1) return 'monitoring';
|
||||||
if (path.indexOf('/secubox/system') !== -1) return 'system';
|
if (path.indexOf('/secubox/system') !== -1) return 'system';
|
||||||
|
if (path.indexOf('/secubox/apps') !== -1) return 'apps';
|
||||||
|
if (path.indexOf('/secubox/admin') !== -1) return 'apps';
|
||||||
|
if (path.indexOf('/secubox/services') !== -1) return 'apps';
|
||||||
|
if (path.indexOf('/secubox/iot') !== -1) return 'apps';
|
||||||
|
if (path.indexOf('/secubox/zigbee2mqtt') !== -1) return 'apps';
|
||||||
return 'dashboard';
|
return 'dashboard';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,296 @@
|
|||||||
|
'use strict';
|
||||||
|
'require view';
|
||||||
|
'require dom';
|
||||||
|
'require ui';
|
||||||
|
'require secubox-theme/theme as Theme';
|
||||||
|
'require secubox-portal/header as SbHeader';
|
||||||
|
|
||||||
|
var lang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
|
||||||
|
(document.documentElement && document.documentElement.getAttribute('lang')) ||
|
||||||
|
(navigator.language ? navigator.language.split('-')[0] : 'en');
|
||||||
|
Theme.init({ language: lang });
|
||||||
|
|
||||||
|
// Extended Apps catalog - apps not in main nav sections
|
||||||
|
var appCategories = [
|
||||||
|
{
|
||||||
|
id: 'admin',
|
||||||
|
name: 'Administration',
|
||||||
|
icon: '\ud83d\udee0\ufe0f',
|
||||||
|
description: 'SecuBox administration and app management',
|
||||||
|
apps: [
|
||||||
|
{ id: 'secubox-admin', name: 'SecuBox Admin', icon: '\ud83d\udcbb', path: 'admin/secubox/admin', desc: 'App catalog, updates, and system configuration' },
|
||||||
|
{ id: 'cyber-dashboard', name: 'Cyber Dashboard', icon: '\ud83d\udcca', path: 'admin/secubox/admin/cyber-dashboard', desc: 'Advanced analytics and insights' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'services',
|
||||||
|
name: 'Services',
|
||||||
|
icon: '\ud83d\udd27',
|
||||||
|
description: 'Server and service management',
|
||||||
|
apps: [
|
||||||
|
{ id: 'vhost-manager', name: 'Virtual Hosts', icon: '\ud83c\udf10', path: 'admin/secubox/services/vhosts', desc: 'Web server virtual hosts and SSL certificates' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'iot',
|
||||||
|
name: 'IoT & Smart Home',
|
||||||
|
icon: '\ud83c\udfe0',
|
||||||
|
description: 'Internet of Things and home automation',
|
||||||
|
apps: [
|
||||||
|
{ id: 'zigbee2mqtt', name: 'Zigbee2MQTT', icon: '\ud83d\udca1', path: 'admin/secubox/zigbee2mqtt', desc: 'Zigbee device bridge for smart home' },
|
||||||
|
{ id: 'magicmirror', name: 'MagicMirror', icon: '\ud83e\ude9e', path: 'admin/secubox/iot/magicmirror', desc: 'Smart mirror display management' },
|
||||||
|
{ id: 'mqtt-bridge', name: 'MQTT Bridge', icon: '\ud83d\udd17', path: 'admin/secubox/network/mqtt-bridge', desc: 'MQTT message broker and bridge' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return view.extend({
|
||||||
|
render: function() {
|
||||||
|
// Main wrapper with SecuBox header
|
||||||
|
var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
|
||||||
|
wrapper.appendChild(SbHeader.render());
|
||||||
|
|
||||||
|
var container = E('div', { 'class': 'sb-apps-view' }, [
|
||||||
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
||||||
|
E('style', {}, this.getStyles()),
|
||||||
|
this.renderHeader(),
|
||||||
|
this.renderAppGrid()
|
||||||
|
]);
|
||||||
|
|
||||||
|
wrapper.appendChild(container);
|
||||||
|
return wrapper;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderHeader: function() {
|
||||||
|
return E('div', { 'class': 'sb-apps-header' }, [
|
||||||
|
E('div', { 'class': 'sb-apps-title-row' }, [
|
||||||
|
E('h1', { 'class': 'sb-apps-title' }, [
|
||||||
|
E('span', { 'class': 'sb-apps-icon' }, '\ud83d\udce6'),
|
||||||
|
_('Extended Apps')
|
||||||
|
]),
|
||||||
|
E('span', { 'class': 'sb-apps-badge' }, appCategories.reduce(function(sum, cat) {
|
||||||
|
return sum + cat.apps.length;
|
||||||
|
}, 0) + ' ' + _('apps'))
|
||||||
|
]),
|
||||||
|
E('p', { 'class': 'sb-apps-subtitle' },
|
||||||
|
_('Additional SecuBox applications for administration, IoT, and advanced features'))
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderAppGrid: function() {
|
||||||
|
var self = this;
|
||||||
|
return E('div', { 'class': 'sb-apps-categories' },
|
||||||
|
appCategories.map(function(category) {
|
||||||
|
return self.renderCategory(category);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderCategory: function(category) {
|
||||||
|
var self = this;
|
||||||
|
return E('div', { 'class': 'sb-apps-category' }, [
|
||||||
|
E('div', { 'class': 'sb-apps-category-header' }, [
|
||||||
|
E('span', { 'class': 'sb-apps-category-icon' }, category.icon),
|
||||||
|
E('div', {}, [
|
||||||
|
E('h2', { 'class': 'sb-apps-category-title' }, category.name),
|
||||||
|
E('p', { 'class': 'sb-apps-category-desc' }, category.description)
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
E('div', { 'class': 'sb-apps-grid' },
|
||||||
|
category.apps.map(function(app) {
|
||||||
|
return self.renderAppCard(app);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderAppCard: function(app) {
|
||||||
|
return E('a', {
|
||||||
|
'class': 'sb-app-card',
|
||||||
|
'href': L.url(app.path)
|
||||||
|
}, [
|
||||||
|
E('div', { 'class': 'sb-app-card-icon' }, app.icon),
|
||||||
|
E('div', { 'class': 'sb-app-card-content' }, [
|
||||||
|
E('h3', { 'class': 'sb-app-card-name' }, app.name),
|
||||||
|
E('p', { 'class': 'sb-app-card-desc' }, app.desc)
|
||||||
|
]),
|
||||||
|
E('div', { 'class': 'sb-app-card-arrow' }, '\u2192')
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
getStyles: function() {
|
||||||
|
return `
|
||||||
|
.sb-apps-view {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #0a0a0f;
|
||||||
|
color: #fafafa;
|
||||||
|
padding: 20px;
|
||||||
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-header {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
padding: 24px;
|
||||||
|
background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
|
||||||
|
border: 1px solid rgba(102, 126, 234, 0.2);
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-title-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.75rem;
|
||||||
|
font-weight: 700;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-icon {
|
||||||
|
font-size: 2rem;
|
||||||
|
-webkit-text-fill-color: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-badge {
|
||||||
|
padding: 6px 14px;
|
||||||
|
background: rgba(102, 126, 234, 0.2);
|
||||||
|
border: 1px solid rgba(102, 126, 234, 0.3);
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #a5b4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-subtitle {
|
||||||
|
margin: 8px 0 0 0;
|
||||||
|
color: #a0a0b0;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-categories {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-category {
|
||||||
|
background: #12121a;
|
||||||
|
border: 1px solid #2a2a35;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-category-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
border-bottom: 1px solid #2a2a35;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-category-icon {
|
||||||
|
font-size: 2rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-category-title {
|
||||||
|
margin: 0 0 4px 0;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-category-desc {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #71717a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-app-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
background: #1a1a24;
|
||||||
|
border: 1px solid #2a2a35;
|
||||||
|
border-radius: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-app-card:hover {
|
||||||
|
background: #1f1f2a;
|
||||||
|
border-color: #667eea;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 8px 24px rgba(102, 126, 234, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-app-card-icon {
|
||||||
|
font-size: 2rem;
|
||||||
|
line-height: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-app-card-content {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-app-card-name {
|
||||||
|
margin: 0 0 4px 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-app-card-desc {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #71717a;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-app-card-arrow {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: #667eea;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-8px);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-app-card:hover .sb-app-card-arrow {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.sb-apps-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sb-apps-title {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -15,6 +15,14 @@
|
|||||||
"path": "secubox-portal/index"
|
"path": "secubox-portal/index"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"admin/secubox/apps": {
|
||||||
|
"title": "Apps",
|
||||||
|
"order": 60,
|
||||||
|
"action": {
|
||||||
|
"type": "view",
|
||||||
|
"path": "secubox-portal/apps"
|
||||||
|
}
|
||||||
|
},
|
||||||
"admin/secubox-home": {
|
"admin/secubox-home": {
|
||||||
"title": "SecuBox Home",
|
"title": "SecuBox Home",
|
||||||
"order": 0,
|
"order": 0,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user