/** * sidebar.js — Shared sidebar matching the design system style * Replaces existing sidebar in each page with a consistent, themed version. * Uses i18n t() for all labels when available. */ (function() { 'use strict'; // i18n helper — falls back to raw string if i18n.js not loaded var _t = typeof window.t === 'function' ? window.t : function(k) { return k; }; var u = window.POS_USER || {}; var name = u.name || 'Usuario'; var roleLabel = u.roleLabel || ''; var initials = u.initials || '?'; var currentPath = window.location.pathname; var currentTheme = localStorage.getItem('pos_theme') || 'industrial'; var currentLang = localStorage.getItem('pos_lang') || 'es'; var navSections = [ { label: _t('nav_main'), items: [ { name: _t('dashboard'), href: '/pos/dashboard', icon: '' }, { name: _t('pos'), href: '/pos/sale', icon: '' }, { name: _t('catalog'), href: '/pos/catalog', icon: '' }, { name: _t('inventory'), href: '/pos/inventory', icon: '' }, ]}, { label: _t('nav_management'), items: [ { name: _t('customers'), href: '/pos/customers', icon: '' }, { name: 'Cotizaciones', href: '/pos/quotations', icon: '' }, { name: 'Marketplace', href: '/pos/marketplace', icon: '' }, { name: 'MercadoLibre', href: '/pos/marketplace-external', icon: '' }, { name: _t('invoicing'), href: '/pos/invoicing', icon: '' }, { name: _t('accounting'), href: '/pos/accounting', icon: '' }, { name: _t('reports'), href: '/pos/reports', icon: '' }, { name: _t('fleet'), href: '/pos/fleet', icon: '' }, { name: _t('whatsapp'), href: '/pos/whatsapp', icon: '' }, ]}, { label: _t('nav_system'), items: [ { name: _t('config'), href: '/pos/config', icon: '' }, ]}, ]; function svgIcon(paths) { return '' + paths + ''; } // Build nav HTML var navHtml = ''; navSections.forEach(function(sec) { navHtml += ''; sec.items.forEach(function(item) { var active = currentPath === item.href; navHtml += '' + svgIcon(item.icon) + '' + item.name + ''; }); }); // Theme toggle buttons var themeHtml = ''; // Language toggle buttons var langHtml = ''; window.updateThemeButtons = function() { var t = localStorage.getItem('pos_theme') || 'industrial'; document.querySelectorAll('.theme-toggle-btn').forEach(function(b, i) { b.classList.toggle('is-active', i === 0 ? t === 'industrial' : t === 'modern'); }); }; var sidebarHtml = '' + '' + '' + themeHtml + langHtml + ''; // Replace existing sidebar var existing = document.querySelector('aside.sidebar, .sidebar, #sidebar'); if (existing) { existing.className = 'pos-sidebar'; existing.innerHTML = sidebarHtml; existing.removeAttribute('style'); } else { var el = document.createElement('aside'); el.className = 'pos-sidebar'; el.innerHTML = sidebarHtml; document.body.insertBefore(el, document.body.firstChild); } // Offset main content var main = document.querySelector('main, .main-content, #mainContent, .main, .page-content'); if (main) main.classList.add('pos-main-offset'); // ── Tablet/mobile: sidebar toggle + overlay ───────────────────── // Creates a hamburger button + overlay for screens < 1024px. // The CSS in pos-glass.css hides the sidebar by default on tablets // and shows it as a slide-in drawer when .open is added. var sidebar = document.querySelector('.pos-sidebar, .sidebar, #sidebar'); var overlay = document.getElementById('sidebar-overlay'); // Create overlay if it doesn't exist if (!overlay && sidebar) { overlay = document.createElement('div'); overlay.id = 'sidebar-overlay'; overlay.className = 'sidebar-overlay'; overlay.addEventListener('click', function () { closeSidebar(); }); sidebar.parentNode.insertBefore(overlay, sidebar); } // Create hamburger button if it doesn't exist var hamburger = document.getElementById('hamburger-btn'); if (!hamburger) { hamburger = document.createElement('button'); hamburger.id = 'hamburger-btn'; hamburger.className = 'hamburger-btn'; hamburger.setAttribute('aria-label', 'Menú'); hamburger.innerHTML = ''; hamburger.style.cssText = 'display:none;position:fixed;top:10px;left:10px;z-index:' + (parseInt(getComputedStyle(document.documentElement).getPropertyValue('--z-modal') || 1050) + 2) + ';background:var(--glass-bg-strong);backdrop-filter:blur(12px);border:1px solid var(--glass-border);' + 'border-radius:var(--radius-md);padding:8px;cursor:pointer;color:var(--color-text-primary);' + 'box-shadow:0 2px 8px rgba(0,0,0,0.2);'; hamburger.addEventListener('click', function () { toggleSidebar(); }); document.body.appendChild(hamburger); } function toggleSidebar() { if (!sidebar) return; var isOpen = sidebar.classList.contains('open'); sidebar.classList.toggle('open', !isOpen); if (overlay) overlay.classList.toggle('open', !isOpen); document.body.style.overflow = isOpen ? '' : 'hidden'; } function closeSidebar() { if (sidebar) sidebar.classList.remove('open'); if (overlay) overlay.classList.remove('open'); document.body.style.overflow = ''; } // Auto-close sidebar on window resize to desktop window.addEventListener('resize', function () { if (window.innerWidth >= 1024) closeSidebar(); }); // Expose globally so inline onclick handlers and page-specific JS can call them window.toggleSidebar = toggleSidebar; window.closeSidebar = closeSidebar; // Reveal sidebar smoothly after replacement to avoid flash/stun document.body.classList.add('sidebar-ready'); })();