'use strict'; 'require view'; 'require ui'; 'require secubox/api as API'; 'require dom'; // Load CSS document.head.appendChild(E('link', { 'rel': 'stylesheet', 'type': 'text/css', 'href': L.resource('secubox/secubox.css') })); return view.extend({ load: function() { return Promise.all([ API.getDashboardData(), API.getSystemHealth(), API.getAlerts() ]); }, render: function(data) { var dashboard = data[0] || {}; var health = data[1] || {}; var alertsData = data[2] || {}; var status = dashboard.status || {}; var modules = dashboard.modules || []; var counts = dashboard.counts || {}; var alerts = alertsData.alerts || []; var container = E('div', { 'class': 'cbi-map' }); // Header container.appendChild(E('h2', {}, 'SecuBox Central Hub')); container.appendChild(E('p', {}, 'Hostname: ' + (status.hostname || 'Unknown') + ' | ' + 'Uptime: ' + API.formatUptime(status.uptime) + ' | ' + 'Load: ' + (status.load || '0.00') )); // System Health Section container.appendChild(this.renderSystemHealth(health)); // Quick Actions Section container.appendChild(this.renderQuickActions()); // Alerts Section if (alerts.length > 0) { container.appendChild(this.renderAlerts(alerts)); } // Modules Grid container.appendChild(this.renderModulesGrid(modules)); return container; }, renderSystemHealth: function(health) { var cpu = health.cpu || {}; var memory = health.memory || {}; var disk = health.disk || {}; var network = health.network || {}; var section = E('div', { 'class': 'secubox-health-section' }, [ E('h3', {}, 'System Health'), E('div', { 'class': 'secubox-health-grid' }, [ this.renderGauge('CPU', cpu.percent || 0, '%', cpu.load_1min), this.renderGauge('Memory', memory.percent || 0, '%', API.formatBytes(memory.used_kb * 1024) + ' / ' + API.formatBytes(memory.total_kb * 1024)), this.renderGauge('Disk', disk.percent || 0, '%', API.formatBytes(disk.used_kb * 1024) + ' / ' + API.formatBytes(disk.total_kb * 1024)), this.renderGauge('Network', 0, '', 'RX: ' + API.formatBytes(network.rx_bytes) + ' | TX: ' + API.formatBytes(network.tx_bytes)) ]) ]); return section; }, renderGauge: function(label, percent, unit, details) { var color = percent < 70 ? '#22c55e' : percent < 85 ? '#f59e0b' : '#ef4444'; return E('div', { 'class': 'secubox-gauge' }, [ E('div', { 'class': 'secubox-gauge-label' }, label), E('div', { 'class': 'secubox-gauge-chart' }, [ E('svg', { 'width': '120', 'height': '120', 'viewBox': '0 0 120 120' }, [ E('circle', { 'cx': '60', 'cy': '60', 'r': '54', 'fill': 'none', 'stroke': '#1e293b', 'stroke-width': '12' }), E('circle', { 'cx': '60', 'cy': '60', 'r': '54', 'fill': 'none', 'stroke': color, 'stroke-width': '12', 'stroke-dasharray': (339.292 * percent / 100) + ' 339.292', 'stroke-linecap': 'round', 'transform': 'rotate(-90 60 60)' }), E('text', { 'x': '60', 'y': '65', 'text-anchor': 'middle', 'font-size': '24', 'font-weight': 'bold', 'fill': color }, percent + unit) ]) ]), E('div', { 'class': 'secubox-gauge-details' }, details || '') ]); }, renderQuickActions: function() { var self = this; var actions = [ { name: 'restart_rpcd', label: 'Restart RPCD', icon: '๐Ÿ”„' }, { name: 'restart_uhttpd', label: 'Restart uHTTPd', icon: '๐ŸŒ' }, { name: 'clear_cache', label: 'Clear Cache', icon: '๐Ÿงน' }, { name: 'backup_config', label: 'Backup Config', icon: '๐Ÿ’พ' }, { name: 'restart_network', label: 'Restart Network', icon: '๐Ÿ“ก' }, { name: 'restart_firewall', label: 'Restart Firewall', icon: '๐Ÿ›ก๏ธ' } ]; var buttons = actions.map(function(action) { return E('button', { 'class': 'cbi-button cbi-button-action', 'click': function() { self.executeQuickAction(action.name, action.label); } }, action.icon + ' ' + action.label); }); return E('div', { 'class': 'secubox-quick-actions' }, [ E('h3', {}, 'Quick Actions'), E('div', { 'class': 'secubox-actions-grid' }, buttons) ]); }, executeQuickAction: function(action, label) { ui.showModal(_('Quick Action'), [ E('p', { 'class': 'spinning' }, _('Executing: ') + label + '...') ]); API.quickAction(action).then(function(result) { ui.hideModal(); if (result && result.success) { ui.addNotification(null, E('p', result.message || 'Action completed'), 'info'); } else { ui.addNotification(null, E('p', result.message || 'Action failed'), 'error'); } }).catch(function(err) { ui.hideModal(); ui.addNotification(null, E('p', 'Error: ' + err.message), 'error'); }); }, renderAlerts: function(alerts) { var alertItems = alerts.map(function(alert) { var severityClass = 'secubox-alert-' + (alert.severity || 'info'); return E('div', { 'class': 'secubox-alert ' + severityClass }, [ E('strong', {}, alert.module + ': '), E('span', {}, alert.message) ]); }); return E('div', { 'class': 'secubox-alerts-section' }, [ E('h3', {}, 'Recent Alerts (' + alerts.length + ')'), E('div', { 'class': 'secubox-alerts-list' }, alertItems) ]); }, renderModulesGrid: function(modules) { var moduleCards = modules.map(function(module) { var statusClass = module.installed ? (module.running ? 'running' : 'stopped') : 'not-installed'; var statusIcon = module.installed ? (module.running ? 'โœ“' : 'โœ—') : 'โ—‹'; var statusColor = module.installed ? (module.running ? '#22c55e' : '#ef4444') : '#64748b'; return E('div', { 'class': 'secubox-module-card', 'data-status': statusClass }, [ E('div', { 'class': 'secubox-module-header' }, [ E('div', { 'class': 'secubox-module-icon', 'style': 'background-color: ' + (module.color || '#64748b') }, module.icon || '๐Ÿ“ฆ'), E('div', { 'class': 'secubox-module-status', 'style': 'color: ' + statusColor }, statusIcon) ]), E('div', { 'class': 'secubox-module-body' }, [ E('div', { 'class': 'secubox-module-name' }, module.name || module.id), E('div', { 'class': 'secubox-module-description' }, module.description || ''), E('div', { 'class': 'secubox-module-category' }, module.category || 'other') ]), E('div', { 'class': 'secubox-module-footer' }, [ module.installed ? E('a', { 'href': '#', 'class': 'cbi-button cbi-button-link', 'click': function(ev) { ev.preventDefault(); window.location.hash = '#admin/secubox/' + module.id; } }, 'Open Dashboard') : E('span', { 'class': 'secubox-not-installed' }, 'Not Installed') ]) ]); }); return E('div', { 'class': 'secubox-modules-section' }, [ E('h3', {}, 'Installed Modules'), E('div', { 'class': 'secubox-modules-grid' }, moduleCards) ]); }, handleSaveApply: null, handleSave: null, handleReset: null });