const STATES = [ { key: "completed", label: "Completed" }, { key: "manager_review", label: "Manager Review" }, { key: "in_progress", label: "In Progress" }, { key: "not_started", label: "Not Started" }, { key: "comments", label: "Comments" } ]; let draggedItemId = null; function countByState(items) { return items.reduce((acc, item) => { acc[item.state] = (acc[item.state] || 0) + 1; return acc; }, {}); } function createCard(item) { const card = document.createElement("div"); card.className = "kanban-card"; card.draggable = true; card.dataset.id = item.id; card.textContent = item.title; card.addEventListener("dragstart", () => { draggedItemId = item.id; card.classList.add("dragging"); }); card.addEventListener("dragend", () => { draggedItemId = null; card.classList.remove("dragging"); }); return card; } function createColumn(state, items, counts) { const col = document.createElement("div"); col.className = "kanban-column"; col.dataset.state = state.key; const header = document.createElement("h3"); header.innerHTML = ` ${state.label} ${counts[state.key] || 0} `; const list = document.createElement("div"); list.className = "kanban-list"; list.addEventListener("dragover", e => e.preventDefault()); list.addEventListener("drop", async () => { if (!draggedItemId) return; const res = await fetch(`/api/competencies/items/${draggedItemId}/state`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ state: state.key }) }); if (res.ok) { loadBoard(); // simple & safe re-render } else { alert("Failed to update state"); } }); items .filter(i => i.state === state.key) .forEach(i => list.appendChild(createCard(i))); col.appendChild(header); col.appendChild(list); return col; } function renderBoard(items) { const board = document.getElementById("kanban-board"); board.innerHTML = ""; const counts = countByState(items); STATES.forEach(state => { board.appendChild(createColumn(state, items, counts)); }); } async function loadBoard() { const res = await fetch("/api/competencies/items"); const items = await res.json(); renderBoard(items); } loadBoard();