From 2a92546c51b53e5bb6a4b84f93457907b8b0c70a Mon Sep 17 00:00:00 2001 From: sbmsr Date: Thu, 27 Apr 2023 21:51:13 -0400 Subject: [PATCH] solns --- src/App.tsx | 49 ++++++++++++++++++++++++++++++++++------------- src/api/index.tsx | 20 ++++++++++++++----- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 9f58580..96be0de 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useState } from "react"; import "./App.css"; +import { fetchTasks, updateTasks } from "./api"; import KanbanColumn from "./components/KanbanColumn"; import { Column, DraggableTask, DraggedTaskInfo, Task } from "./types"; @@ -13,38 +14,60 @@ export default function App() { // Fetch Tasks useEffect(() => { - // TODO: Pull state from json-server - // Hint: You may want to use the fetchTasks function from api/index.tsx + (async () => { + const tasks = await fetchTasks(); + setKanbanColumns(tasks); + })(); }, []); - // Hint: You will need these states for dragging and dropping tasks const [draggedTaskInfo, setDraggedTaskInfo] = useState(null); const [hoveredColumn, setHoveredColumn] = useState(null); const handleTaskDragStart = (task: Task, column: Column) => { - // TODO: Implement functionality for when the drag starts + setDraggedTaskInfo({ task, column }); }; const handleTaskDragOver = (e: React.DragEvent, column: Column) => { e.preventDefault(); - // TODO: Implement functionality for when an item is being dragged over a column - // Hint: Remember to check if the item is being dragged over a new column + if (column !== hoveredColumn) { + setHoveredColumn(column); + } }; const handleTaskDrop = (column: Column) => { - // TODO: Implement functionality for when the item is dropped - // Hint: Make sure to handle the cases when the item is dropped in the same column or in a new column + if (draggedTaskInfo) { + // If the task is dropped in a different column, remove it from the old one and add it to the new one. + if (column !== draggedTaskInfo.column) { + const taskIndex = kanbanColumns[draggedTaskInfo.column].findIndex( + (task) => task.id === draggedTaskInfo.task.id + ); + if (taskIndex > -1) { + const newColumnTasks = [...kanbanColumns[column], draggedTaskInfo.task]; + const oldColumnTasks = [...kanbanColumns[draggedTaskInfo.column]]; + oldColumnTasks.splice(taskIndex, 1); + const newState = { ...kanbanColumns, [column]: newColumnTasks, [draggedTaskInfo.column]: oldColumnTasks }; + setKanbanColumns(newState); + // Update the tasks in the db + updateTasks(newState).catch((error) => console.error(error)); + } + } + } + + setDraggedTaskInfo(null); // Reset dragInfo state + setHoveredColumn(null); // Reset overColumn state }; const getTasksForColumn = (column: Column): DraggableTask[] => { - // TODO: Handle the bug where card dragged over itself shows duplicate - // Hint: Consider how you can use the dragInfo and overColumn states to prevent this - return [{ id: "1", name: "Task 1", isDragging: false }]; + let tasks = kanbanColumns[column]; + if (draggedTaskInfo && hoveredColumn === column && column !== draggedTaskInfo.column) { + tasks = [...tasks, { ...draggedTaskInfo.task, isDragging: true }]; + } + return tasks; }; const handleTaskDragEnd = () => { - // TODO: Implement functionality for when the drag ends - // Hint: Remember to handle the case when the item is released back to its current column + setDraggedTaskInfo(null); // Reset dragInfo state + setHoveredColumn(null); // Reset overColumn state }; return ( diff --git a/src/api/index.tsx b/src/api/index.tsx index 17d63ea..cce6aa7 100644 --- a/src/api/index.tsx +++ b/src/api/index.tsx @@ -1,10 +1,20 @@ const apiUrl = "http://localhost:3001"; -export const fetchKanbanTasks = async () => { - // TODO: Implement functionality to fetch tasks from the server +export const fetchTasks = async () => { + const response = await fetch(`${apiUrl}/tasks`); + const data = await response.json(); + return data; }; -export const updateKanbanTasks = async (tasks: any) => { - // TODO: Save the new order of the items when tasks are modified to the server - // Hint: You may want to use the fetch API with a "PUT" method +export const updateTasks = async (tasks: any) => { + const response = await fetch(`${apiUrl}/tasks`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(tasks), + }); + + const data = await response.json(); + return data; };