/** * drag-drop.js - Drag and drop service reordering */ const STORAGE_KEY_ORDER = 'services-order'; // Load saved order from localStorage function loadSavedOrder() { try { const saved = localStorage.getItem(STORAGE_KEY_ORDER); return saved ? JSON.parse(saved) : {}; } catch (e) { console.error('Error loading saved order:', e); return {}; } } // Save order to localStorage function saveSavedOrder(orderMap) { try { localStorage.setItem(STORAGE_KEY_ORDER, JSON.stringify(orderMap)); } catch (e) { console.error('Error saving order:', e); } } // Apply saved order to service groups function applySavedOrder() { const orderMap = loadSavedOrder(); document.querySelectorAll('.service-group').forEach(group => { const groupName = group.querySelector('h2')?.textContent; if (!groupName || !orderMap[groupName]) return; const container = group.querySelector('.services-grid'); if (!container) return; const cards = Array.from(container.querySelectorAll('.service-card')); const orderedIds = orderMap[groupName]; // Sort cards based on saved order cards.sort((a, b) => { const aId = a.dataset.serviceId; const bId = b.dataset.serviceId; const aIndex = orderedIds.indexOf(aId); const bIndex = orderedIds.indexOf(bId); if (aIndex === -1 && bIndex === -1) return 0; if (aIndex === -1) return 1; if (bIndex === -1) return -1; return aIndex - bIndex; }); // Re-append in sorted order cards.forEach(card => container.appendChild(card)); }); } // Initialize drag and drop function initDragDrop() { let draggedElement = null; let draggedGroup = null; document.addEventListener('dragstart', (e) => { if (e.target.classList.contains('service-card')) { draggedElement = e.target; draggedGroup = e.target.closest('.service-group'); e.target.style.opacity = '0.5'; e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/html', e.target.innerHTML); } }); document.addEventListener('dragend', (e) => { if (e.target.classList.contains('service-card')) { e.target.style.opacity = '1'; // Remove all drop indicators document.querySelectorAll('.service-card').forEach(card => { card.classList.remove('drag-over'); }); // Save the new order saveCurrentOrder(); } }); document.addEventListener('dragover', (e) => { if (e.preventDefault) { e.preventDefault(); } const target = e.target.closest('.service-card'); if (target && target !== draggedElement && draggedElement) { const targetGroup = target.closest('.service-group'); // Only allow reordering within the same group if (targetGroup === draggedGroup) { e.dataTransfer.dropEffect = 'move'; // Remove previous indicators document.querySelectorAll('.service-card').forEach(card => { card.classList.remove('drag-over'); }); // Add indicator target.classList.add('drag-over'); } } return false; }); document.addEventListener('drop', (e) => { if (e.stopPropagation) { e.stopPropagation(); } const target = e.target.closest('.service-card'); if (target && target !== draggedElement && draggedElement) { const targetGroup = target.closest('.service-group'); // Only allow dropping within the same group if (targetGroup === draggedGroup) { const container = target.parentNode; const targetIndex = Array.from(container.children).indexOf(target); const draggedIndex = Array.from(container.children).indexOf(draggedElement); if (draggedIndex < targetIndex) { container.insertBefore(draggedElement, target.nextSibling); } else { container.insertBefore(draggedElement, target); } } } target?.classList.remove('drag-over'); return false; }); // Make service cards draggable document.querySelectorAll('.service-card').forEach(card => { card.setAttribute('draggable', 'true'); }); } // Save current order of all groups function saveCurrentOrder() { const orderMap = {}; document.querySelectorAll('.service-group').forEach(group => { const groupName = group.querySelector('h2')?.textContent; if (!groupName) return; const cards = group.querySelectorAll('.service-card'); const order = Array.from(cards).map(card => card.dataset.serviceId); orderMap[groupName] = order; }); saveSavedOrder(orderMap); } // Export for use in other modules window.dragDropModule = { init: initDragDrop, applySavedOrder: applySavedOrder };