312 lines
12 KiB
JavaScript
312 lines
12 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function() {
|
|
// Feature management for add form
|
|
const addFeatureBtn = document.getElementById('addFeatureBtn');
|
|
const featuresContainer = document.getElementById('featuresContainer');
|
|
|
|
if (addFeatureBtn) {
|
|
addFeatureBtn.addEventListener('click', function() {
|
|
addFeatureField(featuresContainer);
|
|
});
|
|
}
|
|
|
|
// Feature management for edit form
|
|
const editAddFeatureBtn = document.getElementById('editAddFeatureBtn');
|
|
const editFeaturesContainer = document.getElementById('editFeaturesContainer');
|
|
|
|
if (editAddFeatureBtn) {
|
|
editAddFeatureBtn.addEventListener('click', function() {
|
|
addFeatureField(editFeaturesContainer);
|
|
});
|
|
}
|
|
|
|
// Remove feature buttons
|
|
document.addEventListener('click', function(e) {
|
|
if (e.target.classList.contains('remove-feature-btn')) {
|
|
e.target.closest('.input-group').remove();
|
|
}
|
|
});
|
|
|
|
// Add Pricing Plan Form
|
|
const addPricingPlanForm = document.getElementById('addPricingPlanForm');
|
|
if (addPricingPlanForm) {
|
|
addPricingPlanForm.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
submitPricingPlanForm(this, 'POST', '/api/admin/pricing-plans');
|
|
});
|
|
}
|
|
|
|
// Edit Pricing Plan Form
|
|
const editPricingPlanForm = document.getElementById('editPricingPlanForm');
|
|
if (editPricingPlanForm) {
|
|
editPricingPlanForm.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
const planId = document.getElementById('editPlanId').value;
|
|
submitPricingPlanForm(this, 'PUT', `/api/admin/pricing-plans/${planId}`);
|
|
});
|
|
}
|
|
|
|
// Edit Plan Buttons
|
|
document.addEventListener('click', function(e) {
|
|
if (e.target.classList.contains('edit-plan-btn')) {
|
|
const planId = e.target.getAttribute('data-plan-id');
|
|
loadPlanForEdit(planId);
|
|
}
|
|
});
|
|
|
|
// Delete Plan Buttons
|
|
document.addEventListener('click', function(e) {
|
|
if (e.target.classList.contains('delete-plan-btn')) {
|
|
const planId = e.target.getAttribute('data-plan-id');
|
|
const planName = e.target.closest('.card').querySelector('.card-header h5').textContent;
|
|
showDeleteConfirmation(planId, planName);
|
|
}
|
|
});
|
|
|
|
// Confirm Delete Button
|
|
const confirmDeleteBtn = document.getElementById('confirmDeletePlan');
|
|
if (confirmDeleteBtn) {
|
|
confirmDeleteBtn.addEventListener('click', function() {
|
|
const planId = this.getAttribute('data-plan-id');
|
|
deletePricingPlan(planId);
|
|
});
|
|
}
|
|
|
|
// Toggle switches
|
|
document.addEventListener('change', function(e) {
|
|
if (e.target.classList.contains('plan-status-toggle')) {
|
|
const planId = e.target.getAttribute('data-plan-id');
|
|
const isActive = e.target.checked;
|
|
updatePlanStatus(planId, 'is_active', isActive);
|
|
}
|
|
|
|
if (e.target.classList.contains('plan-popular-toggle')) {
|
|
const planId = e.target.getAttribute('data-plan-id');
|
|
const isPopular = e.target.checked;
|
|
updatePlanStatus(planId, 'is_popular', isPopular);
|
|
}
|
|
|
|
if (e.target.classList.contains('plan-custom-toggle')) {
|
|
const planId = e.target.getAttribute('data-plan-id');
|
|
const isCustom = e.target.checked;
|
|
updatePlanStatus(planId, 'is_custom', isCustom);
|
|
}
|
|
});
|
|
});
|
|
|
|
function addFeatureField(container) {
|
|
const featureGroup = document.createElement('div');
|
|
featureGroup.className = 'input-group mb-2';
|
|
featureGroup.innerHTML = `
|
|
<input type="text" class="form-control feature-input" name="features[]" required>
|
|
<button type="button" class="btn btn-outline-danger remove-feature-btn">
|
|
<i class="fas fa-times"></i>
|
|
</button>
|
|
`;
|
|
container.appendChild(featureGroup);
|
|
}
|
|
|
|
function submitPricingPlanForm(form, method, url) {
|
|
const formData = new FormData(form);
|
|
|
|
// Convert features array
|
|
const features = [];
|
|
form.querySelectorAll('input[name="features[]"]').forEach(input => {
|
|
if (input.value.trim()) {
|
|
features.push(input.value.trim());
|
|
}
|
|
});
|
|
|
|
// Remove features from formData and add as JSON
|
|
formData.delete('features[]');
|
|
formData.append('features', JSON.stringify(features));
|
|
|
|
// Convert checkboxes to boolean values
|
|
const checkboxes = ['is_popular', 'is_custom', 'is_active'];
|
|
checkboxes.forEach(field => {
|
|
formData.set(field, formData.get(field) === 'on');
|
|
});
|
|
|
|
fetch(url, {
|
|
method: method,
|
|
body: formData,
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showNotification('Pricing plan saved successfully!', 'success');
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1000);
|
|
} else {
|
|
showNotification(data.error || 'Error saving pricing plan', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
showNotification('Error saving pricing plan', 'error');
|
|
});
|
|
}
|
|
|
|
function loadPlanForEdit(planId) {
|
|
fetch(`/api/admin/pricing-plans/${planId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
const plan = data.plan;
|
|
|
|
// Populate form fields
|
|
document.getElementById('editPlanId').value = plan.id;
|
|
document.getElementById('editPlanName').value = plan.name;
|
|
document.getElementById('editPlanDescription').value = plan.description || '';
|
|
document.getElementById('editMonthlyPrice').value = plan.monthly_price;
|
|
document.getElementById('editAnnualPrice').value = plan.annual_price;
|
|
document.getElementById('editButtonText').value = plan.button_text;
|
|
document.getElementById('stripeProductId').value = plan.stripe_product_id || '';
|
|
document.getElementById('stripeMonthlyPriceId').value = plan.stripe_monthly_price_id || '';
|
|
document.getElementById('stripeAnnualPriceId').value = plan.stripe_annual_price_id || '';
|
|
document.getElementById('editIsPopular').checked = plan.is_popular;
|
|
document.getElementById('editIsCustom').checked = plan.is_custom;
|
|
document.getElementById('editIsActive').checked = plan.is_active;
|
|
|
|
// Populate quota fields
|
|
document.getElementById('editRoomQuota').value = plan.room_quota || 0;
|
|
document.getElementById('editConversationQuota').value = plan.conversation_quota || 0;
|
|
document.getElementById('editStorageQuota').value = plan.storage_quota_gb || 0;
|
|
document.getElementById('editManagerQuota').value = plan.manager_quota || 0;
|
|
document.getElementById('editAdminQuota').value = plan.admin_quota || 0;
|
|
|
|
// Populate features
|
|
const editFeaturesContainer = document.getElementById('editFeaturesContainer');
|
|
editFeaturesContainer.innerHTML = '';
|
|
|
|
plan.features.forEach(feature => {
|
|
const featureGroup = document.createElement('div');
|
|
featureGroup.className = 'input-group mb-2';
|
|
featureGroup.innerHTML = `
|
|
<input type="text" class="form-control feature-input" name="features[]" value="${feature}" required>
|
|
<button type="button" class="btn btn-outline-danger remove-feature-btn">
|
|
<i class="fas fa-times"></i>
|
|
</button>
|
|
`;
|
|
editFeaturesContainer.appendChild(featureGroup);
|
|
});
|
|
|
|
// Add one empty feature field if no features
|
|
if (plan.features.length === 0) {
|
|
addFeatureField(editFeaturesContainer);
|
|
}
|
|
} else {
|
|
showNotification(data.error || 'Error loading plan', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
showNotification('Error loading plan', 'error');
|
|
});
|
|
}
|
|
|
|
function showDeleteConfirmation(planId, planName) {
|
|
document.getElementById('deletePlanName').textContent = planName;
|
|
document.getElementById('confirmDeletePlan').setAttribute('data-plan-id', planId);
|
|
|
|
const deleteModal = new bootstrap.Modal(document.getElementById('deletePricingPlanModal'));
|
|
deleteModal.show();
|
|
}
|
|
|
|
function deletePricingPlan(planId) {
|
|
fetch(`/api/admin/pricing-plans/${planId}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest',
|
|
'X-CSRFToken': document.querySelector('input[name="csrf_token"]').value
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showNotification('Pricing plan deleted successfully!', 'success');
|
|
|
|
// Close modal
|
|
const deleteModal = bootstrap.Modal.getInstance(document.getElementById('deletePricingPlanModal'));
|
|
deleteModal.hide();
|
|
|
|
// Remove from DOM
|
|
const planElement = document.querySelector(`[data-plan-id="${planId}"]`);
|
|
if (planElement) {
|
|
planElement.remove();
|
|
}
|
|
|
|
// Check if no plans left
|
|
const remainingPlans = document.querySelectorAll('[data-plan-id]');
|
|
if (remainingPlans.length === 0) {
|
|
window.location.reload();
|
|
}
|
|
} else {
|
|
showNotification(data.error || 'Error deleting plan', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
showNotification('Error deleting plan', 'error');
|
|
});
|
|
}
|
|
|
|
function updatePlanStatus(planId, field, value) {
|
|
fetch(`/api/admin/pricing-plans/${planId}/status`, {
|
|
method: 'PATCH',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest',
|
|
'X-CSRFToken': document.querySelector('input[name="csrf_token"]').value
|
|
},
|
|
body: JSON.stringify({
|
|
field: field,
|
|
value: value
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showNotification('Plan status updated successfully!', 'success');
|
|
} else {
|
|
showNotification(data.error || 'Error updating plan status', 'error');
|
|
// Revert the toggle
|
|
const toggle = document.querySelector(`[data-plan-id="${planId}"].${field.replace('is_', 'plan-')}-toggle`);
|
|
if (toggle) {
|
|
toggle.checked = !value;
|
|
}
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
showNotification('Error updating plan status', 'error');
|
|
// Revert the toggle
|
|
const toggle = document.querySelector(`[data-plan-id="${planId}"].${field.replace('is_', 'plan-')}-toggle`);
|
|
if (toggle) {
|
|
toggle.checked = !value;
|
|
}
|
|
});
|
|
}
|
|
|
|
function showNotification(message, type) {
|
|
// Create notification element
|
|
const notification = document.createElement('div');
|
|
notification.className = `alert alert-${type === 'success' ? 'success' : 'danger'} alert-dismissible fade show position-fixed`;
|
|
notification.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
|
|
notification.innerHTML = `
|
|
${message}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
// Auto-remove after 5 seconds
|
|
setTimeout(() => {
|
|
if (notification.parentNode) {
|
|
notification.remove();
|
|
}
|
|
}, 5000);
|
|
}
|