1
1
import React , { useEffect , useState } from "react" ;
2
2
import "./App.css" ;
3
+ import { fetchTasks , updateTasks } from "./api" ;
3
4
import KanbanColumn from "./components/KanbanColumn" ;
4
5
import { Column , DraggableTask , DraggedTaskInfo , Task } from "./types" ;
5
6
@@ -13,38 +14,60 @@ export default function App() {
13
14
14
15
// Fetch Tasks
15
16
useEffect ( ( ) => {
16
- // TODO: Pull state from json-server
17
- // Hint: You may want to use the fetchTasks function from api/index.tsx
17
+ ( async ( ) => {
18
+ const tasks = await fetchTasks ( ) ;
19
+ setKanbanColumns ( tasks ) ;
20
+ } ) ( ) ;
18
21
} , [ ] ) ;
19
22
20
- // Hint: You will need these states for dragging and dropping tasks
21
23
const [ draggedTaskInfo , setDraggedTaskInfo ] = useState < DraggedTaskInfo | null > ( null ) ;
22
24
const [ hoveredColumn , setHoveredColumn ] = useState < Column | null > ( null ) ;
23
25
24
26
const handleTaskDragStart = ( task : Task , column : Column ) => {
25
- // TODO: Implement functionality for when the drag starts
27
+ setDraggedTaskInfo ( { task , column } ) ;
26
28
} ;
27
29
28
30
const handleTaskDragOver = ( e : React . DragEvent , column : Column ) => {
29
31
e . preventDefault ( ) ;
30
- // TODO: Implement functionality for when an item is being dragged over a column
31
- // Hint: Remember to check if the item is being dragged over a new column
32
+ if ( column !== hoveredColumn ) {
33
+ setHoveredColumn ( column ) ;
34
+ }
32
35
} ;
33
36
34
37
const handleTaskDrop = ( column : Column ) => {
35
- // TODO: Implement functionality for when the item is dropped
36
- // Hint: Make sure to handle the cases when the item is dropped in the same column or in a new column
38
+ if ( draggedTaskInfo ) {
39
+ // If the task is dropped in a different column, remove it from the old one and add it to the new one.
40
+ if ( column !== draggedTaskInfo . column ) {
41
+ const taskIndex = kanbanColumns [ draggedTaskInfo . column ] . findIndex (
42
+ ( task ) => task . id === draggedTaskInfo . task . id
43
+ ) ;
44
+ if ( taskIndex > - 1 ) {
45
+ const newColumnTasks = [ ...kanbanColumns [ column ] , draggedTaskInfo . task ] ;
46
+ const oldColumnTasks = [ ...kanbanColumns [ draggedTaskInfo . column ] ] ;
47
+ oldColumnTasks . splice ( taskIndex , 1 ) ;
48
+ const newState = { ...kanbanColumns , [ column ] : newColumnTasks , [ draggedTaskInfo . column ] : oldColumnTasks } ;
49
+ setKanbanColumns ( newState ) ;
50
+ // Update the tasks in the db
51
+ updateTasks ( newState ) . catch ( ( error ) => console . error ( error ) ) ;
52
+ }
53
+ }
54
+ }
55
+
56
+ setDraggedTaskInfo ( null ) ; // Reset dragInfo state
57
+ setHoveredColumn ( null ) ; // Reset overColumn state
37
58
} ;
38
59
39
60
const getTasksForColumn = ( column : Column ) : DraggableTask [ ] => {
40
- // TODO: Handle the bug where card dragged over itself shows duplicate
41
- // Hint: Consider how you can use the dragInfo and overColumn states to prevent this
42
- return [ { id : "1" , name : "Task 1" , isDragging : false } ] ;
61
+ let tasks = kanbanColumns [ column ] ;
62
+ if ( draggedTaskInfo && hoveredColumn === column ) {
63
+ tasks = [ ...tasks , { ...draggedTaskInfo . task , isDragging : true } ] ;
64
+ }
65
+ return tasks ;
43
66
} ;
44
67
45
68
const handleTaskDragEnd = ( ) => {
46
- // TODO: Implement functionality for when the drag ends
47
- // Hint: Remember to handle the case when the item is released back to its current column
69
+ setDraggedTaskInfo ( null ) ; // Reset dragInfo state
70
+ setHoveredColumn ( null ) ; // Reset overColumn state
48
71
} ;
49
72
50
73
return (
0 commit comments