// static/store/js/content-pages.js // Use centralized logger const contentPagesLog = window.LogConfig.loggers.contentPages || window.LogConfig.createLogger('contentPages'); // ============================================ // STORE CONTENT PAGES MANAGER // ============================================ function storeContentPagesManager() { 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: '', // Modal state showDeletePageConfirm: false, pageToDelete: null, // Data platformPages: [], // Platform default pages customPages: [], // Store's own pages (overrides + custom) overrideMap: {}, // Map of slug -> page id for quick lookup cmsUsage: null, // CMS usage statistics // Initialize async init() { contentPagesLog.info('=== STORE CONTENT PAGES MANAGER INITIALIZING ==='); // Prevent multiple initializations if (window._storeContentPagesInitialized) { contentPagesLog.warn('Content pages manager already initialized, skipping...'); return; } window._storeContentPagesInitialized = true; try { // IMPORTANT: Call parent init first to set storeCode from URL const parentInit = data().init; if (parentInit) { await parentInit.call(this); } await Promise.all([ this.loadPages(), this.loadCmsUsage() ]); contentPagesLog.info('=== STORE 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 store pages in parallel const [platformResponse, storeResponse] = await Promise.all([ apiClient.get('/store/content-pages/'), apiClient.get('/store/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_page); // Store's custom pages (includes overrides) this.customPages = storeResponse.data || storeResponse || []; // Build override map for quick lookups this.overrideMap = {}; this.customPages.forEach(page => { if (page.is_store_override) { this.overrideMap[page.slug] = page.id; } }); contentPagesLog.info(`Loaded ${this.platformPages.length} platform pages, ${this.customPages.length} store 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('/store/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 store 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 store 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('/store/content-pages/', payload); const newPage = response.data || response; contentPagesLog.info('Override created:', newPage.id); // Redirect to edit the new page window.location.href = `/store/${this.storeCode}/content-pages/${newPage.id}/edit`; } catch (err) { contentPagesLog.error('Error creating override:', err); this.error = err.message || 'Failed to create override'; } }, // Prompt delete page confirmation promptDeletePage(page) { this.pageToDelete = page; this.showDeletePageConfirm = true; }, // Delete a page async deletePage(page) { try { contentPagesLog.info('Deleting page:', page.id); await apiClient.delete(`/store/content-pages/${page.id}`); // Remove from local state this.customPages = this.customPages.filter(p => p.id !== page.id); // Update override map if (page.is_store_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.STORE_CONFIG?.locale || 'en-GB'; return date.toLocaleDateString(locale, { day: '2-digit', month: 'short', year: 'numeric' }); } }; }