// static/vendor/js/content-pages.js // Use centralized logger const contentPagesLog = window.LogConfig.loggers.contentPages || window.LogConfig.createLogger('contentPages'); // ============================================ // VENDOR CONTENT PAGES MANAGER // ============================================ function vendorContentPagesManager() { return { // Inherit base layout functionality from init-alpine.js ...data(), // Page identifier for sidebar active state currentPage: 'content-pages', // State loading: false, error: null, activeTab: 'platform', searchQuery: '', // Data platformPages: [], // Platform default pages customPages: [], // Vendor's own pages (overrides + custom) overrideMap: {}, // Map of slug -> page id for quick lookup cmsUsage: null, // CMS usage statistics // Initialize async init() { contentPagesLog.info('=== VENDOR CONTENT PAGES MANAGER INITIALIZING ==='); // Prevent multiple initializations if (window._vendorContentPagesInitialized) { contentPagesLog.warn('Content pages manager already initialized, skipping...'); return; } window._vendorContentPagesInitialized = true; try { // IMPORTANT: Call parent init first to set vendorCode from URL const parentInit = data().init; if (parentInit) { await parentInit.call(this); } await Promise.all([ this.loadPages(), this.loadCmsUsage() ]); contentPagesLog.info('=== VENDOR CONTENT PAGES MANAGER INITIALIZATION COMPLETE ==='); } catch (error) { contentPagesLog.error('Failed to initialize content pages:', error); this.error = 'Failed to initialize. Please refresh the page.'; this.loading = false; } }, // Load all pages async loadPages() { this.loading = true; this.error = null; try { contentPagesLog.info('Loading content pages...'); // Load platform defaults and vendor pages in parallel const [platformResponse, vendorResponse] = await Promise.all([ apiClient.get('/vendor/content-pages/'), apiClient.get('/vendor/content-pages/overrides') ]); // Platform pages - filter to only show actual platform defaults const allPages = platformResponse.data || platformResponse || []; this.platformPages = allPages.filter(p => p.is_platform_default); // Vendor's custom pages (includes overrides) this.customPages = vendorResponse.data || vendorResponse || []; // Build override map for quick lookups this.overrideMap = {}; this.customPages.forEach(page => { if (page.is_vendor_override) { this.overrideMap[page.slug] = page.id; } }); contentPagesLog.info(`Loaded ${this.platformPages.length} platform pages, ${this.customPages.length} vendor pages`); } catch (err) { contentPagesLog.error('Error loading pages:', err); this.error = err.message || 'Failed to load pages'; } finally { this.loading = false; } }, // Load CMS usage statistics async loadCmsUsage() { try { contentPagesLog.info('Loading CMS usage...'); const response = await apiClient.get('/vendor/content-pages/usage'); this.cmsUsage = response.data || response; contentPagesLog.info('CMS usage loaded:', this.cmsUsage); } catch (err) { contentPagesLog.error('Error loading CMS usage:', err); // Non-critical - don't set error state } }, // Check if vendor has overridden a platform page hasOverride(slug) { return slug in this.overrideMap; }, // Get override page ID getOverrideId(slug) { return this.overrideMap[slug]; }, // Create an override for a platform page async createOverride(platformPage) { contentPagesLog.info('Creating override for:', platformPage.slug); try { // Create a new vendor page with the same slug as the platform page const payload = { slug: platformPage.slug, title: platformPage.title, content: platformPage.content, content_format: platformPage.content_format || 'html', meta_description: platformPage.meta_description, meta_keywords: platformPage.meta_keywords, is_published: true, show_in_header: platformPage.show_in_header, show_in_footer: platformPage.show_in_footer, display_order: platformPage.display_order }; const response = await apiClient.post('/vendor/content-pages/', payload); const newPage = response.data || response; contentPagesLog.info('Override created:', newPage.id); // Redirect to edit the new page window.location.href = `/vendor/${this.vendorCode}/content-pages/${newPage.id}/edit`; } catch (err) { contentPagesLog.error('Error creating override:', err); this.error = err.message || 'Failed to create override'; } }, // Delete a page async deletePage(page) { const message = page.is_vendor_override ? `Are you sure you want to delete your override for "${page.title}"? The platform default will be shown instead.` : `Are you sure you want to delete "${page.title}"? This cannot be undone.`; if (!confirm(message)) { return; } try { contentPagesLog.info('Deleting page:', page.id); await apiClient.delete(`/vendor/content-pages/${page.id}`); // Remove from local state this.customPages = this.customPages.filter(p => p.id !== page.id); // Update override map if (page.is_vendor_override) { delete this.overrideMap[page.slug]; } contentPagesLog.info('Page deleted successfully'); } catch (err) { contentPagesLog.error('Error deleting page:', err); this.error = err.message || 'Failed to delete page'; } }, // Filtered platform pages based on search get filteredPlatformPages() { if (!this.searchQuery) { return this.platformPages; } const query = this.searchQuery.toLowerCase(); return this.platformPages.filter(page => page.title.toLowerCase().includes(query) || page.slug.toLowerCase().includes(query) ); }, // Filtered custom pages based on search get filteredCustomPages() { if (!this.searchQuery) { return this.customPages; } const query = this.searchQuery.toLowerCase(); return this.customPages.filter(page => page.title.toLowerCase().includes(query) || page.slug.toLowerCase().includes(query) ); }, // Format date for display formatDate(dateStr) { if (!dateStr) return '—'; const date = new Date(dateStr); const locale = window.VENDOR_CONFIG?.locale || 'en-GB'; return date.toLocaleDateString(locale, { day: '2-digit', month: 'short', year: 'numeric' }); } }; }