96 lines
4.1 KiB
JavaScript
96 lines
4.1 KiB
JavaScript
'use strict';
|
|
'require view';
|
|
'require vhost-manager/api as API';
|
|
'require secubox-theme/theme as Theme';
|
|
'require vhost-manager/ui as VHostUI';
|
|
|
|
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 });
|
|
|
|
var SERVICES = [
|
|
{ icon: '🖥️', name: _('LuCI UI'), domain: 'router.local', backend: 'http://127.0.0.1:80', category: _('Core'), description: _('Expose the management UI behind nginx with optional SSL and auth.') },
|
|
{ icon: '📈', name: _('Netdata'), domain: 'metrics.local', backend: 'http://127.0.0.1:19999', category: _('Monitoring'), description: _('High-resolution telemetry for CPU, memory, and interfaces.') },
|
|
{ icon: '🛡️', name: _('CrowdSec'), domain: 'crowdsec.local', backend: 'http://127.0.0.1:8080', category: _('Security'), description: _('Review bouncer decisions and live intrusion alerts.') },
|
|
{ icon: '🏠', name: _('Home Assistant'), domain: 'home.local', backend: 'http://192.168.1.13:8123', category: _('Automation'), description: _('Publish your smart-home UI securely with SSL and auth.') },
|
|
{ icon: '🎬', name: _('Media Server'), domain: 'media.local', backend: 'http://192.168.1.12:8096', category: _('Entertainment'), description: _('Jellyfin or Plex front-end available via a friendly hostname.') },
|
|
{ icon: '🗄️', name: _('Nextcloud'), domain: 'cloud.local', backend: 'http://192.168.1.20:80', category: _('Productivity'), description: _('Bring private SaaS back on-prem with HTTPS and caching headers.') }
|
|
];
|
|
|
|
return view.extend({
|
|
load: function() {
|
|
return Promise.all([
|
|
API.listVHosts()
|
|
]);
|
|
},
|
|
|
|
render: function(data) {
|
|
var vhosts = data[0] || [];
|
|
var active = {};
|
|
vhosts.forEach(function(v) {
|
|
active[v.domain] = true;
|
|
});
|
|
|
|
return E('div', { 'class': 'vhost-page' }, [
|
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox-theme/secubox-theme.css') }),
|
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('vhost-manager/common.css') }),
|
|
E('link', { 'rel': 'stylesheet', 'href': L.resource('vhost-manager/dashboard.css') }),
|
|
VHostUI.renderTabs('internal'),
|
|
this.renderHeader(vhosts),
|
|
this.renderServices(active)
|
|
]);
|
|
},
|
|
|
|
renderHeader: function(vhosts) {
|
|
var configured = vhosts.filter(function(vhost) {
|
|
return SERVICES.some(function(s) { return s.domain === vhost.domain; });
|
|
}).length;
|
|
|
|
return E('div', { 'class': 'sh-page-header' }, [
|
|
E('div', {}, [
|
|
E('h2', { 'class': 'sh-page-title' }, [
|
|
E('span', { 'class': 'sh-page-title-icon' }, '🏠'),
|
|
_('Internal Service Catalog')
|
|
]),
|
|
E('p', { 'class': 'sh-page-subtitle' },
|
|
_('Pre-built recipes for publishing popular LAN services with SSL, auth, and redirects.'))
|
|
]),
|
|
E('div', { 'class': 'sh-stats-grid' }, [
|
|
this.renderStat(SERVICES.length, _('Templates')),
|
|
this.renderStat(configured, _('Configured'))
|
|
])
|
|
]);
|
|
},
|
|
|
|
renderStat: function(value, label) {
|
|
return E('div', { 'class': 'sh-stat-badge' }, [
|
|
E('div', { 'class': 'sh-stat-value' }, value.toString()),
|
|
E('div', { 'class': 'sh-stat-label' }, label)
|
|
]);
|
|
},
|
|
|
|
renderServices: function(active) {
|
|
return E('div', { 'class': 'vhost-card-grid' },
|
|
SERVICES.map(function(service) {
|
|
var isActive = !!active[service.domain];
|
|
return E('div', { 'class': 'vhost-card' }, [
|
|
E('div', { 'class': 'vhost-card-title' }, [service.icon, service.name]),
|
|
E('div', { 'class': 'vhost-card-meta' }, service.category),
|
|
E('p', { 'class': 'vhost-card-meta' }, service.description),
|
|
E('div', { 'class': 'vhost-card-meta' }, _('Domain: %s').format(service.domain)),
|
|
E('div', { 'class': 'vhost-card-meta' }, _('Backend: %s').format(service.backend)),
|
|
E('div', { 'class': 'vhost-actions' }, [
|
|
E('span', { 'class': 'vhost-pill ' + (isActive ? 'success' : '') },
|
|
isActive ? _('Published') : _('Not configured')),
|
|
E('a', {
|
|
'class': 'sh-btn-secondary',
|
|
'href': L.url('admin', 'secubox', 'services', 'vhosts', 'vhosts')
|
|
}, isActive ? _('Manage') : _('Create'))
|
|
])
|
|
]);
|
|
})
|
|
);
|
|
}
|
|
});
|