| |
| |
| |
|
|
| class SidebarManager { |
| constructor() { |
| this.sidebar = null; |
| this.toggleBtn = null; |
| this.overlay = null; |
| this.isCollapsed = false; |
| this.isMobile = window.innerWidth <= 1024; |
| |
| this.init(); |
| } |
|
|
| init() { |
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', () => this.setup()); |
| } else { |
| this.setup(); |
| } |
| } |
|
|
| setup() { |
| this.sidebar = document.getElementById('sidebar-modern') || document.querySelector('.sidebar-modern'); |
| this.toggleBtn = document.getElementById('sidebar-collapse-btn'); |
| this.overlay = document.getElementById('sidebar-overlay-modern') || document.querySelector('.sidebar-overlay-modern'); |
|
|
| if (!this.sidebar) { |
| console.warn('Sidebar not found'); |
| return; |
| } |
|
|
| |
| this.loadState(); |
|
|
| |
| this.setupEventListeners(); |
|
|
| |
| this.handleResize(); |
| } |
|
|
| setupEventListeners() { |
| |
| if (this.toggleBtn) { |
| this.toggleBtn.addEventListener('click', () => this.toggle()); |
| } |
|
|
| |
| if (this.overlay) { |
| this.overlay.addEventListener('click', () => this.close()); |
| } |
|
|
| |
| window.addEventListener('resize', () => this.handleResize()); |
|
|
| |
| document.addEventListener('keydown', (e) => { |
| if (e.key === 'Escape' && this.isMobile && this.sidebar.classList.contains('open')) { |
| this.close(); |
| } |
| }); |
|
|
| |
| const navLinks = this.sidebar.querySelectorAll('.nav-link-modern'); |
| navLinks.forEach(link => { |
| link.addEventListener('click', () => { |
| if (this.isMobile) { |
| this.close(); |
| } |
| }); |
| }); |
|
|
| |
| this.setActivePage(); |
| } |
|
|
| toggle() { |
| if (this.isMobile) { |
| |
| this.sidebar.classList.toggle('open'); |
| this.overlay?.classList.toggle('active'); |
| } else { |
| |
| this.isCollapsed = !this.isCollapsed; |
| this.sidebar.classList.toggle('collapsed'); |
| this.saveState(); |
| |
| |
| window.dispatchEvent(new CustomEvent('sidebar-toggle', { |
| detail: { collapsed: this.isCollapsed } |
| })); |
| } |
| } |
|
|
| open() { |
| if (this.isMobile) { |
| this.sidebar.classList.add('open'); |
| this.overlay?.classList.add('active'); |
| document.body.style.overflow = 'hidden'; |
| } |
| } |
|
|
| close() { |
| if (this.isMobile) { |
| this.sidebar.classList.remove('open'); |
| this.overlay?.classList.remove('active'); |
| document.body.style.overflow = ''; |
| } |
| } |
|
|
| collapse() { |
| if (!this.isMobile && !this.isCollapsed) { |
| this.isCollapsed = true; |
| this.sidebar.classList.add('collapsed'); |
| this.saveState(); |
| } |
| } |
|
|
| expand() { |
| if (!this.isMobile && this.isCollapsed) { |
| this.isCollapsed = false; |
| this.sidebar.classList.remove('collapsed'); |
| this.saveState(); |
| } |
| } |
|
|
| handleResize() { |
| const wasMobile = this.isMobile; |
| this.isMobile = window.innerWidth <= 1024; |
|
|
| |
| if (wasMobile !== this.isMobile) { |
| |
| if (!this.isMobile) { |
| this.sidebar.classList.remove('open'); |
| this.overlay?.classList.remove('active'); |
| document.body.style.overflow = ''; |
| |
| |
| if (this.isCollapsed) { |
| this.sidebar.classList.add('collapsed'); |
| } |
| } else { |
| |
| this.sidebar.classList.remove('collapsed'); |
| } |
| } |
| } |
|
|
| setActivePage() { |
| |
| const path = window.location.pathname; |
| const pageName = this.getPageNameFromPath(path); |
|
|
| if (!pageName) return; |
|
|
| |
| const navLinks = this.sidebar.querySelectorAll('.nav-link-modern'); |
| navLinks.forEach(link => { |
| link.classList.remove('active'); |
| link.removeAttribute('aria-current'); |
| }); |
|
|
| |
| const activeLink = this.sidebar.querySelector(`[data-page="${pageName}"]`); |
| if (activeLink) { |
| activeLink.classList.add('active'); |
| activeLink.setAttribute('aria-current', 'page'); |
| } |
| } |
|
|
| getPageNameFromPath(path) { |
| |
| |
| const match = path.match(/\/pages\/([^\/]+)\//); |
| return match ? match[1] : null; |
| } |
|
|
| saveState() { |
| try { |
| localStorage.setItem('sidebar_collapsed', JSON.stringify(this.isCollapsed)); |
| } catch (error) { |
| console.warn('Failed to save sidebar state:', error); |
| } |
| } |
|
|
| loadState() { |
| try { |
| const saved = localStorage.getItem('sidebar_collapsed'); |
| if (saved !== null) { |
| this.isCollapsed = JSON.parse(saved); |
| if (this.isCollapsed && !this.isMobile) { |
| this.sidebar.classList.add('collapsed'); |
| } |
| } |
| } catch (error) { |
| console.warn('Failed to load sidebar state:', error); |
| } |
| } |
|
|
| |
| getState() { |
| return { |
| isCollapsed: this.isCollapsed, |
| isMobile: this.isMobile, |
| isOpen: this.sidebar?.classList.contains('open') || false |
| }; |
| } |
| } |
|
|
| |
| const sidebarManager = new SidebarManager(); |
|
|
| |
| if (typeof module !== 'undefined' && module.exports) { |
| module.exports = sidebarManager; |
| } |
|
|
| export default sidebarManager; |
|
|
|
|