/** * Enhanced Sidebar Functionality * Version: 2.0 * Last Updated: 2025-11-19 */ (function() { 'use strict'; // Configuration const CONFIG = { STORAGE_KEY_COLLAPSED: 'sidebarCollapsed', STORAGE_KEY_SECTIONS: 'sidebarOpenSections', ANIMATION_DURATION: 300, MOBILE_BREAKPOINT: 1024 }; // State Management const state = { isCollapsed: false, openSections: new Set(), isMobile: window.innerWidth <= CONFIG.MOBILE_BREAKPOINT }; // Initialize function init() { loadState(); setupEventListeners(); setActiveLink(); updateBadges(); // Update mobile state on resize window.addEventListener('resize', debounce(handleResize, 250)); console.log('✅ Sidebar Enhanced initialized'); } // Load saved state from localStorage function loadState() { const sidebar = document.getElementById('sidebar'); // Load collapsed state state.isCollapsed = localStorage.getItem(CONFIG.STORAGE_KEY_COLLAPSED) === 'true'; if (state.isCollapsed && !state.isMobile) { sidebar?.classList.add('collapsed'); } // Load open sections try { const savedSections = localStorage.getItem(CONFIG.STORAGE_KEY_SECTIONS); if (savedSections) { state.openSections = new Set(JSON.parse(savedSections)); restoreOpenSections(); } } catch (e) { console.warn('Failed to load sidebar sections state:', e); } } // Save state to localStorage function saveState() { localStorage.setItem(CONFIG.STORAGE_KEY_COLLAPSED, state.isCollapsed); localStorage.setItem(CONFIG.STORAGE_KEY_SECTIONS, JSON.stringify([...state.openSections])); } // Restore open sections function restoreOpenSections() { state.openSections.forEach(sectionId => { const section = document.querySelector(`[data-section-id="${sectionId}"]`); if (section) { const header = section.querySelector('.sidebar-section-header'); const content = section.querySelector('.sidebar-section-content'); const icon = header?.querySelector('.fa-chevron-down'); if (content && icon) { content.style.maxHeight = content.scrollHeight + 'px'; icon.style.transform = 'rotate(180deg)'; } } }); } // Setup event listeners function setupEventListeners() { // Toggle collapse button const toggleBtn = document.getElementById('sidebarToggle'); if (toggleBtn) { toggleBtn.addEventListener('click', toggleSidebarCollapse); } // Mobile menu button const mobileBtn = document.querySelector('.mobile-menu-btn'); if (mobileBtn) { mobileBtn.addEventListener('click', openSidebar); } // Overlay const overlay = document.getElementById('sidebarOverlay'); if (overlay) { overlay.addEventListener('click', closeSidebar); } // Section headers document.querySelectorAll('.sidebar-section-header').forEach((header, index) => { const section = header.closest('.sidebar-section'); if (section && !section.dataset.sectionId) { section.dataset.sectionId = `section-${index}`; } header.addEventListener('click', () => toggleSection(header)); }); // Add keyboard shortcuts document.addEventListener('keydown', handleKeyboard); // Add tooltips for collapsed state addTooltips(); } // Toggle sidebar collapse function toggleSidebarCollapse() { if (state.isMobile) { closeSidebar(); return; } const sidebar = document.getElementById('sidebar'); state.isCollapsed = !state.isCollapsed; sidebar?.classList.toggle('collapsed'); saveState(); // Trigger custom event window.dispatchEvent(new CustomEvent('sidebarToggle', { detail: { collapsed: state.isCollapsed } })); } // Toggle section function toggleSection(button) { const section = button.closest('.sidebar-section'); const sectionId = section?.dataset.sectionId; const content = button.nextElementSibling; const icon = button.querySelector('.fa-chevron-down'); const isOpen = content?.style.maxHeight; if (!content || !icon || !sectionId) return; if (isOpen) { // Close section content.style.maxHeight = null; icon.style.transform = 'rotate(0deg)'; state.openSections.delete(sectionId); } else { // Close all other sections (accordion behavior) document.querySelectorAll('.sidebar-section-content').forEach(c => { c.style.maxHeight = null; }); document.querySelectorAll('.sidebar-section-header .fa-chevron-down').forEach(i => { i.style.transform = 'rotate(0deg)'; }); state.openSections.clear(); // Open clicked section content.style.maxHeight = content.scrollHeight + 'px'; icon.style.transform = 'rotate(180deg)'; state.openSections.add(sectionId); } saveState(); } // Open sidebar (mobile) function openSidebar() { const sidebar = document.getElementById('sidebar'); const overlay = document.getElementById('sidebarOverlay'); sidebar?.classList.add('active'); overlay?.classList.add('active'); document.body.style.overflow = 'hidden'; } // Close sidebar (mobile) function closeSidebar() { const sidebar = document.getElementById('sidebar'); const overlay = document.getElementById('sidebarOverlay'); sidebar?.classList.remove('active'); overlay?.classList.remove('active'); document.body.style.overflow = ''; } // Set active link function setActiveLink() { const currentPath = window.location.pathname; document.querySelectorAll('.sidebar-item, .sidebar-subitem').forEach(link => { const href = link.getAttribute('href'); if (href && currentPath.includes(href)) { link.classList.add('active'); // Open parent section if subitem const section = link.closest('.sidebar-section'); if (section) { const sectionId = section.dataset.sectionId; const header = section.querySelector('.sidebar-section-header'); const content = section.querySelector('.sidebar-section-content'); const icon = header?.querySelector('.fa-chevron-down'); if (content && icon && sectionId) { content.style.maxHeight = content.scrollHeight + 'px'; icon.style.transform = 'rotate(180deg)'; state.openSections.add(sectionId); } } } }); } // Update badges with real-time data function updateBadges() { // This would typically fetch data from an API // For now, we'll just add some example logic // Update orders count const ordersCount = document.getElementById('ordersCount'); if (ordersCount) { // Example: fetch from API // ordersCount.textContent = '5'; } // Update stock count const stockCount = document.getElementById('stockCount'); if (stockCount) { // Example: fetch from API // stockCount.textContent = '3'; } // Refresh every 30 seconds setTimeout(updateBadges, 30000); } // Add tooltips for collapsed sidebar function addTooltips() { document.querySelectorAll('.sidebar-item, .sidebar-subitem').forEach(item => { const text = item.querySelector('span')?.textContent; if (text) { item.setAttribute('title', text.trim()); } }); } // Handle keyboard shortcuts function handleKeyboard(e) { // Alt + S: Toggle sidebar if (e.altKey && e.key === 's') { e.preventDefault(); toggleSidebarCollapse(); } // Escape: Close mobile sidebar if (e.key === 'Escape' && state.isMobile) { closeSidebar(); } } // Handle window resize function handleResize() { const wasMobile = state.isMobile; state.isMobile = window.innerWidth <= CONFIG.MOBILE_BREAKPOINT; if (wasMobile !== state.isMobile) { const sidebar = document.getElementById('sidebar'); if (state.isMobile) { // Switched to mobile sidebar?.classList.remove('collapsed'); closeSidebar(); } else { // Switched to desktop sidebar?.classList.remove('active'); if (state.isCollapsed) { sidebar?.classList.add('collapsed'); } } } } // Utility: Debounce function function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } // Public API window.SidebarEnhanced = { toggle: toggleSidebarCollapse, open: openSidebar, close: closeSidebar, toggleSection: toggleSection, updateBadges: updateBadges, getState: () => ({ ...state }) }; // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();