diff --git a/package-lock.json b/package-lock.json
index e6a160a..1a1791e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,11 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
+ "uuid4": "^2.0.3",
"web-vitals": "^2.1.4"
+ },
+ "devDependencies": {
+ "tailwindcss": "^3.4.1"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -17332,6 +17336,11 @@
"uuid": "dist/bin/uuid"
}
},
+ "node_modules/uuid4": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/uuid4/-/uuid4-2.0.3.tgz",
+ "integrity": "sha512-CTpAkEVXMNJl2ojgtpLXHgz23dh8z81u6/HEPiQFOvBc/c2pde6TVHmH4uwY0d/GLF3tb7+VDAj4+2eJaQSdZQ=="
+ },
"node_modules/v8-to-istanbul": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz",
diff --git a/package.json b/package.json
index 88a269e..37f020b 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
+ "uuid4": "^2.0.3",
"web-vitals": "^2.1.4"
},
"scripts": {
@@ -34,5 +35,8 @@
"last 1 firefox version",
"last 1 safari version"
]
+ },
+ "devDependencies": {
+ "tailwindcss": "^3.4.1"
}
}
diff --git a/src/App.css b/src/App.css
index 13088c2..5e5f622 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,4 +1,4 @@
-:root {
+/* :root {
--peach: #ffe6e6;
--pink: #e1afd1;
--lightPurple: #ad88c6;
@@ -46,4 +46,4 @@
to {
transform: rotate(360deg);
}
-}
+} */
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
index 0ff7d8a..a74fc28 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,12 +1,17 @@
import "./App.css";
+import todoData from "./todoData";
+import TodoList from "./components/TodoList";
+import LandingPage from "./components/LandingPage";
+
// TODO: Import the todoData and pass it as a prop to the TodoList component
function App() {
return (
-
-
- {/* Call the TodoList Component Here */}
-
+
);
}
diff --git a/src/assets/todo.jpeg b/src/assets/todo.jpeg
new file mode 100644
index 0000000..71f5044
Binary files /dev/null and b/src/assets/todo.jpeg differ
diff --git a/src/assets/todoo.avif b/src/assets/todoo.avif
new file mode 100644
index 0000000..630b634
Binary files /dev/null and b/src/assets/todoo.avif differ
diff --git a/src/components/AddTask.js b/src/components/AddTask.js
new file mode 100644
index 0000000..9eace56
--- /dev/null
+++ b/src/components/AddTask.js
@@ -0,0 +1,160 @@
+import React, { useState } from 'react';
+import uuid4 from 'uuid4';
+import { users } from "../usersData"
+
+function AddTask({ todoList, setTodoList, listType, setFilteredList }) {
+ let defaultDate = new Date()
+ defaultDate.setDate(defaultDate.getDate() + 3)
+
+ const [isOpen, setIsOpen] = useState(false);
+ const [todoTitle, setTitle] = useState("");
+ const [todoLevel, setLevel] = useState("");
+ const [todoUser, setUser] = useState(null);
+ const [todoStart, setStart] = useState(defaultDate);
+ const [todoEnd, setEnd] = useState(defaultDate);
+ const [todoDescription, setDescription] = useState("");
+
+
+ const addTask = () => {
+ setIsOpen(!isOpen);
+ };
+
+ const handleSubmit = (event) => {
+ event.preventDefault();
+
+ const startDate = new Date(todoStart);
+ const endDate = new Date(todoEnd);
+
+ // Check if end date is before start date
+ if (endDate < startDate) {
+ alert("End date must be after start date");
+ return;
+ }
+ const newTask = {
+ id: uuid4(),
+ title: todoTitle,
+ level: todoLevel,
+ user: todoUser,
+ startDate: todoStart,
+ endDate: todoEnd,
+ description: todoDescription,
+ done: false
+ };
+ const updatedTodoList = [...todoList, newTask]; // Update todoList with the new task
+ setTodoList(updatedTodoList); // Update todoList state
+
+ // Update filteredList using the updated todoList
+ if (listType === "completed") {
+ setFilteredList(updatedTodoList.filter(todo => todo.done));
+ } else if (listType === "active") {
+ setFilteredList(updatedTodoList.filter(todo => !todo.done));
+ } else {
+ setFilteredList(updatedTodoList);
+ }
+
+ // Reset values and close modal
+ addTask();
+ setTitle("");
+ setLevel("");
+ setStart(defaultDate);
+ setEnd(defaultDate);
+ setDescription("");
+
+ };
+ const handleUser = (event) => {
+ const userId = event.target.value;
+ const user = users.find(user => user.id === Number(userId));
+ setUser(user);
+ }
+
+
+ return (
+ <>
+ {/* Modal toggle */}
+
+
+ {/* Main modal */}
+ {isOpen && (
+
+
+ {/* Modal content */}
+
+ {/* Modal header */}
+
+
+ Add New Task
+
+
+
+ {/* Modal body */}
+
+
+
+
+ )}
+ >
+ );
+}
+
+export default AddTask;
diff --git a/src/components/EditTask.js b/src/components/EditTask.js
new file mode 100644
index 0000000..e24d590
--- /dev/null
+++ b/src/components/EditTask.js
@@ -0,0 +1,126 @@
+import React from 'react';
+import { useState } from 'react';
+import { users } from '../usersData';
+
+function EditTask({ todo, setIsEditing, handleCancel, handleEditList }) {
+ const [editedTitle, setEditTitle] = useState(todo.title);
+ const [editedLevel, setEditLevel] = useState(todo.level);
+ const [editedUser, setEditUser] = useState(todo.user);
+ const [editedStart, setEditStart] = useState(todo.startDate);
+ const [editedEnd, setEditEnd] = useState(todo.endDate);
+ const [editedDescription, setEditDescription] = useState(todo.description);
+
+ // Implement your edit functionality here
+ const handleSave = () => {
+ if (editedTitle === "") return;
+
+ const updatedTask = {
+ ...todo,
+ title: editedTitle,
+ level: editedLevel ? editedLevel : "",
+ user: editedUser ? editedUser : "Not assigned",
+ startDate: editedStart ? editedStart : "",
+ endDate: editedEnd ? editedEnd : "",
+ description: editedDescription ? editedDescription : "",
+ done: todo.done
+ };
+ handleEditList(updatedTask);
+ setIsEditing(false);
+ }
+
+ const handleEditUser = (event) => {
+ const userId = event.target.value;
+ const user = users.find(user => user.id === Number(userId));
+ setEditUser(user);
+ }
+ return (
+ <>
+ {/* Main modal */}
+
+
+ {/* Modal content */}
+
+ {/* Modal header */}
+
+
+ Edit Task
+
+
+
+ {/* Modal body */}
+
+
+
+
+
+
+ {
+ setEditTitle(event.target.value);
+ }} value={editedTitle} className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5" placeholder="Type task name" required />
+
+
+
+
+
+
+
+
+
+
+
+ {
+ setEditStart(event.target.value);
+ }} value={editedStart} className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5" />
+
+
+
+ {
+ setEditEnd(event.target.value);
+ }} value={editedEnd} className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default EditTask;
diff --git a/src/components/LandingPage.js b/src/components/LandingPage.js
new file mode 100644
index 0000000..0b5d453
--- /dev/null
+++ b/src/components/LandingPage.js
@@ -0,0 +1,24 @@
+import React from 'react';
+import backgroundImage from '../assets/todoo.avif';
+
+function LandingPage() {
+ return (
+
+
+

+
+
To Do List
+
Organize your tasks efficiently with our Todo List app.
+
+
+ );
+}
+
+export default LandingPage;
diff --git a/src/components/Task.js b/src/components/Task.js
new file mode 100644
index 0000000..6cd605a
--- /dev/null
+++ b/src/components/Task.js
@@ -0,0 +1,100 @@
+import { useState } from 'react';
+import EditTask from './EditTask';
+
+function Task({ todo, taskView, handleView, handleEditList }) {
+ const [isEditing, setIsEditing] = useState(false);
+
+ const handleEdit = () => {
+ setIsEditing(true);
+ };
+
+ const handleCancel = () => {
+ setIsEditing(false);
+ };
+
+ return (
+ <>
+ {/* Main modal */}
+ {taskView && (
+
+
+ {/* Modal header */}
+
+
+ {todo.title}
+
+
+
+ {/* Modal body */}
+
+
+ {isEditing ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
{todo.title}
+
+
+
+
{todo.level}
+
+
+
+
{todo.user ? todo.user.name : "Not Assigned"}
+
+
+
+
{todo.startDate ? todo.startDate : "--:--:--"}
+
+
+
+
+
{todo.endDate ? todo.startDate : "--:--:--"}
+
+
+
+
{todo.description}
+
+
+
+
+
+
+ )
+ }
+ >
+ );
+
+}
+export default Task;
\ No newline at end of file
diff --git a/src/components/TodoItem.js b/src/components/TodoItem.js
new file mode 100644
index 0000000..5570239
--- /dev/null
+++ b/src/components/TodoItem.js
@@ -0,0 +1,51 @@
+import React, { useState } from "react";
+import Task from "./Task";
+
+function TodoItem({ todoId, todo, handleDelete, handleEditList }) {
+ const [isDone, setDone] = useState(todo.done);
+ const [taskView, setTaskView] = useState(false);
+
+ const handleDone = () => {
+ setDone((prevDone) => !prevDone); // Use functional state update for consistency
+ handleEditList({ ...todo, done: !isDone });
+ };
+
+ const handleView = () => {
+ setTaskView((prevView) => !prevView); // Functional state update
+ };
+
+ return (
+
+
+
+
+ {todo.title}
+
+
+ handleDelete(todoId)}
+ className="text-sm text-red-500 hover:underline"
+ >
+ Delete
+
+ {taskView && (
+
+ )}
+
+ );
+}
+
+export default TodoItem;
diff --git a/src/components/TodoList.js b/src/components/TodoList.js
new file mode 100644
index 0000000..93663b2
--- /dev/null
+++ b/src/components/TodoList.js
@@ -0,0 +1,110 @@
+import { useState, useEffect } from "react";
+import TodoItem from "./TodoItem";
+import AddTask from "./AddTask";
+
+function TodoList({ todoData }) {
+ const options = ["All", "Active", "Completed"];
+
+ const [todoList, setTodoList] = useState(todoData);
+ const [listType, setType] = useState("All");
+ const [filteredList, setFilteredList] = useState(todoList);
+ const [searchQuery, setSearchQuery] = useState("");
+
+ const handleSearch = (event) => {
+ const query = event.target.value;
+ setSearchQuery(query);
+
+ const searchList = todoList.filter((todo) => {
+ return todo.title.toLowerCase().indexOf(query.toLowerCase()) !== -1;
+ });
+
+ setFilteredList(searchList);
+ };
+
+ const handleDelete = (todoId) => {
+ console.log(todoId);
+ const updatedList = todoList.filter((item) => item.id !== todoId);
+ console.log(updatedList);
+ setTodoList(updatedList);
+
+ if (listType === "Completed") {
+ setFilteredList(updatedList.filter(todo => todo.done));
+ } else if (listType === "Active") {
+ setFilteredList(updatedList.filter(todo => !todo.done));
+ } else {
+ setFilteredList(updatedList);
+ }
+ };
+
+ const handleEditList = (updatedTask) => {
+ console.log(todoList);
+ console.log(updatedTask);
+ setTodoList((todoList) =>
+ todoList.map((todo) =>
+ todo.id === updatedTask.id ? updatedTask : todo
+ )
+ );
+ console.log(todoList);
+
+ };
+
+ const handleSelect = (type) => {
+ setType(type);
+ if (type === "All") {
+ setFilteredList(todoList);
+ } else if (type === "Completed") {
+ setFilteredList(todoList.filter(todo => todo.done));
+ } else if (type === "Active") {
+ setFilteredList(todoList.filter(todo => !todo.done));
+ }
+ }
+
+ return (
+
+
+
+
+
+ {options.map((type, index) => (
+ - handleSelect(type)}
+ className={`cursor-pointer text-gray-600 hover:text-gray-900 ${listType === type ? "font-bold text-blue-600" : ""
+ }`}
+ >
+ {type}
+
+ ))}
+
+ {
+ filteredList.map((todo) => (
+
+ ))
+ }
+
+
+ );
+}
+
+export default TodoList;
diff --git a/src/index.css b/src/index.css
index ec2585e..a1ef556 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,4 +1,8 @@
-body {
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+/* body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
@@ -10,4 +14,4 @@ body {
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
-}
+} */
\ No newline at end of file
diff --git a/src/todoData.js b/src/todoData.js
index d12d26f..386eed3 100644
--- a/src/todoData.js
+++ b/src/todoData.js
@@ -2,7 +2,7 @@ const todoData = [
{
id: 1,
title: "Go bungee jumping",
- done: false,
+ done: true,
},
{
id: 2,
@@ -17,12 +17,12 @@ const todoData = [
{
id: 4,
title: "Write a book",
- done: false,
+ done: true,
},
{
id: 5,
title: "Travel to every continent",
- done: false,
+ done: true,
},
{
id: 6,
diff --git a/src/usersData.js b/src/usersData.js
new file mode 100644
index 0000000..9587c45
--- /dev/null
+++ b/src/usersData.js
@@ -0,0 +1,22 @@
+export const users = [
+ {
+ id: 1,
+ name: "Alex"
+ },
+ {
+ id: 2,
+ name: "John"
+ },
+ {
+ id: 3,
+ name: "Jessica"
+ },
+ {
+ id: 4,
+ name: "Marco"
+ },
+ {
+ id: 5,
+ name: "Rebecca"
+ }
+]
\ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..e5b64f3
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,9 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ["./src/**/*.{html,js}"],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
+