/** * Store Email Templates Management Page * * Allows stores to customize email templates sent to their customers. * Platform-only templates (billing, subscription) cannot be overridden. */ const storeEmailTemplatesLog = window.LogConfig?.loggers?.storeEmailTemplates || window.LogConfig?.createLogger?.('storeEmailTemplates', false) || { info: () => {}, debug: () => {}, warn: () => {}, error: () => {} }; storeEmailTemplatesLog.info('Loading...'); function storeEmailTemplates() { storeEmailTemplatesLog.info('storeEmailTemplates() called'); return { // Inherit base layout state ...data(), // Set page identifier currentPage: 'email-templates', // Loading states loading: true, error: '', saving: false, // Data templates: [], supportedLanguages: ['en', 'fr', 'de', 'lb'], // Edit Modal showEditModal: false, editingTemplate: null, editLanguage: 'en', loadingTemplate: false, templateSource: 'platform', editForm: { subject: '', body_html: '', body_text: '' }, reverting: false, // Revert confirm state showRevertConfirm: false, // Preview Modal showPreviewModal: false, previewData: null, // Test Email Modal showTestEmailModal: false, testEmailAddress: '', sendingTest: false, // Lifecycle async init() { // Load i18n translations await I18n.loadModule('messaging'); if (window._storeEmailTemplatesInitialized) return; window._storeEmailTemplatesInitialized = true; storeEmailTemplatesLog.info('Email templates init() called'); // Call parent init to set storeCode and other base state const parentInit = data().init; if (parentInit) { await parentInit.call(this); } await this.loadData(); }, // Data Loading async loadData() { this.loading = true; this.error = ''; try { const response = await apiClient.get('/store/email-templates'); this.templates = response.templates || []; this.supportedLanguages = response.supported_languages || ['en', 'fr', 'de', 'lb']; } catch (error) { storeEmailTemplatesLog.error('Failed to load templates:', error); this.error = error.detail || 'Failed to load templates'; } finally { this.loading = false; } }, // Category styling getCategoryClass(category) { const classes = { 'AUTH': 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400', 'ORDERS': 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400', 'BILLING': 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400', 'SYSTEM': 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400', 'MARKETING': 'bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-400', 'TEAM': 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400' }; return classes[category] || 'bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300'; }, // Edit Template async editTemplate(template) { this.editingTemplate = template; this.editLanguage = 'en'; this.showEditModal = true; await this.loadTemplateLanguage(); }, async loadTemplateLanguage() { if (!this.editingTemplate) return; this.loadingTemplate = true; try { const data = await apiClient.get( `/store/email-templates/${this.editingTemplate.code}/${this.editLanguage}` ); this.templateSource = data.source; this.editForm = { subject: data.subject || '', body_html: data.body_html || '', body_text: data.body_text || '' }; } catch (error) { if (error.status === 404) { // No template for this language this.templateSource = 'none'; this.editForm = { subject: '', body_html: '', body_text: '' }; Utils.showToast(`No template available for ${this.editLanguage.toUpperCase()}`, 'info'); } else { storeEmailTemplatesLog.error('Failed to load template:', error); Utils.showToast(I18n.t('messaging.messages.failed_to_load_template'), 'error'); } } finally { this.loadingTemplate = false; } }, closeEditModal() { this.showEditModal = false; this.editingTemplate = null; this.editForm = { subject: '', body_html: '', body_text: '' }; }, async saveTemplate() { if (!this.editingTemplate) return; this.saving = true; try { await apiClient.put( `/store/email-templates/${this.editingTemplate.code}/${this.editLanguage}`, { subject: this.editForm.subject, body_html: this.editForm.body_html, body_text: this.editForm.body_text || null } ); Utils.showToast(I18n.t('messaging.messages.template_saved_successfully'), 'success'); this.templateSource = 'store_override'; // Refresh list to show updated status await this.loadData(); } catch (error) { storeEmailTemplatesLog.error('Failed to save template:', error); Utils.showToast(error.detail || 'Failed to save template', 'error'); } finally { this.saving = false; } }, async revertToDefault() { if (!this.editingTemplate) return; this.reverting = true; try { await apiClient.delete( `/store/email-templates/${this.editingTemplate.code}/${this.editLanguage}` ); Utils.showToast(I18n.t('messaging.messages.reverted_to_platform_default'), 'success'); // Reload the template to show platform version await this.loadTemplateLanguage(); // Refresh list await this.loadData(); } catch (error) { storeEmailTemplatesLog.error('Failed to revert template:', error); Utils.showToast(error.detail || 'Failed to revert', 'error'); } finally { this.reverting = false; } }, // Preview async previewTemplate() { if (!this.editingTemplate) return; try { const data = await apiClient.post( `/store/email-templates/${this.editingTemplate.code}/preview`, { language: this.editLanguage, variables: {} } ); this.previewData = data; this.showPreviewModal = true; } catch (error) { storeEmailTemplatesLog.error('Failed to preview template:', error); Utils.showToast(I18n.t('messaging.messages.failed_to_load_preview'), 'error'); } }, // Test Email sendTestEmail() { this.showTestEmailModal = true; }, async confirmSendTestEmail() { if (!this.testEmailAddress || !this.editingTemplate) return; this.sendingTest = true; try { const result = await apiClient.post( `/store/email-templates/${this.editingTemplate.code}/test`, { to_email: this.testEmailAddress, language: this.editLanguage, variables: {} } ); if (result.success) { Utils.showToast(`Test email sent to ${this.testEmailAddress}`, 'success'); this.showTestEmailModal = false; this.testEmailAddress = ''; } else { Utils.showToast(result.message || 'Failed to send test email', 'error'); } } catch (error) { storeEmailTemplatesLog.error('Failed to send test email:', error); Utils.showToast(I18n.t('messaging.messages.failed_to_send_test_email'), 'error'); } finally { this.sendingTest = false; } } }; }