Files
orion/static/admin/js/vendors.js

241 lines
8.5 KiB
JavaScript

// Admin Vendor Creation Component
function vendorCreation() {
return {
currentUser: {},
formData: {
vendor_code: '',
name: '',
subdomain: '',
description: '',
owner_email: '',
business_phone: '',
website: '',
business_address: '',
tax_number: ''
},
loading: false,
errors: {},
showCredentials: false,
credentials: null,
init() {
if (!this.checkAuth()) {
return;
}
},
checkAuth() {
if (!Auth.isAuthenticated()) {
window.location.href = '/static/admin/login.html';
return false;
}
const user = Auth.getCurrentUser();
if (!user || user.role !== 'admin') {
Utils.showToast('Access denied. Admin privileges required.', 'error');
Auth.logout();
window.location.href = '/static/admin/login.html';
return false;
}
this.currentUser = user;
return true;
},
async handleLogout() {
const confirmed = await Utils.confirm(
'Are you sure you want to logout?',
'Confirm Logout'
);
if (confirmed) {
Auth.logout();
Utils.showToast('Logged out successfully', 'success', 2000);
setTimeout(() => {
window.location.href = '/static/admin/login.html';
}, 500);
}
},
// Auto-format vendor code (uppercase)
formatVendorCode() {
this.formData.vendor_code = this.formData.vendor_code
.toUpperCase()
.replace(/[^A-Z0-9_-]/g, '');
},
// Auto-format subdomain (lowercase)
formatSubdomain() {
this.formData.subdomain = this.formData.subdomain
.toLowerCase()
.replace(/[^a-z0-9-]/g, '');
},
clearErrors() {
this.errors = {};
},
validateForm() {
this.clearErrors();
let isValid = true;
// Required fields validation
if (!this.formData.vendor_code.trim()) {
this.errors.vendor_code = 'Vendor code is required';
isValid = false;
}
if (!this.formData.name.trim()) {
this.errors.name = 'Vendor name is required';
isValid = false;
}
if (!this.formData.subdomain.trim()) {
this.errors.subdomain = 'Subdomain is required';
isValid = false;
}
if (!this.formData.owner_email.trim()) {
this.errors.owner_email = 'Owner email is required';
isValid = false;
}
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (this.formData.owner_email && !emailRegex.test(this.formData.owner_email)) {
this.errors.owner_email = 'Invalid email format';
isValid = false;
}
// Subdomain validation (must start and end with alphanumeric)
const subdomainRegex = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
if (this.formData.subdomain && this.formData.subdomain.length > 1 &&
!subdomainRegex.test(this.formData.subdomain)) {
this.errors.subdomain = 'Subdomain must start and end with a letter or number';
isValid = false;
}
return isValid;
},
async handleSubmit() {
if (!this.validateForm()) {
Utils.showToast('Please fix validation errors', 'error');
window.scrollTo({ top: 0, behavior: 'smooth' });
return;
}
this.loading = true;
try {
// Prepare data (remove empty fields)
const submitData = {};
for (const [key, value] of Object.entries(this.formData)) {
if (value !== '' && value !== null && value !== undefined) {
submitData[key] = value;
}
}
console.log('Submitting vendor data:', submitData);
const response = await apiClient.post('/admin/vendors', submitData);
console.log('Vendor creation response:', response);
// Store credentials - be flexible with response structure
this.credentials = {
vendor_code: response.vendor_code || this.formData.vendor_code,
subdomain: response.subdomain || this.formData.subdomain,
name: response.name || this.formData.name,
owner_username: response.owner_username || `${this.formData.subdomain}_owner`,
owner_email: response.owner_email || this.formData.owner_email,
temporary_password: response.temporary_password || 'PASSWORD_NOT_RETURNED',
login_url: response.login_url ||
`http://localhost:8000/vendor/${this.formData.subdomain}/login` ||
`${this.formData.subdomain}.platform.com/vendor/login`
};
console.log('Stored credentials:', this.credentials);
// Check if password was returned
if (!response.temporary_password) {
console.warn('⚠️ Warning: temporary_password not returned from API');
console.warn('Full API response:', response);
Utils.showToast('Vendor created but password not returned. Check server logs.', 'warning', 5000);
}
// Show credentials display
this.showCredentials = true;
// Success notification
Utils.showToast('Vendor created successfully!', 'success');
// Scroll to top to see credentials
window.scrollTo({ top: 0, behavior: 'smooth' });
} catch (error) {
console.error('Error creating vendor:', error);
// Check for specific validation errors
if (error.message.includes('vendor_code') || error.message.includes('Vendor code')) {
this.errors.vendor_code = 'Vendor code already exists';
} else if (error.message.includes('subdomain')) {
this.errors.subdomain = 'Subdomain already exists';
} else if (error.message.includes('email')) {
this.errors.owner_email = 'Email already in use';
}
Utils.showToast(
error.message || 'Failed to create vendor',
'error'
);
} finally {
this.loading = false;
}
},
resetForm() {
this.formData = {
vendor_code: '',
name: '',
subdomain: '',
description: '',
owner_email: '',
business_phone: '',
website: '',
business_address: '',
tax_number: ''
};
this.clearErrors();
this.showCredentials = false;
this.credentials = null;
},
copyToClipboard(text, label) {
if (!text) {
Utils.showToast('Nothing to copy', 'error');
return;
}
navigator.clipboard.writeText(text).then(() => {
Utils.showToast(`${label} copied to clipboard`, 'success', 2000);
}).catch((err) => {
console.error('Failed to copy:', err);
// Fallback for older browsers
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
Utils.showToast(`${label} copied to clipboard`, 'success', 2000);
} catch (err) {
Utils.showToast('Failed to copy to clipboard', 'error');
}
document.body.removeChild(textArea);
});
}
}
}