241 lines
8.5 KiB
JavaScript
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);
|
|
});
|
|
}
|
|
}
|
|
} |