/** * Alpine.data('contentToggle') - Admin content enable/disable toggle * Alpine.data('contentDelete') - Admin content delete with confirmation */ import Alpine from '@alpinejs/csp'; function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return String(text).replace(/[&<>"']/g, m => map[m]); } Alpine.data('contentToggle', () => ({ toggleStatus(contentId, currentStatus, el) { const csrf = document.querySelector('meta[name="csrf-token"]')?.content; if (!contentId || !csrf) { showToast('Error: Missing required data', 'error'); return; } el.disabled = true; el.style.opacity = '0.6'; fetch('/admin/content-toggle-status', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrf, 'X-Requested-With': 'XMLHttpRequest' }, body: JSON.stringify({ id: contentId }) }) .then(r => r.json()) .then(data => { if (data.success) { const row = el.closest('tr'); const statusCell = row.cells[5]; const ns = data.status; if (ns === 1) { statusCell.innerHTML = 'Enabled'; el.className = 'content-toggle-status text-green-600 dark:text-green-400 hover:text-green-900 dark:hover:text-green-300'; el.innerHTML = ''; } else { statusCell.innerHTML = 'Disabled'; el.className = 'content-toggle-status text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-300'; el.innerHTML = ''; } el.setAttribute('data-current-status', ns); el.title = ns === 1 ? 'Disable' : 'Enable'; showToast(data.message, 'success'); } else { showToast(data.message || 'Failed to toggle content status', 'error'); } el.disabled = false; el.style.opacity = '1'; }) .catch(() => { showToast('An error occurred while toggling content status', 'error'); el.disabled = false; el.style.opacity = '1'; }); }, deleteContent(contentId, contentTitle, el) { const csrf = document.querySelector('meta[name="csrf-token"]')?.content; if (!contentId || !csrf) { showToast('Error: Missing required data', 'error'); return; } showConfirm({ title: 'Delete Content', message: 'Are you sure you want to delete "' + contentTitle + '"?', details: 'This action cannot be undone.', type: 'danger', confirmText: 'Delete', cancelText: 'Cancel', onConfirm: function() { el.disabled = true; el.style.opacity = '0.6'; fetch('/admin/content-delete', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrf, 'X-Requested-With': 'XMLHttpRequest' }, body: JSON.stringify({ id: contentId }) }) .then(r => r.json()) .then(data => { if (data.success) { const row = el.closest('tr'); if (row) { row.style.transition = 'opacity 0.3s'; row.style.opacity = '0'; setTimeout(() => { row.remove(); const tbody = document.querySelector('tbody'); if (tbody && tbody.children.length === 0) location.reload(); }, 300); } showToast(data.message, 'success'); } else { showToast(data.message || 'Failed to delete content', 'error'); el.disabled = false; el.style.opacity = '1'; } }) .catch(() => { showToast('An error occurred while deleting content', 'error'); el.disabled = false; el.style.opacity = '1'; }); } }); } }));