// Nexus โ€” Shared Sidebar + Layout Component // Usage: Include after Alpine.js. Call initLayout() on each page. // Sets sidebar, highlights active nav item, loads user info. function initLayout(activeNav) { // activeNav: 'index'|'servers'|'files'|'push'|'scripts'|'credentials'|'schedules'|'retries'|'audit'|'settings' const navItems = [ { id:'index', icon:'๐Ÿ ', label:'ไปช่กจ็›˜', href:'/app/index.html' }, { id:'servers', icon:'๐Ÿ–ฅ', label:'ๆœๅŠกๅ™จ', href:'/app/servers.html' }, { id:'files', icon:'๐Ÿ“', label:'ๆ–‡ไปถ็ฎก็†', href:'/app/files.html' }, { id:'push', icon:'๐Ÿ“ค', label:'ๆŽจ้€', href:'/app/push.html' }, { id:'scripts', icon:'๐Ÿ“œ', label:'่„šๆœฌๅบ“', href:'/app/scripts.html' }, { id:'credentials', icon:'๐Ÿ”‘', label:'ๅ‡ญๆฎ', href:'/app/credentials.html' }, { id:'schedules', icon:'โฐ', label:'่ฐƒๅบฆ', href:'/app/schedules.html' }, { id:'retries', icon:'๐Ÿ”„', label:'้‡่ฏ•้˜Ÿๅˆ—', href:'/app/retries.html' }, ]; const bottomNav = [ { id:'audit', icon:'๐Ÿ“‹', label:'ๅฎก่ฎกๆ—ฅๅฟ—', href:'/app/audit.html' }, { id:'settings', icon:'โš™๏ธ', label:'่ฎพ็ฝฎ', href:'/app/settings.html' }, ]; // Build sidebar HTML const navHtml = navItems.map(n => `${n.icon} ${n.label}` ).join(''); const bottomHtml = bottomNav.map(n => `${n.icon} ${n.label}` ).join(''); // Find sidebar container const sidebar = document.querySelector('[data-sidebar]'); if (!sidebar) return; sidebar.innerHTML = `
Nexus
...
`; // Load user info loadLayoutUser(); } async function loadLayoutUser() { try { const r = await apiFetch(API + '/auth/me'); if (!r) { doLogout(); return; } const u = await r.json(); const el = document.getElementById('sidebarUser'); if (el) el.textContent = u.username; const headerEl = document.getElementById('headerUser'); if (headerEl) headerEl.textContent = u.username; // Set brand name const brandEl = document.getElementById('brandName'); if (brandEl && u.system_name) brandEl.textContent = u.system_name; } catch(e) {} }