// Categories page JavaScript let routes = {}; // Initialize on page load document.addEventListener('DOMContentLoaded', function() { if (window.categoryRoutes) { routes = window.categoryRoutes; loadCategoryTrees(); } }); function loadCategoryTrees() { loadM1Tree(); loadM2Tree(); } function loadM1Tree() { const container = document.getElementById('m1-tree-container'); if (!container) return; container.innerHTML = '
Loading categories...
'; fetch(routes.magento1CategoryTree) .then(response => response.json()) .then(data => { if (data.success) { container.innerHTML = ''; if (data.tree && data.tree.length > 0) { renderTree(container, data.tree, 'm1'); } else { container.innerHTML = '
No categories found
'; } } else { container.innerHTML = `
Error: ${data.message || 'Failed to load categories'}
`; } }) .catch(error => { container.innerHTML = `
Error: ${error.message}
`; }); } function loadM2Tree() { const container = document.getElementById('m2-tree-container'); if (!container) return; container.innerHTML = '
Loading categories...
'; fetch(routes.magento2CategoryTree) .then(response => response.json()) .then(data => { if (data.success) { container.innerHTML = ''; if (data.tree && data.tree.length > 0) { renderTree(container, data.tree, 'm2'); } else { container.innerHTML = '
No categories found
'; } } else { container.innerHTML = `
Error: ${data.message || 'Failed to load categories'}
`; } }) .catch(error => { container.innerHTML = `
Error: ${error.message}
`; }); } function renderTree(container, nodes, source = 'm2') { nodes.forEach(node => { const nodeElement = createTreeNode(node, source); container.appendChild(nodeElement); }); } function createTreeNode(node, source = 'm2') { const nodeDiv = document.createElement('div'); nodeDiv.className = 'tree-node'; const hasChildren = node.children && node.children.length > 0; const canDelete = node.id != 0 && node.id != 1; const itemDiv = document.createElement('div'); itemDiv.className = 'tree-node-item'; const toggle = document.createElement('span'); toggle.className = hasChildren ? 'tree-toggle collapsed' : 'tree-toggle leaf'; if (hasChildren) { toggle.onclick = function(e) { e.stopPropagation(); toggleNode(this); }; } const label = document.createElement('div'); label.className = 'tree-label'; const labelText = document.createElement('span'); labelText.className = 'tree-label-text'; labelText.textContent = `[${node.id}] ${node.name || 'Unnamed Category'}`; const badge = document.createElement('span'); badge.className = `tree-badge ${node.is_active ? 'active' : 'inactive'}`; badge.textContent = node.is_active ? 'Active' : 'Inactive'; label.appendChild(labelText); label.appendChild(badge); if (canDelete) { const deleteBtn = document.createElement('button'); deleteBtn.className = 'tree-delete-btn'; deleteBtn.textContent = 'Delete'; deleteBtn.onclick = function(e) { e.stopPropagation(); showDeleteConfirmPopup(deleteBtn, node.id, node.name, source, hasChildren, node.children ? node.children.length : 0); }; label.appendChild(deleteBtn); } itemDiv.appendChild(toggle); itemDiv.appendChild(label); nodeDiv.appendChild(itemDiv); if (hasChildren) { const childrenDiv = document.createElement('div'); childrenDiv.className = 'tree-children'; node.children.forEach(child => { childrenDiv.appendChild(createTreeNode(child, source)); }); nodeDiv.appendChild(childrenDiv); } return nodeDiv; } function toggleNode(toggleElement) { const nodeItem = toggleElement.parentElement; const nodeDiv = nodeItem.parentElement; const childrenDivs = nodeDiv.querySelectorAll('.tree-children'); if (childrenDivs.length > 0) { let isExpanded = false; childrenDivs.forEach(div => { if (div.style.display !== 'none') { isExpanded = true; } }); if (isExpanded) { childrenDivs.forEach(div => { div.style.display = 'none'; }); toggleElement.classList.remove('expanded'); toggleElement.classList.add('collapsed'); } else { childrenDivs.forEach(div => { div.style.display = 'block'; }); toggleElement.classList.remove('collapsed'); toggleElement.classList.add('expanded'); } } } function showDeleteConfirmPopup(buttonElement, categoryId, categoryName, source, hasChildren, childrenCount) { const existingPopup = document.querySelector('.delete-confirm-popup'); const existingOverlay = document.querySelector('.popup-overlay'); if (existingPopup) existingPopup.remove(); if (existingOverlay) existingOverlay.remove(); const overlay = document.createElement('div'); overlay.className = 'popup-overlay'; overlay.onclick = function() { closeDeleteConfirmPopup(); }; document.body.appendChild(overlay); const popup = document.createElement('div'); popup.className = 'delete-confirm-popup'; popup.style.position = 'fixed'; popup.style.top = '50%'; popup.style.left = '50%'; popup.style.transform = 'translate(-50%, -50%)'; popup.style.zIndex = '10000'; const title = document.createElement('h3'); title.textContent = 'Delete Category'; const message = document.createElement('p'); if (hasChildren) { message.innerHTML = `Are you sure you want to delete "${categoryName}" and all ${childrenCount} subcategory(ies)? This action cannot be undone.`; } else { message.innerHTML = `Are you sure you want to delete the category "${categoryName}"? This action cannot be undone.`; } const buttonsDiv = document.createElement('div'); buttonsDiv.className = 'popup-buttons'; const cancelBtn = document.createElement('button'); cancelBtn.className = 'popup-btn popup-btn-cancel'; cancelBtn.textContent = 'Cancel'; cancelBtn.onclick = function(e) { e.stopPropagation(); closeDeleteConfirmPopup(); }; const deleteBtn = document.createElement('button'); deleteBtn.className = 'popup-btn popup-btn-delete'; deleteBtn.textContent = 'Delete'; deleteBtn.onclick = function(e) { e.stopPropagation(); closeDeleteConfirmPopup(); deleteCategory(categoryId, categoryName, source); }; buttonsDiv.appendChild(cancelBtn); buttonsDiv.appendChild(deleteBtn); popup.appendChild(title); popup.appendChild(message); popup.appendChild(buttonsDiv); document.body.appendChild(popup); } function closeDeleteConfirmPopup() { const popup = document.querySelector('.delete-confirm-popup'); const overlay = document.querySelector('.popup-overlay'); if (popup) popup.remove(); if (overlay) overlay.remove(); } function deleteCategory(categoryId, categoryName, source) { const container = source === 'm1' ? document.getElementById('m1-tree-container') : document.getElementById('m2-tree-container'); if (!container) return; const originalContent = container.innerHTML; container.innerHTML = '
Deleting category...
'; const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content; const deleteRoute = routes.deleteCategory.replace(':id', categoryId); fetch(deleteRoute, { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }, body: JSON.stringify({ source: source }) }) .then(response => response.json()) .then(data => { if (data.success) { if (source === 'm1') { loadM1Tree(); } else { loadM2Tree(); location.reload(); } } else { container.innerHTML = originalContent; alert('Error: ' + (data.message || 'Failed to delete category')); } }) .catch(error => { container.innerHTML = originalContent; alert('Error: ' + error.message); }); }