refactor: complete JS i18n migration for confirm dialogs and toast messages
Migrate 34 hardcoded user-facing strings to use I18n.t() for translation: - CMS: media file operations (5 strings) - Marketplace: Letzshop integration (16 strings) - Messaging: notifications, messages, email templates (5 strings) - Tenancy: platform modules, menu config, theme (5 strings) - Core: menu config, settings, storefront cart (5 strings) - Catalog: product creation (3 strings) - Utils: clipboard operations (2 strings) Added confirmations and messages keys to module locale files. Added I18n.loadModule() calls to JS files that were missing them. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1,49 @@
|
||||
{}
|
||||
{
|
||||
"notifications": {
|
||||
"title": "Notifications",
|
||||
"mark_read": "Mark as Read",
|
||||
"mark_all_read": "Mark All as Read",
|
||||
"no_notifications": "No notifications",
|
||||
"new_order": "New Order",
|
||||
"order_updated": "Order Updated",
|
||||
"low_stock": "Low Stock Alert",
|
||||
"import_complete": "Import Complete",
|
||||
"import_failed": "Import Failed"
|
||||
},
|
||||
"messages": {
|
||||
"failed_to_load_template": "Failed to load template",
|
||||
"template_saved_successfully": "Template saved successfully",
|
||||
"reverted_to_platform_default": "Reverted to platform default",
|
||||
"failed_to_load_preview": "Failed to load preview",
|
||||
"failed_to_send_test_email": "Failed to send test email",
|
||||
"failed_to_load_conversations": "Failed to load conversations",
|
||||
"failed_to_load_conversation": "Failed to load conversation",
|
||||
"conversation_closed": "Conversation closed",
|
||||
"failed_to_close_conversation": "Failed to close conversation",
|
||||
"conversation_reopened": "Conversation reopened",
|
||||
"failed_to_reopen_conversation": "Failed to reopen conversation",
|
||||
"conversation_created": "Conversation created",
|
||||
"notification_marked_as_read": "Notification marked as read",
|
||||
"all_notifications_marked_as_read": "All notifications marked as read",
|
||||
"notification_deleted": "Notification deleted",
|
||||
"notification_settings_saved": "Notification settings saved",
|
||||
"failed_to_load_templates": "Failed to load templates",
|
||||
"failed_to_load_recipients": "Failed to load recipients",
|
||||
"failed_to_load_notifications": "Failed to load notifications",
|
||||
"failed_to_mark_notification_as_read": "Failed to mark notification as read",
|
||||
"failed_to_mark_all_as_read": "Failed to mark all as read",
|
||||
"failed_to_delete_notification": "Failed to delete notification",
|
||||
"failed_to_load_alerts": "Failed to load alerts",
|
||||
"alert_resolved_successfully": "Alert resolved successfully",
|
||||
"failed_to_resolve_alert": "Failed to resolve alert",
|
||||
"no_template_for_language": "No template for {language} - create one by saving",
|
||||
"failed_to_save_template": "Failed to save template",
|
||||
"test_email_sent": "Test email sent to {email}"
|
||||
},
|
||||
"confirmations": {
|
||||
"delete_notification": "Are you sure you want to delete this notification?",
|
||||
"close_conversation": "Close this conversation?",
|
||||
"close_conversation_admin": "Are you sure you want to close this conversation?",
|
||||
"delete_customization": "Are you sure you want to delete your customization and revert to the platform default?"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ function adminMessages(initialConversationId = null) {
|
||||
* Initialize component
|
||||
*/
|
||||
async init() {
|
||||
// Load i18n translations
|
||||
await I18n.loadModule('messaging');
|
||||
|
||||
// Guard against multiple initialization
|
||||
if (window._adminMessagesInitialized) return;
|
||||
window._adminMessagesInitialized = true;
|
||||
@@ -141,7 +144,7 @@ function adminMessages(initialConversationId = null) {
|
||||
messagesLog.debug(`Loaded ${this.conversations.length} conversations`);
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to load conversations:', error);
|
||||
Utils.showToast('Failed to load conversations', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_conversations'), 'error');
|
||||
} finally {
|
||||
this.loadingConversations = false;
|
||||
}
|
||||
@@ -197,7 +200,7 @@ function adminMessages(initialConversationId = null) {
|
||||
this.scrollToBottom();
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to load conversation:', error);
|
||||
Utils.showToast('Failed to load conversation', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_conversation'), 'error');
|
||||
} finally {
|
||||
this.loadingMessages = false;
|
||||
}
|
||||
@@ -301,7 +304,7 @@ function adminMessages(initialConversationId = null) {
|
||||
* Close conversation
|
||||
*/
|
||||
async closeConversation() {
|
||||
if (!confirm('Are you sure you want to close this conversation?')) return;
|
||||
if (!confirm(I18n.t('messaging.confirmations.close_conversation_admin'))) return;
|
||||
|
||||
try {
|
||||
await apiClient.post(`/admin/messages/${this.selectedConversationId}/close`);
|
||||
@@ -316,10 +319,10 @@ function adminMessages(initialConversationId = null) {
|
||||
conv.is_closed = true;
|
||||
}
|
||||
|
||||
Utils.showToast('Conversation closed', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.conversation_closed'), 'success');
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to close conversation:', error);
|
||||
Utils.showToast('Failed to close conversation', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_close_conversation'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -340,10 +343,10 @@ function adminMessages(initialConversationId = null) {
|
||||
conv.is_closed = false;
|
||||
}
|
||||
|
||||
Utils.showToast('Conversation reopened', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.conversation_reopened'), 'success');
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to reopen conversation:', error);
|
||||
Utils.showToast('Failed to reopen conversation', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_reopen_conversation'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -367,7 +370,7 @@ function adminMessages(initialConversationId = null) {
|
||||
messagesLog.debug(`Loaded ${this.recipients.length} recipients`);
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to load recipients:', error);
|
||||
Utils.showToast('Failed to load recipients', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_recipients'), 'error');
|
||||
} finally {
|
||||
this.loadingRecipients = false;
|
||||
}
|
||||
@@ -416,7 +419,7 @@ function adminMessages(initialConversationId = null) {
|
||||
await this.loadConversations();
|
||||
await this.selectConversation(response.id);
|
||||
|
||||
Utils.showToast('Conversation created', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.conversation_created'), 'success');
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to create conversation:', error);
|
||||
Utils.showToast(error.message || 'Failed to create conversation', 'error');
|
||||
|
||||
@@ -71,6 +71,9 @@ function adminNotifications() {
|
||||
* Initialize component
|
||||
*/
|
||||
async init() {
|
||||
// Load i18n translations
|
||||
await I18n.loadModule('messaging');
|
||||
|
||||
// Guard against multiple initialization
|
||||
if (window._adminNotificationsInitialized) return;
|
||||
window._adminNotificationsInitialized = true;
|
||||
@@ -114,7 +117,7 @@ function adminNotifications() {
|
||||
notificationsLog.debug(`Loaded ${this.notifications.length} notifications`);
|
||||
} catch (error) {
|
||||
notificationsLog.error('Failed to load notifications:', error);
|
||||
Utils.showToast('Failed to load notifications', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_notifications'), 'error');
|
||||
} finally {
|
||||
this.loadingNotifications = false;
|
||||
}
|
||||
@@ -131,10 +134,10 @@ function adminNotifications() {
|
||||
notification.is_read = true;
|
||||
this.stats.unread_count = Math.max(0, this.stats.unread_count - 1);
|
||||
|
||||
Utils.showToast('Notification marked as read', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.notification_marked_as_read'), 'success');
|
||||
} catch (error) {
|
||||
notificationsLog.error('Failed to mark as read:', error);
|
||||
Utils.showToast('Failed to mark notification as read', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_mark_notification_as_read'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -149,10 +152,10 @@ function adminNotifications() {
|
||||
this.notifications.forEach(n => n.is_read = true);
|
||||
this.stats.unread_count = 0;
|
||||
|
||||
Utils.showToast('All notifications marked as read', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.all_notifications_marked_as_read'), 'success');
|
||||
} catch (error) {
|
||||
notificationsLog.error('Failed to mark all as read:', error);
|
||||
Utils.showToast('Failed to mark all as read', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_mark_all_as_read'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -160,7 +163,7 @@ function adminNotifications() {
|
||||
* Delete notification
|
||||
*/
|
||||
async deleteNotification(notificationId) {
|
||||
if (!confirm('Are you sure you want to delete this notification?')) {
|
||||
if (!confirm(I18n.t('messaging.confirmations.delete_notification'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -175,10 +178,10 @@ function adminNotifications() {
|
||||
this.stats.unread_count = Math.max(0, this.stats.unread_count - 1);
|
||||
}
|
||||
|
||||
Utils.showToast('Notification deleted', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.notification_deleted'), 'success');
|
||||
} catch (error) {
|
||||
notificationsLog.error('Failed to delete notification:', error);
|
||||
Utils.showToast('Failed to delete notification', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_delete_notification'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -225,7 +228,7 @@ function adminNotifications() {
|
||||
notificationsLog.debug(`Loaded ${this.alerts.length} alerts`);
|
||||
} catch (error) {
|
||||
notificationsLog.error('Failed to load alerts:', error);
|
||||
Utils.showToast('Failed to load alerts', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_alerts'), 'error');
|
||||
} finally {
|
||||
this.loadingAlerts = false;
|
||||
}
|
||||
@@ -272,10 +275,10 @@ function adminNotifications() {
|
||||
}
|
||||
this.alertStats.resolved_today++;
|
||||
|
||||
Utils.showToast('Alert resolved successfully', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.alert_resolved_successfully'), 'success');
|
||||
} catch (error) {
|
||||
notificationsLog.error('Failed to resolve alert:', error);
|
||||
Utils.showToast('Failed to resolve alert', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_resolve_alert'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ function vendorEmailTemplates() {
|
||||
|
||||
// Lifecycle
|
||||
async init() {
|
||||
// Load i18n translations
|
||||
await I18n.loadModule('messaging');
|
||||
|
||||
if (window._vendorEmailTemplatesInitialized) return;
|
||||
window._vendorEmailTemplatesInitialized = true;
|
||||
|
||||
@@ -134,7 +137,7 @@ function vendorEmailTemplates() {
|
||||
Utils.showToast(`No template available for ${this.editLanguage.toUpperCase()}`, 'info');
|
||||
} else {
|
||||
vendorEmailTemplatesLog.error('Failed to load template:', error);
|
||||
Utils.showToast('Failed to load template', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_template'), 'error');
|
||||
}
|
||||
} finally {
|
||||
this.loadingTemplate = false;
|
||||
@@ -166,7 +169,7 @@ function vendorEmailTemplates() {
|
||||
}
|
||||
);
|
||||
|
||||
Utils.showToast('Template saved successfully', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.template_saved_successfully'), 'success');
|
||||
this.templateSource = 'vendor_override';
|
||||
// Refresh list to show updated status
|
||||
await this.loadData();
|
||||
@@ -181,7 +184,7 @@ function vendorEmailTemplates() {
|
||||
async revertToDefault() {
|
||||
if (!this.editingTemplate) return;
|
||||
|
||||
if (!confirm('Are you sure you want to delete your customization and revert to the platform default?')) {
|
||||
if (!confirm(I18n.t('messaging.confirmations.delete_customization'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -192,7 +195,7 @@ function vendorEmailTemplates() {
|
||||
`/vendor/email-templates/${this.editingTemplate.code}/${this.editLanguage}`
|
||||
);
|
||||
|
||||
Utils.showToast('Reverted to platform default', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.reverted_to_platform_default'), 'success');
|
||||
// Reload the template to show platform version
|
||||
await this.loadTemplateLanguage();
|
||||
// Refresh list
|
||||
@@ -222,7 +225,7 @@ function vendorEmailTemplates() {
|
||||
this.showPreviewModal = true;
|
||||
} catch (error) {
|
||||
vendorEmailTemplatesLog.error('Failed to preview template:', error);
|
||||
Utils.showToast('Failed to load preview', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_preview'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -255,7 +258,7 @@ function vendorEmailTemplates() {
|
||||
}
|
||||
} catch (error) {
|
||||
vendorEmailTemplatesLog.error('Failed to send test email:', error);
|
||||
Utils.showToast('Failed to send test email', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_send_test_email'), 'error');
|
||||
} finally {
|
||||
this.sendingTest = false;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,9 @@ function vendorMessages(initialConversationId = null) {
|
||||
* Initialize component
|
||||
*/
|
||||
async init() {
|
||||
// Load i18n translations
|
||||
await I18n.loadModule('messaging');
|
||||
|
||||
// Guard against multiple initialization
|
||||
if (window._vendorMessagesInitialized) return;
|
||||
window._vendorMessagesInitialized = true;
|
||||
@@ -143,7 +146,7 @@ function vendorMessages(initialConversationId = null) {
|
||||
messagesLog.debug(`Loaded ${this.conversations.length} conversations`);
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to load conversations:', error);
|
||||
Utils.showToast('Failed to load conversations', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_conversations'), 'error');
|
||||
} finally {
|
||||
this.loadingConversations = false;
|
||||
}
|
||||
@@ -192,7 +195,7 @@ function vendorMessages(initialConversationId = null) {
|
||||
this.scrollToBottom();
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to load conversation:', error);
|
||||
Utils.showToast('Failed to load conversation', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_load_conversation'), 'error');
|
||||
} finally {
|
||||
this.loadingMessages = false;
|
||||
}
|
||||
@@ -276,7 +279,7 @@ function vendorMessages(initialConversationId = null) {
|
||||
* Close conversation
|
||||
*/
|
||||
async closeConversation() {
|
||||
if (!confirm('Close this conversation?')) return;
|
||||
if (!confirm(I18n.t('messaging.confirmations.close_conversation'))) return;
|
||||
|
||||
try {
|
||||
await apiClient.post(`/vendor/messages/${this.selectedConversationId}/close`);
|
||||
@@ -288,10 +291,10 @@ function vendorMessages(initialConversationId = null) {
|
||||
const conv = this.conversations.find(c => c.id === this.selectedConversationId);
|
||||
if (conv) conv.is_closed = true;
|
||||
|
||||
Utils.showToast('Conversation closed', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.conversation_closed'), 'success');
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to close conversation:', error);
|
||||
Utils.showToast('Failed to close conversation', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_close_conversation'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -309,10 +312,10 @@ function vendorMessages(initialConversationId = null) {
|
||||
const conv = this.conversations.find(c => c.id === this.selectedConversationId);
|
||||
if (conv) conv.is_closed = false;
|
||||
|
||||
Utils.showToast('Conversation reopened', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.conversation_reopened'), 'success');
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to reopen conversation:', error);
|
||||
Utils.showToast('Failed to reopen conversation', 'error');
|
||||
Utils.showToast(I18n.t('messaging.messages.failed_to_reopen_conversation'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -356,7 +359,7 @@ function vendorMessages(initialConversationId = null) {
|
||||
await this.loadConversations();
|
||||
await this.selectConversation(response.id);
|
||||
|
||||
Utils.showToast('Conversation created', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.conversation_created'), 'success');
|
||||
} catch (error) {
|
||||
messagesLog.error('Failed to create conversation:', error);
|
||||
Utils.showToast(error.message || 'Failed to create conversation', 'error');
|
||||
|
||||
@@ -51,6 +51,9 @@ function vendorNotifications() {
|
||||
},
|
||||
|
||||
async init() {
|
||||
// Load i18n translations
|
||||
await I18n.loadModule('messaging');
|
||||
|
||||
vendorNotificationsLog.info('Notifications init() called');
|
||||
|
||||
// Guard against multiple initialization
|
||||
@@ -121,7 +124,7 @@ function vendorNotifications() {
|
||||
notification.is_read = true;
|
||||
this.stats.unread_count = Math.max(0, this.stats.unread_count - 1);
|
||||
|
||||
Utils.showToast('Notification marked as read', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.notification_marked_as_read'), 'success');
|
||||
} catch (error) {
|
||||
vendorNotificationsLog.error('Failed to mark as read:', error);
|
||||
Utils.showToast(error.message || 'Failed to mark notification as read', 'error');
|
||||
@@ -139,7 +142,7 @@ function vendorNotifications() {
|
||||
this.notifications.forEach(n => n.is_read = true);
|
||||
this.stats.unread_count = 0;
|
||||
|
||||
Utils.showToast('All notifications marked as read', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.all_notifications_marked_as_read'), 'success');
|
||||
} catch (error) {
|
||||
vendorNotificationsLog.error('Failed to mark all as read:', error);
|
||||
Utils.showToast(error.message || 'Failed to mark all as read', 'error');
|
||||
@@ -150,7 +153,7 @@ function vendorNotifications() {
|
||||
* Delete notification
|
||||
*/
|
||||
async deleteNotification(notificationId) {
|
||||
if (!confirm('Are you sure you want to delete this notification?')) {
|
||||
if (!confirm(I18n.t('messaging.confirmations.delete_notification'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -165,7 +168,7 @@ function vendorNotifications() {
|
||||
this.stats.unread_count = Math.max(0, this.stats.unread_count - 1);
|
||||
}
|
||||
|
||||
Utils.showToast('Notification deleted', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.notification_deleted'), 'success');
|
||||
} catch (error) {
|
||||
vendorNotificationsLog.error('Failed to delete notification:', error);
|
||||
Utils.showToast(error.message || 'Failed to delete notification', 'error');
|
||||
@@ -195,7 +198,7 @@ function vendorNotifications() {
|
||||
async saveSettings() {
|
||||
try {
|
||||
await apiClient.put(`/vendor/notifications/settings`, this.settingsForm);
|
||||
Utils.showToast('Notification settings saved', 'success');
|
||||
Utils.showToast(I18n.t('messaging.messages.notification_settings_saved'), 'success');
|
||||
this.showSettingsModal = false;
|
||||
} catch (error) {
|
||||
vendorNotificationsLog.error('Failed to save settings:', error);
|
||||
|
||||
Reference in New Issue
Block a user