import { useMemo, useState, useEffect } from "react"; import ColumnContainerCard from "./columnContainerWrapper"; import { DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from "@dnd-kit/core"; import { SortableContext, arrayMove } from "@dnd-kit/sortable"; import { createPortal } from "react-dom"; import TaskCard from "./taskCard"; import { AiOutlinePlusCircle } from "react-icons/ai"; import axiosInstance from "src/api/AxiosConfig"; function KanbanBoard() { const [columns, setColumns] = useState([]); const columnsId = useMemo(() => columns.map((col) => col.id), [columns]); const [boardId, setBoardData] = useState(); const [tasks, setTasks] = useState([]); const [activeColumn, setActiveColumn] = useState(null); const [activeTask, setActiveTask] = useState(null); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 10, }, }) ); // Example // { // "id": 95, // "title": "Test Todo", // "notes": "Test TodoTest TodoTest Todo", // "importance": 1, // "difficulty": 1, // "challenge": false, // "fromSystem": false, // "creation_date": "2023-11-20T19:50:16.369308Z", // "last_update": "2023-11-20T19:50:16.369308Z", // "is_active": true, // "is_full_day_event": false, // "start_event": "2023-11-20T19:49:49Z", // "end_event": "2023-11-23T18:00:00Z", // "google_calendar_id": null, // "completed": true, // "completion_date": "2023-11-20T19:50:16.369308Z", // "priority": 3, // "user": 1, // "list_board": 1, // "tags": [] // } // ] // [ // { // "id": 8, // "name": "test", // "position": 2, // "board": 3 // } // ] useEffect(() => { const fetchData = async () => { try { const tasksResponse = await axiosInstance.get("/todo"); // Transform const transformedTasks = tasksResponse.data.map((task) => ({ id: task.id, columnId: task.list_board, content: task.title, difficulty: task.difficulty, notes: task.notes, importance: task.importance, difficulty: task.difficulty, challenge: task.challenge, fromSystem: task.fromSystem, creation_date: task.creation_date, last_update: task.last_update, is_active: task.is_active, is_full_day_event: task.is_full_day_event, start_event: task.start_event, end_event: task.end_event, google_calendar_id: task.google_calendar_id, completed: task.completed, completion_date: task.completion_date, priority: task.priority, user: task.user, list_board: task.list_board, tags: task.tags, })); setTasks(transformedTasks); const columnsResponse = await axiosInstance.get("/lists"); // Transform const transformedColumns = columnsResponse.data.map((column) => ({ id: column.id, title: column.name, })); setColumns(transformedColumns); } catch (error) { console.error("Error fetching data from API:", error); } }; fetchData(); }, []); useEffect(() => { const fetchBoardData = async () => { try { const response = await axiosInstance.get("boards/"); if (response.data && response.data.length > 0) { setBoardData(response.data[0]); } } catch (error) { console.error("Error fetching board data:", error); } }; fetchBoardData(); }, []); return (
{columns.map((col) => ( task.columnId === col.id)} /> ))}
{/* create new column */}
{createPortal( {activeColumn && ( task.columnId === activeColumn.id)} /> )} {activeTask && } , document.body )}
); function createTask(columnId, setTasks) { const newTaskData = { title: `Task ${tasks.length + 1}`, importance: 1, difficulty: 1, challenge: false, fromSystem: false, is_active: false, is_full_day_event: false, completed: false, priority: 1, list_board: columnId, }; axiosInstance .post("todo/", newTaskData) .then((response) => { const newTask = { id: response.data.id, columnId, content: response.data.title, }; }) .catch((error) => { console.error("Error creating task:", error); }); setTasks((tasks) => [...tasks, newTask]); } function deleteTask(id) { const newTasks = tasks.filter((task) => task.id !== id); axiosInstance .delete(`todo/${id}/`) .then((response) => { setTasks(newTasks); }) .catch((error) => { console.error("Error deleting Task:", error); }); setTasks(newTasks); } function updateTask(id, content) { const newTasks = tasks.map((task) => { if (task.id !== id) return task; return { ...task, content }; }); if (content === "") return deleteTask(id); setTasks(newTasks); } function createNewColumn() { axiosInstance .post("lists/", { name: `Column ${columns.length + 1}`, position: 1, board: boardId.id }) .then((response) => { const newColumn = { id: response.data.id, title: response.data.name, }; setColumns((prevColumns) => [...prevColumns, newColumn]); }) .catch((error) => { console.error("Error creating ListBoard:", error); }); } function deleteColumn(id) { axiosInstance .delete(`lists/${id}/`) .then((response) => { setColumns((prevColumns) => prevColumns.filter((col) => col.id !== id)); }) .catch((error) => { console.error("Error deleting ListBoard:", error); }); const tasksToDelete = tasks.filter((t) => t.columnId === id); tasksToDelete.forEach((task) => { axiosInstance .delete(`todo/${task.id}/`) .then((response) => { setTasks((prevTasks) => prevTasks.filter((t) => t.id !== task.id)); }) .catch((error) => { console.error("Error deleting Task:", error); }); }); } function updateColumn(id, title) { // Update the column axiosInstance .patch(`lists/${id}/`, { name: title }) // Adjust the payload based on your API requirements .then((response) => { setColumns((prevColumns) => prevColumns.map((col) => (col.id === id ? { ...col, title } : col))); }) .catch((error) => { console.error("Error updating ListBoard:", error); }); } function onDragStart(event) { if (event.active.data.current?.type === "Column") { setActiveColumn(event.active.data.current.column); return; } if (event.active.data.current?.type === "Task") { setActiveTask(event.active.data.current.task); return; } } function onDragEnd(event) { setActiveColumn(null); setActiveTask(null); const { active, over } = event; if (!over) return; const activeId = active.id; const overId = over.id; const isActiveAColumn = active.data.current?.type === "Column"; const isActiveATask = active.data.current?.type === "Task"; const isOverAColumn = over.data.current?.type === "Column"; const isOverATask = over.data.current?.type === "Task"; // Reorder columns if the dragged item is a column if (isActiveAColumn && isOverAColumn) { setColumns((columns) => { const activeColumnIndex = columns.findIndex((col) => col.id === activeId); const overColumnIndex = columns.findIndex((col) => col.id === overId); const reorderedColumns = arrayMove(columns, activeColumnIndex, overColumnIndex); return reorderedColumns; }); } // Reorder tasks within the same column if (isActiveATask && isOverATask) { setTasks((tasks) => { const activeIndex = tasks.findIndex((t) => t.id === activeId); const overIndex = tasks.findIndex((t) => t.id === overId); const reorderedTasks = arrayMove(tasks, activeIndex, overIndex); return reorderedTasks; }); } // Move tasks between columns and update columnId if (isActiveATask && isOverAColumn) { setTasks((tasks) => { const activeIndex = tasks.findIndex((t) => t.id === activeId); tasks[activeIndex].columnId = overId; axiosInstance .put(`todo/change_task_list_board/`, { todo_id: activeId, new_list_board_id: overId, new_index: 0 }) .then((response) => {}) .catch((error) => { console.error("Error updating task columnId:", error); }); return arrayMove(tasks, activeIndex, activeIndex); }); } } function onDragOver(event) { const { active, over } = event; if (!over) return; const activeId = active.id; const overId = over.id; if (activeId === overId) return; const isActiveATask = active.data.current?.type === "Task"; const isOverATask = over.data.current?.type === "Task"; if (!isActiveATask) return; if (isActiveATask && isOverATask) { setTasks((tasks) => { const activeIndex = tasks.findIndex((t) => t.id === activeId); const overIndex = tasks.findIndex((t) => t.id === overId); if (tasks[activeIndex].columnId !== tasks[overIndex].columnId) { tasks[activeIndex].columnId = tasks[overIndex].columnId; return arrayMove(tasks, activeIndex, overIndex - 1); } return arrayMove(tasks, activeIndex, overIndex); }); } const isOverAColumn = over.data.current?.type === "Column"; if (isActiveATask && isOverAColumn) { setTasks((tasks) => { const activeIndex = tasks.findIndex((t) => t.id === activeId); tasks[activeIndex].columnId = overId; return arrayMove(tasks, activeIndex, activeIndex); }); } } function generateId() { return Math.floor(Math.random() * 10001); } } export default KanbanBoard;