// static/admin/js/letzshop-vendor-directory.js /** * Admin Letzshop Vendor Directory page logic * Browse and import vendors from Letzshop marketplace */ const letzshopVendorDirectoryLog = window.LogConfig.loggers.letzshopVendorDirectory || window.LogConfig.createLogger('letzshopVendorDirectory', false); letzshopVendorDirectoryLog.info('Loading...'); function letzshopVendorDirectory() { letzshopVendorDirectoryLog.info('letzshopVendorDirectory() called'); return { // Inherit base layout state ...data(), // Set page identifier for sidebar highlighting currentPage: 'letzshop-vendor-directory', // Data vendors: [], stats: {}, companies: [], total: 0, page: 1, limit: 20, hasMore: false, // State loading: true, syncing: false, creating: false, error: '', successMessage: '', // Filters filters: { search: '', city: '', category: '', only_unclaimed: false, }, // Modals showDetailModal: false, showCreateModal: false, selectedVendor: null, createVendorData: { slug: '', name: '', company_id: '', }, createError: '', // Init async init() { // Guard against multiple initialization if (window._letzshopVendorDirectoryInitialized) return; window._letzshopVendorDirectoryInitialized = true; letzshopVendorDirectoryLog.info('init() called'); await Promise.all([ this.loadStats(), this.loadVendors(), this.loadCompanies(), ]); }, // API calls async loadStats() { try { const data = await apiClient.get('/admin/letzshop/vendor-directory/stats'); if (data.success) { this.stats = data.stats; } } catch (e) { letzshopVendorDirectoryLog.error('Failed to load stats:', e); } }, async loadVendors() { this.loading = true; this.error = ''; try { const params = new URLSearchParams({ page: this.page, limit: this.limit, }); if (this.filters.search) params.append('search', this.filters.search); if (this.filters.city) params.append('city', this.filters.city); if (this.filters.category) params.append('category', this.filters.category); if (this.filters.only_unclaimed) params.append('only_unclaimed', 'true'); const data = await apiClient.get(`/admin/letzshop/vendor-directory/vendors?${params}`); if (data.success) { this.vendors = data.vendors; this.total = data.total; this.hasMore = data.has_more; } else { this.error = data.detail || 'Failed to load vendors'; } } catch (e) { this.error = 'Failed to load vendors'; letzshopVendorDirectoryLog.error('Failed to load vendors:', e); } finally { this.loading = false; } }, async loadCompanies() { try { const data = await apiClient.get('/admin/companies?limit=100'); if (data.companies) { this.companies = data.companies; } } catch (e) { letzshopVendorDirectoryLog.error('Failed to load companies:', e); } }, async triggerSync() { this.syncing = true; this.error = ''; this.successMessage = ''; try { const data = await apiClient.post('/admin/letzshop/vendor-directory/sync'); if (data.success) { this.successMessage = data.message + (data.mode === 'celery' ? ` (Task ID: ${data.task_id})` : ''); // Reload data after a delay to allow sync to complete setTimeout(() => { this.loadStats(); this.loadVendors(); }, 3000); } else { this.error = data.detail || 'Failed to trigger sync'; } } catch (e) { this.error = 'Failed to trigger sync'; letzshopVendorDirectoryLog.error('Failed to trigger sync:', e); } finally { this.syncing = false; } }, async createVendor() { if (!this.createVendorData.company_id || !this.createVendorData.slug) return; this.creating = true; this.createError = ''; try { const data = await apiClient.post( `/admin/letzshop/vendor-directory/vendors/${this.createVendorData.slug}/create-vendor?company_id=${this.createVendorData.company_id}` ); if (data.success) { this.showCreateModal = false; this.successMessage = data.message; this.loadVendors(); this.loadStats(); } else { this.createError = data.detail || 'Failed to create vendor'; } } catch (e) { this.createError = 'Failed to create vendor'; letzshopVendorDirectoryLog.error('Failed to create vendor:', e); } finally { this.creating = false; } }, // Modal handlers showVendorDetail(vendor) { this.selectedVendor = vendor; this.showDetailModal = true; }, openCreateVendorModal(vendor) { this.createVendorData = { slug: vendor.slug, name: vendor.name, company_id: '', }; this.createError = ''; this.showCreateModal = true; }, // Utilities formatDate(dateStr) { if (!dateStr) return '-'; const date = new Date(dateStr); return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); }, }; } letzshopVendorDirectoryLog.info('Loaded');