function makeSortable(list, itemSelector, idAttr) { const reorderUrl = list.dataset.reorderUrl if (!reorderUrl) return let dragEl = null list.addEventListener('dragstart', (e) => { dragEl = e.target.closest(itemSelector) if (dragEl) { dragEl.classList.add('opacity-50') e.dataTransfer.effectAllowed = 'move' } }) list.addEventListener('dragend', () => { if (dragEl) { dragEl.classList.remove('opacity-50') dragEl = null } }) list.addEventListener('dragover', (e) => { e.preventDefault() const target = e.target.closest(itemSelector) if (target && target !== dragEl) { const rect = target.getBoundingClientRect() const mid = rect.top + rect.height / 2 if (e.clientY < mid) { target.before(dragEl) } else { target.after(dragEl) } } }) list.addEventListener('drop', (e) => { e.preventDefault() const items = list.querySelectorAll(itemSelector) const order = Array.from(items).map(el => Number.parseInt(el.getAttribute(idAttr), 10)) globalThis.fetch(reorderUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(order), }) }) list.querySelectorAll(itemSelector).forEach(el => { el.setAttribute('draggable', 'true') }) } export function initSortable() { const categoriesList = document.getElementById('categories-list') if (categoriesList) { makeSortable(categoriesList, '[data-id]', 'data-id') } document.querySelectorAll('.billets-list').forEach(list => { makeSortable(list, '[data-billet-id]', 'data-billet-id') }) }