desvergue-de-alexandro
js 88 lines 3.24 KB
Raw
1 /**
2 * MAPS Connect - Layout compartido (menú lateral plegable)
3 */
4
5 const NAV_ITEMS = [
6 { href: 'inicio.html', label: 'Inicio' },
7 { href: 'perfil.html', label: 'Mi Perfil' },
8 { href: 'foro.html', label: 'Foro de Dudas' },
9 { href: 'tips.html', label: 'Tips Académicos' },
10 { href: 'recursos.html', label: 'Apuntes' },
11 { href: 'mensajes.html', label: 'Mensajes' },
12 { href: 'empresarial.html', label: 'Semestre Empresarial' },
13 { href: 'circulos.html', label: 'Círculos de Estudio' }
14 ];
15
16 const Layout = {
17 init(currentPage) {
18 if (!Auth.requireAuth()) return;
19
20 this.renderSidebar(currentPage);
21 this.renderTopbar();
22 this.bindToggle();
23 },
24
25 renderSidebar(currentPage) {
26 const sidebar = document.getElementById('sidebar');
27 if (!sidebar) return;
28
29 const user = Auth.getUser();
30 const navLinks = NAV_ITEMS.map(item => {
31 const active = item.href === currentPage ? 'active' : '';
32 return `<li><a href="${item.href}" class="${active}">${item.label}</a></li>`;
33 }).join('');
34
35 sidebar.innerHTML = `
36 <div class="sidebar-header">
37 <h1>MAPS Connect</h1>
38 <small>${user?.nombre || 'Usuario'}</small>
39 </div>
40 <ul class="sidebar-nav">${navLinks}</ul>
41 <div class="sidebar-footer">
42 <button class="btn btn-sm btn-outline" id="btn-logout">Cerrar sesión</button>
43 </div>
44 `;
45
46 document.getElementById('btn-logout')?.addEventListener('click', () => Auth.logout());
47 },
48
49 renderTopbar() {
50 const topbar = document.getElementById('topbar');
51 if (!topbar) return;
52
53 topbar.innerHTML = `
54 <button class="menu-backdrop" id="menu-backdrop" type="button" aria-label="Cerrar menú"></button>
55 <button class="menu-toggle" id="sidebar-toggle" type="button"
56 aria-label="Abrir menú" aria-controls="sidebar" aria-expanded="false">
57 <span aria-hidden="true">☰</span>
58 </button>
59 <span id="topbar-title" class="visually-hidden"></span>
60 `;
61 },
62
63 bindToggle() {
64 const toggle = document.getElementById('sidebar-toggle');
65 const sidebar = document.getElementById('sidebar');
66 const layout = document.querySelector('.app-layout');
67 const backdrop = document.getElementById('menu-backdrop');
68
69 const setMenuState = isOpen => {
70 sidebar?.classList.toggle('open', isOpen);
71 layout?.classList.toggle('menu-open', isOpen);
72 toggle.setAttribute('aria-expanded', String(isOpen));
73 toggle.setAttribute('aria-label', isOpen ? 'Cerrar menú' : 'Abrir menú');
74 };
75
76 toggle?.addEventListener('click', () => setMenuState(!sidebar?.classList.contains('open')));
77 backdrop?.addEventListener('click', () => setMenuState(false));
78 document.addEventListener('keydown', event => {
79 if (event.key === 'Escape' && sidebar?.classList.contains('open')) setMenuState(false);
80 });
81 },
82
83 setPageTitle(title) {
84 const el = document.getElementById('topbar-title');
85 if (el) el.textContent = title;
86 document.title = `${title} | MAPS Connect`;
87 }
88 };