// static/admin/js/vendor-detail.js // ✅ Use centralized logger - ONE LINE! // Create custom logger for vendor detail const detailLog = window.LogConfig.createLogger('VENDOR-DETAIL'); function adminVendorDetail() { return { // Inherit base layout functionality from init-alpine.js ...data(), // Vendor detail page specific state currentPage: 'vendor-detail', vendor: null, subscription: null, loading: false, error: null, vendorCode: null, showSubscriptionModal: false, // Initialize async init() { detailLog.info('=== VENDOR DETAIL PAGE INITIALIZING ==='); // Prevent multiple initializations if (window._vendorDetailInitialized) { detailLog.warn('Vendor detail page already initialized, skipping...'); return; } window._vendorDetailInitialized = true; // Get vendor code from URL const path = window.location.pathname; const match = path.match(/\/admin\/vendors\/([^\/]+)$/); if (match) { this.vendorCode = match[1]; detailLog.info('Viewing vendor:', this.vendorCode); await this.loadVendor(); // Load subscription after vendor is loaded if (this.vendor?.id) { await this.loadSubscription(); } } else { detailLog.error('No vendor code in URL'); this.error = 'Invalid vendor URL'; Utils.showToast('Invalid vendor URL', 'error'); } detailLog.info('=== VENDOR DETAIL PAGE INITIALIZATION COMPLETE ==='); }, // Load vendor data async loadVendor() { detailLog.info('Loading vendor details...'); this.loading = true; this.error = null; try { const url = `/admin/vendors/${this.vendorCode}`; window.LogConfig.logApiCall('GET', url, null, 'request'); const startTime = performance.now(); const response = await apiClient.get(url); const duration = performance.now() - startTime; window.LogConfig.logApiCall('GET', url, response, 'response'); window.LogConfig.logPerformance('Load Vendor Details', duration); this.vendor = response; detailLog.info(`Vendor loaded in ${duration}ms`, { vendor_code: this.vendor.vendor_code, name: this.vendor.name, is_verified: this.vendor.is_verified, is_active: this.vendor.is_active }); detailLog.debug('Full vendor data:', this.vendor); } catch (error) { window.LogConfig.logError(error, 'Load Vendor Details'); this.error = error.message || 'Failed to load vendor details'; Utils.showToast('Failed to load vendor details', 'error'); } finally { this.loading = false; } }, // Format date (matches dashboard pattern) formatDate(dateString) { if (!dateString) { detailLog.debug('formatDate called with empty dateString'); return '-'; } const formatted = Utils.formatDate(dateString); detailLog.debug(`Date formatted: ${dateString} -> ${formatted}`); return formatted; }, // Load subscription data for this vendor async loadSubscription() { if (!this.vendor?.id) { detailLog.warn('Cannot load subscription: no vendor ID'); return; } detailLog.info('Loading subscription for vendor:', this.vendor.id); try { const url = `/admin/subscriptions/${this.vendor.id}`; window.LogConfig.logApiCall('GET', url, null, 'request'); const response = await apiClient.get(url); window.LogConfig.logApiCall('GET', url, response, 'response'); this.subscription = response; detailLog.info('Subscription loaded:', { tier: this.subscription?.tier, status: this.subscription?.status, orders_this_period: this.subscription?.orders_this_period }); } catch (error) { // 404 means no subscription exists - that's OK if (error.status === 404) { detailLog.info('No subscription found for vendor'); this.subscription = null; } else { detailLog.warn('Failed to load subscription:', error.message); } } }, // Get usage bar color based on percentage getUsageBarColor(current, limit) { if (!limit || limit === 0) return 'bg-blue-500'; const percent = (current / limit) * 100; if (percent >= 90) return 'bg-red-500'; if (percent >= 75) return 'bg-yellow-500'; return 'bg-green-500'; }, // Create a new subscription for this vendor async createSubscription() { if (!this.vendor?.id) { Utils.showToast('No vendor loaded', 'error'); return; } detailLog.info('Creating subscription for vendor:', this.vendor.id); try { // Create a trial subscription with default tier const url = `/admin/subscriptions/${this.vendor.id}`; const data = { tier: 'essential', status: 'trial', trial_days: 14, is_annual: false }; window.LogConfig.logApiCall('POST', url, data, 'request'); const response = await apiClient.post(url, data); window.LogConfig.logApiCall('POST', url, response, 'response'); this.subscription = response; Utils.showToast('Subscription created successfully', 'success'); detailLog.info('Subscription created:', this.subscription); } catch (error) { window.LogConfig.logError(error, 'Create Subscription'); Utils.showToast(error.message || 'Failed to create subscription', 'error'); } }, // Delete vendor async deleteVendor() { detailLog.info('Delete vendor requested:', this.vendorCode); if (!confirm(`Are you sure you want to delete vendor "${this.vendor.name}"?\n\nThis action cannot be undone and will delete:\n- All products\n- All orders\n- All customers\n- All team members`)) { detailLog.info('Delete cancelled by user'); return; } // Second confirmation for safety if (!confirm(`FINAL CONFIRMATION\n\nType the vendor code to confirm: ${this.vendor.vendor_code}\n\nAre you absolutely sure?`)) { detailLog.info('Delete cancelled by user (second confirmation)'); return; } try { const url = `/admin/vendors/${this.vendorCode}?confirm=true`; window.LogConfig.logApiCall('DELETE', url, null, 'request'); detailLog.info('Deleting vendor:', this.vendorCode); await apiClient.delete(url); window.LogConfig.logApiCall('DELETE', url, null, 'response'); Utils.showToast('Vendor deleted successfully', 'success'); detailLog.info('Vendor deleted successfully'); // Redirect to vendors list setTimeout(() => window.location.href = '/admin/vendors', 1500); } catch (error) { window.LogConfig.logError(error, 'Delete Vendor'); Utils.showToast(error.message || 'Failed to delete vendor', 'error'); } }, // Refresh vendor data async refresh() { detailLog.info('=== VENDOR REFRESH TRIGGERED ==='); await this.loadVendor(); Utils.showToast('Vendor details refreshed', 'success'); detailLog.info('=== VENDOR REFRESH COMPLETE ==='); } }; } detailLog.info('Vendor detail module loaded');