// Admin Components Loader class AdminApp { constructor() { this.currentUser = null; this.currentSection = 'dashboard'; this.components = { sidebar: '/admin/sidebar.html', topbar: '/admin/topbar.html', sections: { dashboard: '/admin/dashboard.html', properties: '/admin/properties.html', leads: '/admin/leads.html', testimonials: '/admin/testimonials.html', faq: '/admin/faq.html', services: '/admin/services.html', settings: '/admin/settings.html' } }; } async init() { try { await this.checkAuth(); await this.loadComponent('sidebar', '#sidebar-container'); await this.loadComponent('topbar', '#topbar-container'); await this.loadSection(this.currentSection); this.setupNavigation(); this.setupTopbar(); console.log('Admin app initialized'); } catch (e) { console.error('Init failed:', e); window.location.href = '/login'; } } async checkAuth() { const res = await API.getMe(); if (!res.success || !res.data) { throw new Error('Not authenticated'); } this.currentUser = res.data; localStorage.setItem('user', JSON.stringify(this.currentUser)); } async loadComponent(name, container) { try { const response = await fetch(this.components[name]); if (!response.ok) throw new Error(`Failed to load ${name}`); const html = await response.text(); const element = document.querySelector(container); if (element) { element.innerHTML = html; this.executeScripts(element); } } catch (e) { console.error(`Failed to load component ${name}:`, e); } } async loadSection(sectionName) { const sectionPath = this.components.sections[sectionName]; if (!sectionPath) { console.error('Unknown section:', sectionName); return; } try { const response = await fetch(sectionPath); if (!response.ok) throw new Error(`Failed to load section ${sectionName}`); const html = await response.text(); // Hide all sections document.querySelectorAll('.section').forEach(s => s.classList.remove('active')); // Remove old section if exists const oldSection = document.getElementById(`section-${sectionName}`); if (oldSection) { oldSection.remove(); } // Add new section const mainContent = document.getElementById('main-content'); if (mainContent) { const div = document.createElement('div'); div.innerHTML = html; const section = div.firstElementChild; section.classList.add('active'); mainContent.appendChild(section); this.executeScripts(section); } // Load section data await this.loadSectionData(sectionName); // Update page title this.updatePageTitle(sectionName); } catch (e) { console.error(`Failed to load section ${sectionName}:`, e); } } async loadSectionData(sectionName) { const loaders = { 'dashboard': loadDashboard, 'properties': loadProperties, 'leads': loadLeads, 'testimonials': loadTestimonials, 'faq': loadFAQ, 'services': loadServices, 'settings': loadSettings }; if (loaders[sectionName]) { await loaders[sectionName](); } } executeScripts(container) { container.querySelectorAll('script').forEach(script => { const newScript = document.createElement('script'); if (script.src) { newScript.src = script.src; } else { newScript.textContent = script.textContent; } document.body.appendChild(newScript); script.remove(); }); } setupNavigation() { document.querySelectorAll('.sidebar-link[data-section]').forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); const section = link.dataset.section; this.navigateTo(section); }); }); } setupTopbar() { // Sidebar toggle const toggle = document.getElementById('sidebarToggle'); if (toggle) { toggle.addEventListener('click', () => { document.getElementById('sidebar')?.classList.toggle('collapsed'); }); } // Language switcher document.querySelectorAll('.lang-btn').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.lang-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); const lang = btn.dataset.lang; this.changeLanguage(lang); }); }); // Update user info this.updateUserInfo(); } navigateTo(section) { // Update nav document.querySelectorAll('.sidebar-link').forEach(link => { link.classList.remove('active'); }); document.querySelector(`.sidebar-link[data-section="${section}"]`)?.classList.add('active'); // Update hash window.location.hash = section; // Load section this.currentSection = section; this.loadSection(section); } updatePageTitle(section) { const titles = { 'dashboard': 'Dashboard', 'properties': 'Propiedades', 'leads': 'Leads', 'testimonials': 'Testimonios', 'faq': 'FAQ', 'services': 'Servicios', 'settings': 'Configuración' }; const titleEl = document.getElementById('pageTitle'); if (titleEl) { titleEl.textContent = titles[section] || section; } } updateUserInfo() { if (!this.currentUser) return; const userName = this.currentUser.name || 'Admin'; const userAvatar = userName.charAt(0).toUpperCase(); // Sidebar document.getElementById('sidebarUserName').textContent = userName; document.getElementById('sidebarUserRole').textContent = this.getRoleName(this.currentUser.role); document.getElementById('sidebarAvatar').textContent = userAvatar; // Topbar document.getElementById('topbarUserName').textContent = userName; document.getElementById('topbarUserRole').textContent = this.getRoleName(this.currentUser.role); document.getElementById('topbarAvatar').src = `https://ui-avatars.com/api/?name=${encodeURIComponent(userName)}&background=1a5f4a&color=fff`; } getRoleName(role) { const roles = { admin: 'Administrador', agent: 'Agente', editor: 'Editor' }; return roles[role] || role; } changeLanguage(lang) { // TODO: Implement i18n console.log('Language changed to:', lang); } } // Initialize app const app = new AdminApp(); document.addEventListener('DOMContentLoaded', () => app.init()); // Handle hash navigation window.addEventListener('hashchange', () => { const section = window.location.hash.substring(1); if (section) app.navigateTo(section); }); // Logout function function logout() { API.logout().then(() => { localStorage.removeItem('user'); window.location.href = '/login'; }).catch(() => { window.location.href = '/login'; }); }