// static/admin/js/settings.js // noqa: JS-003 - Uses ...baseData which is data() with safety check const settingsLog = window.LogConfig?.loggers?.settings || console; function adminSettings() { // Get base data with safety check for standalone usage const baseData = typeof data === 'function' ? data() : {}; return { // Inherit base layout functionality from init-alpine.js ...baseData, // Settings-specific state currentPage: 'settings', loading: true, saving: false, error: null, successMessage: null, activeTab: 'display', displaySettings: { rows_per_page: 20 }, logSettings: { log_level: 'INFO', log_file_max_size_mb: 10, log_file_backup_count: 5, db_log_retention_days: 30, file_logging_enabled: true, db_logging_enabled: true }, notificationSettings: { email_enabled: true, in_app_enabled: true, critical_only: false }, shippingSettings: { carrier_greco_label_url: 'https://dispatchweb.fr/Tracky/Home/', carrier_colissimo_label_url: '', carrier_xpresslogistics_label_url: '' }, emailSettings: { provider: 'smtp', from_email: '', from_name: '', reply_to: '', smtp_host: '', smtp_port: 587, smtp_user: '', mailgun_domain: '', aws_region: '', debug: false, enabled: true, is_configured: false, has_db_overrides: false }, // Email editing form (separate from display to track changes) emailForm: { provider: 'smtp', from_email: '', from_name: '', reply_to: '', smtp_host: '', smtp_port: 587, smtp_user: '', smtp_password: '', smtp_use_tls: true, smtp_use_ssl: false, sendgrid_api_key: '', mailgun_api_key: '', mailgun_domain: '', aws_access_key_id: '', aws_secret_access_key: '', aws_region: 'eu-west-1', enabled: true, debug: false }, emailEditMode: false, testEmailAddress: '', sendingTestEmail: false, async init() { // Guard against multiple initialization if (window._adminSettingsInitialized) return; window._adminSettingsInitialized = true; try { settingsLog.info('=== SETTINGS PAGE INITIALIZING ==='); await Promise.all([ this.loadDisplaySettings(), this.loadLogSettings(), this.loadShippingSettings(), this.loadEmailSettings() ]); } catch (error) { settingsLog.error('Init failed:', error); this.error = 'Failed to initialize settings page'; } }, async refresh() { this.error = null; this.successMessage = null; await Promise.all([ this.loadDisplaySettings(), this.loadLogSettings(), this.loadShippingSettings(), this.loadEmailSettings() ]); }, async loadDisplaySettings() { try { const data = await apiClient.get('/admin/settings/display/rows-per-page'); this.displaySettings.rows_per_page = data.rows_per_page || 20; settingsLog.info('Display settings loaded:', this.displaySettings); } catch (error) { settingsLog.error('Failed to load display settings:', error); // Use default value on error this.displaySettings.rows_per_page = 20; } }, async saveDisplaySettings() { this.saving = true; this.error = null; this.successMessage = null; try { const data = await apiClient.put(`/admin/settings/display/rows-per-page?rows=${this.displaySettings.rows_per_page}`); this.successMessage = data.message || 'Display settings saved successfully'; // Clear the cached platform settings so pages pick up the new value if (window.PlatformSettings) { window.PlatformSettings.clearCache(); } // Auto-hide success message after 5 seconds setTimeout(() => { this.successMessage = null; }, 5000); settingsLog.info('Display settings saved successfully'); } catch (error) { settingsLog.error('Failed to save display settings:', error); this.error = error.response?.data?.detail || 'Failed to save display settings'; } finally { this.saving = false; } }, async loadLogSettings() { this.loading = true; this.error = null; try { const data = await apiClient.get('/admin/logs/settings'); this.logSettings = data; settingsLog.info('Log settings loaded:', this.logSettings); } catch (error) { settingsLog.error('Failed to load log settings:', error); this.error = error.response?.data?.detail || 'Failed to load log settings'; } finally { this.loading = false; } }, async saveLogSettings() { this.saving = true; this.error = null; this.successMessage = null; try { const data = await apiClient.put('/admin/logs/settings', this.logSettings); this.successMessage = data.message || 'Log settings saved successfully'; // Auto-hide success message after 5 seconds setTimeout(() => { this.successMessage = null; }, 5000); settingsLog.info('Log settings saved successfully'); } catch (error) { settingsLog.error('Failed to save log settings:', error); this.error = error.response?.data?.detail || 'Failed to save log settings'; } finally { this.saving = false; } }, async cleanupOldLogs() { if (!confirm(`This will delete all logs older than ${this.logSettings.db_log_retention_days} days. Continue?`)) { return; } this.error = null; this.successMessage = null; try { const data = await apiClient.delete( `/admin/logs/database/cleanup?retention_days=${this.logSettings.db_log_retention_days}&confirm=true` ); this.successMessage = data.message || 'Old logs cleaned up successfully'; // Auto-hide success message after 5 seconds setTimeout(() => { this.successMessage = null; }, 5000); settingsLog.info('Old logs cleaned up successfully'); } catch (error) { settingsLog.error('Failed to cleanup logs:', error); this.error = error.response?.data?.detail || 'Failed to cleanup old logs'; } }, async saveNotificationSettings() { this.saving = true; this.error = null; this.successMessage = null; try { // TODO: Implement API endpoint for notification settings // const data = await apiClient.put('/admin/notifications/settings', this.notificationSettings); // For now, just show success (settings are client-side only) this.successMessage = 'Notification settings saved successfully'; // Auto-hide success message after 5 seconds setTimeout(() => { this.successMessage = null; }, 5000); settingsLog.info('Notification settings saved:', this.notificationSettings); } catch (error) { settingsLog.error('Failed to save notification settings:', error); this.error = error.response?.data?.detail || 'Failed to save notification settings'; } finally { this.saving = false; } }, async loadShippingSettings() { try { // Load each carrier setting with defaults to avoid 404 errors const carriers = [ { name: 'greco', default: 'https://dispatchweb.fr/Tracky/Home/' }, { name: 'colissimo', default: '' }, { name: 'xpresslogistics', default: '' } ]; for (const carrier of carriers) { const key = `carrier_${carrier.name}_label_url`; // Use default query param to avoid 404 for non-existent settings const data = await apiClient.get(`/admin/settings/${key}?default=${encodeURIComponent(carrier.default)}`); if (data && data.value !== undefined) { this.shippingSettings[key] = data.value; } } settingsLog.info('Shipping settings loaded:', this.shippingSettings); } catch (error) { settingsLog.error('Failed to load shipping settings:', error); // On error, keep existing defaults } }, async saveShippingSettings() { this.saving = true; this.error = null; this.successMessage = null; try { // Save each carrier setting using upsert const carriers = [ { key: 'carrier_greco_label_url', name: 'Greco' }, { key: 'carrier_colissimo_label_url', name: 'Colissimo' }, { key: 'carrier_xpresslogistics_label_url', name: 'XpressLogistics' } ]; for (const carrier of carriers) { await apiClient.post('/admin/settings/upsert', { key: carrier.key, value: this.shippingSettings[carrier.key] || '', category: 'shipping', value_type: 'string', description: `Label URL prefix for ${carrier.name} carrier` }); } this.successMessage = 'Shipping settings saved successfully'; // Auto-hide success message after 5 seconds setTimeout(() => { this.successMessage = null; }, 5000); settingsLog.info('Shipping settings saved:', this.shippingSettings); } catch (error) { settingsLog.error('Failed to save shipping settings:', error); this.error = error.response?.data?.detail || 'Failed to save shipping settings'; } finally { this.saving = false; } }, getShippingLabelUrl(carrier, shipmentNumber) { // Helper to generate full label URL const prefix = this.shippingSettings[`carrier_${carrier}_label_url`] || ''; if (!prefix || !shipmentNumber) return null; return prefix + shipmentNumber; }, // ===================================================================== // EMAIL SETTINGS // ===================================================================== async loadEmailSettings() { try { const data = await apiClient.get('/admin/settings/email/status'); this.emailSettings = { provider: data.provider || 'smtp', from_email: data.from_email || '', from_name: data.from_name || '', reply_to: data.reply_to || '', smtp_host: data.smtp_host || '', smtp_port: data.smtp_port || 587, smtp_user: data.smtp_user || '', mailgun_domain: data.mailgun_domain || '', aws_region: data.aws_region || '', debug: data.debug || false, enabled: data.enabled !== false, is_configured: data.is_configured || false, has_db_overrides: data.has_db_overrides || false }; // Populate edit form with current values this.populateEmailForm(); settingsLog.info('Email settings loaded:', this.emailSettings); } catch (error) { settingsLog.error('Failed to load email settings:', error); // Use defaults on error } }, populateEmailForm() { // Copy current settings to form (passwords are not loaded from API) this.emailForm = { provider: this.emailSettings.provider, from_email: this.emailSettings.from_email, from_name: this.emailSettings.from_name, reply_to: this.emailSettings.reply_to || '', smtp_host: this.emailSettings.smtp_host || '', smtp_port: this.emailSettings.smtp_port || 587, smtp_user: this.emailSettings.smtp_user || '', smtp_password: '', // Never populated from API smtp_use_tls: true, smtp_use_ssl: false, sendgrid_api_key: '', mailgun_api_key: '', mailgun_domain: this.emailSettings.mailgun_domain || '', aws_access_key_id: '', aws_secret_access_key: '', aws_region: this.emailSettings.aws_region || 'eu-west-1', enabled: this.emailSettings.enabled, debug: this.emailSettings.debug }; }, enableEmailEditing() { this.emailEditMode = true; this.populateEmailForm(); }, cancelEmailEditing() { this.emailEditMode = false; this.populateEmailForm(); }, async saveEmailSettings() { this.saving = true; this.error = null; this.successMessage = null; try { // Only send non-empty values to update const payload = {}; // Always send these core fields if (this.emailForm.provider) payload.provider = this.emailForm.provider; if (this.emailForm.from_email) payload.from_email = this.emailForm.from_email; if (this.emailForm.from_name) payload.from_name = this.emailForm.from_name; if (this.emailForm.reply_to) payload.reply_to = this.emailForm.reply_to; payload.enabled = this.emailForm.enabled; payload.debug = this.emailForm.debug; // Provider-specific fields if (this.emailForm.provider === 'smtp') { if (this.emailForm.smtp_host) payload.smtp_host = this.emailForm.smtp_host; if (this.emailForm.smtp_port) payload.smtp_port = this.emailForm.smtp_port; if (this.emailForm.smtp_user) payload.smtp_user = this.emailForm.smtp_user; if (this.emailForm.smtp_password) payload.smtp_password = this.emailForm.smtp_password; payload.smtp_use_tls = this.emailForm.smtp_use_tls; payload.smtp_use_ssl = this.emailForm.smtp_use_ssl; } else if (this.emailForm.provider === 'sendgrid') { if (this.emailForm.sendgrid_api_key) payload.sendgrid_api_key = this.emailForm.sendgrid_api_key; } else if (this.emailForm.provider === 'mailgun') { if (this.emailForm.mailgun_api_key) payload.mailgun_api_key = this.emailForm.mailgun_api_key; if (this.emailForm.mailgun_domain) payload.mailgun_domain = this.emailForm.mailgun_domain; } else if (this.emailForm.provider === 'ses') { if (this.emailForm.aws_access_key_id) payload.aws_access_key_id = this.emailForm.aws_access_key_id; if (this.emailForm.aws_secret_access_key) payload.aws_secret_access_key = this.emailForm.aws_secret_access_key; if (this.emailForm.aws_region) payload.aws_region = this.emailForm.aws_region; } const data = await apiClient.put('/admin/settings/email/settings', payload); this.successMessage = data.message || 'Email settings saved successfully'; this.emailEditMode = false; // Reload to get updated status await this.loadEmailSettings(); setTimeout(() => { this.successMessage = null; }, 5000); settingsLog.info('Email settings saved successfully'); } catch (error) { settingsLog.error('Failed to save email settings:', error); this.error = error.message || 'Failed to save email settings'; } finally { this.saving = false; } }, async resetEmailSettings() { if (!confirm('This will reset all email settings to use .env defaults. Continue?')) { return; } this.saving = true; this.error = null; this.successMessage = null; try { const data = await apiClient.delete('/admin/settings/email/settings'); this.successMessage = data.message || 'Email settings reset to defaults'; this.emailEditMode = false; // Reload to get .env values await this.loadEmailSettings(); setTimeout(() => { this.successMessage = null; }, 5000); settingsLog.info('Email settings reset successfully'); } catch (error) { settingsLog.error('Failed to reset email settings:', error); this.error = error.message || 'Failed to reset email settings'; } finally { this.saving = false; } }, async sendTestEmail() { if (!this.testEmailAddress) { this.error = 'Please enter a test email address'; return; } this.sendingTestEmail = true; this.error = null; this.successMessage = null; try { const data = await apiClient.post('/admin/settings/email/test', { to_email: this.testEmailAddress }); if (data.success) { this.successMessage = `Test email sent to ${this.testEmailAddress}`; setTimeout(() => { this.successMessage = null; }, 5000); } else { this.error = data.message || 'Failed to send test email'; } } catch (error) { settingsLog.error('Failed to send test email:', error); this.error = error.message || 'Failed to send test email'; } finally { this.sendingTestEmail = false; } } }; } settingsLog.info('Settings module loaded');