From b041e85147d958b02e21d1b8e62d7336eafd6495 Mon Sep 17 00:00:00 2001 From: ianthehamster Date: Sat, 4 Nov 2023 16:46:54 +0800 Subject: [PATCH 01/16] Finishing up implementation of project --- .../Low Fidelity Wireframes Template.jpg | Bin 0 -> 65332 bytes project-walkthrough | 74 +++++++++++ public/index.html | 5 + src/App.css | 56 +++++++- src/App.js | 16 ++- src/components/Header.js | 22 ++++ src/components/Task.js | 52 ++++++++ src/components/TaskComposer.js | 63 +++++++++ src/components/TaskList.js | 123 ++++++++++++++++++ src/components/TaskListInProgress.js | 119 +++++++++++++++++ src/components/TaskListInReview.js | 105 +++++++++++++++ src/components/TaskUpdate.js | 65 +++++++++ 12 files changed, 694 insertions(+), 6 deletions(-) create mode 100644 project-planning/Low Fidelity Wireframes Template.jpg create mode 100644 project-walkthrough create mode 100644 src/components/Header.js create mode 100644 src/components/Task.js create mode 100644 src/components/TaskComposer.js create mode 100644 src/components/TaskList.js create mode 100644 src/components/TaskListInProgress.js create mode 100644 src/components/TaskListInReview.js create mode 100644 src/components/TaskUpdate.js diff --git a/project-planning/Low Fidelity Wireframes Template.jpg b/project-planning/Low Fidelity Wireframes Template.jpg new file mode 100644 index 0000000000000000000000000000000000000000..86a662b7239490441c8dd7b61722c0b3b8fa7da2 GIT binary patch literal 65332 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 { + e.preventDefault(); + + const updatedTask = { + title: this.state.title, + task: this.state.task, + }; + + this.props.updateTask(this.props.id, updatedTask); + + this.props.updateTask(this.props.id, updatedTask); + + // Close the update form by calling the callback function + this.props.onUpdateComplete(); +}; +/** Everytime the update button is clicked and the update form is submitted, we create an 'updatedTask' object with the new 'title' and 'task' values from the local state + * + */ + +// Delete Logic + +/** Defining handleDeleteClick Method in Task.js + * handleDeleteClick = () =>{ + * this.props.deleteTask(this.props.id) + * } + * Inside the handleDeleteClick function, you can call a deleteTask function that is passed as a prop from TaskList.js + */ + +/** Passing the deleteTask function as a prop in the render method + * + */ + +/** Handling deletion in deleteTask function + * deleteTask = (id) => { + this.setState((prevState)=>{ + const updatedTasks = prevState.tasks.filter((task)=>{ + task.id !== id + return { tasks: updatedTasks } + }) + }) + } + + deleteTask takes in the id argument which is the id of the task to be deleted + + this.setState() method is called to update the state in the TaskList Component and it takes the previous state (prevState) as an argument to update the current state based on its previous value + + we declare an updatedTasks variable which is assigned the result of the filter method applied to the prevState.tasks array + filter() creates a new array by iterating over the original array's elements and including only those that meet a certain condition (excludes task with specific id -> task.id !== id) + + Finally, this.setState returns an object with property tasks set to updatedTasks, which does not have the deleted task + */ diff --git a/public/index.html b/public/index.html index bd669818..470d376e 100644 --- a/public/index.html +++ b/public/index.html @@ -15,6 +15,11 @@ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ --> + + + --> diff --git a/src/App.css b/src/App.css index 6cd8ff17..0f1e7bfc 100644 --- a/src/App.css +++ b/src/App.css @@ -5,41 +5,47 @@ height: 100vh; /* height of 100vh ensures that the layout spans the full height */ } +.task-list, +.task-in-progress, +.task-in-review { + flex: 1; /* Equal distribution of space */ + box-sizing: border-box; /* Include padding and border in the width calculation */ + width: calc(33.33% - 40px); /* 33.33% width with 20px margin on each side */ + margin: 0 20px; + border: 1px solid #ccc; + padding: 16px; + border-radius: 8px; +} + .task-container { display: flex; flex: 1; /* This allows the task components to take up the available space */ } .task-list { - margin: 0 20px; + background: #de0c0c; } .task-in-progress { - margin: 0 20px; + background: yellow; } .task-in-review { - margin: 0 20px; + background: rgb(17, 219, 31); +} + +.task-composer { + margin: 20px 0px 50px; } /* Style the Header as you need it. For example: */ .header { background: #333; color: #fff; - display: flex; + display: flex; /* flex container to enable */ padding: 10px; - /* position: fixed; */ - /* justify-content: center; */ -} - -.nav-container { - display: flex; - margin-right: 50px; -} - -.nav-container-2 { - display: flex; - margin-left: 50px; + justify-content: center; + align-items: center; } .header-link { diff --git a/src/components/Header.js b/src/components/Header.js index 37aedae0..66dd33f4 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -3,21 +3,12 @@ import React from "react"; function Header() { return ( diff --git a/src/components/Task.js b/src/components/Task.js index f3edf9ee..31154b50 100644 --- a/src/components/Task.js +++ b/src/components/Task.js @@ -1,4 +1,7 @@ import React from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faTrash, faEdit } from "@fortawesome/free-solid-svg-icons"; + import TaskUpdate from "./TaskUpdate"; class Task extends React.Component { @@ -42,8 +45,17 @@ class Task extends React.Component {

Title: {this.props.title}

Task: {this.props.task}

- - + + + {this.props.additionalButton && ( + + )}
); } diff --git a/src/components/TaskComposer.js b/src/components/TaskComposer.js index e70e6c8f..32d1c3dd 100644 --- a/src/components/TaskComposer.js +++ b/src/components/TaskComposer.js @@ -1,3 +1,5 @@ +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faCheck } from "@fortawesome/free-solid-svg-icons"; import React from "react"; class TaskComposer extends React.Component { @@ -34,7 +36,7 @@ class TaskComposer extends React.Component { render() { return ( -
+

Title

@@ -54,6 +56,7 @@ class TaskComposer extends React.Component { />
+
); diff --git a/src/components/TaskList.js b/src/components/TaskList.js index e12e2661..637f4c41 100644 --- a/src/components/TaskList.js +++ b/src/components/TaskList.js @@ -19,6 +19,7 @@ export default class TaskList extends React.Component { task: "Fixing coding bugs on the software for Machine Learning AI", }, ], + tasksInProgress: [], }; } @@ -91,14 +92,58 @@ export default class TaskList extends React.Component { } } + resetLocalStorage = () => { + localStorage.clear(); + // You may also want to reinitialize the state to the default values here + this.setState({ + tasks: [ + { + id: 0, + title: "Reverse Engineer the Needler", + task: "Coding a software to reverse engineer the Needler for Miranda Keyes", + }, + { + id: 1, + title: "Fixing bugs", + task: "Fixing coding bugs on the software for Machine Learning AI", + }, + ], + }); + }; + + moveTaskToInProgress = (task) => { + // Removing task from TaskList + const updatedOpenTasks = this.state.tasks.filter((t) => t.id !== task.id); + + // Add task to "Tasks In Progress" + this.setState( + (prevState) => ({ + tasksInProgress: [...prevState.tasksInProgress, task], + tasks: updatedOpenTasks, + }), + () => { + localStorage.setItem("tasks", JSON.stringify(this.state.tasks)); + localStorage.setItem( + "tasksInProgress", + JSON.stringify(this.state.tasksInProgress) + ); + } + ); + }; + render() { console.log(this.state.tasks); const { tasks } = this.state; const numberOfTasks = tasks.length; return (
-

Open Tasks

+

+ Open Tasks +

{numberOfTasks}

+
+ +
this.moveTaskToInProgress(task)} // Pass the moveTaskToInProgress function + additionalButton={true} + additionalButtonLabel="Move to In Progress" + additionalButtonClick={() => this.moveTaskToInProgress(task)} /> ))} diff --git a/src/components/TaskListInProgress.js b/src/components/TaskListInProgress.js index 93383ac2..3401e66f 100644 --- a/src/components/TaskListInProgress.js +++ b/src/components/TaskListInProgress.js @@ -7,6 +7,7 @@ export default class TaskListInProgress extends React.Component { super(props); this.state = { + tasksInProgress: [], tasks: [ { id: 0, @@ -86,6 +87,41 @@ export default class TaskListInProgress extends React.Component { }); } } + resetLocalStorage = () => { + localStorage.clear(); + // You may also want to reinitialize the state to the default values here + this.setState({ + tasks: [ + { + id: 0, + title: "React Website - ORION Project", + task: "Coding a frontend website for Doctor Halsey", + }, + ], + }); + }; + + moveTaskToOpen = (task) => { + // Remove task from "Tasks in Progress" + const updatedInProgressTasks = this.state.tasks.filter( + (t) => t.id !== task.id + ); + + // Add task to "Open Tasks" + this.setState( + (prevState) => ({ + tasksInProgress: updatedInProgressTasks, + tasks: [...prevState.tasks, task], + }), + () => { + localStorage.setItem( + "tasksInProgress", + JSON.stringify(this.state.tasksInProgress) + ); + localStorage.setItem("tasks", JSON.stringify(this.state.tasks)); + } + ); + }; render() { console.log(this.state.tasks); @@ -93,8 +129,13 @@ export default class TaskListInProgress extends React.Component { const numberOfTasks = tasks.length; return (
-

