diff --git a/app/modules/catalog/static/admin/js/product-create.js b/app/modules/catalog/static/admin/js/product-create.js index 431a5d3d..02f8ed57 100644 --- a/app/modules/catalog/static/admin/js/product-create.js +++ b/app/modules/catalog/static/admin/js/product-create.js @@ -66,22 +66,27 @@ function adminVendorProductCreate() { }, async init() { - // Load i18n translations - await I18n.loadModule('catalog'); + try { + // Load i18n translations + await I18n.loadModule('catalog'); - adminVendorProductCreateLog.info('Vendor Product Create init() called'); + adminVendorProductCreateLog.info('Vendor Product Create init() called'); - // Guard against multiple initialization - if (window._adminVendorProductCreateInitialized) { - adminVendorProductCreateLog.warn('Already initialized, skipping'); - return; + // Guard against multiple initialization + if (window._adminVendorProductCreateInitialized) { + adminVendorProductCreateLog.warn('Already initialized, skipping'); + return; + } + window._adminVendorProductCreateInitialized = true; + + // Initialize Tom Select + this.initVendorSelect(); + + adminVendorProductCreateLog.info('Vendor Product Create initialization complete'); + } catch (error) { + adminVendorProductCreateLog.error('Init failed:', error); + this.error = 'Failed to initialize product create page'; } - window._adminVendorProductCreateInitialized = true; - - // Initialize Tom Select - this.initVendorSelect(); - - adminVendorProductCreateLog.info('Vendor Product Create initialization complete'); }, /** diff --git a/app/modules/catalog/static/admin/js/product-edit.js b/app/modules/catalog/static/admin/js/product-edit.js index 021df2b5..8b54be98 100644 --- a/app/modules/catalog/static/admin/js/product-edit.js +++ b/app/modules/catalog/static/admin/js/product-edit.js @@ -76,11 +76,6 @@ function adminVendorProductEdit() { }, async init() { - // Load i18n translations - await I18n.loadModule('catalog'); - - adminVendorProductEditLog.info('Vendor Product Edit init() called, ID:', this.productId); - // Guard against multiple initialization if (window._adminVendorProductEditInitialized) { adminVendorProductEditLog.warn('Already initialized, skipping'); @@ -88,10 +83,20 @@ function adminVendorProductEdit() { } window._adminVendorProductEditInitialized = true; - // Load product data - await this.loadProduct(); + try { + // Load i18n translations + await I18n.loadModule('catalog'); - adminVendorProductEditLog.info('Vendor Product Edit initialization complete'); + adminVendorProductEditLog.info('Vendor Product Edit init() called, ID:', this.productId); + + // Load product data + await this.loadProduct(); + + adminVendorProductEditLog.info('Vendor Product Edit initialization complete'); + } catch (error) { + adminVendorProductEditLog.error('Init failed:', error); + this.error = 'Failed to initialize product edit page'; + } }, /** diff --git a/app/modules/catalog/static/vendor/js/products.js b/app/modules/catalog/static/vendor/js/products.js index 189ec524..c8d423a2 100644 --- a/app/modules/catalog/static/vendor/js/products.js +++ b/app/modules/catalog/static/vendor/js/products.js @@ -112,37 +112,37 @@ function vendorProducts() { }, async init() { - // Load i18n translations - await I18n.loadModule('catalog'); - - vendorProductsLog.info('Products init() called'); - - // Guard against multiple initialization - if (window._vendorProductsInitialized) { - vendorProductsLog.warn('Already initialized, skipping'); - return; - } - window._vendorProductsInitialized = true; - - // IMPORTANT: Call parent init first to set vendorCode from URL - const parentInit = data().init; - if (parentInit) { - await parentInit.call(this); - } - - // Load platform settings for rows per page - if (window.PlatformSettings) { - this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); - } - try { + // Load i18n translations + await I18n.loadModule('catalog'); + + vendorProductsLog.info('Products init() called'); + + // Guard against multiple initialization + if (window._vendorProductsInitialized) { + vendorProductsLog.warn('Already initialized, skipping'); + return; + } + window._vendorProductsInitialized = true; + + // IMPORTANT: Call parent init first to set vendorCode from URL + const parentInit = data().init; + if (parentInit) { + await parentInit.call(this); + } + + // Load platform settings for rows per page + if (window.PlatformSettings) { + this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); + } + await this.loadProducts(); + + vendorProductsLog.info('Products initialization complete'); } catch (error) { vendorProductsLog.error('Init failed:', error); this.error = 'Failed to initialize products page'; } - - vendorProductsLog.info('Products initialization complete'); }, /** diff --git a/app/modules/customers/static/vendor/js/customers.js b/app/modules/customers/static/vendor/js/customers.js index 3f232f9d..794eba3f 100644 --- a/app/modules/customers/static/vendor/js/customers.js +++ b/app/modules/customers/static/vendor/js/customers.js @@ -97,37 +97,37 @@ function vendorCustomers() { }, async init() { - // Load i18n translations - await I18n.loadModule('customers'); - - vendorCustomersLog.info('Customers init() called'); - - // Guard against multiple initialization - if (window._vendorCustomersInitialized) { - vendorCustomersLog.warn('Already initialized, skipping'); - return; - } - window._vendorCustomersInitialized = true; - - // IMPORTANT: Call parent init first to set vendorCode from URL - const parentInit = data().init; - if (parentInit) { - await parentInit.call(this); - } - - // Load platform settings for rows per page - if (window.PlatformSettings) { - this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); - } - try { + // Load i18n translations + await I18n.loadModule('customers'); + + vendorCustomersLog.info('Customers init() called'); + + // Guard against multiple initialization + if (window._vendorCustomersInitialized) { + vendorCustomersLog.warn('Already initialized, skipping'); + return; + } + window._vendorCustomersInitialized = true; + + // IMPORTANT: Call parent init first to set vendorCode from URL + const parentInit = data().init; + if (parentInit) { + await parentInit.call(this); + } + + // Load platform settings for rows per page + if (window.PlatformSettings) { + this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); + } + await this.loadCustomers(); + + vendorCustomersLog.info('Customers initialization complete'); } catch (error) { vendorCustomersLog.error('Init failed:', error); this.error = 'Failed to initialize customers page'; } - - vendorCustomersLog.info('Customers initialization complete'); }, /** diff --git a/app/modules/dev_tools/static/admin/js/components.js b/app/modules/dev_tools/static/admin/js/components.js index 8700da5d..9d424876 100644 --- a/app/modules/dev_tools/static/admin/js/components.js +++ b/app/modules/dev_tools/static/admin/js/components.js @@ -468,32 +468,36 @@ function adminComponents() { // ✅ CRITICAL: Proper initialization with guard async init() { - // Load i18n translations - await I18n.loadModule('dev_tools'); + try { + // Load i18n translations + await I18n.loadModule('dev_tools'); - componentsLog.info('=== COMPONENTS PAGE INITIALIZING ==='); + componentsLog.info('=== COMPONENTS PAGE INITIALIZING ==='); - // Prevent multiple initializations - if (window._componentsInitialized) { - componentsLog.warn('Components page already initialized, skipping...'); - return; - } - window._componentsInitialized = true; + // Prevent multiple initializations + if (window._componentsInitialized) { + componentsLog.warn('Components page already initialized, skipping...'); + return; + } + window._componentsInitialized = true; - // Set active section from URL hash if present - this.setActiveSectionFromHash(); - - // Listen for hash changes - window.addEventListener('hashchange', () => { + // Set active section from URL hash if present this.setActiveSectionFromHash(); - }); - // Initialize charts after DOM is ready - this.$nextTick(() => { - this.initializeCharts(); - }); + // Listen for hash changes + window.addEventListener('hashchange', () => { + this.setActiveSectionFromHash(); + }); - componentsLog.info('=== COMPONENTS PAGE INITIALIZATION COMPLETE ==='); + // Initialize charts after DOM is ready + this.$nextTick(() => { + this.initializeCharts(); + }); + + componentsLog.info('=== COMPONENTS PAGE INITIALIZATION COMPLETE ==='); + } catch (error) { + componentsLog.error('Init failed:', error); + } }, /** diff --git a/app/modules/dev_tools/static/admin/js/icons-page.js b/app/modules/dev_tools/static/admin/js/icons-page.js index b6fcd87f..0418c1e7 100644 --- a/app/modules/dev_tools/static/admin/js/icons-page.js +++ b/app/modules/dev_tools/static/admin/js/icons-page.js @@ -16,6 +16,9 @@ function adminIcons() { // ✅ CRITICAL: Set page identifier currentPage: 'icons', + // Loading state + loading: false, + // Search and filter searchQuery: '', activeCategory: 'all', @@ -45,11 +48,6 @@ function adminIcons() { // ✅ CRITICAL: Proper initialization with guard async init() { - // Load i18n translations - await I18n.loadModule('dev_tools'); - - iconsLog.info('=== ICONS PAGE INITIALIZING ==='); - // Prevent multiple initializations if (window._iconsPageInitialized) { iconsLog.warn('Icons page already initialized, skipping...'); @@ -57,15 +55,27 @@ function adminIcons() { } window._iconsPageInitialized = true; - const startTime = performance.now(); + this.loading = true; + try { + // Load i18n translations + await I18n.loadModule('dev_tools'); - // Load icons from global Icons object - this.loadIcons(); + iconsLog.info('=== ICONS PAGE INITIALIZING ==='); - const duration = performance.now() - startTime; - window.LogConfig.logPerformance('Icons Page Init', duration); + const startTime = performance.now(); - iconsLog.info('=== ICONS PAGE INITIALIZATION COMPLETE ==='); + // Load icons from global Icons object + this.loadIcons(); + + const duration = performance.now() - startTime; + window.LogConfig.logPerformance('Icons Page Init', duration); + + iconsLog.info('=== ICONS PAGE INITIALIZATION COMPLETE ==='); + } catch (error) { + iconsLog.error('Init failed:', error); + } finally { + this.loading = false; + } }, /** diff --git a/app/modules/inventory/static/vendor/js/inventory.js b/app/modules/inventory/static/vendor/js/inventory.js index 303fc873..2a62b365 100644 --- a/app/modules/inventory/static/vendor/js/inventory.js +++ b/app/modules/inventory/static/vendor/js/inventory.js @@ -128,37 +128,37 @@ function vendorInventory() { }, async init() { - // Load i18n translations - await I18n.loadModule('inventory'); - - vendorInventoryLog.info('Inventory init() called'); - - // Guard against multiple initialization - if (window._vendorInventoryInitialized) { - vendorInventoryLog.warn('Already initialized, skipping'); - return; - } - window._vendorInventoryInitialized = true; - - // IMPORTANT: Call parent init first to set vendorCode from URL - const parentInit = data().init; - if (parentInit) { - await parentInit.call(this); - } - - // Load platform settings for rows per page - if (window.PlatformSettings) { - this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); - } - try { + // Load i18n translations + await I18n.loadModule('inventory'); + + vendorInventoryLog.info('Inventory init() called'); + + // Guard against multiple initialization + if (window._vendorInventoryInitialized) { + vendorInventoryLog.warn('Already initialized, skipping'); + return; + } + window._vendorInventoryInitialized = true; + + // IMPORTANT: Call parent init first to set vendorCode from URL + const parentInit = data().init; + if (parentInit) { + await parentInit.call(this); + } + + // Load platform settings for rows per page + if (window.PlatformSettings) { + this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); + } + await this.loadInventory(); + + vendorInventoryLog.info('Inventory initialization complete'); } catch (error) { vendorInventoryLog.error('Init failed:', error); this.error = 'Failed to initialize inventory page'; } - - vendorInventoryLog.info('Inventory initialization complete'); }, /** diff --git a/app/modules/orders/static/vendor/js/order-detail.js b/app/modules/orders/static/vendor/js/order-detail.js index 0cfa1ab2..a6fe9e67 100644 --- a/app/modules/orders/static/vendor/js/order-detail.js +++ b/app/modules/orders/static/vendor/js/order-detail.js @@ -53,11 +53,6 @@ function vendorOrderDetail() { ], async init() { - // Load i18n translations - await I18n.loadModule('orders'); - - orderDetailLog.info('Order detail init() called, orderId:', this.orderId); - // Guard against multiple initialization if (window._orderDetailInitialized) { orderDetailLog.warn('Already initialized, skipping'); @@ -65,26 +60,31 @@ function vendorOrderDetail() { } window._orderDetailInitialized = true; - // IMPORTANT: Call parent init first to set vendorCode from URL - const parentInit = data().init; - if (parentInit) { - await parentInit.call(this); - } - - if (!this.orderId) { - this.error = 'Order ID not provided'; - this.loading = false; - return; - } - try { + // Load i18n translations + await I18n.loadModule('orders'); + + orderDetailLog.info('Order detail init() called, orderId:', this.orderId); + + // IMPORTANT: Call parent init first to set vendorCode from URL + const parentInit = data().init; + if (parentInit) { + await parentInit.call(this); + } + + if (!this.orderId) { + this.error = 'Order ID not provided'; + this.loading = false; + return; + } + await this.loadOrderDetails(); + + orderDetailLog.info('Order detail initialization complete'); } catch (error) { orderDetailLog.error('Init failed:', error); this.error = 'Failed to load order details'; } - - orderDetailLog.info('Order detail initialization complete'); }, /** diff --git a/app/modules/orders/static/vendor/js/orders.js b/app/modules/orders/static/vendor/js/orders.js index 96cd80d2..64222f4d 100644 --- a/app/modules/orders/static/vendor/js/orders.js +++ b/app/modules/orders/static/vendor/js/orders.js @@ -128,37 +128,37 @@ function vendorOrders() { }, async init() { - // Load i18n translations - await I18n.loadModule('orders'); - - vendorOrdersLog.info('Orders init() called'); - - // Guard against multiple initialization - if (window._vendorOrdersInitialized) { - vendorOrdersLog.warn('Already initialized, skipping'); - return; - } - window._vendorOrdersInitialized = true; - - // IMPORTANT: Call parent init first to set vendorCode from URL - const parentInit = data().init; - if (parentInit) { - await parentInit.call(this); - } - - // Load platform settings for rows per page - if (window.PlatformSettings) { - this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); - } - try { + // Load i18n translations + await I18n.loadModule('orders'); + + vendorOrdersLog.info('Orders init() called'); + + // Guard against multiple initialization + if (window._vendorOrdersInitialized) { + vendorOrdersLog.warn('Already initialized, skipping'); + return; + } + window._vendorOrdersInitialized = true; + + // IMPORTANT: Call parent init first to set vendorCode from URL + const parentInit = data().init; + if (parentInit) { + await parentInit.call(this); + } + + // Load platform settings for rows per page + if (window.PlatformSettings) { + this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); + } + await this.loadOrders(); + + vendorOrdersLog.info('Orders initialization complete'); } catch (error) { vendorOrdersLog.error('Init failed:', error); this.error = 'Failed to initialize orders page'; } - - vendorOrdersLog.info('Orders initialization complete'); }, /** diff --git a/app/modules/payments/locales/de.json b/app/modules/payments/locales/de.json new file mode 100644 index 00000000..90f49116 --- /dev/null +++ b/app/modules/payments/locales/de.json @@ -0,0 +1,12 @@ +{ + "payments": { + "title": "Zahlungen", + "menu": { + "payments": "Zahlungen" + }, + "messages": { + "payment_successful": "Zahlung erfolgreich verarbeitet", + "payment_failed": "Zahlungsverarbeitung fehlgeschlagen" + } + } +} diff --git a/app/modules/payments/locales/en.json b/app/modules/payments/locales/en.json new file mode 100644 index 00000000..8a83ad34 --- /dev/null +++ b/app/modules/payments/locales/en.json @@ -0,0 +1,12 @@ +{ + "payments": { + "title": "Payments", + "menu": { + "payments": "Payments" + }, + "messages": { + "payment_successful": "Payment processed successfully", + "payment_failed": "Payment processing failed" + } + } +} diff --git a/app/modules/payments/locales/fr.json b/app/modules/payments/locales/fr.json new file mode 100644 index 00000000..3ee1a6c7 --- /dev/null +++ b/app/modules/payments/locales/fr.json @@ -0,0 +1,12 @@ +{ + "payments": { + "title": "Paiements", + "menu": { + "payments": "Paiements" + }, + "messages": { + "payment_successful": "Paiement traité avec succès", + "payment_failed": "Échec du traitement du paiement" + } + } +} diff --git a/app/modules/payments/locales/lb.json b/app/modules/payments/locales/lb.json new file mode 100644 index 00000000..2ed07269 --- /dev/null +++ b/app/modules/payments/locales/lb.json @@ -0,0 +1,12 @@ +{ + "payments": { + "title": "Bezuelungen", + "menu": { + "payments": "Bezuelungen" + }, + "messages": { + "payment_successful": "Bezuelung erfollegräich veraarbecht", + "payment_failed": "Bezuelungsveraarbechtung ass feelgeschloen" + } + } +} diff --git a/app/modules/payments/static/vendor/js/.gitkeep b/app/modules/payments/static/vendor/js/.gitkeep new file mode 100644 index 00000000..61500fab --- /dev/null +++ b/app/modules/payments/static/vendor/js/.gitkeep @@ -0,0 +1 @@ +// Placeholder to keep directory in git diff --git a/app/modules/payments/templates/payments/vendor/.gitkeep b/app/modules/payments/templates/payments/vendor/.gitkeep new file mode 100644 index 00000000..879f526d --- /dev/null +++ b/app/modules/payments/templates/payments/vendor/.gitkeep @@ -0,0 +1 @@ +# Placeholder to keep directory in git diff --git a/app/modules/tenancy/static/admin/js/admin-user-edit.js b/app/modules/tenancy/static/admin/js/admin-user-edit.js index 99a13c4f..ec1d00b1 100644 --- a/app/modules/tenancy/static/admin/js/admin-user-edit.js +++ b/app/modules/tenancy/static/admin/js/admin-user-edit.js @@ -29,37 +29,42 @@ function adminUserEditPage() { // Initialize async init() { - // Load i18n translations - await I18n.loadModule('tenancy'); + try { + // Load i18n translations + await I18n.loadModule('tenancy'); - adminUserEditLog.info('=== ADMIN USER EDIT PAGE INITIALIZING ==='); + adminUserEditLog.info('=== ADMIN USER EDIT PAGE INITIALIZING ==='); - // Prevent multiple initializations - if (window._adminUserEditInitialized) { - adminUserEditLog.warn('Admin user edit page already initialized, skipping...'); - return; + // Prevent multiple initializations + if (window._adminUserEditInitialized) { + adminUserEditLog.warn('Admin user edit page already initialized, skipping...'); + return; + } + window._adminUserEditInitialized = true; + + // Get current user ID + this.currentUserId = this.adminProfile?.id || null; + + // Get user ID from URL + const path = window.location.pathname; + const match = path.match(/\/admin\/admin-users\/(\d+)\/edit/); + + if (match) { + this.userId = parseInt(match[1], 10); + adminUserEditLog.info('Editing admin user:', this.userId); + await this.loadAdminUser(); + await this.loadAllPlatforms(); + } else { + adminUserEditLog.error('No user ID in URL'); + Utils.showToast(I18n.t('tenancy.messages.invalid_admin_user_url'), 'error'); + setTimeout(() => window.location.href = '/admin/admin-users', 2000); + } + + adminUserEditLog.info('=== ADMIN USER EDIT PAGE INITIALIZATION COMPLETE ==='); + } catch (error) { + adminUserEditLog.error('Init failed:', error); + this.error = 'Failed to initialize admin user edit page'; } - window._adminUserEditInitialized = true; - - // Get current user ID - this.currentUserId = this.adminProfile?.id || null; - - // Get user ID from URL - const path = window.location.pathname; - const match = path.match(/\/admin\/admin-users\/(\d+)\/edit/); - - if (match) { - this.userId = parseInt(match[1], 10); - adminUserEditLog.info('Editing admin user:', this.userId); - await this.loadAdminUser(); - await this.loadAllPlatforms(); - } else { - adminUserEditLog.error('No user ID in URL'); - Utils.showToast(I18n.t('tenancy.messages.invalid_admin_user_url'), 'error'); - setTimeout(() => window.location.href = '/admin/admin-users', 2000); - } - - adminUserEditLog.info('=== ADMIN USER EDIT PAGE INITIALIZATION COMPLETE ==='); }, // Load admin user data diff --git a/static/shared/js/i18n.js b/static/shared/js/i18n.js index ecb1165e..51c0ba02 100644 --- a/static/shared/js/i18n.js +++ b/static/shared/js/i18n.js @@ -15,6 +15,15 @@ * const message = I18n.t('catalog.messages.product_created'); * const withVars = I18n.t('common.welcome', { name: 'John' }); */ + +// Create logger for i18n module (with silent fallback if LogConfig not yet loaded) +const i18nLog = window.LogConfig ? window.LogConfig.createLogger('I18N') : { + warn: () => {}, // Silent fallback - i18n loads early before LogConfig + error: () => {}, + info: () => {}, + debug: () => {} +}; + const I18n = { _translations: {}, _language: 'en', @@ -50,7 +59,7 @@ const I18n = { this._loaded.add('shared'); } } catch (e) { - console.warn('[i18n] Failed to load shared translations:', e); + i18nLog.warn('Failed to load shared translations:', e); } }, @@ -70,7 +79,7 @@ const I18n = { this._loaded.add(module); } } catch (e) { - console.warn(`[i18n] Failed to load ${module} translations:`, e); + i18nLog.warn(`Failed to load ${module} translations:`, e); } }, @@ -88,7 +97,7 @@ const I18n = { if (value && typeof value === 'object' && k in value) { value = value[k]; } else { - console.warn(`[i18n] Missing translation: ${key}`); + i18nLog.warn(`Missing translation: ${key}`); return key; } } @@ -136,18 +145,22 @@ const I18n = { async setLanguage(language) { if (language === this._language) return; - const loadedModules = [...this._loaded]; - this._language = language; - this._translations = {}; - this._loaded.clear(); + try { + const loadedModules = [...this._loaded]; + this._language = language; + this._translations = {}; + this._loaded.clear(); - // Reload all previously loaded modules - for (const module of loadedModules) { - if (module === 'shared') { - await this.loadShared(); - } else { - await this.loadModule(module); + // Reload all previously loaded modules + for (const module of loadedModules) { + if (module === 'shared') { + await this.loadShared(); + } else { + await this.loadModule(module); + } } + } catch (e) { + i18nLog.error('Failed to change language:', e); } } };