diff --git a/index.html b/index.html
index f7ac4e4..fcd932a 100644
--- a/index.html
+++ b/index.html
@@ -4,6 +4,11 @@
+
+
+
+
+
Todo
diff --git a/package.json b/package.json
index caf6289..8faa9b3 100644
--- a/package.json
+++ b/package.json
@@ -10,8 +10,11 @@
"preview": "vite preview"
},
"dependencies": {
+ "lottie-react": "^2.4.1",
+ "moment": "^2.30.1",
"react": "^19.0.0",
- "react-dom": "^19.0.0"
+ "react-dom": "^19.0.0",
+ "zustand": "^5.0.5"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
diff --git a/src/App.css b/src/App.css
new file mode 100644
index 0000000..630835d
--- /dev/null
+++ b/src/App.css
@@ -0,0 +1,22 @@
+.main {
+ padding: 20px 100px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.innerMain {
+ border: 1px solid black;
+ width: 400px;
+}
+
+h1 {
+ color: black;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 70px;
+ font-family: "Rampart One", sans-serif;
+ font-weight: 400;
+}
diff --git a/src/App.jsx b/src/App.jsx
index 5427540..ee7863c 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,5 +1,17 @@
+import NewTask from "./components/NewTask";
+import StatusBar from "./components/StatusBar";
+import TaskList from "./components/TaskList";
+import "./App.css";
+
export const App = () => {
return (
- React Boilerplate
- )
-}
+
+ );
+};
diff --git a/src/components/NewTask.css b/src/components/NewTask.css
new file mode 100644
index 0000000..cd02d59
--- /dev/null
+++ b/src/components/NewTask.css
@@ -0,0 +1,10 @@
+.toDoBox {
+ border: 1px solid black;
+ background-color: #eee;
+ box-shadow: 0.25rem 0.25rem rgba(12, 23, 14, 0.388);
+ display: flex;
+ flex-direction: column;
+ padding: 1rem;
+ margin: 1rem;
+ gap: 10px;
+}
diff --git a/src/components/NewTask.jsx b/src/components/NewTask.jsx
new file mode 100644
index 0000000..df4eef4
--- /dev/null
+++ b/src/components/NewTask.jsx
@@ -0,0 +1,34 @@
+import React, { useState } from "react";
+import { useNoteStore } from "../store";
+import "./NewTask.css";
+
+const NewTask = () => {
+ const [toDo, setToDo] = useState("");
+
+ const { addNewTask } = useNoteStore();
+
+ const addToDo = () => {
+ if (toDo) {
+ addNewTask(toDo);
+ }
+ setToDo("");
+ };
+
+ return (
+
+ );
+};
+
+export default NewTask;
diff --git a/src/components/StatusBar.css b/src/components/StatusBar.css
new file mode 100644
index 0000000..4a1f91b
--- /dev/null
+++ b/src/components/StatusBar.css
@@ -0,0 +1,17 @@
+.statusBar {
+ border: 1px solid black;
+ background-color: #b9b8b4;
+ box-shadow: 0.25rem 0.25rem rgba(12, 23, 14, 0.388);
+ display: flex;
+ flex-direction: row;
+ padding: 1rem;
+ margin: 1rem;
+ gap: 10px;
+ justify-content: space-around;
+}
+
+.actionButton {
+ border-radius: 5px;
+ padding: 2px;
+ background-color: #2febe5;
+}
diff --git a/src/components/StatusBar.jsx b/src/components/StatusBar.jsx
new file mode 100644
index 0000000..4abcb16
--- /dev/null
+++ b/src/components/StatusBar.jsx
@@ -0,0 +1,22 @@
+import React from "react";
+import { useNoteStore } from "../store";
+
+import "./StatusBar.css";
+
+const StatusBar = () => {
+ const { todos, checkAllTasks, removeAllDoneTasks } = useNoteStore();
+
+ return (
+
+ {todos.length} tasks
+
+
+
+ );
+};
+
+export default StatusBar;
diff --git a/src/components/Task.css b/src/components/Task.css
new file mode 100644
index 0000000..f5569e8
--- /dev/null
+++ b/src/components/Task.css
@@ -0,0 +1,33 @@
+.taskBox {
+ border: 1px solid black;
+ background-color: #74cd07;
+ box-shadow: 0.25rem 0.25rem rgba(12, 23, 14, 0.388);
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ justify-content: space-around;
+}
+
+.taskDone {
+ background-color: #c5c3c1;
+}
+
+.taskDetails {
+ background-color: rgba(112, 82, 41, 0.363);
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+}
+
+.taskMain {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ padding: 0.1rem 0.2rem;
+}
+
+.removeButton {
+ border-radius: 5px;
+ padding: 2px;
+ background-color: #b0d790;
+}
diff --git a/src/components/Task.jsx b/src/components/Task.jsx
new file mode 100644
index 0000000..07e86b9
--- /dev/null
+++ b/src/components/Task.jsx
@@ -0,0 +1,41 @@
+import React from "react";
+import { useNoteStore } from "../store";
+import moment from "moment";
+
+import "./Task.css";
+
+const Task = ({ todo }) => {
+ const { toggleChecked, removeTask } = useNoteStore();
+
+ const toggle = (todo) => {
+ toggleChecked(todo.text, todo.date);
+ };
+
+ return (
+
+
+ {todo.text}
+
+
+
+ {moment(todo.date).fromNow()}
+
+
+
+ );
+};
+
+export default Task;
diff --git a/src/components/TaskList.css b/src/components/TaskList.css
new file mode 100644
index 0000000..4f8eab8
--- /dev/null
+++ b/src/components/TaskList.css
@@ -0,0 +1,10 @@
+.taskList {
+ border: 1px solid black;
+ background-color: #f1daa9;
+ display: flex;
+ flex-direction: column;
+ padding: 1rem;
+ margin: 1rem;
+ gap: 10px;
+ justify-content: space-around;
+}
diff --git a/src/components/TaskList.jsx b/src/components/TaskList.jsx
new file mode 100644
index 0000000..dbebea1
--- /dev/null
+++ b/src/components/TaskList.jsx
@@ -0,0 +1,17 @@
+import React from "react";
+import Task from "./Task";
+import { useNoteStore } from "../store";
+import "./TaskList.css";
+
+const TaskList = () => {
+ const { todos } = useNoteStore();
+ return (
+
+ {todos.map((todo) => (
+
+ ))}
+
+ );
+};
+
+export default TaskList;
diff --git a/src/index.css b/src/index.css
index f7c0aef..11430b3 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,3 +1,9 @@
:root {
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ font-family: "Handlee", Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
}
diff --git a/src/store.jsx b/src/store.jsx
new file mode 100644
index 0000000..4325709
--- /dev/null
+++ b/src/store.jsx
@@ -0,0 +1,83 @@
+import moment from "moment";
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+
+export const useNoteStore = create( persist( (set) => {
+ return {
+ todos: [
+ {
+ text: "test",
+ date: moment.now(),
+ checked: false,
+ },
+ {
+ text: "test2",
+ date: moment.now(),
+ checked: true,
+ },
+ ],
+ addNewTask: (newTodo) =>
+ set((state) => {
+ const newTodos = [...state.todos];
+ newTodos.push({ text: newTodo, date: moment.now(), checked: false });
+ return { todos: newTodos };
+ }),
+ removeTask: (todotext, date) =>
+ set((state) => {
+ const newTodos = [];
+ for (const index in state.todos) {
+ const todo = state.todos[index];
+ if (todotext === todo.text && date === todo.date) {
+ // skip
+ } else {
+ newTodos.push(todo);
+ }
+ }
+ return { todos: newTodos };
+ }),
+ toggleChecked: (todotext, date) =>
+ set((state) => {
+ const newTodos = [];
+ for (const index in state.todos) {
+ const todo = state.todos[index];
+ if (todotext === todo.text && date === todo.date) {
+ newTodos.push({
+ text: todo.text,
+ date: todo.date,
+ checked: !todo.checked,
+ });
+ } else {
+ newTodos.push(todo);
+ }
+ }
+ return { todos: newTodos };
+ }),
+ checkAllTasks: () =>
+ set((state) => {
+ const newTodos = [];
+ for (const index in state.todos) {
+ const todo = state.todos[index];
+ newTodos.push({
+ text: todo.text,
+ date: todo.date,
+ checked: true,
+ });
+ }
+ return { todos: newTodos };
+ }),
+ removeAllDoneTasks: () =>
+ set((state) => {
+ const newTodos = [];
+ for (const index in state.todos) {
+ const todo = state.todos[index];
+ if (todo.checked === false) {
+ newTodos.push(todo);
+ }
+ }
+ return { todos: newTodos };
+ }),
+ };
+}, {
+ name: 'todo-tasks'
+}
+));