diff --git a/README.md b/README.md
index d1c68b5..4172b2c 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
-# Todo
\ No newline at end of file
+# Todo
+https://nowapp.netlify.app/
\ No newline at end of file
diff --git a/package.json b/package.json
index caf6289..1f583a3 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,8 @@
},
"dependencies": {
"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.jsx b/src/App.jsx
index 5427540..a3ffff2 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,5 +1,16 @@
+
+import { Header } from './components/Header';
+import { TodoForm } from './components/TodoForm';
+import { TodoList } from './components/TodoList';
+import './index.css';
+
export const App = () => {
return (
-
React Boilerplate
+
+
+
+
+
+
)
-}
+}
\ No newline at end of file
diff --git a/src/Store/useTodoStore.jsx b/src/Store/useTodoStore.jsx
new file mode 100644
index 0000000..479b2da
--- /dev/null
+++ b/src/Store/useTodoStore.jsx
@@ -0,0 +1,24 @@
+import { create } from 'zustand';
+import { nanoid } from 'nanoid';
+
+export const useTodoStore = create((set) => ({
+ tasks: [
+ { id: nanoid(), title: 'Your first task is to find what feels effortless to you.', completed: false },
+ { id: nanoid(), title: 'Your second task is to put maximum effort into it.', completed: false },
+ ],
+ addTask: (title) =>
+ set((state) => ({
+ tasks: [...state.tasks, { id: nanoid(), title, completed: false }],
+ })),
+ removeTask: (id) =>
+ set((state) => ({
+ tasks: state.tasks.filter((task) => task.id !== id),
+ })),
+ toggleTask: (id) =>
+ set((state) => ({
+ tasks: state.tasks.map((task) =>
+ task.id === id ? { ...task, completed: !task.completed } : task
+ ),
+ })),
+}))
+
diff --git a/src/components/EmptyState.jsx b/src/components/EmptyState.jsx
new file mode 100644
index 0000000..05c0db8
--- /dev/null
+++ b/src/components/EmptyState.jsx
@@ -0,0 +1,8 @@
+import { React } from 'react';
+
+
+export const EmptyState = () => (
+
+
No tasks. Add one or two!
+
+)
\ No newline at end of file
diff --git a/src/components/Header.jsx b/src/components/Header.jsx
new file mode 100644
index 0000000..637583e
--- /dev/null
+++ b/src/components/Header.jsx
@@ -0,0 +1,13 @@
+import { useTodoStore } from '../Store/useTodoStore';
+
+export const Header = () => {
+ const tasks = useTodoStore((state) => state.tasks);
+ const incomplete = tasks.filter((t) => !t.completed).length;
+
+ return (
+
+ );
+}
diff --git a/src/components/TodoForm.jsx b/src/components/TodoForm.jsx
new file mode 100644
index 0000000..fc3acfb
--- /dev/null
+++ b/src/components/TodoForm.jsx
@@ -0,0 +1,29 @@
+import React, { useState } from 'react';
+import { useTodoStore } from '../Store/useTodoStore';
+
+export const TodoForm = () => {
+ const [title, setTitle] = useState('');
+ const addTask = useTodoStore((state) => state.addTask);
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ if (!title.trim()) return;
+ addTask(title);
+ setTitle('');
+ };
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/TodoItem.jsx b/src/components/TodoItem.jsx
new file mode 100644
index 0000000..d162dc2
--- /dev/null
+++ b/src/components/TodoItem.jsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import { useTodoStore } from '../Store/useTodoStore';
+
+export const TodoItem = ({ task }) => {
+ const toggleTask = useTodoStore((state) => state.toggleTask);
+ const removeTask = useTodoStore((state) => state.removeTask);
+
+ return (
+
+ toggleTask(task.id)}
+ role="button"
+ tabIndex={0}
+ onKeyDown={(e) => e.key === 'Enter' && toggleTask(task.id)}
+ aria-label="Toggle task"
+ >
+ {task.title}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/TodoList.jsx b/src/components/TodoList.jsx
new file mode 100644
index 0000000..0ad8ce0
--- /dev/null
+++ b/src/components/TodoList.jsx
@@ -0,0 +1,37 @@
+import { React } from 'react';
+import { useTodoStore } from '../Store/useTodoStore';
+import { TodoItem } from './TodoItem';
+import { EmptyState } from './EmptyState';
+
+export const TodoList = () => {
+ const tasks = useTodoStore((state) => state.tasks);
+ const toggleTask = useTodoStore((state) => state.toggleTask);
+ const removeTask = useTodoStore((state) => state.removeTask);
+
+
+
+ if (tasks.length === 0) return ;
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/index.css b/src/index.css
index f7c0aef..4f91a3a 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,3 +1,99 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
}
+
+body {
+ margin: 0;
+ background-color: #f5f0e8;
+ color: #000;
+}
+
+.app-container {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 2rem;
+}
+
+h1 {
+ font-size: 4rem;
+ margin-bottom: 2.5rem;
+ font-family: libre;
+}
+
+p {
+ color: rgb(96, 95, 95);
+
+}
+
+
+
+.input-form {
+ padding: 2rem;
+ border-radius: 8px;
+ font-size: 1.5rem;
+ border-color: white;
+}
+
+.task-submit {
+ padding: 2rem;
+ border-color: white;
+ border-radius: 8px;
+ font-size: 1.5rem;
+}
+
+ul {
+ list-style-type: none;
+ font-size: 2rem;
+}
+
+.checkbox-wrapper {
+ display: flex;
+ align-items: center;
+ gap: 0.6rem;
+ cursor: pointer;
+}
+
+.checkbox-wrapper input[type="checkbox"] {
+ display: none;
+}
+
+.custom-checkbox {
+ width: 18px;
+ height: 18px;
+ border: 2px solid #7a6c5d;
+ border-radius: 4px;
+ background-color: transparent;
+ position: relative;
+ flex-shrink: 0;
+}
+
+.checkbox-wrapper input[type="checkbox"]:checked+.custom-checkbox::after {
+ content: "";
+ position: absolute;
+ top: 2px;
+ left: 5px;
+ width: 4px;
+ height: 8px;
+ border: solid #7a6c5d;
+ border-width: 0 2px 2px 0;
+ transform: rotate(45deg);
+}
+
+.task-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.4rem 0.6rem;
+ border-bottom: 1px solid #eee;
+ position: relative;
+}
+
+.delete-button {
+ height: 32px;
+ border: 2px solid #7a6c5d;
+ border-radius: 4px;
+ background-color: transparent;
+
+}
\ No newline at end of file