Tasks In Progress

+

+ Tasks In Progress +

{numberOfTasks}

+
+ +
this.moveTaskToOpen(task)} /> ))} diff --git a/src/components/TaskListInReview.js b/src/components/TaskListInReview.js index 2eec31c9..d77d5898 100644 --- a/src/components/TaskListInReview.js +++ b/src/components/TaskListInReview.js @@ -79,7 +79,9 @@ export default class TaskListInReview extends React.Component { const numberOfTasks = tasks.length; return (
-

Tasks In Review

+

+ Tasks In Review +

{numberOfTasks}

Date: Sat, 11 Nov 2023 16:42:28 +0800 Subject: [PATCH 05/16] Fixing state --- src/App.js | 234 ++++++++++++++++++++++++++- src/components/TaskList.js | 155 ++---------------- src/components/TaskListInProgress.js | 147 ++--------------- src/components/TaskListInReview.js | 98 ++--------- 4 files changed, 272 insertions(+), 362 deletions(-) diff --git a/src/App.js b/src/App.js index 9c58f8a3..003ce9af 100644 --- a/src/App.js +++ b/src/App.js @@ -9,14 +9,242 @@ import TaskListInProgress from "./components/TaskListInProgress"; import TaskListInReview from "./components/TaskListInReview"; class App extends React.Component { + constructor(props) { + super(props); + + this.state = { + tasks: [ + { + id: 0, + title: "Reverse Engineer the Needler", + task: "Coding a software to reverse engineer the Needler for Miranda Keyes", + }, + { + id: 1, + title: "Fixing bugs", + task: "Fixing coding bugs on the software for Machine Learning AI", + }, + ], + tasksInProgress: [ + { + id: 0, + title: "React Website - ORION Project", + task: "Coding a frontend website for Doctor Halsey", + }, + ], + tasksInReview: [ + { + id: 0, + title: "Project Fireteam Osiris", + task: "Implementing a MongoDB Database for Spartan Locke", + }, + ], + }; + } + + // OPEN TASKS SECTION + updateTask = (id, updatedTask) => { + this.setState((prevState) => { + const updatedTasks = prevState.tasks.map((task) => { + if (task.id === id) { + return { ...task, ...updatedTask }; + } + return task; + }); + return { tasks: updatedTasks }; + }, this.updateLocalStorage); + }; + + addTaskToDo = (task) => { + const newId = this.state.tasks.length; + const newTask = { ...task, id: newId }; + this.setState( + (prevState) => ({ tasks: [...prevState.tasks, newTask] }), + this.updateLocalStorage + ); + }; + + deleteTask = (id) => { + this.setState( + (prevState) => ({ + tasks: prevState.tasks.filter((task) => task.id !== id), + }), + this.updateLocalStorage + ); + }; + + updateLocalStorage = () => { + localStorage.setItem("tasks", JSON.stringify(this.state.tasks)); + localStorage.setItem( + "tasksInProgress", + JSON.stringify(this.state.tasksInProgress) + ); + localStorage.setItem( + "tasksInReview", + JSON.stringify(this.state.tasksInReview) + ); + }; + + resetLocalStorage = () => { + localStorage.clear(); + this.setState( + { + tasks: [ + { + id: 0, + title: "Reverse Engineer the Needler", + task: "Coding a software to reverse engineer the Needler for Miranda Keyes", + }, + { + id: 1, + title: "Fixing bugs", + task: "Fixing coding bugs on the software for Machine Learning AI", + }, + ], + tasksInProgress: [], + }, + this.updateLocalStorage + ); + }; + + componentDidMount() { + const savedTasks = localStorage.getItem("tasks"); + const savedTasksInProgress = localStorage.getItem("tasksInProgress"); + const savedTasksInReview = localStorage.getItem("tasksInReview"); + + if (savedTasks) { + this.setState({ + tasks: JSON.parse(savedTasks), + tasksInProgress: JSON.parse(savedTasksInProgress) || [], + tasksInReview: JSON.parse(savedTasksInReview), + }); + } + } + + // TASKS IN PROGRESS SECTION + updateTaskInProgress = (id, updatedTask) => { + this.setState((prevState) => { + const updatedTasks = prevState.tasksInProgress.map((task) => { + if (task.id === id) { + return { ...task, ...updatedTask }; + } + return task; + }); + return { tasksInProgress: updatedTasks }; + }, this.updateLocalStorage); + }; + + addTaskToDoInProgress = (task) => { + const newId = this.state.tasksInProgress.length; + const newTask = { ...task, id: newId }; + this.setState( + (prevState) => ({ + tasksInProgress: [...prevState.tasksInProgress, newTask], + }), + this.updateLocalStorage + ); + }; + + deleteTaskInProgress = (id) => { + this.setState( + (prevState) => ({ + tasksInProgress: prevState.tasksInProgress.filter( + (task) => task.id !== id + ), + }), + this.updateLocalStorage + ); + }; + + resetLocalStorageInProgress = () => { + localStorage.clear(); + this.setState( + { + tasksInProgress: [ + { + id: 0, + title: "React Website - ORION Project", + task: "Coding a frontend website for Doctor Halsey", + }, + ], + }, + this.updateLocalStorage + ); + }; + + // TASKS IN REVIEW + updateTaskInReview = (id, updatedTask) => { + this.setState((prevState) => { + const updatedTasks = prevState.tasksInReview.map((task) => { + if (task.id === id) { + return { ...task, ...updatedTask }; + } + return task; + }); + return { tasksInReview: updatedTasks }; + }, this.updateLocalStorage); + }; + + addTaskToDoInReview = (task) => { + const newId = this.state.tasksInReview.length; + const newTask = { ...task, id: newId }; + this.setState( + (prevState) => ({ tasksInReview: [...prevState.tasksInReview, newTask] }), + this.updateLocalStorage + ); + }; + + deleteTaskInReview = (id) => { + this.setState( + (prevState) => ({ + tasks: prevState.tasksInReview.filter((task) => task.id !== id), + }), + this.updateLocalStorage + ); + }; + + resetLocalStorageInReview = () => { + localStorage.clear(); + this.setState( + { + tasksInReview: [ + { + id: 0, + title: "Project Fireteam Osiris", + task: "Implementing a MongoDB Database for Spartan Locke", + }, + ], + }, + this.updateLocalStorage + ); + }; + render() { return (
- - - + + +
); diff --git a/src/components/TaskList.js b/src/components/TaskList.js index 637f4c41..f6e11e9a 100644 --- a/src/components/TaskList.js +++ b/src/components/TaskList.js @@ -3,163 +3,28 @@ import Task from "./Task"; import TaskComposer from "./TaskComposer"; export default class TaskList extends React.Component { - constructor(props) { - super(props); - - this.state = { - tasks: [ - { - id: 0, - title: "Reverse Engineer the Needler", - task: "Coding a software to reverse engineer the Needler for Miranda Keyes", - }, - { - id: 1, - title: "Fixing bugs", - task: "Fixing coding bugs on the software for Machine Learning AI", - }, - ], - tasksInProgress: [], - }; - } - - updateTask = (id, updatedTask) => { - this.setState( - (prevState) => { - const updatedTasks = prevState.tasks.map((task) => { - if (task.id === id) { - return { ...task, ...updatedTask }; - } - return task; - }); - return { tasks: updatedTasks }; - }, - () => { - localStorage.setItem("tasks", JSON.stringify(this.state.tasks)); - } - ); - }; - - addTaskToDo = (task) => { - // let newArray = [...this.state.tasks, task]; - // this.setState({ - // tasks: newArray, - // }); - - const newId = this.state.tasks.length; - - const newTask = { ...task, id: newId }; - - this.setState( - (prevState) => { - const updatedTasks = [...prevState.tasks, newTask]; - // Update state - return { - tasks: updatedTasks, - }; - }, - () => { - // After updating TaskList component state, update localStorage - localStorage.setItem("tasks", JSON.stringify(this.state.tasks)); - } - ); - }; - - deleteTask = (id) => { - this.setState( - (prevState) => { - const updatedTasks = prevState.tasks.filter((task) => task.id !== id); - // Update state - return { tasks: updatedTasks }; - }, - () => { - // After updating TaskList component state, update localStorage - localStorage.setItem("tasks", JSON.stringify(this.state.tasks)); - } - ); - }; - - componentDidMount() { - // componentDidMount() lifecycle method is called whenever TaskList component is mounted in the app (i.e., browser is refreshed) - // componentDidMount() is used for actions that need to be performed when a component is initally added to the DOM (e.g., fetching data from localStorage) - // Load data from localStorage - const savedTasks = localStorage.getItem("tasks"); - - if (savedTasks) { - this.setState({ - tasks: JSON.parse(savedTasks), - }); - } - } - - resetLocalStorage = () => { - localStorage.clear(); - // You may also want to reinitialize the state to the default values here - this.setState({ - tasks: [ - { - id: 0, - title: "Reverse Engineer the Needler", - task: "Coding a software to reverse engineer the Needler for Miranda Keyes", - }, - { - id: 1, - title: "Fixing bugs", - task: "Fixing coding bugs on the software for Machine Learning AI", - }, - ], - }); - }; - - moveTaskToInProgress = (task) => { - // Removing task from TaskList - const updatedOpenTasks = this.state.tasks.filter((t) => t.id !== task.id); - - // Add task to "Tasks In Progress" - this.setState( - (prevState) => ({ - tasksInProgress: [...prevState.tasksInProgress, task], - tasks: updatedOpenTasks, - }), - () => { - localStorage.setItem("tasks", JSON.stringify(this.state.tasks)); - localStorage.setItem( - "tasksInProgress", - JSON.stringify(this.state.tasksInProgress) - ); - } - ); - }; - render() { - console.log(this.state.tasks); - const { tasks } = this.state; - const numberOfTasks = tasks.length; + const { tasks, updateTask, addTaskToDo, deleteTask, resetLocalStorage } = + this.props; + return (

Open Tasks

-

{numberOfTasks}

+

{tasks.length}

- +
- - {this.state.tasks && this.state.tasks.length > 0 ? ( + + {tasks && tasks.length > 0 ? (
    - {this.state.tasks.map((task) => ( + {tasks.map((task) => ( this.moveTaskToInProgress(task)} // Pass the moveTaskToInProgress function - additionalButton={true} - additionalButtonLabel="Move to In Progress" - additionalButtonClick={() => this.moveTaskToInProgress(task)} + updateTask={updateTask} // Pass the updateTask function + deleteTask={deleteTask} // Pass the deleteTask function /> ))}
diff --git a/src/components/TaskListInProgress.js b/src/components/TaskListInProgress.js index 3401e66f..277d66d9 100644 --- a/src/components/TaskListInProgress.js +++ b/src/components/TaskListInProgress.js @@ -3,152 +3,35 @@ import Task from "./Task"; import TaskComposer from "./TaskComposer"; export default class TaskListInProgress extends React.Component { - constructor(props) { - super(props); - - this.state = { - tasksInProgress: [], - tasks: [ - { - id: 0, - title: "React Website - ORION Project", - task: "Coding a frontend website for Doctor Halsey", - }, - ], - }; - } - - updateTask = (id, updatedTask) => { - this.setState( - (prevState) => { - const updatedTasks = prevState.tasks.map((task) => { - if (task.id === id) { - return { ...task, ...updatedTask }; - } - return task; - }); - return { tasks: updatedTasks }; - }, - () => { - localStorage.setItem( - "tasksInProgress", - JSON.stringify(this.state.tasks) - ); - } - ); - }; - - addTaskToDo = (task) => { - // let newArray = [...this.state.tasks, task]; - // this.setState({ - // tasks: newArray, - // }); - - const newId = this.state.tasks.length; - - const newTask = { ...task, id: newId }; - - this.setState( - (prevState) => { - return { - tasks: [...prevState.tasks, newTask], - }; - }, - () => { - localStorage.setItem( - "tasksInProgress", - JSON.stringify(this.state.tasks) - ); - } - ); - }; - - deleteTask = (id) => { - this.setState( - (prevState) => { - const updatedTasks = prevState.tasks.filter((task) => task.id !== id); - return { tasks: updatedTasks }; - }, - () => { - localStorage.setItem( - "tasksInProgress", - JSON.stringify(this.state.tasks) - ); - } - ); - }; - - componentDidMount() { - const savedTasks = localStorage.getItem("tasksInProgress"); - - if (savedTasks) { - this.setState({ - tasks: JSON.parse(savedTasks), - }); - } - } - resetLocalStorage = () => { - localStorage.clear(); - // You may also want to reinitialize the state to the default values here - this.setState({ - tasks: [ - { - id: 0, - title: "React Website - ORION Project", - task: "Coding a frontend website for Doctor Halsey", - }, - ], - }); - }; - - moveTaskToOpen = (task) => { - // Remove task from "Tasks in Progress" - const updatedInProgressTasks = this.state.tasks.filter( - (t) => t.id !== task.id - ); - - // Add task to "Open Tasks" - this.setState( - (prevState) => ({ - tasksInProgress: updatedInProgressTasks, - tasks: [...prevState.tasks, task], - }), - () => { - localStorage.setItem( - "tasksInProgress", - JSON.stringify(this.state.tasksInProgress) - ); - localStorage.setItem("tasks", JSON.stringify(this.state.tasks)); - } - ); - }; - render() { - console.log(this.state.tasks); - const { tasks } = this.state; - const numberOfTasks = tasks.length; + const { + tasksInProgress, + updateTask, + addTaskToDo, + deleteTask, + resetLocalStorage, + } = this.props; return (

Tasks In Progress

-

{numberOfTasks}

+

{tasksInProgress.length}

- +
- {this.state.tasks && this.state.tasks.length > 0 ? ( + {tasksInProgress && tasksInProgress.length > 0 ? (
    - {this.state.tasks.map((task) => ( + {tasksInProgress.map((task) => ( this.moveTaskToOpen(task)} + updateTask={updateTask} // Pass the updateTask function + deleteTask={deleteTask} // Pass the deleteTask function /> ))}
diff --git a/src/components/TaskListInReview.js b/src/components/TaskListInReview.js index d77d5898..dcd93ddb 100644 --- a/src/components/TaskListInReview.js +++ b/src/components/TaskListInReview.js @@ -3,98 +3,32 @@ import Task from "./Task"; import TaskComposer from "./TaskComposer"; export default class TaskListInReview extends React.Component { - constructor(props) { - super(props); - - this.state = { - tasks: [ - { - id: 0, - title: "Project Fireteam Osiris", - task: "Implementing a MongoDB Database for Spartan Locke", - }, - ], - }; - } - - updateTask = (id, updatedTask) => { - this.setState( - (prevState) => { - const updatedTasks = prevState.tasks.map((task) => { - if (task.id === id) { - return { ...task, ...updatedTask }; - } - return task; - }); - return { tasks: updatedTasks }; - }, - () => { - localStorage.setItem("tasksInReview", JSON.stringify(this.state.tasks)); - } - ); - }; - - addTaskToDo = (task) => { - const newId = this.state.tasks.length; - - const newTask = { ...task, id: newId }; - - this.setState( - (prevState) => { - return { - tasks: [...prevState.tasks, newTask], - }; - }, - () => { - localStorage.setItem("tasksInReview", JSON.stringify(this.state.tasks)); - } - ); - }; - - deleteTask = (id) => { - this.setState( - (prevState) => { - const updatedTasks = prevState.tasks.filter((task) => task.id !== id); - return { tasks: updatedTasks }; - }, - () => { - localStorage.setItem("tasksInReview", JSON.stringify(this.state.tasks)); - } - ); - }; - - componentDidMount() { - const savedTasks = localStorage.getItem("tasksInReview"); - - if (savedTasks) { - this.setState({ - tasks: JSON.parse(savedTasks), - }); - } - } - render() { - console.log(this.state.tasks); - const { tasks } = this.state; - const numberOfTasks = tasks.length; + const { + tasksInReview, + updateTask, + addTaskToDo, + deleteTask, + resetLocalStorage, + } = this.props; return (

Tasks In Review

-

{numberOfTasks}

- - {this.state.tasks && this.state.tasks.length > 0 ? ( +

{tasksInReview.length}

+
+ +
+ + {tasksInReview && tasksInReview.length > 0 ? (
    - {this.state.tasks.map((task) => ( + {tasksInReview.map((task) => ( ))}
From 35587351c9ad3ed23fe38774d16e7f1758afd650 Mon Sep 17 00:00:00 2001 From: ianthehamster Date: Sat, 11 Nov 2023 17:06:34 +0800 Subject: [PATCH 06/16] Correcting bugs in tasksInReview --- package-lock.json | 153 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + src/App.js | 3 +- src/index.js | 2 + 4 files changed, 158 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index c91166ec..a6fa9096 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,8 @@ "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/react-fontawesome": "^0.2.0", "react": "^18.1.0", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.1.0", "react-scripts": "5.0.1" } @@ -2914,6 +2916,21 @@ } } }, + "node_modules/@react-dnd/asap": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", + "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==" + }, + "node_modules/@react-dnd/invariant": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", + "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==" + }, + "node_modules/@react-dnd/shallowequal": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", + "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -5842,6 +5859,16 @@ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, + "node_modules/dnd-core": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", + "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", + "dependencies": { + "@react-dnd/asap": "^5.0.1", + "@react-dnd/invariant": "^4.0.1", + "redux": "^4.2.0" + } + }, "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -7753,6 +7780,19 @@ "he": "bin/he" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -13130,6 +13170,43 @@ "node": ">=8" } }, + "node_modules/react-dnd": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", + "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", + "dependencies": { + "@react-dnd/invariant": "^4.0.1", + "@react-dnd/shallowequal": "^4.0.1", + "dnd-core": "^16.0.1", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2" + }, + "peerDependencies": { + "@types/hoist-non-react-statics": ">= 3.3.1", + "@types/node": ">= 12", + "@types/react": ">= 16", + "react": ">= 16.14" + }, + "peerDependenciesMeta": { + "@types/hoist-non-react-statics": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-dnd-html5-backend": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", + "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", + "dependencies": { + "dnd-core": "^16.0.1" + } + }, "node_modules/react-dom": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz", @@ -13278,6 +13355,14 @@ "node": "*" } }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -17888,6 +17973,21 @@ "source-map": "^0.7.3" } }, + "@react-dnd/asap": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", + "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==" + }, + "@react-dnd/invariant": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", + "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==" + }, + "@react-dnd/shallowequal": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", + "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -20039,6 +20139,16 @@ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, + "dnd-core": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", + "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", + "requires": { + "@react-dnd/asap": "^5.0.1", + "@react-dnd/invariant": "^4.0.1", + "redux": "^4.2.0" + } + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -21419,6 +21529,21 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -25173,6 +25298,26 @@ } } }, + "react-dnd": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", + "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", + "requires": { + "@react-dnd/invariant": "^4.0.1", + "@react-dnd/shallowequal": "^4.0.1", + "dnd-core": "^16.0.1", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2" + } + }, + "react-dnd-html5-backend": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", + "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", + "requires": { + "dnd-core": "^16.0.1" + } + }, "react-dom": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz", @@ -25288,6 +25433,14 @@ } } }, + "redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", diff --git a/package.json b/package.json index 3c7dc499..5307cbb7 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,8 @@ "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/react-fontawesome": "^0.2.0", "react": "^18.1.0", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.1.0", "react-scripts": "5.0.1" }, diff --git a/src/App.js b/src/App.js index 003ce9af..6d23ee9f 100644 --- a/src/App.js +++ b/src/App.js @@ -101,7 +101,6 @@ class App extends React.Component { task: "Fixing coding bugs on the software for Machine Learning AI", }, ], - tasksInProgress: [], }, this.updateLocalStorage ); @@ -197,7 +196,7 @@ class App extends React.Component { deleteTaskInReview = (id) => { this.setState( (prevState) => ({ - tasks: prevState.tasksInReview.filter((task) => task.id !== id), + tasksInReview: prevState.tasksInReview.filter((task) => task.id !== id), }), this.updateLocalStorage ); diff --git a/src/index.js b/src/index.js index 31508db1..0bb293f2 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; +import { DndProvider } from "react-dnd"; +import { HTML5Backend } from "react-dnd-html5-backend"; import "./index.css"; import App from "./App"; From 3af73beedd5632d8d87f3c73c5086da40bd49a99 Mon Sep 17 00:00:00 2001 From: ianthehamster Date: Sat, 11 Nov 2023 17:08:50 +0800 Subject: [PATCH 07/16] Fixing bugs --- src/App.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index 003ce9af..6d23ee9f 100644 --- a/src/App.js +++ b/src/App.js @@ -101,7 +101,6 @@ class App extends React.Component { task: "Fixing coding bugs on the software for Machine Learning AI", }, ], - tasksInProgress: [], }, this.updateLocalStorage ); @@ -197,7 +196,7 @@ class App extends React.Component { deleteTaskInReview = (id) => { this.setState( (prevState) => ({ - tasks: prevState.tasksInReview.filter((task) => task.id !== id), + tasksInReview: prevState.tasksInReview.filter((task) => task.id !== id), }), this.updateLocalStorage ); From 80bd1267b913298dcde7448548a93368e44f6869 Mon Sep 17 00:00:00 2001 From: ianthehamster Date: Sun, 12 Nov 2023 13:14:18 +0800 Subject: [PATCH 08/16] Updated buttons for in progress and in review --- src/App.js | 41 ++++++++++++++++++++++++++++ src/components/Task.js | 32 +++++++++++++++++++--- src/components/TaskList.js | 12 ++++++-- src/components/TaskListInProgress.js | 4 +++ src/components/TaskListInReview.js | 1 + 5 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/App.js b/src/App.js index 6d23ee9f..60089c9e 100644 --- a/src/App.js +++ b/src/App.js @@ -42,6 +42,45 @@ class App extends React.Component { }; } + // Transfer tasks from Open Tasks to Tasks In Progress + moveTaskOpen = (id) => { + // Find the task in state.tasks using the find method + const taskToMove = this.state.tasks.find((task) => task.id === id); + /** find() + * find() method loops through the array elements and returns the first element that is true for task.id === id + */ + + // if there is a taskToMove + if (taskToMove) { + this.setState( + (prevState) => ({ + // Wrap the arrow function in () to represent object literal and not function block! + tasks: prevState.tasks.filter((task) => task.id !== id), + tasksInProgress: [...prevState.tasksInProgress, taskToMove], + }), + this.updateLocalStorage + ); + } + }; + + // Transfer tasks from In Progress to In Review + moveTaskInProgress = (id) => { + const taskToMove = this.state.tasksInProgress.find( + (task) => task.id === id + ); + if (taskToMove) { + this.setState( + (prevState) => ({ + tasksInProgress: prevState.tasksInProgress.filter( + (task) => task.id !== id + ), + tasksInReview: [...prevState.tasksInReview, taskToMove], + }), + this.updateLocalStorage + ); + } + }; + // OPEN TASKS SECTION updateTask = (id, updatedTask) => { this.setState((prevState) => { @@ -229,6 +268,7 @@ class App extends React.Component { addTaskToDo={this.addTaskToDo} deleteTask={this.deleteTask} resetLocalStorage={this.resetLocalStorage} + moveTaskOpen={this.moveTaskOpen} /> { + this.props.moveTaskOpen(this.props.id); + }; + + handleMoveTaskInProgressClick = () => { + this.props.moveTaskInProgress(this.props.id); + }; + render() { + // showButton prop is received as a parameter in the 'render' method and is then destructured from this.props + + const { showButton } = this.props; + const { showButtonInProgress } = this.props; + if (this.state.isEditing) { return ( - {this.props.additionalButton && ( - + )} + {showButtonInProgress && ( + )}
diff --git a/src/components/TaskList.js b/src/components/TaskList.js index f6e11e9a..a3658ea2 100644 --- a/src/components/TaskList.js +++ b/src/components/TaskList.js @@ -4,8 +4,14 @@ import TaskComposer from "./TaskComposer"; export default class TaskList extends React.Component { render() { - const { tasks, updateTask, addTaskToDo, deleteTask, resetLocalStorage } = - this.props; + const { + tasks, + updateTask, + addTaskToDo, + deleteTask, + resetLocalStorage, + moveTaskOpen, + } = this.props; return (
@@ -23,8 +29,10 @@ export default class TaskList extends React.Component { ))} diff --git a/src/components/TaskListInProgress.js b/src/components/TaskListInProgress.js index 277d66d9..731e5881 100644 --- a/src/components/TaskListInProgress.js +++ b/src/components/TaskListInProgress.js @@ -10,6 +10,7 @@ export default class TaskListInProgress extends React.Component { addTaskToDo, deleteTask, resetLocalStorage, + moveTaskInProgress, } = this.props; return (
@@ -30,8 +31,11 @@ export default class TaskListInProgress extends React.Component { ))} diff --git a/src/components/TaskListInReview.js b/src/components/TaskListInReview.js index dcd93ddb..a3d52287 100644 --- a/src/components/TaskListInReview.js +++ b/src/components/TaskListInReview.js @@ -27,6 +27,7 @@ export default class TaskListInReview extends React.Component { From 2ca445d43acc6c72a5f5a11aae20bef1a56269da Mon Sep 17 00:00:00 2001 From: ianthehamster Date: Tue, 14 Nov 2023 23:39:04 +0800 Subject: [PATCH 09/16] Updated changes --- package-lock.json | 893 ++++++++++++++++++++++++++- package.json | 3 + src/App.css | 24 +- src/App.js | 68 +- src/components/Task.js | 25 +- src/components/TaskCompleter.js | 75 +++ src/components/TaskComposer.js | 6 +- src/components/TaskList.js | 4 +- src/components/TaskListCompleted.js | 43 ++ src/components/TaskListInProgress.js | 4 +- src/components/TaskListInReview.js | 4 +- src/index.css | 2 +- 12 files changed, 1125 insertions(+), 26 deletions(-) create mode 100644 src/components/TaskCompleter.js create mode 100644 src/components/TaskListCompleted.js diff --git a/package-lock.json b/package-lock.json index c91166ec..fa3fedf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,11 @@ "name": "project1-bootcamp", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/react-fontawesome": "^0.2.0", + "@mui/material": "^5.14.18", "react": "^18.1.0", "react-dom": "^18.1.0", "react-scripts": "5.0.1" @@ -1766,11 +1769,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1788,6 +1791,11 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", @@ -1999,6 +2007,158 @@ "postcss": "^8.3" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@eslint/eslintrc": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz", @@ -2059,6 +2219,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@floating-ui/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", + "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "dependencies": { + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "dependencies": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz", + "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==", + "dependencies": { + "@floating-ui/dom": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz", @@ -2833,6 +3027,236 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==" }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.24", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.24.tgz", + "integrity": "sha512-bKt2pUADHGQtqWDZ8nvL2Lvg2GNJyd/ZUgZAJoYzRgmnxBL9j36MSlS3+exEdYkikcnvVafcBtD904RypFKb0w==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@floating-ui/react-dom": "^2.0.4", + "@mui/types": "^7.2.9", + "@mui/utils": "^5.14.18", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.18.tgz", + "integrity": "sha512-yFpF35fEVDV81nVktu0BE9qn2dD/chs7PsQhlyaV3EnTeZi9RZBuvoEfRym1/jmhJ2tcfeWXiRuHG942mQXJJQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + } + }, + "node_modules/@mui/material": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.18.tgz", + "integrity": "sha512-y3UiR/JqrkF5xZR0sIKj6y7xwuEiweh9peiN3Zfjy1gXWXhz5wjlaLdoxFfKIEBUFfeQALxr/Y8avlHH+B9lpQ==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/base": "5.0.0-beta.24", + "@mui/core-downloads-tracker": "^5.14.18", + "@mui/system": "^5.14.18", + "@mui/types": "^7.2.9", + "@mui/utils": "^5.14.18", + "@types/react-transition-group": "^4.4.8", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/private-theming": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.18.tgz", + "integrity": "sha512-WSgjqRlzfHU+2Rou3HlR2Gqfr4rZRsvFgataYO3qQ0/m6gShJN+lhVEvwEiJ9QYyVzMDvNpXZAcqp8Y2Vl+PAw==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/utils": "^5.14.18", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.18.tgz", + "integrity": "sha512-pW8bpmF9uCB5FV2IPk6mfbQCjPI5vGI09NOLhtGXPeph/4xIfC3JdIX0TILU0WcTs3aFQqo6s2+1SFgIB9rCXA==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.18.tgz", + "integrity": "sha512-hSQQdb3KF72X4EN2hMEiv8EYJZSflfdd1TRaGPoR7CIAG347OxCslpBUwWngYobaxgKvq6xTrlIl+diaactVww==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/private-theming": "^5.14.18", + "@mui/styled-engine": "^5.14.18", + "@mui/types": "^7.2.9", + "@mui/utils": "^5.14.18", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.9.tgz", + "integrity": "sha512-k1lN/PolaRZfNsRdAqXtcR71sTnv3z/VCCGPxU8HfdftDkzi335MdJ6scZxvofMAd/K/9EbzCZTFBmlNpQVdCg==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.18.tgz", + "integrity": "sha512-HZDRsJtEZ7WMSnrHV9uwScGze4wM/Y+u6pDVo+grUjt5yXzn+wI8QX/JwTHh9YSw/WpnUL80mJJjgCnWj2VrzQ==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@types/prop-types": "^15.7.10", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2914,6 +3338,15 @@ } } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3435,6 +3868,11 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.0.tgz", "integrity": "sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw==" }, + "node_modules/@types/prop-types": { + "version": "15.7.10", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.10.tgz", + "integrity": "sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==" + }, "node_modules/@types/q": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", @@ -3450,6 +3888,24 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "node_modules/@types/react": { + "version": "18.2.37", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz", + "integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.9.tgz", + "integrity": "sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -3463,6 +3919,11 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, + "node_modules/@types/scheduler": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.6.tgz", + "integrity": "sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==" + }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -4968,6 +5429,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -5634,6 +6103,11 @@ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -5877,6 +6351,15 @@ "utila": "~0.4" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -7186,6 +7669,11 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -7753,6 +8241,19 @@ "he": "bin/he" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -13232,6 +13733,21 @@ } } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -14294,6 +14810,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -17092,11 +17613,18 @@ } }, "@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + } } }, "@babel/runtime-corejs3": { @@ -17235,6 +17763,132 @@ "integrity": "sha512-T5ZyNSw9G0x0UDFiXV40a7VjKw2b+l4G+S0sctKqxhx8cg9QtMUAGwJBVU9mHPDPoZEmwm0tEoukjl4zb9MU7Q==", "requires": {} }, + "@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + } + } + }, + "@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "requires": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "requires": { + "@emotion/memoize": "^0.8.1" + } + }, + "@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "requires": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + } + }, + "@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "requires": {} + }, + "@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "@eslint/eslintrc": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz", @@ -17279,6 +17933,36 @@ } } }, + "@floating-ui/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", + "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "requires": { + "@floating-ui/utils": "^0.1.3" + } + }, + "@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "requires": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "@floating-ui/react-dom": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz", + "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==", + "requires": { + "@floating-ui/dom": "^1.5.1" + } + }, + "@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, "@fortawesome/fontawesome-common-types": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz", @@ -17849,6 +18533,111 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==" }, + "@mui/base": { + "version": "5.0.0-beta.24", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.24.tgz", + "integrity": "sha512-bKt2pUADHGQtqWDZ8nvL2Lvg2GNJyd/ZUgZAJoYzRgmnxBL9j36MSlS3+exEdYkikcnvVafcBtD904RypFKb0w==", + "requires": { + "@babel/runtime": "^7.23.2", + "@floating-ui/react-dom": "^2.0.4", + "@mui/types": "^7.2.9", + "@mui/utils": "^5.14.18", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1" + } + }, + "@mui/core-downloads-tracker": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.18.tgz", + "integrity": "sha512-yFpF35fEVDV81nVktu0BE9qn2dD/chs7PsQhlyaV3EnTeZi9RZBuvoEfRym1/jmhJ2tcfeWXiRuHG942mQXJJQ==" + }, + "@mui/material": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.18.tgz", + "integrity": "sha512-y3UiR/JqrkF5xZR0sIKj6y7xwuEiweh9peiN3Zfjy1gXWXhz5wjlaLdoxFfKIEBUFfeQALxr/Y8avlHH+B9lpQ==", + "requires": { + "@babel/runtime": "^7.23.2", + "@mui/base": "5.0.0-beta.24", + "@mui/core-downloads-tracker": "^5.14.18", + "@mui/system": "^5.14.18", + "@mui/types": "^7.2.9", + "@mui/utils": "^5.14.18", + "@types/react-transition-group": "^4.4.8", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "@mui/private-theming": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.18.tgz", + "integrity": "sha512-WSgjqRlzfHU+2Rou3HlR2Gqfr4rZRsvFgataYO3qQ0/m6gShJN+lhVEvwEiJ9QYyVzMDvNpXZAcqp8Y2Vl+PAw==", + "requires": { + "@babel/runtime": "^7.23.2", + "@mui/utils": "^5.14.18", + "prop-types": "^15.8.1" + } + }, + "@mui/styled-engine": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.18.tgz", + "integrity": "sha512-pW8bpmF9uCB5FV2IPk6mfbQCjPI5vGI09NOLhtGXPeph/4xIfC3JdIX0TILU0WcTs3aFQqo6s2+1SFgIB9rCXA==", + "requires": { + "@babel/runtime": "^7.23.2", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + } + }, + "@mui/system": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.18.tgz", + "integrity": "sha512-hSQQdb3KF72X4EN2hMEiv8EYJZSflfdd1TRaGPoR7CIAG347OxCslpBUwWngYobaxgKvq6xTrlIl+diaactVww==", + "requires": { + "@babel/runtime": "^7.23.2", + "@mui/private-theming": "^5.14.18", + "@mui/styled-engine": "^5.14.18", + "@mui/types": "^7.2.9", + "@mui/utils": "^5.14.18", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + } + }, + "@mui/types": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.9.tgz", + "integrity": "sha512-k1lN/PolaRZfNsRdAqXtcR71sTnv3z/VCCGPxU8HfdftDkzi335MdJ6scZxvofMAd/K/9EbzCZTFBmlNpQVdCg==", + "requires": {} + }, + "@mui/utils": { + "version": "5.14.18", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.18.tgz", + "integrity": "sha512-HZDRsJtEZ7WMSnrHV9uwScGze4wM/Y+u6pDVo+grUjt5yXzn+wI8QX/JwTHh9YSw/WpnUL80mJJjgCnWj2VrzQ==", + "requires": { + "@babel/runtime": "^7.23.2", + "@types/prop-types": "^15.7.10", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -17888,6 +18677,11 @@ "source-map": "^0.7.3" } }, + "@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -18279,6 +19073,11 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.0.tgz", "integrity": "sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw==" }, + "@types/prop-types": { + "version": "15.7.10", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.10.tgz", + "integrity": "sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==" + }, "@types/q": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", @@ -18294,6 +19093,24 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, + "@types/react": { + "version": "18.2.37", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz", + "integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-transition-group": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.9.tgz", + "integrity": "sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg==", + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -18307,6 +19124,11 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, + "@types/scheduler": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.6.tgz", + "integrity": "sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==" + }, "@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -19421,6 +20243,11 @@ "wrap-ansi": "^7.0.0" } }, + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -19887,6 +20714,11 @@ } } }, + "csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -20068,6 +20900,15 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -21039,6 +21880,11 @@ "pkg-dir": "^4.1.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -21419,6 +22265,21 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -25252,6 +26113,17 @@ "workbox-webpack-plugin": "^6.4.1" } }, + "react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -26033,6 +26905,11 @@ "postcss-selector-parser": "^6.0.4" } }, + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/package.json b/package.json index 3c7dc499..a9844675 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,11 @@ "version": "0.1.0", "private": true, "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/react-fontawesome": "^0.2.0", + "@mui/material": "^5.14.18", "react": "^18.1.0", "react-dom": "^18.1.0", "react-scripts": "5.0.1" diff --git a/src/App.css b/src/App.css index 0f1e7bfc..433cf799 100644 --- a/src/App.css +++ b/src/App.css @@ -15,6 +15,7 @@ border: 1px solid #ccc; padding: 16px; border-radius: 8px; + opacity: 80%; } .task-container { @@ -23,15 +24,15 @@ } .task-list { - background: #de0c0c; + background: #e97e7e; } .task-in-progress { - background: yellow; + background: rgb(244, 244, 162); } .task-in-review { - background: rgb(17, 219, 31); + background: rgb(146, 246, 153); } .task-composer { @@ -51,3 +52,20 @@ .header-link { color: whitesmoke; } + +.content { + color: black; +} + +.main { + opacity: 80%; +} + +.buttons { + margin: 10px; + margin-bottom: 20px; +} + +button { + margin-top: 15px; +} diff --git a/src/App.js b/src/App.js index 60089c9e..1587bacb 100644 --- a/src/App.js +++ b/src/App.js @@ -7,6 +7,7 @@ import Header from "./components/Header"; import TaskList from "./components/TaskList"; import TaskListInProgress from "./components/TaskListInProgress"; import TaskListInReview from "./components/TaskListInReview"; +import TaskListCompleted from "./components/TaskListCompleted"; class App extends React.Component { constructor(props) { @@ -39,6 +40,20 @@ class App extends React.Component { task: "Implementing a MongoDB Database for Spartan Locke", }, ], + tasksCompleted: [ + { + id: 0, + title: "Improved M-41 SPNKER with upgrades to tracking", + task: "Added tracking to lock on to targets with greater distance and speed of the payload", + timeTaken: "", + keyTakeaways: "", + }, + { + id: 1, + title: "Fixed software", + task: "Fixing coding bugs on the software for Machine Learning AI", + }, + ], }; } @@ -52,11 +67,14 @@ class App extends React.Component { // if there is a taskToMove if (taskToMove) { + const newId = this.state.tasksInProgress.length + 1; + const updatedTask = { ...taskToMove, id: newId }; + this.setState( (prevState) => ({ // Wrap the arrow function in () to represent object literal and not function block! tasks: prevState.tasks.filter((task) => task.id !== id), - tasksInProgress: [...prevState.tasksInProgress, taskToMove], + tasksInProgress: [...prevState.tasksInProgress, updatedTask], }), this.updateLocalStorage ); @@ -69,12 +87,14 @@ class App extends React.Component { (task) => task.id === id ); if (taskToMove) { + const newId = this.state.tasksInReview.length + 1; + const updatedTask = { ...taskToMove, id: newId }; this.setState( (prevState) => ({ tasksInProgress: prevState.tasksInProgress.filter( (task) => task.id !== id ), - tasksInReview: [...prevState.tasksInReview, taskToMove], + tasksInReview: [...prevState.tasksInReview, updatedTask], }), this.updateLocalStorage ); @@ -122,6 +142,10 @@ class App extends React.Component { "tasksInReview", JSON.stringify(this.state.tasksInReview) ); + localStorage.setItem( + "tasksCompleted", + JSON.stringify(this.state.tasksCompleted) + ); }; resetLocalStorage = () => { @@ -257,6 +281,41 @@ class App extends React.Component { ); }; + // Tasks Completed + resetLocalStorageCompleted = () => { + localStorage.removeItem("tasksCompleted"); + this.setState( + { + tasksCompleted: [ + { + id: 0, + title: "Improved M-41 SPNKER with upgrades to tracking", + tasksCompleted: + "Added tracking to lock on to targets with greater distance and speed of the payload", + }, + ], + }, + this.updateLocalStorage + ); + }; + + reflectionToDo = (id, timeTaken, keyTakeaways) => { + this.setState((prevState) => { + const reflectedTasks = prevState.tasksCompleted.map((task) => { + if (task.id === id) { + return { + ...task, + timeTaken: timeTaken !== undefined ? timeTaken : task.timeTaken, + keyTakeaways: + keyTakeaways !== undefined ? keyTakeaways : task.keyTakeaways, + }; + } + return task; + }); + return { tasksCompleted: reflectedTasks }; + }, this.updateLocalStorage); + }; + render() { return (
@@ -285,6 +344,11 @@ class App extends React.Component { deleteTask={this.deleteTaskInReview} resetLocalStorage={this.resetLocalStorageInReview} /> +
); diff --git a/src/components/Task.js b/src/components/Task.js index d0f6edf1..ee7d9d4c 100644 --- a/src/components/Task.js +++ b/src/components/Task.js @@ -4,6 +4,7 @@ import { faTrash, faEdit, faArrowRight, + faCheck, } from "@fortawesome/free-solid-svg-icons"; import TaskUpdate from "./TaskUpdate"; @@ -16,6 +17,8 @@ class Task extends React.Component { isEditing: false, title: this.props.title, // Initialize title in the local state task: this.props.task, // Initialize task in the local state + timeTaken: this.props.timeTaken, + keyTakeaways: this.props.keyTakeaways, }; } @@ -40,11 +43,16 @@ class Task extends React.Component { this.props.moveTaskInProgress(this.props.id); }; + handleReflectedTaskClick = () => { + this.props.reflectionToDo(this.props.id); + }; + render() { // showButton prop is received as a parameter in the 'render' method and is then destructured from this.props const { showButton } = this.props; const { showButtonInProgress } = this.props; + const { showButtonCompleted } = this.props; if (this.state.isEditing) { return ( @@ -59,17 +67,21 @@ class Task extends React.Component { } return ( -
+

Title: {this.props.title}

Task: {this.props.task}

- - {showButton && ( - @@ -80,6 +92,11 @@ class Task extends React.Component { )} + {showButtonCompleted && ( + + )}
); } diff --git a/src/components/TaskCompleter.js b/src/components/TaskCompleter.js new file mode 100644 index 00000000..59609660 --- /dev/null +++ b/src/components/TaskCompleter.js @@ -0,0 +1,75 @@ +import React from "react"; + +class TaskCompleter extends React.Component { + constructor(props) { + super(props); + + this.state = { + timeTaken: "", + keyTakeaways: "", + }; + } + + handleSubmit = (e) => { + e.preventDefault(); + + const { tasksCompleted, id, reflectionToDo } = this.props; + const { timeTaken, keyTakeaways } = this.state; + + const index = tasksCompleted.findIndex((task) => task.id === id); // loops through the array of objects and returns the index of the matching task + + console.log(index); + + if (index !== -1) { + reflectionToDo(index, timeTaken, keyTakeaways); + tasksCompleted[index].timeTaken = timeTaken; + tasksCompleted[index].keyTakeaways = keyTakeaways; + + // Log the updated task + console.log(tasksCompleted[index]); + } + + // Resets the state of TaskComposer after + this.setState({ + timeTaken: "", + keyTakeaways: "", + }); + }; + + handleChange = (e) => { + const { name, value } = e.target; + + this.setState({ + [name]: value, + }); + }; + + render() { + return ( +
+
+
+

Time taken to complete:

+ +
+
Key Takeaways:
+ +
+ +
+
+ ); + } +} + +export default TaskCompleter; diff --git a/src/components/TaskComposer.js b/src/components/TaskComposer.js index 32d1c3dd..27db0c68 100644 --- a/src/components/TaskComposer.js +++ b/src/components/TaskComposer.js @@ -36,7 +36,7 @@ class TaskComposer extends React.Component { render() { return ( -
+

Title

@@ -55,7 +55,9 @@ class TaskComposer extends React.Component { onChange={this.handleChange} />
- +
diff --git a/src/components/TaskList.js b/src/components/TaskList.js index a3658ea2..6128b697 100644 --- a/src/components/TaskList.js +++ b/src/components/TaskList.js @@ -14,13 +14,13 @@ export default class TaskList extends React.Component { } = this.props; return ( -
+

Open Tasks

{tasks.length}

- +
{tasks && tasks.length > 0 ? ( diff --git a/src/components/TaskListCompleted.js b/src/components/TaskListCompleted.js new file mode 100644 index 00000000..6538aa38 --- /dev/null +++ b/src/components/TaskListCompleted.js @@ -0,0 +1,43 @@ +import React from "react"; +import Task from "./Task"; +import TaskCompleter from "./TaskCompleter"; + +export default class TaskListCompleted extends React.Component { + render() { + const { tasksCompleted, resetLocalStorageCompleted, reflectionToDo } = + this.props; + + return ( +
+

+ Completed Tasks +

+

{tasksCompleted.length}

+
+ +
+ {tasksCompleted && tasksCompleted.length > 0 ? ( +
    + {tasksCompleted.map((task) => ( +
  • + + +
  • + ))} +
+ ) : ( +

No Tasks

+ )} +
+ ); + } +} diff --git a/src/components/TaskListInProgress.js b/src/components/TaskListInProgress.js index 731e5881..65329f09 100644 --- a/src/components/TaskListInProgress.js +++ b/src/components/TaskListInProgress.js @@ -13,13 +13,13 @@ export default class TaskListInProgress extends React.Component { moveTaskInProgress, } = this.props; return ( -
+

Tasks In Progress

{tasksInProgress.length}

- +
+

Tasks In Review

{tasksInReview.length}

- +
{tasksInReview && tasksInReview.length > 0 ? ( diff --git a/src/index.css b/src/index.css index ba2422af..f372de54 100644 --- a/src/index.css +++ b/src/index.css @@ -10,7 +10,7 @@ body { -moz-osx-font-smoothing: grayscale; color: rgb(18, 2, 2); height: 100vh; - background: url(https://i.pinimg.com/1200x/44/9a/c4/449ac4efb9d56353883a9a9d1f843c4c.jpg) + background: url(https://i.pinimg.com/736x/8e/d5/e3/8ed5e319555b7762ce632e3fe70115da.jpg) center/cover no-repeat; } From c2bd1a1135a58becb5513c8cbc811d693f2cc75a Mon Sep 17 00:00:00 2001 From: ianthehamster Date: Wed, 15 Nov 2023 13:56:36 +0800 Subject: [PATCH 10/16] Adding functionality to Completed Tasks --- src/App.css | 17 ++++++++++---- src/App.js | 36 ++++++++++++++++++++++++++--- src/components/Header.js | 2 +- src/components/Task.js | 14 ++++++++++- src/components/TaskListCompleted.js | 7 ++++-- src/components/TaskListInReview.js | 4 +++- src/index.css | 1 + 7 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/App.css b/src/App.css index 433cf799..deb43950 100644 --- a/src/App.css +++ b/src/App.css @@ -11,11 +11,12 @@ flex: 1; /* Equal distribution of space */ box-sizing: border-box; /* Include padding and border in the width calculation */ width: calc(33.33% - 40px); /* 33.33% width with 20px margin on each side */ - margin: 0 20px; + margin: 20px 20px; border: 1px solid #ccc; padding: 16px; - border-radius: 8px; + border-radius: 12px; opacity: 80%; + font-size: 10px; } .task-container { @@ -41,16 +42,18 @@ /* Style the Header as you need it. For example: */ .header { - background: #333; + /* background: #333; */ color: #fff; + font-size: 35px; display: flex; /* flex container to enable */ padding: 10px; justify-content: center; align-items: center; + opacity: 30%; } .header-link { - color: whitesmoke; + color: white; } .content { @@ -64,8 +67,14 @@ .buttons { margin: 10px; margin-bottom: 20px; + border-radius: 25%; } button { margin-top: 15px; + border-radius: 25%; +} + +.adjustments { + margin-bottom: 50px; } diff --git a/src/App.js b/src/App.js index 1587bacb..f6e1a1ea 100644 --- a/src/App.js +++ b/src/App.js @@ -1,8 +1,7 @@ import React from "react"; -// import logo from "./logo.png"; + import "./App.css"; import Header from "./components/Header"; -// import Todo from "./components/Todo"; import TaskList from "./components/TaskList"; import TaskListInProgress from "./components/TaskListInProgress"; @@ -283,7 +282,7 @@ class App extends React.Component { // Tasks Completed resetLocalStorageCompleted = () => { - localStorage.removeItem("tasksCompleted"); + localStorage.clear(); this.setState( { tasksCompleted: [ @@ -316,6 +315,35 @@ class App extends React.Component { }, this.updateLocalStorage); }; + deleteTaskCompleted = (id) => { + this.setState( + (prevState) => ({ + tasksCompleted: prevState.tasksCompleted.filter( + (task) => task.id !== id + ), + }), + this.updateLocalStorage + ); + }; + + // Move task from In Review to Completed + moveTaskInReview = (id) => { + const taskToMove = this.state.tasksInReview.find((task) => task.id === id); + if (taskToMove) { + const newId = this.state.tasksCompleted.length + 1; + const updatedTask = { ...taskToMove, id: newId }; + this.setState( + (prevState) => ({ + tasksInReview: prevState.tasksInReview.filter( + (task) => task.id !== id + ), + tasksCompleted: [...prevState.tasksCompleted, updatedTask], + }), + this.updateLocalStorage + ); + } + }; + render() { return (
@@ -342,10 +370,12 @@ class App extends React.Component { updateTask={this.updateTaskInReview} addTaskToDo={this.addTaskToDoInReview} deleteTask={this.deleteTaskInReview} + moveTaskInReview={this.moveTaskInReview} resetLocalStorage={this.resetLocalStorageInReview} /> diff --git a/src/components/Header.js b/src/components/Header.js index 66dd33f4..87ead82c 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -8,7 +8,7 @@ function Header() { className="header-link" href="https://github.com/ianthehamster/project1-bootcamp" > - Welcome to the Task Management App! + UNSC Task Management Platform
diff --git a/src/components/Task.js b/src/components/Task.js index ee7d9d4c..5f9b7e81 100644 --- a/src/components/Task.js +++ b/src/components/Task.js @@ -43,6 +43,10 @@ class Task extends React.Component { this.props.moveTaskInProgress(this.props.id); }; + handleMoveTaskInReviewClick = () => { + this.props.moveTaskInReview(this.props.id); + }; + handleReflectedTaskClick = () => { this.props.reflectionToDo(this.props.id); }; @@ -53,6 +57,7 @@ class Task extends React.Component { const { showButton } = this.props; const { showButtonInProgress } = this.props; const { showButtonCompleted } = this.props; + const { showButtonInReview } = this.props; if (this.state.isEditing) { return ( @@ -68,7 +73,9 @@ class Task extends React.Component { return (
-

Title: {this.props.title}

+

+ Title: {this.props.title} +

Task: {this.props.task}

{showButtonCompleted &&

TimeTaken: {this.props.timeTaken}

} {showButtonCompleted && ( @@ -92,6 +99,11 @@ class Task extends React.Component { )} + {showButtonInReview && ( + + )} {showButtonCompleted && ( +
{tasksCompleted && tasksCompleted.length > 0 ? (
    @@ -24,6 +26,7 @@ export default class TaskListCompleted extends React.Component { key={task.id} {...task} showButtonCompleted={true} + deleteTask={deleteTask} reflectionToDo={reflectionToDo} /> @@ -27,9 +28,10 @@ export default class TaskListInReview extends React.Component { ))}
diff --git a/src/index.css b/src/index.css index f372de54..da133db7 100644 --- a/src/index.css +++ b/src/index.css @@ -12,6 +12,7 @@ body { height: 100vh; background: url(https://i.pinimg.com/736x/8e/d5/e3/8ed5e319555b7762ce632e3fe70115da.jpg) center/cover no-repeat; + background-attachment: fixed; } code { From ff27146bc17917d7d7c4b7ea6558983f5df68258 Mon Sep 17 00:00:00 2001 From: ianthehamster Date: Wed, 15 Nov 2023 13:59:19 +0800 Subject: [PATCH 11/16] Added styling to input fields --- src/App.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/App.css b/src/App.css index deb43950..ba57b342 100644 --- a/src/App.css +++ b/src/App.css @@ -78,3 +78,15 @@ button { .adjustments { margin-bottom: 50px; } + +form input[type="text"], +form input[type="email"], +/* Add more selectors for other input types if needed */ +form input[type="submit"] { + border-radius: 8px; /* Adjust the value as needed */ + /* Other styling properties */ + /* For example: */ + border: 1px solid #ccc; + padding: 8px; + margin-bottom: 10px; +} From c8cf488464357aa2b4b85abe659016aa224f7b97 Mon Sep 17 00:00:00 2001 From: ianthehamster Date: Wed, 15 Nov 2023 20:36:45 +0800 Subject: [PATCH 12/16] Final touching up --- src/App.css | 6 ++++- src/App.js | 2 ++ src/components/TaskComposer.js | 48 ++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/App.css b/src/App.css index ba57b342..8e5e877c 100644 --- a/src/App.css +++ b/src/App.css @@ -16,7 +16,7 @@ padding: 16px; border-radius: 12px; opacity: 80%; - font-size: 10px; + font-size: 30px; } .task-container { @@ -90,3 +90,7 @@ form input[type="submit"] { padding: 8px; margin-bottom: 10px; } + +form textarea[type="text"] { + border-radius: 8px; +} diff --git a/src/App.js b/src/App.js index f6e1a1ea..af461abb 100644 --- a/src/App.js +++ b/src/App.js @@ -385,4 +385,6 @@ class App extends React.Component { } } +// MAKE TASK INPUT FIELD BIGGER! +// MAKE THE BUTTON TO export default App; diff --git a/src/components/TaskComposer.js b/src/components/TaskComposer.js index 27db0c68..708051fd 100644 --- a/src/components/TaskComposer.js +++ b/src/components/TaskComposer.js @@ -9,6 +9,7 @@ class TaskComposer extends React.Component { this.state = { title: "", task: "", + isFormVisible: false, }; } @@ -34,10 +35,42 @@ class TaskComposer extends React.Component { }); }; + // handleChange = (e) => { + // const { name, value } = e.target; + + // if (name === "task") { + // const textarea = document.getElementById("userInput"); + + // textarea.addEventListener("keydown", function (event) { + // if (event.key === "Enter") { + // const userInput = textarea.value.trim() + // const sentences = userInput.split('\n') + // } + // }); + // this.setState({ + // [name]: value, + // }); + // } + // }; + + toggleFormVisibility = () => { + this.setState((prevState) => ({ + isFormVisible: !prevState.isFormVisible, + })); + }; + render() { + const { isFormVisible } = this.state; return (
-
+ +

Title


Task
- */} +