From f84390f77358576aded19c9f54f7222c8d33a450 Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Sun, 30 Apr 2023 16:34:44 -0500 Subject: [PATCH 01/11] able to fetch data and load them --- src/App.tsx | 41 ++++++++++++++++++++++----------- src/api/index.tsx | 4 ++++ src/components/KanbanColumn.tsx | 8 ++++--- src/index.tsx | 12 ++++------ src/types/index.ts | 12 +++++----- 5 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 9f58580..f9f9f29 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,13 +1,16 @@ -import React, { useEffect, useState } from "react"; -import "./App.css"; -import KanbanColumn from "./components/KanbanColumn"; -import { Column, DraggableTask, DraggedTaskInfo, Task } from "./types"; +import React, { useEffect, useState } from 'react'; +import './App.css'; +import KanbanColumn from './components/KanbanColumn'; +import { Column, DraggableTask, DraggedTaskInfo, Task } from './types'; +import { fetchKanbanTasks } from './api/index'; export default function App() { - const [kanbanColumns, setKanbanColumns] = useState>({ + const [kanbanColumns, setKanbanColumns] = useState< + Record + >({ Backlog: [], - "In Progress": [], - "In Review": [], + 'In Progress': [], + 'In Review': [], Done: [], }); @@ -15,10 +18,14 @@ export default function App() { useEffect(() => { // TODO: Pull state from json-server // Hint: You may want to use the fetchTasks function from api/index.tsx + fetchKanbanTasks().then((tasks) => { + setKanbanColumns(tasks); + }); }, []); // Hint: You will need these states for dragging and dropping tasks - const [draggedTaskInfo, setDraggedTaskInfo] = useState(null); + const [draggedTaskInfo, setDraggedTaskInfo] = + useState(null); const [hoveredColumn, setHoveredColumn] = useState(null); const handleTaskDragStart = (task: Task, column: Column) => { @@ -39,7 +46,11 @@ export default function App() { 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 tasksForColumns = kanbanColumns[column].map((element) => { + element.isDragging = false; + return element; + }); + return tasksForColumns; }; const handleTaskDragEnd = () => { @@ -49,11 +60,13 @@ export default function App() { return (
-

Codebase Mentor Kanban Board

+

+ Codebase Mentor Kanban Board +

{ // TODO: Implement functionality to fetch tasks from the server + + const tasks = await(await fetch(`${apiUrl}/tasks`)).json(); + return tasks + }; export const updateKanbanTasks = async (tasks: any) => { diff --git a/src/components/KanbanColumn.tsx b/src/components/KanbanColumn.tsx index 6fd89ba..4adadd9 100644 --- a/src/components/KanbanColumn.tsx +++ b/src/components/KanbanColumn.tsx @@ -1,5 +1,5 @@ -import React from "react"; -import { Column, DraggableTask, Task } from "../types"; +import React from 'react'; +import { Column, DraggableTask, Task } from '../types'; interface KanbanColumnProps { title: Column; @@ -29,7 +29,9 @@ export default function KanbanColumn({ {tasks.map((task) => (
  • onTaskDragStart(task, title)} onDragEnd={onTaskDragEnd} diff --git a/src/index.tsx b/src/index.tsx index 3fd3a69..f84c765 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,7 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import App from "./App"; +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; -ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - - +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + ); diff --git a/src/types/index.ts b/src/types/index.ts index 88451e3..4a299fb 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,13 +1,13 @@ +export interface Task { + id: string; + name: string; +} +export type Column = "Backlog" | "In Progress" | "In Review" | "Done"; + export interface DraggedTaskInfo { task: Task; column: Column; } -export type Column = "Backlog" | "In Progress" | "In Review" | "Done"; - -export interface Task { - id: string; - name: string; -} export type DraggableTask = Task & { isDragging?: boolean | undefined }; From 3a4267fbb3c22e3a0bc57f252868a20f84cd873a Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Sun, 30 Apr 2023 21:17:22 -0500 Subject: [PATCH 02/11] drag and drop works --- db.json | 31 +++++++++++++---- src/App.tsx | 62 ++++++++++++++++++++++++++++----- src/api/index.tsx | 2 ++ src/components/KanbanColumn.tsx | 10 +++--- src/types/index.ts | 3 +- 5 files changed, 88 insertions(+), 20 deletions(-) diff --git a/db.json b/db.json index aababa0..4b946eb 100644 --- a/db.json +++ b/db.json @@ -1,11 +1,30 @@ { "tasks": { "Backlog": [ - { "id": "task1", "name": "Write specs" }, - { "id": "task2", "name": "Design mockups" } + { + "id": "task1", + "name": "Write specs ded" + }, + { + "id": "task2", + "name": "Design mockups" + }, + { + "id": "task3", + "name": "Develop features" + }, + { + "id": "task4", + "name": "Test application" + } ], - "In Progress": [{ "id": "task3", "name": "Develop features" }], - "In Review": [{ "id": "task4", "name": "Test application" }], - "Done": [{ "id": "task5", "name": "Deploy application" }] + "In Progress": [], + "In Review": [], + "Done": [ + { + "id": "task5", + "name": "Deploy application" + } + ] } -} +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index f9f9f29..bd59802 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,36 +21,82 @@ export default function App() { fetchKanbanTasks().then((tasks) => { setKanbanColumns(tasks); }); - }, []); + }, [kanbanColumns]); // 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) => { + const handleTaskDragStart = ( + task: DraggableTask, + column: Column, + e: React.DragEvent + ) => { // TODO: Implement functionality for when the drag starts + let neededInfo = { task, column }; + + e.dataTransfer.setData('sourceColumn', neededInfo.column); + setDraggedTaskInfo({ task, column }); }; const handleTaskDragOver = (e: React.DragEvent, column: Column) => { e.preventDefault(); + // console.log(e) + // 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 + // console.log('item is being dragged over a column', e); }; - const handleTaskDrop = (column: Column) => { + const handleTaskDrop = (e: React.DragEvent, column: Column) => { + e.preventDefault(); // 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 + let sourceCln = e.dataTransfer.getData('sourceColumn'); + + if (column === 'Backlog') { + if (draggedTaskInfo?.column === 'Backlog') return; + let newColumns = kanbanColumns; + if (draggedTaskInfo) { + newColumns[sourceCln].splice( + newColumns[sourceCln].findIndex(function (element) { + return element.id === draggedTaskInfo.task.id; + }), + 1 + ); + newColumns[column].push(draggedTaskInfo.task); + console.log(); + + const requestOptions = { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(kanbanColumns), + }; + fetch('http://localhost:3001/tasks', requestOptions); + } + } else if (column === 'In Progress') { + if (draggedTaskInfo?.column === 'In Progress') return; + console.log(draggedTaskInfo); + } else if (column === 'In Review') { + if (draggedTaskInfo?.column === 'In Review') return; + console.log(draggedTaskInfo); + } else if (column === 'Done') { + if (draggedTaskInfo?.column === 'Done') return; + console.log(draggedTaskInfo); + } }; 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 - let tasksForColumns = kanbanColumns[column].map((element) => { - element.isDragging = false; - return element; - }); - return tasksForColumns; + // let tasksForColumns = kanbanColumns[column].map((element) => { + // element.isDragging = false; + // return element; + // }); + + return kanbanColumns[column]; }; const handleTaskDragEnd = () => { diff --git a/src/api/index.tsx b/src/api/index.tsx index 64fbb3e..04ddebc 100644 --- a/src/api/index.tsx +++ b/src/api/index.tsx @@ -11,4 +11,6 @@ export const fetchKanbanTasks = async () => { 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 + + }; diff --git a/src/components/KanbanColumn.tsx b/src/components/KanbanColumn.tsx index 4adadd9..4e2ce0e 100644 --- a/src/components/KanbanColumn.tsx +++ b/src/components/KanbanColumn.tsx @@ -6,8 +6,9 @@ interface KanbanColumnProps { tasks: DraggableTask[]; onTaskDragStart: (task: Task, column: Column) => void; onTaskDragOver: (e: React.DragEvent, column: Column) => void; - onTaskDrop: (column: Column) => void; + onTaskDrop: (e: React.DragEvent, column: Column) => void; onTaskDragEnd: () => void; + e:React.DragEvent } export default function KanbanColumn({ @@ -17,23 +18,24 @@ export default function KanbanColumn({ onTaskDragOver, onTaskDrop, onTaskDragEnd, +e }: KanbanColumnProps) { return (
    onTaskDragOver(e, title)} - onDrop={() => onTaskDrop(title)} + onDrop={(e) => onTaskDrop(e, title)} >

    {title}

      - {tasks.map((task) => ( + {tasks.map((task, index) => (
    • onTaskDragStart(task, title)} + onDragStart={(e) => onTaskDragStart(task, title,e)} onDragEnd={onTaskDragEnd} > {task.name} diff --git a/src/types/index.ts b/src/types/index.ts index 4a299fb..3b5017c 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -2,12 +2,11 @@ export interface Task { id: string; name: string; } -export type Column = "Backlog" | "In Progress" | "In Review" | "Done"; +export type Column = 'Backlog' | 'In Progress' | 'In Review' | 'Done'; export interface DraggedTaskInfo { task: Task; column: Column; } - export type DraggableTask = Task & { isDragging?: boolean | undefined }; From c384a075d3810727207316970ebba6decbbc3701 Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Sun, 30 Apr 2023 21:26:47 -0500 Subject: [PATCH 03/11] Saving progress. Basic drag and drop works --- db.json | 24 ++++++++++++------------ src/App.tsx | 48 ++++++++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/db.json b/db.json index 4b946eb..82aed82 100644 --- a/db.json +++ b/db.json @@ -1,29 +1,29 @@ { "tasks": { - "Backlog": [ + "Backlog": [], + "In Progress": [ { - "id": "task1", - "name": "Write specs ded" + "id": "task5", + "name": "Deploy application" }, { - "id": "task2", - "name": "Design mockups" + "id": "task4", + "name": "Test application" }, { "id": "task3", "name": "Develop features" - }, - { - "id": "task4", - "name": "Test application" } ], - "In Progress": [], "In Review": [], "Done": [ { - "id": "task5", - "name": "Deploy application" + "id": "task2", + "name": "Design mockups" + }, + { + "id": "task1", + "name": "Write specs ded" } ] } diff --git a/src/App.tsx b/src/App.tsx index bd59802..7ee8f9d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -29,6 +29,28 @@ export default function App() { const [hoveredColumn, setHoveredColumn] = useState(null); + const updateColumns = (e: React.DragEvent, column: Column) => { + let newColumns = kanbanColumns; + if (draggedTaskInfo) { + let sourceCln = e.dataTransfer.getData('sourceColumn'); + newColumns[sourceCln].splice( + newColumns[sourceCln].findIndex(function (element: Task) { + return element.id === draggedTaskInfo.task.id; + }), + 1 + ); + newColumns[column].push(draggedTaskInfo.task); + console.log(); + + const requestOptions = { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(kanbanColumns), + }; + fetch('http://localhost:3001/tasks', requestOptions); + } + }; + const handleTaskDragStart = ( task: DraggableTask, column: Column, @@ -54,37 +76,19 @@ export default function App() { e.preventDefault(); // 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 - let sourceCln = e.dataTransfer.getData('sourceColumn'); if (column === 'Backlog') { if (draggedTaskInfo?.column === 'Backlog') return; - let newColumns = kanbanColumns; - if (draggedTaskInfo) { - newColumns[sourceCln].splice( - newColumns[sourceCln].findIndex(function (element) { - return element.id === draggedTaskInfo.task.id; - }), - 1 - ); - newColumns[column].push(draggedTaskInfo.task); - console.log(); - - const requestOptions = { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(kanbanColumns), - }; - fetch('http://localhost:3001/tasks', requestOptions); - } + updateColumns(e, column); } else if (column === 'In Progress') { if (draggedTaskInfo?.column === 'In Progress') return; - console.log(draggedTaskInfo); + updateColumns(e, column); } else if (column === 'In Review') { if (draggedTaskInfo?.column === 'In Review') return; - console.log(draggedTaskInfo); + updateColumns(e, column); } else if (column === 'Done') { if (draggedTaskInfo?.column === 'Done') return; - console.log(draggedTaskInfo); + updateColumns(e, column); } }; From a3b25ad09898048134bc192096ad9bcf9d52fc9c Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Mon, 1 May 2023 12:55:22 -0500 Subject: [PATCH 04/11] kanban works with local storage --- db.json | 26 ++++++++-------- src/App.tsx | 54 +++++++++++++++++++++++---------- src/components/KanbanColumn.tsx | 12 +++++--- 3 files changed, 58 insertions(+), 34 deletions(-) diff --git a/db.json b/db.json index 82aed82..97b0088 100644 --- a/db.json +++ b/db.json @@ -1,30 +1,30 @@ { "tasks": { - "Backlog": [], - "In Progress": [ - { - "id": "task5", - "name": "Deploy application" - }, + "Backlog": [ { "id": "task4", "name": "Test application" }, { - "id": "task3", - "name": "Develop features" + "id": "task1", + "name": "Write specs ded" } ], - "In Review": [], - "Done": [ + "In Progress": [ + { + "id": "task5", + "name": "Deploy application" + }, { "id": "task2", "name": "Design mockups" }, { - "id": "task1", - "name": "Write specs ded" + "id": "task3", + "name": "Develop features" } - ] + ], + "In Review": [], + "Done": [] } } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 7ee8f9d..8d66886 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,49 +5,61 @@ import { Column, DraggableTask, DraggedTaskInfo, Task } from './types'; import { fetchKanbanTasks } from './api/index'; export default function App() { + const [kanbanColumns, setKanbanColumns] = useState< - Record +Record >({ Backlog: [], 'In Progress': [], 'In Review': [], Done: [], }); - + + // Fetch Tasks useEffect(() => { // TODO: Pull state from json-server // Hint: You may want to use the fetchTasks function from api/index.tsx fetchKanbanTasks().then((tasks) => { setKanbanColumns(tasks); + console.log("rerended") + localStorage.setItem('initialdata', JSON.stringify(tasks)); }); - }, [kanbanColumns]); + }, []); + + let tempo_item = JSON.parse(localStorage.getItem('initialdata')||""); // Hint: You will need these states for dragging and dropping tasks const [draggedTaskInfo, setDraggedTaskInfo] = useState(null); + const [hoveredColumn, setHoveredColumn] = useState(null); + const updateColumns = (e: React.DragEvent, column: Column) => { - let newColumns = kanbanColumns; + + + if (draggedTaskInfo) { + let sourceCln = e.dataTransfer.getData('sourceColumn'); - newColumns[sourceCln].splice( - newColumns[sourceCln].findIndex(function (element: Task) { + tempo_item[sourceCln].splice( + tempo_item[sourceCln].findIndex(function (element: Task) { return element.id === draggedTaskInfo.task.id; }), 1 ); - newColumns[column].push(draggedTaskInfo.task); - console.log(); - + tempo_item[column].push(draggedTaskInfo.task); + localStorage.setItem('initialdata', JSON.stringify(tempo_item)); + setKanbanColumns(tempo_item) const requestOptions = { method: 'PUT', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(kanbanColumns), + body: JSON.stringify(tempo_item), }; fetch('http://localhost:3001/tasks', requestOptions); + } }; @@ -56,16 +68,17 @@ export default function App() { column: Column, e: React.DragEvent ) => { + + // TODO: Implement functionality for when the drag starts let neededInfo = { task, column }; - e.dataTransfer.setData('sourceColumn', neededInfo.column); setDraggedTaskInfo({ task, column }); }; const handleTaskDragOver = (e: React.DragEvent, column: Column) => { e.preventDefault(); - // console.log(e) + console.log(e.target) // 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 @@ -74,6 +87,7 @@ export default function App() { const handleTaskDrop = (e: React.DragEvent, column: Column) => { e.preventDefault(); + // 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 @@ -90,15 +104,15 @@ export default function App() { if (draggedTaskInfo?.column === 'Done') return; updateColumns(e, column); } + + }; 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 - // let tasksForColumns = kanbanColumns[column].map((element) => { - // element.isDragging = false; - // return element; - // }); + + return kanbanColumns[column]; }; @@ -106,6 +120,14 @@ export default function App() { 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 + // const requestOptions = { + // method: 'PUT', + // headers: { 'Content-Type': 'application/json' }, + // body: JSON.stringify(kanbanColumns), + // }; + // fetch('http://localhost:3001/tasks', requestOptions); + + }; return ( diff --git a/src/components/KanbanColumn.tsx b/src/components/KanbanColumn.tsx index 4e2ce0e..5691cc6 100644 --- a/src/components/KanbanColumn.tsx +++ b/src/components/KanbanColumn.tsx @@ -1,14 +1,14 @@ -import React from 'react'; +import React,{useEffect} from 'react'; import { Column, DraggableTask, Task } from '../types'; interface KanbanColumnProps { title: Column; tasks: DraggableTask[]; - onTaskDragStart: (task: Task, column: Column) => void; + onTaskDragStart: (task: Task, column: Column, e:React.DragEvent) => void; onTaskDragOver: (e: React.DragEvent, column: Column) => void; onTaskDrop: (e: React.DragEvent, column: Column) => void; onTaskDragEnd: () => void; - e:React.DragEvent + } export default function KanbanColumn({ @@ -17,14 +17,16 @@ export default function KanbanColumn({ onTaskDragStart, onTaskDragOver, onTaskDrop, - onTaskDragEnd, -e + onTaskDragEnd }: KanbanColumnProps) { + + return (
      onTaskDragOver(e, title)} onDrop={(e) => onTaskDrop(e, title)} + >

      {title}

        From f1f6c662b61b393bbcce6916a12d4dc6a8ad311e Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Mon, 1 May 2023 18:43:37 -0500 Subject: [PATCH 05/11] kanban works and task drop preview too --- db.json | 32 ++++++------ src/App.tsx | 87 +++++++++++++++++---------------- src/components/KanbanColumn.tsx | 41 +++++++++++----- 3 files changed, 92 insertions(+), 68 deletions(-) diff --git a/db.json b/db.json index 97b0088..97e902e 100644 --- a/db.json +++ b/db.json @@ -2,29 +2,31 @@ "tasks": { "Backlog": [ { - "id": "task4", - "name": "Test application" + "id": "task2", + "name": "Design mockups" }, { - "id": "task1", - "name": "Write specs ded" + "id": "task3", + "name": "Develop features" } ], "In Progress": [ { - "id": "task5", - "name": "Deploy application" - }, - { - "id": "task2", - "name": "Design mockups" - }, + "id": "task1", + "name": "Write specs" + } + ], + "In Review": [ { - "id": "task3", - "name": "Develop features" + "id": "task4", + "name": "Test application" } ], - "In Review": [], - "Done": [] + "Done": [ + { + "id": "task5", + "name": "Deploy application" + } + ] } } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 8d66886..213f5f6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,44 +5,37 @@ import { Column, DraggableTask, DraggedTaskInfo, Task } from './types'; import { fetchKanbanTasks } from './api/index'; export default function App() { - const [kanbanColumns, setKanbanColumns] = useState< -Record + Record >({ Backlog: [], 'In Progress': [], 'In Review': [], Done: [], }); - - + // Fetch Tasks useEffect(() => { // TODO: Pull state from json-server // Hint: You may want to use the fetchTasks function from api/index.tsx fetchKanbanTasks().then((tasks) => { setKanbanColumns(tasks); - console.log("rerended") + console.log('rerended'); localStorage.setItem('initialdata', JSON.stringify(tasks)); }); }, []); + const [createplaceholder, setCreatePlaceholder] = useState(false); - let tempo_item = JSON.parse(localStorage.getItem('initialdata')||""); + let tempo_item = JSON.parse(localStorage.getItem('initialdata') || ''); // Hint: You will need these states for dragging and dropping tasks const [draggedTaskInfo, setDraggedTaskInfo] = useState(null); - const [hoveredColumn, setHoveredColumn] = useState(null); - const updateColumns = (e: React.DragEvent, column: Column) => { - - - if (draggedTaskInfo) { - let sourceCln = e.dataTransfer.getData('sourceColumn'); tempo_item[sourceCln].splice( tempo_item[sourceCln].findIndex(function (element: Task) { @@ -51,15 +44,15 @@ Record 1 ); tempo_item[column].push(draggedTaskInfo.task); - localStorage.setItem('initialdata', JSON.stringify(tempo_item)); - setKanbanColumns(tempo_item) - const requestOptions = { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(tempo_item), - }; - fetch('http://localhost:3001/tasks', requestOptions); + localStorage.setItem('initialdata', JSON.stringify(tempo_item)); + setKanbanColumns(tempo_item); + // const requestOptions = { + // method: 'PUT', + // headers: { 'Content-Type': 'application/json' }, + // body: JSON.stringify(tempo_item), + // }; + // fetch('http://localhost:3001/tasks', requestOptions); } }; @@ -68,21 +61,30 @@ Record column: Column, e: React.DragEvent ) => { - - // TODO: Implement functionality for when the drag starts let neededInfo = { task, column }; + e.dataTransfer.setData('sourceColumn', neededInfo.column); + setDraggedTaskInfo({ task, column }); }; const handleTaskDragOver = (e: React.DragEvent, column: Column) => { e.preventDefault(); - console.log(e.target) - // 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 // console.log('item is being dragged over a column', e); + // setHoveredColumn(column) + + if (draggedTaskInfo?.column !== column) { + setCreatePlaceholder(true); + setHoveredColumn(column) + console.log(createplaceholder); + } else { + setCreatePlaceholder(false); + console.log(createplaceholder); + setHoveredColumn(column) + } }; const handleTaskDrop = (e: React.DragEvent, column: Column) => { @@ -104,32 +106,19 @@ Record if (draggedTaskInfo?.column === 'Done') return; updateColumns(e, column); } - - }; 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 kanbanColumns[column]; }; 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 - // const requestOptions = { - // method: 'PUT', - // headers: { 'Content-Type': 'application/json' }, - // body: JSON.stringify(kanbanColumns), - // }; - // fetch('http://localhost:3001/tasks', requestOptions); - - }; - return (

        @@ -142,7 +131,11 @@ Record onTaskDragStart={handleTaskDragStart} onTaskDragOver={handleTaskDragOver} onTaskDrop={handleTaskDrop} - onTaskDragEnd={handleTaskDragEnd} + createplaceholder={createplaceholder} + draggedTaskInfo={draggedTaskInfo} + hoveredColumn={hoveredColumn} + + // onTaskDragEnd={handleTaskDragEnd} /> onTaskDragStart={handleTaskDragStart} onTaskDragOver={handleTaskDragOver} onTaskDrop={handleTaskDrop} - onTaskDragEnd={handleTaskDragEnd} + createplaceholder={createplaceholder} + draggedTaskInfo={draggedTaskInfo} + hoveredColumn={hoveredColumn} + + // onTaskDragEnd={handleTaskDragEnd} /> onTaskDragStart={handleTaskDragStart} onTaskDragOver={handleTaskDragOver} onTaskDrop={handleTaskDrop} - onTaskDragEnd={handleTaskDragEnd} + createplaceholder={createplaceholder} + draggedTaskInfo={draggedTaskInfo} + hoveredColumn={hoveredColumn} + + // onTaskDragEnd={handleTaskDragEnd} /> onTaskDragStart={handleTaskDragStart} onTaskDragOver={handleTaskDragOver} onTaskDrop={handleTaskDrop} - onTaskDragEnd={handleTaskDragEnd} + createplaceholder={createplaceholder} + draggedTaskInfo={draggedTaskInfo} + hoveredColumn={hoveredColumn} + + // onTaskDragEnd={handleTaskDragEnd} />

  • diff --git a/src/components/KanbanColumn.tsx b/src/components/KanbanColumn.tsx index 5691cc6..a203f58 100644 --- a/src/components/KanbanColumn.tsx +++ b/src/components/KanbanColumn.tsx @@ -1,14 +1,17 @@ -import React,{useEffect} from 'react'; -import { Column, DraggableTask, Task } from '../types'; +import React, { useEffect } from 'react'; +import { Column, DraggableTask, DraggedTaskInfo, Task } from '../types'; interface KanbanColumnProps { title: Column; tasks: DraggableTask[]; - onTaskDragStart: (task: Task, column: Column, e:React.DragEvent) => void; + onTaskDragStart: (task: Task, column: Column, e: React.DragEvent) => void; onTaskDragOver: (e: React.DragEvent, column: Column) => void; onTaskDrop: (e: React.DragEvent, column: Column) => void; - onTaskDragEnd: () => void; + createplaceholder: boolean; + draggedTaskInfo: DraggedTaskInfo | null; + hoveredColumn: Column | null; + // onTaskDragEnd: () => void; } export default function KanbanColumn({ @@ -17,32 +20,46 @@ export default function KanbanColumn({ onTaskDragStart, onTaskDragOver, onTaskDrop, - onTaskDragEnd -}: KanbanColumnProps) { - - + createplaceholder, + draggedTaskInfo, + hoveredColumn, +}: // onTaskDragEnd, + +KanbanColumnProps) { + useEffect(() => { + console.log(createplaceholder); + }, [createplaceholder]); + return (
    onTaskDragOver(e, title)} onDrop={(e) => onTaskDrop(e, title)} - >

    {title}

      - {tasks.map((task, index) => ( + {tasks.map((task) => (
    • onTaskDragStart(task, title,e)} - onDragEnd={onTaskDragEnd} + onDragStart={(e) => onTaskDragStart(task, title, e)} + // onDragEnd={onTaskDragEnd} > {task.name}
    • ))} + {createplaceholder && draggedTaskInfo && hoveredColumn === title ? ( +
    • + {draggedTaskInfo.task.name} +
    • + ) : ( +
    • + )}
    ); From 0a4839ff27f12b7f5ff79dedbbce3d3c84425775 Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Mon, 1 May 2023 18:47:24 -0500 Subject: [PATCH 06/11] Challenge completed. Committing before I start clean up --- db.json | 8 ++++---- src/App.tsx | 17 +++++++++-------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/db.json b/db.json index 97e902e..1615749 100644 --- a/db.json +++ b/db.json @@ -6,14 +6,14 @@ "name": "Design mockups" }, { - "id": "task3", - "name": "Develop features" + "id": "task1", + "name": "Write specs" } ], "In Progress": [ { - "id": "task1", - "name": "Write specs" + "id": "task3", + "name": "Develop features" } ], "In Review": [ diff --git a/src/App.tsx b/src/App.tsx index 213f5f6..a0f6a13 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -47,12 +47,13 @@ export default function App() { localStorage.setItem('initialdata', JSON.stringify(tempo_item)); setKanbanColumns(tempo_item); - // const requestOptions = { - // method: 'PUT', - // headers: { 'Content-Type': 'application/json' }, - // body: JSON.stringify(tempo_item), - // }; - // fetch('http://localhost:3001/tasks', requestOptions); + setCreatePlaceholder(false); + const requestOptions = { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(tempo_item), + }; + fetch('http://localhost:3001/tasks', requestOptions); } }; @@ -78,12 +79,12 @@ export default function App() { if (draggedTaskInfo?.column !== column) { setCreatePlaceholder(true); - setHoveredColumn(column) + setHoveredColumn(column); console.log(createplaceholder); } else { setCreatePlaceholder(false); console.log(createplaceholder); - setHoveredColumn(column) + setHoveredColumn(column); } }; From e0689e0c34b2cb1aac89ad864c84aef1fc8c7cbf Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Mon, 1 May 2023 19:17:01 -0500 Subject: [PATCH 07/11] final commit before PR --- .eslintrc.json | 25 ++ db.json | 8 +- package-lock.json | 678 ++++++++++++++++++++++++++++++++ package.json | 4 + src/App.tsx | 37 +- src/api/index.tsx | 12 +- src/components/KanbanColumn.tsx | 11 +- 7 files changed, 721 insertions(+), 54 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..cf60bc5 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "env": { + "browser": true, + "es2021": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended" + ], + "overrides": [ + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "react", + "@typescript-eslint" + ], + "rules": { + } +} diff --git a/db.json b/db.json index 1615749..2ee4263 100644 --- a/db.json +++ b/db.json @@ -1,13 +1,13 @@ { "tasks": { "Backlog": [ - { - "id": "task2", - "name": "Design mockups" - }, { "id": "task1", "name": "Write specs" + }, + { + "id": "task2", + "name": "Design mockups" } ], "In Progress": [ diff --git a/package-lock.json b/package-lock.json index f881ce6..7ac0f65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,12 @@ "devDependencies": { "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.2", "@vitejs/plugin-react": "^2.0.0", "autoprefixer": "^10.4.14", + "eslint": "^8.39.0", + "eslint-plugin-react": "^7.32.2", "postcss": "^8.4.23", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -664,6 +668,12 @@ "node": ">= 8" } }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -701,6 +711,321 @@ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", + "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/type-utils": "5.59.2", + "@typescript-eslint/utils": "5.59.2", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", + "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", + "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", + "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/utils": "5.59.2", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", + "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", + "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", + "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", + "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.59.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@vitejs/plugin-react": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-2.2.0.tgz", @@ -853,6 +1178,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", @@ -1459,6 +1793,18 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -3007,6 +3353,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -3982,6 +4348,12 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -4265,6 +4637,15 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -4930,6 +5311,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -5294,6 +5684,27 @@ "json5": "lib/cli.js" } }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6108,6 +6519,12 @@ "fastq": "^1.6.0" } }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -6145,6 +6562,205 @@ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", "dev": true }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", + "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/type-utils": "5.59.2", + "@typescript-eslint/utils": "5.59.2", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/parser": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", + "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", + "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", + "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/utils": "5.59.2", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", + "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", + "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/utils": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", + "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", + "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.2", + "eslint-visitor-keys": "^3.3.0" + } + }, "@vitejs/plugin-react": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-2.2.0.tgz", @@ -6258,6 +6874,12 @@ "is-string": "^1.0.7" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array.prototype.flat": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", @@ -6682,6 +7304,15 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -7719,6 +8350,20 @@ "define-properties": "^1.1.3" } }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -8424,6 +9069,12 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -8620,6 +9271,12 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -9068,6 +9725,12 @@ "object-inspect": "^1.9.0" } }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -9322,6 +9985,21 @@ } } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 83724d8..c08305c 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,12 @@ "devDependencies": { "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.2", "@vitejs/plugin-react": "^2.0.0", "autoprefixer": "^10.4.14", + "eslint": "^8.39.0", + "eslint-plugin-react": "^7.32.2", "postcss": "^8.4.23", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/App.tsx b/src/App.tsx index a0f6a13..15e594c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import './App.css'; import KanbanColumn from './components/KanbanColumn'; import { Column, DraggableTask, DraggedTaskInfo, Task } from './types'; -import { fetchKanbanTasks } from './api/index'; +import { fetchKanbanTasks, updateKanbanTasks } from './api/index'; export default function App() { const [kanbanColumns, setKanbanColumns] = useState< @@ -14,13 +14,9 @@ export default function App() { Done: [], }); - // Fetch Tasks useEffect(() => { - // TODO: Pull state from json-server - // Hint: You may want to use the fetchTasks function from api/index.tsx fetchKanbanTasks().then((tasks) => { setKanbanColumns(tasks); - console.log('rerended'); localStorage.setItem('initialdata', JSON.stringify(tasks)); }); }, []); @@ -28,7 +24,6 @@ export default function App() { let tempo_item = JSON.parse(localStorage.getItem('initialdata') || ''); - // Hint: You will need these states for dragging and dropping tasks const [draggedTaskInfo, setDraggedTaskInfo] = useState(null); @@ -53,7 +48,7 @@ export default function App() { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(tempo_item), }; - fetch('http://localhost:3001/tasks', requestOptions); + updateKanbanTasks(requestOptions); } }; @@ -62,28 +57,20 @@ export default function App() { column: Column, e: React.DragEvent ) => { - // TODO: Implement functionality for when the drag starts let neededInfo = { task, column }; - e.dataTransfer.setData('sourceColumn', neededInfo.column); - 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 - // console.log('item is being dragged over a column', e); - // setHoveredColumn(column) if (draggedTaskInfo?.column !== column) { setCreatePlaceholder(true); setHoveredColumn(column); - console.log(createplaceholder); } else { setCreatePlaceholder(false); - console.log(createplaceholder); + setHoveredColumn(column); } }; @@ -91,9 +78,6 @@ export default function App() { const handleTaskDrop = (e: React.DragEvent, column: Column) => { e.preventDefault(); - // 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 (column === 'Backlog') { if (draggedTaskInfo?.column === 'Backlog') return; updateColumns(e, column); @@ -110,16 +94,9 @@ export default function App() { }; 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 kanbanColumns[column]; }; - 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 - }; return (

    @@ -135,8 +112,6 @@ export default function App() { createplaceholder={createplaceholder} draggedTaskInfo={draggedTaskInfo} hoveredColumn={hoveredColumn} - - // onTaskDragEnd={handleTaskDragEnd} />

    diff --git a/src/api/index.tsx b/src/api/index.tsx index 04ddebc..3ff0d76 100644 --- a/src/api/index.tsx +++ b/src/api/index.tsx @@ -1,16 +1,14 @@ -const apiUrl = "http://localhost:3001"; +const apiUrl = 'http://localhost:3001'; export const fetchKanbanTasks = async () => { // TODO: Implement functionality to fetch tasks from the server - - const tasks = await(await fetch(`${apiUrl}/tasks`)).json(); - return tasks - + + const tasks = await (await fetch(`${apiUrl}/tasks`)).json(); + return tasks; }; 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 - - + fetch(`${apiUrl}/tasks`, tasks); }; diff --git a/src/components/KanbanColumn.tsx b/src/components/KanbanColumn.tsx index a203f58..0547e1f 100644 --- a/src/components/KanbanColumn.tsx +++ b/src/components/KanbanColumn.tsx @@ -10,8 +10,6 @@ interface KanbanColumnProps { createplaceholder: boolean; draggedTaskInfo: DraggedTaskInfo | null; hoveredColumn: Column | null; - - // onTaskDragEnd: () => void; } export default function KanbanColumn({ @@ -23,12 +21,8 @@ export default function KanbanColumn({ createplaceholder, draggedTaskInfo, hoveredColumn, -}: // onTaskDragEnd, - -KanbanColumnProps) { - useEffect(() => { - console.log(createplaceholder); - }, [createplaceholder]); +}: KanbanColumnProps) { + useEffect(() => {}, [createplaceholder]); return (
    onTaskDragStart(task, title, e)} - // onDragEnd={onTaskDragEnd} > {task.name} From 3ddd5f79295324dc6377c9ce5a9df217be61e690 Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Mon, 1 May 2023 19:49:09 -0500 Subject: [PATCH 08/11] making some changes to pass the automated tests --- db.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db.json b/db.json index 2ee4263..60df14d 100644 --- a/db.json +++ b/db.json @@ -13,7 +13,7 @@ "In Progress": [ { "id": "task3", - "name": "Develop features" + "name": "Build Application" } ], "In Review": [ @@ -29,4 +29,4 @@ } ] } -} \ No newline at end of file +} From fe07b87656f755376df443e21394415b50fed5f1 Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Mon, 1 May 2023 19:57:19 -0500 Subject: [PATCH 09/11] Changing db data to initial value --- db.json | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/db.json b/db.json index 60df14d..aababa0 100644 --- a/db.json +++ b/db.json @@ -1,32 +1,11 @@ { "tasks": { "Backlog": [ - { - "id": "task1", - "name": "Write specs" - }, - { - "id": "task2", - "name": "Design mockups" - } + { "id": "task1", "name": "Write specs" }, + { "id": "task2", "name": "Design mockups" } ], - "In Progress": [ - { - "id": "task3", - "name": "Build Application" - } - ], - "In Review": [ - { - "id": "task4", - "name": "Test application" - } - ], - "Done": [ - { - "id": "task5", - "name": "Deploy application" - } - ] + "In Progress": [{ "id": "task3", "name": "Develop features" }], + "In Review": [{ "id": "task4", "name": "Test application" }], + "Done": [{ "id": "task5", "name": "Deploy application" }] } } From d20ccc143e17ee430e9eda7981cb924f43ac3131 Mon Sep 17 00:00:00 2001 From: dev_only <121720839+brudevtek@users.noreply.github.com> Date: Tue, 2 May 2023 09:33:23 -0500 Subject: [PATCH 10/11] Made changes to display empty columns if api fetch returns bad or no data and local storage is empty --- db.json | 33 +++++++++++++++++++++++++++------ src/App.tsx | 11 ++++++++++- src/components/KanbanColumn.tsx | 2 +- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/db.json b/db.json index aababa0..2ee4263 100644 --- a/db.json +++ b/db.json @@ -1,11 +1,32 @@ { "tasks": { "Backlog": [ - { "id": "task1", "name": "Write specs" }, - { "id": "task2", "name": "Design mockups" } + { + "id": "task1", + "name": "Write specs" + }, + { + "id": "task2", + "name": "Design mockups" + } ], - "In Progress": [{ "id": "task3", "name": "Develop features" }], - "In Review": [{ "id": "task4", "name": "Test application" }], - "Done": [{ "id": "task5", "name": "Deploy application" }] + "In Progress": [ + { + "id": "task3", + "name": "Develop features" + } + ], + "In Review": [ + { + "id": "task4", + "name": "Test application" + } + ], + "Done": [ + { + "id": "task5", + "name": "Deploy application" + } + ] } -} +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 15e594c..028fc35 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,7 +22,16 @@ export default function App() { }, []); const [createplaceholder, setCreatePlaceholder] = useState(false); - let tempo_item = JSON.parse(localStorage.getItem('initialdata') || ''); + let empty_local_data = { + Backlog: [], + 'In Progress': [], + 'In Review': [], + Done: [], + }; + + let tempo_item = + JSON.parse(localStorage.getItem('initialdata') || 'false') || + empty_local_data; const [draggedTaskInfo, setDraggedTaskInfo] = useState(null); diff --git a/src/components/KanbanColumn.tsx b/src/components/KanbanColumn.tsx index 0547e1f..acc6667 100644 --- a/src/components/KanbanColumn.tsx +++ b/src/components/KanbanColumn.tsx @@ -32,7 +32,7 @@ export default function KanbanColumn({ >

    {title}

      - {tasks.map((task) => ( + {tasks && tasks.map((task) => (
    • Date: Tue, 2 May 2023 14:30:38 -0500 Subject: [PATCH 11/11] Made changes to address the empty li element --- src/App.tsx | 1 + src/components/KanbanColumn.tsx | 29 ++++++++++++++--------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 028fc35..ea794f2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,6 +18,7 @@ export default function App() { fetchKanbanTasks().then((tasks) => { setKanbanColumns(tasks); localStorage.setItem('initialdata', JSON.stringify(tasks)); + }); }, []); const [createplaceholder, setCreatePlaceholder] = useState(false); diff --git a/src/components/KanbanColumn.tsx b/src/components/KanbanColumn.tsx index acc6667..e461651 100644 --- a/src/components/KanbanColumn.tsx +++ b/src/components/KanbanColumn.tsx @@ -32,26 +32,25 @@ export default function KanbanColumn({ >

      {title}

        - {tasks && tasks.map((task) => ( -
      • onTaskDragStart(task, title, e)} - > - {task.name} -
      • - ))} - {createplaceholder && draggedTaskInfo && hoveredColumn === title ? ( + {tasks && + tasks.map((task) => ( +
      • onTaskDragStart(task, title, e)} + > + {task.name} +
      • + ))} + {createplaceholder && draggedTaskInfo && hoveredColumn === title && (
      • {draggedTaskInfo.task.name}
      • - ) : ( -
      • )}