Skip to content

Commit b3e98d0

Browse files
committed
feat: delete, mark as completed and update ui on real time
1 parent 73b8825 commit b3e98d0

File tree

7 files changed

+78
-20
lines changed

7 files changed

+78
-20
lines changed

app/page.tsx

+19-16
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,40 @@ import DarkModeToggler from "@/components/DarkModeToggler"
33
import Form from "@/components/Form"
44
import TodosContents from "@/components/TodosContents"
55
import ThemeProvider from "@/provider/ThemeProvider"
6+
import TodoProvider from "@/provider/TodoProvider"
67

78
const Home = () => {
89

910
return (
1011
<ThemeProvider>
11-
<main className="bg-bg h-screen">
12+
<TodoProvider>
13+
<main className="bg-bg h-screen">
1214

13-
<BackgroundImage />
15+
<BackgroundImage />
1416

15-
<section className="container relative max-w-2xl mx-auto p-5">
17+
<section className="container relative max-w-2xl mx-auto p-5">
1618

17-
<div className="flex items-center justify-between sm:pt-16 pt-8">
18-
<h1 className="uppercase tracking-widest md:text-4xl text-2xl font-bold text-white">
19-
Todo
20-
</h1>
19+
<div className="flex items-center justify-between sm:pt-16 pt-8">
20+
<h1 className="uppercase tracking-widest md:text-4xl text-2xl font-bold text-white">
21+
Todo
22+
</h1>
2123

22-
<DarkModeToggler />
24+
<DarkModeToggler />
2325

24-
</div>
26+
</div>
2527

26-
<div className="bg-card-bg rounded-md shadow-lg px-5 py-2 mt-8">
27-
<Form />
28-
</div>
28+
<div className="bg-card-bg rounded-md shadow-lg px-5 py-2 mt-8">
29+
<Form />
30+
</div>
2931

30-
<TodosContents />
32+
<TodosContents />
3133

32-
</section>
34+
</section>
3335

34-
<p className="text-grayish-text text-center md:mt-0 pb-10 mt-20">Drag and drop yo reorder list</p>
36+
<p className="text-grayish-text text-center md:mt-0 pb-10 mt-20">Drag and drop yo reorder list</p>
3537

36-
</main>
38+
</main>
39+
</TodoProvider>
3740
</ThemeProvider>
3841
)
3942
}

components/Form.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
'use client'
2+
import { TodoContext } from '@/context/TodoContext'
23
import React from 'react'
34

45
const Form = () => {
56

67
const [todo, setTodo] = React.useState('')
78
const [todos, setTodos] = React.useState<TodoType[]>([])
89

10+
const { isManipulated, setIsManipulated } = React.useContext(TodoContext)
11+
912
React.useEffect(() => {
13+
setIsManipulated(false)
1014
const todos = JSON.parse(localStorage.getItem('todos') || '[]')
1115
setTodos(todos)
12-
}, [])
16+
}, [isManipulated])
1317

1418
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
1519
e.preventDefault()
@@ -24,6 +28,7 @@ const Form = () => {
2428

2529
todos.unshift(newTodo)
2630
localStorage.setItem('todos', JSON.stringify(todos))
31+
setIsManipulated(true)
2732

2833
setTodo('')
2934
}

components/ListItem.tsx

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,34 @@
1+
'use client'
2+
import React from 'react'
13
import Image from 'next/image'
4+
import { TodoContext } from '@/context/TodoContext'
5+
6+
const ListItem = ({ id, content, completed, todos }: ListItemProps) => {
7+
8+
const { setIsManipulated } = React.useContext(TodoContext)
9+
10+
const handleChange = () => {
11+
const todo = todos.find(todo => todo.id === Number(id))
12+
todo!.completed = !todo?.completed
13+
localStorage.setItem('todos', JSON.stringify(todos))
14+
setIsManipulated(true)
15+
}
16+
17+
const deleteItem = () => {
18+
const newTodos = todos.filter(todo => todo.id !== Number(id))
19+
localStorage.setItem('todos', JSON.stringify(newTodos))
20+
setIsManipulated(true)
21+
}
222

3-
const ListItem = ({ id, content }: ListItemProps) => {
423
return (
524
<>
625
<div className="todo_item flex items-center justify-between w-full group px-5 py-2 relative">
726
<div>
827
<input
28+
onChange={handleChange}
929
id={id}
1030
type="checkbox"
31+
checked={completed}
1132
className="todo_checkbox appearance-none h-0 cursor-pointer
1233
before:h-6 before:w-6 before:rounded-full
1334
before:border before:border-divider
@@ -35,7 +56,7 @@ const ListItem = ({ id, content }: ListItemProps) => {
3556
</label>
3657
</div>
3758

38-
<button className="group-hover:block hidden" aria-label="delete todo item">
59+
<button onClick={deleteItem} className="group-hover:block hidden" aria-label="delete todo item">
3960
<Image src='/images/icon-cross.svg' height={15} width={15} alt="" />
4061
</button>
4162

components/TodosContents.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@
22
import React from 'react'
33
import ListItem from './ListItem'
44
import ListControls from './ListControls'
5+
import { TodoContext } from '@/context/TodoContext'
56

67
const TodosContainer = () => {
78

89
const [todos, setTodos] = React.useState<TodoType[]>([])
910
const [loading, setLoading] = React.useState(true)
1011

12+
const { isManipulated, setIsManipulated } = React.useContext(TodoContext)
13+
1114
React.useEffect(() => {
15+
setIsManipulated(false)
1216
const todos = JSON.parse(localStorage.getItem('todos') || '[]')
1317
setTodos(todos)
1418
setLoading(false)
15-
}, [])
19+
}, [isManipulated])
1620

1721
const renderTodos = () => {
1822

@@ -27,6 +31,7 @@ const TodosContainer = () => {
2731
id={todo.id.toString()}
2832
content={todo.content}
2933
completed={todo.completed}
34+
todos={todos}
3035
/>
3136
)
3237
})

context/TodoContext.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use client'
2+
import React from 'react'
3+
4+
export const TodoContext = React.createContext({
5+
isManipulated: false,
6+
setIsManipulated: (isManipulated: boolean) => { },
7+
})

provider/TodoProvider.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use client'
2+
import React from 'react'
3+
import { TodoContext } from '@/context/TodoContext'
4+
5+
const TodoProvider = ({ children }: ChildrenProps) => {
6+
7+
const [isManipulated, setIsManipulated] = React.useState(false)
8+
9+
return (
10+
<TodoContext.Provider value={{ isManipulated, setIsManipulated }}>
11+
{children}
12+
</TodoContext.Provider>
13+
)
14+
}
15+
16+
export default TodoProvider

types/types.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type ListItemProps = {
66
id: string,
77
content: string,
88
completed: boolean,
9+
todos: TodoType[],
910
}
1011

1112
type TodoType = {

0 commit comments

Comments
 (0)