// Vendor Login Component function vendorLogin() { return { vendor: null, credentials: { username: '', password: '' }, loading: false, checked: false, error: null, success: null, errors: {}, init() { // Check if already logged in if (this.checkExistingAuth()) { return; } // Detect vendor from URL this.detectVendor(); }, checkExistingAuth() { const token = localStorage.getItem('vendor_token'); const vendorContext = localStorage.getItem('vendor_context'); if (token && vendorContext) { try { const vendor = JSON.parse(vendorContext); window.location.href = `/vendor/${vendor.vendor_code}/dashboard`; return true; } catch (e) { localStorage.removeItem('vendor_token'); localStorage.removeItem('vendor_context'); } } return false; }, async detectVendor() { this.loading = true; try { const vendorCode = this.getVendorCodeFromUrl(); if (!vendorCode) { this.error = 'Vendor code not found in URL. Please use the correct vendor login link.'; this.checked = true; this.loading = false; return; } console.log('Detected vendor code:', vendorCode); // Fetch vendor information const response = await fetch(`/api/v1/public/vendors/by-code/${vendorCode}`); if (!response.ok) { throw new Error('Vendor not found'); } this.vendor = await response.json(); this.checked = true; console.log('Loaded vendor:', this.vendor); } catch (error) { console.error('Error detecting vendor:', error); this.error = 'Unable to load vendor information. The vendor may not exist or is inactive.'; this.checked = true; } finally { this.loading = false; } }, getVendorCodeFromUrl() { // Try multiple methods to get vendor code // Method 1: From URL path /vendor/VENDORCODE/login or /vendor/VENDORCODE/ const pathParts = window.location.pathname.split('/').filter(p => p); const vendorIndex = pathParts.indexOf('vendor'); if (vendorIndex !== -1 && pathParts[vendorIndex + 1]) { const code = pathParts[vendorIndex + 1]; // Don't return if it's a generic route like 'login', 'dashboard', etc. if (!['login', 'dashboard', 'admin', 'products', 'orders'].includes(code.toLowerCase())) { return code.toUpperCase(); } } // Method 2: From query parameter ?vendor=VENDORCODE const urlParams = new URLSearchParams(window.location.search); const queryVendor = urlParams.get('vendor'); if (queryVendor) { return queryVendor.toUpperCase(); } // Method 3: From subdomain (for production) const hostname = window.location.hostname; const parts = hostname.split('.'); if (parts.length > 2 && parts[0] !== 'www') { // Assume subdomain is vendor code return parts[0].toUpperCase(); } return null; }, clearErrors() { this.error = null; this.errors = {}; }, validateForm() { this.clearErrors(); let isValid = true; if (!this.credentials.username.trim()) { this.errors.username = 'Username is required'; isValid = false; } if (!this.credentials.password) { this.errors.password = 'Password is required'; isValid = false; } return isValid; }, async handleLogin() { if (!this.validateForm()) { return; } this.loading = true; this.clearErrors(); try { const response = await apiClient.post('/vendor/auth/login', { username: this.credentials.username.trim(), password: this.credentials.password, vendor_code: this.vendor.vendor_code }); // Store authentication data localStorage.setItem('vendor_token', response.access_token); localStorage.setItem('vendor_user', JSON.stringify(response.user)); localStorage.setItem('vendor_context', JSON.stringify(response.vendor)); localStorage.setItem('vendor_role', response.vendor_role); // Show success message this.success = 'Login successful! Redirecting...'; Utils.showToast('Login successful!', 'success', 2000); // Redirect after short delay setTimeout(() => { window.location.href = `/vendor/${this.vendor.vendor_code}/dashboard`; }, 1000); } catch (error) { console.error('Login error:', error); this.error = error.message || 'Login failed. Please check your credentials.'; Utils.showToast(this.error, 'error'); } finally { this.loading = false; } } } }