// BOC — Business Operations Center // Single-page app shell. One sidebar, dynamic modules. // Linus principle: write it once, route everything through it. const API_BASE = '/api/v1'; // Module registry — add new modules here const modules = { '/': () => import('./modules/dashboard.js'), '/crm': () => import('./modules/crm.js'), '/sales': () => import('./modules/sales.js'), '/finance': () => import('./modules/finance.js'), '/hr': () => import('./modules/hr.js'), '/legal': () => import('./modules/legal.js'), '/marketing': () => import('./modules/marketing.js'), '/support': () => import('./modules/support.js'), '/automation': () => import('./modules/automation.js'), }; // Sidebar configuration — one source of truth const sidebarItems = [ { path: '/', label: 'Dashboard', icon: 'grid' }, { path: '/crm', label: 'CRM', icon: 'users' }, { path: '/sales', label: 'Sales', icon: 'dollar' }, { path: '/finance', label: 'Finance', icon: 'bar-chart' }, { path: '/hr', label: 'HR', icon: 'user' }, { path: '/legal', label: 'Legal', icon: 'file-text' }, { path: '/marketing', label: 'Marketing', icon: 'megaphone' }, { path: '/support', label: 'Support', icon: 'help-circle' }, { path: '/automation', label: 'Automation', icon: 'zap' }, ]; // Auth utilities function getToken() { return localStorage.getItem('boc_token'); } function getUser() { const u = localStorage.getItem('boc_user'); return u ? JSON.parse(u) : null; } function apiRequest(endpoint, options = {}) { const token = getToken(); const url = endpoint.startsWith('http') ? endpoint : `${API_BASE}${endpoint}`; return fetch(url, { ...options, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, ...options.headers } }); } // Router async function navigate(path) { const app = document.getElementById('app'); const loader = modules[path] || modules['/']; try { const mod = await loader(); app.innerHTML = ''; await mod.render(app); updateActiveNav(path); } catch (err) { app.innerHTML = `