// static/admin/js/letzshop.js /** * Admin Letzshop management page logic */ // Use centralized logger (with fallback) const letzshopLog = window.LogConfig?.createLogger?.('letzshop') || window.LogConfig?.loggers?.letzshop || { info: () => {}, warn: () => {}, error: () => {}, debug: () => {} }; letzshopLog.info('Loading...'); function adminLetzshop() { letzshopLog.info('adminLetzshop() called'); return { // Inherit base layout state ...data(), // Set page identifier currentPage: 'letzshop', // Loading states loading: false, savingConfig: false, loadingOrders: false, // Messages error: '', successMessage: '', // Vendors data vendors: [], totalVendors: 0, page: 1, limit: 50, // Filters filters: { configuredOnly: false }, // Stats stats: { total: 0, configured: 0, autoSync: 0, pendingOrders: 0 }, // Configuration modal showConfigModal: false, selectedVendor: null, vendorCredentials: null, configForm: { api_key: '', auto_sync_enabled: false, sync_interval_minutes: 15 }, showApiKey: false, // Orders modal showOrdersModal: false, vendorOrders: [], async init() { // Guard against multiple initialization if (window._adminLetzshopInitialized) { return; } window._adminLetzshopInitialized = true; letzshopLog.info('Initializing...'); await this.loadVendors(); }, /** * Load vendors with Letzshop status */ async loadVendors() { this.loading = true; this.error = ''; try { const params = new URLSearchParams({ skip: ((this.page - 1) * this.limit).toString(), limit: this.limit.toString(), configured_only: this.filters.configuredOnly.toString() }); const response = await apiClient.get(`/admin/letzshop/vendors?${params}`); this.vendors = response.vendors || []; this.totalVendors = response.total || 0; // Calculate stats this.stats.total = this.totalVendors; this.stats.configured = this.vendors.filter(v => v.is_configured).length; this.stats.autoSync = this.vendors.filter(v => v.auto_sync_enabled).length; this.stats.pendingOrders = this.vendors.reduce((sum, v) => sum + (v.pending_orders || 0), 0); letzshopLog.info('Loaded vendors:', this.vendors.length); } catch (error) { letzshopLog.error('Failed to load vendors:', error); this.error = error.message || 'Failed to load vendors'; } finally { this.loading = false; } }, /** * Refresh all data */ async refreshData() { await this.loadVendors(); this.successMessage = 'Data refreshed'; setTimeout(() => this.successMessage = '', 3000); }, /** * Open configuration modal for a vendor */ async openConfigModal(vendor) { this.selectedVendor = vendor; this.vendorCredentials = null; this.configForm = { api_key: '', auto_sync_enabled: vendor.auto_sync_enabled || false, sync_interval_minutes: 15 }; this.showApiKey = false; this.showConfigModal = true; // Load existing credentials if configured if (vendor.is_configured) { try { const response = await apiClient.get(`/admin/letzshop/vendors/${vendor.vendor_id}/credentials`); this.vendorCredentials = response; this.configForm.auto_sync_enabled = response.auto_sync_enabled; this.configForm.sync_interval_minutes = response.sync_interval_minutes || 15; } catch (error) { if (error.status !== 404) { letzshopLog.error('Failed to load credentials:', error); } } } }, /** * Save vendor configuration */ async saveVendorConfig() { if (!this.configForm.api_key && !this.vendorCredentials) { this.error = 'Please enter an API key'; return; } this.savingConfig = true; this.error = ''; try { const payload = { auto_sync_enabled: this.configForm.auto_sync_enabled, sync_interval_minutes: parseInt(this.configForm.sync_interval_minutes) }; if (this.configForm.api_key) { payload.api_key = this.configForm.api_key; } await apiClient.post( `/admin/letzshop/vendors/${this.selectedVendor.vendor_id}/credentials`, payload ); this.showConfigModal = false; this.successMessage = 'Configuration saved successfully'; await this.loadVendors(); } catch (error) { letzshopLog.error('Failed to save config:', error); this.error = error.message || 'Failed to save configuration'; } finally { this.savingConfig = false; setTimeout(() => this.successMessage = '', 5000); } }, /** * Delete vendor configuration */ async deleteVendorConfig() { if (!confirm('Are you sure you want to remove Letzshop configuration for this vendor?')) { return; } try { await apiClient.delete(`/admin/letzshop/vendors/${this.selectedVendor.vendor_id}/credentials`); this.showConfigModal = false; this.successMessage = 'Configuration removed'; await this.loadVendors(); } catch (error) { letzshopLog.error('Failed to delete config:', error); this.error = error.message || 'Failed to remove configuration'; } setTimeout(() => this.successMessage = '', 5000); }, /** * Test connection for a vendor */ async testConnection(vendor) { this.error = ''; try { const response = await apiClient.post(`/admin/letzshop/vendors/${vendor.vendor_id}/test`); if (response.success) { this.successMessage = `Connection successful for ${vendor.vendor_name} (${response.response_time_ms?.toFixed(0)}ms)`; } else { this.error = response.error_details || 'Connection failed'; } } catch (error) { letzshopLog.error('Connection test failed:', error); this.error = error.message || 'Connection test failed'; } setTimeout(() => this.successMessage = '', 5000); }, /** * Trigger sync for a vendor */ async triggerSync(vendor) { this.error = ''; try { const response = await apiClient.post(`/admin/letzshop/vendors/${vendor.vendor_id}/sync`); if (response.success) { this.successMessage = response.message || 'Sync completed'; await this.loadVendors(); } else { this.error = response.message || 'Sync failed'; } } catch (error) { letzshopLog.error('Sync failed:', error); this.error = error.message || 'Sync failed'; } setTimeout(() => this.successMessage = '', 5000); }, /** * View orders for a vendor */ async viewOrders(vendor) { this.selectedVendor = vendor; this.vendorOrders = []; this.loadingOrders = true; this.showOrdersModal = true; try { const response = await apiClient.get(`/admin/letzshop/vendors/${vendor.vendor_id}/orders?limit=100`); this.vendorOrders = response.orders || []; } catch (error) { letzshopLog.error('Failed to load orders:', error); this.error = error.message || 'Failed to load orders'; } finally { this.loadingOrders = false; } }, /** * Format date for display */ formatDate(dateStr) { if (!dateStr) return 'N/A'; const date = new Date(dateStr); return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } }; } letzshopLog.info('Module loaded');