(() => { const getCsrfToken = () => { const meta = document.querySelector('meta[name="csrf-token"]'); return meta ? meta.getAttribute("content") : ""; }; const initWeekDragAndDrop = () => { const board = document.querySelector(".week-board"); if (!board) return; let draggedEntry = null; board.querySelectorAll(".draggable-plan-entry").forEach((entry) => { entry.addEventListener("dragstart", () => { draggedEntry = entry; entry.classList.add("is-dragging"); }); entry.addEventListener("dragend", () => { entry.classList.remove("is-dragging"); draggedEntry = null; board.querySelectorAll(".drop-slot").forEach((slot) => slot.classList.remove("is-drag-over")); }); }); board.querySelectorAll(".drop-slot").forEach((slot) => { slot.addEventListener("dragover", (event) => { event.preventDefault(); if (!draggedEntry) return; slot.classList.add("is-drag-over"); }); slot.addEventListener("dragleave", () => { slot.classList.remove("is-drag-over"); }); slot.addEventListener("drop", async (event) => { event.preventDefault(); slot.classList.remove("is-drag-over"); if (!draggedEntry) return; // Keep DnD lightweight: move on the server, then refresh into the canonical rendered state. const moveUrl = draggedEntry.dataset.moveUrl; const payload = new URLSearchParams({ csrf_token: getCsrfToken(), target_date: slot.dataset.targetDate, target_daypart_id: slot.dataset.targetDaypartId, }); try { const response = await fetch(moveUrl, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", "X-Requested-With": "XMLHttpRequest", }, body: payload.toString(), }); if (!response.ok) { throw new Error("move failed"); } const result = await response.json(); if (result.redirect_url) { window.location.href = result.redirect_url; } else { window.location.reload(); } } catch (_error) { window.location.reload(); } }); }); }; document.addEventListener("DOMContentLoaded", () => { initWeekDragAndDrop(); }); })();