Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
react-todo
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Manivasagam S
react-todo
Commits
69a4433d
Commit
69a4433d
authored
May 13, 2025
by
Manivasagam S
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new code update
parent
63cb6e09
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
174 additions
and
55 deletions
+174
-55
index.html
index.html
+6
-0
App.jsx
src/App.jsx
+4
-1
Todo.module.css
src/Styles/Todo.module.css
+11
-3
TodoForm.module.css
src/Styles/TodoForm.module.css
+34
-27
TodoItem.module.css
src/Styles/TodoItem.module.css
+53
-2
TodoList.module.css
src/Styles/TodoList.module.css
+1
-2
todo.js
src/api/todo.js
+1
-1
TodoForm.jsx
src/component/TodoForm.jsx
+5
-3
TodoItem.jsx
src/component/TodoItem.jsx
+41
-7
db.json
src/db.json
+6
-6
Todo.jsx
src/pages/Todo.jsx
+12
-3
No files found.
index.html
View file @
69a4433d
...
...
@@ -5,6 +5,12 @@
<link
rel=
"icon"
type=
"image/svg+xml"
href=
"/vite.svg"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<title>
Vite + React
</title>
<style>
#root
{
display
:
flex
;
justify-content
:
center
;
}
</style>
</head>
<body>
<div
id=
"root"
></div>
...
...
src/App.jsx
View file @
69a4433d
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
Todo
from
"./pages/Todo"
;
function
App
()
{
return
<
Todo
/>;
return
(
<
Todo
/>
)
}
export
default
App
;
src/Styles/Todo.module.css
View file @
69a4433d
...
...
@@ -2,17 +2,25 @@
margin
:
0
;
padding
:
0
;
}
body
{
background-color
:
#f5f5f5
;
background-image
:
radial-gradient
(
#ccc
0.5px
,
transparent
1px
);
background-size
:
10px
10px
;
}
}
.wrapper
{
height
:
100vh
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
width
:
90%
;
box-sizing
:
border-box
;
}
.container
{
max-width
:
34.375rem
;
width
:
90%
;
margin
:
200px
auto
;
/* margin: 200px auto; */
background
:
#fff
;
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0.1
);
box-sizing
:
border-box
;
...
...
src/Styles/TodoForm.module.css
View file @
69a4433d
.form
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
12px
;
justify-content
:
space-evenly
;
padding
:
0.438rem
;
padding-bottom
:
1.5rem
;
padding-top
:
5px
;
padding-left
:
1rem
;
padding-right
:
1.1rem
;
gap
:
15px
;
padding
:
1rem
;
}
.input-wrapper
{
box-sizing
:
border-box
;
}
.input
{
border-radius
:
3px
;
border
:
1px
solid
#dbd8d8
;
box-shadow
:
inset
0
0
4px
rgba
(
93
,
81
,
81
,
0.2
),
0
0
4px
rgba
(
233
,
228
,
228
,
0.1
);
height
:
2.063rem
;
width
:
100%
;
max-width
:
24rem
;
font-size
:
1.063rem
;
padding
:
6px
10px
;
font-size
:
1rem
;
padding
:
1rem
0.7rem
;
transition
:
all
0.3s
ease
;
padding-left
:
rem
;
box-sizing
:
border-box
;
width
:
100%
;
max-width
:
100%
;
}
.input
:focus
{
...
...
@@ -28,7 +27,7 @@
border
:
1px
solid
#acbbcb
;
}
.inputError
{
.inputError
{
border-color
:
rgb
(
216
,
76
,
76
);
}
...
...
@@ -38,30 +37,38 @@
background
:
#fff
;
cursor
:
pointer
;
color
:
#333
;
padding
:
1
0px
;
padding
:
1
rem
2rem
;
font-size
:
0.938rem
;
width
:
5.625rem
;
height
:
2.940rem
;
max-height
:
3.25rem
;
/* min-width: 150px; */
max-width
:
100%
;
flex-grow
:
1
;
}
.errorText
{
display
:
flex
;
display
:
block
;
color
:
rgb
(
216
,
76
,
76
);
font-size
:
0.875rem
;
padding
:
1px
0px
10px
2
0px
;
padding
-block
:
1
0px
;
width
:
100%
;
max-width
:
25rem
;
margin-top
:
-13
px
;
padding-left
:
2
px
;
}
::placeholder
{
font-size
:
0.938rem
;
}
@media
(
max-width
:
768px
)
{
.input
{
max-width
:
35rem
;
}
.input-wrapper
{
max-width
:
100%
;
width
:
100%
;
}
@media
(
min-width
:
540px
)
{
.input-wrapper
{
max-width
:
auto
;
width
:
auto
;
flex-grow
:
1
;
}
.button
{
flex-grow
:
0
;
}
}
src/Styles/TodoItem.module.css
View file @
69a4433d
...
...
@@ -44,6 +44,7 @@
height
:
1.125rem
;
min-width
:
2.25rem
;
cursor
:
pointer
;
margin-top
:
2px
}
.listButton
{
...
...
@@ -59,12 +60,11 @@
cursor
:
pointer
;
color
:
#999
;
transition
:
color
0.2s
ease
;
margin-top
:
4px
;
}
.deletebutton
:hover
{
color
:
#e74c3c
;
}
.error
{
color
:
red
;
font-size
:
0.9rem
;
...
...
@@ -73,3 +73,53 @@
margin-right
:
auto
;
width
:
790rem
;
}
.modalOverlay
{
position
:
fixed
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
background-color
:
rgba
(
13
,
13
,
13
,
0.4
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
.modal
{
background-color
:
white
;
padding
:
2rem
2rem
;
border-radius
:
8px
;
text-align
:
center
;
max-width
:
auto
;
}
.modalButtons
{
display
:
flex
;
justify-content
:
space-around
;
flex-direction
:
column
;
margin-top
:
1rem
;
gap
:
5px
}
.confirmButton
,
.cancelButton
{
padding
:
0.6rem
2rem
;
border
:
none
;
border-radius
:
4px
;
cursor
:
pointer
;
}
.confirmButton
{
background-color
:
#e53935
;
color
:
white
;
padding
:
0.6rem
2.5rem
;
}
.cancelButton
{
background-color
:
#ccc
;
}
@media
(
min-width
:
540px
){
.modalButtons
{
display
:
flex
;
flex-direction
:
row
;
}
}
\ No newline at end of file
src/Styles/TodoList.module.css
View file @
69a4433d
...
...
@@ -2,8 +2,7 @@
ul
{
margin
:
0
;
padding
:
0
;
max-height
:
15.625rem
;
max-height
:
84vh
;
overflow-y
:
auto
;
scroll-behavior
:
smooth
;
}
src/api/todo.js
View file @
69a4433d
import
axios
from
"axios"
;
const
URL
=
"http://192.168.1.59:
4
000/todos"
;
const
URL
=
"http://192.168.1.59:
3
000/todos"
;
export
const
getTodos
=
()
=>
axios
.
get
(
URL
);
export
const
addTodo
=
(
newTodo
)
=>
axios
.
post
(
URL
,
newTodo
);
export
const
deleteTodo
=
(
id
)
=>
axios
.
delete
(
`
${
URL
}
/
${
id
}
`
);
...
...
src/component/TodoForm.jsx
View file @
69a4433d
import
React
from
"react"
;
import
styles
from
"../styles/TodoForm.module.css"
;
const
TodoForm
=
({
input
,
error
,
setInput
,
handleSubmit
})
=>
{
const
TodoForm
=
({
input
,
error
,
handleInputChange
,
handleSubmit
})
=>
{
return
(
<
div
>
<
form
className=
{
styles
.
form
}
onSubmit=
{
handleSubmit
}
>
<
div
className=
{
styles
[
'input-wrapper'
]
}
>
<
input
type=
"text"
value=
{
input
}
className=
{
`${styles.input} ${error ? styles.inputError : ""}`
}
placeholder=
"Enter Item"
onChange=
{
(
e
)
=>
setInput
(
e
.
target
.
value
)
}
onChange=
{
handleInputChange
}
/>
{
error
&&
<
div
className=
{
styles
.
errorText
}
>
{
error
}
</
div
>
}
</
div
>
<
button
type=
"submit"
className=
{
styles
.
button
}
>
Submit
</
button
>
</
form
>
{
error
&&
<
div
className=
{
styles
.
errorText
}
>
{
error
}
</
div
>
}
</
div
>
);
};
...
...
src/component/TodoItem.jsx
View file @
69a4433d
import
React
from
"react"
;
import
React
,
{
useState
,
useEffect
}
from
"react"
;
import
{
TiDelete
}
from
"react-icons/ti"
;
import
styles
from
"../styles/TodoItem.module.css"
;
const
TodoItem
=
({
item
,
handleToggleComplete
,
handleUpdate
,
handleDelete
,
error
})
=>
(
const
TodoItem
=
({
item
,
handleToggleComplete
,
handleUpdate
,
handleDelete
,
error
})
=>
{
const
[
showConfirm
,
setShowConfirm
]
=
useState
(
false
);
const
[
text
,
setText
]
=
useState
(
item
.
text
);
useEffect
(()
=>
{
const
handler
=
setTimeout
(()
=>
{
if
(
text
!==
item
.
text
)
{
handleUpdate
(
item
.
id
,
text
);
}
},
1000
);
return
()
=>
{
clearTimeout
(
handler
);
};
},
[
text
,
item
.
id
,
item
.
text
,
handleUpdate
]);
const
confirmDelete
=
()
=>
{
handleDelete
(
item
.
id
);
setShowConfirm
(
false
);
};
return
(
<
li
className=
{
styles
.
list
}
>
<
input
type=
"checkbox"
checked=
{
item
.
completed
}
onChange=
{
()
=>
handleToggleComplete
(
item
.
id
,
!
item
.
completed
)
}
onChange=
{
()
=>
handleToggleComplete
(
item
.
id
,
!
item
.
completed
)
}
className=
{
styles
.
listCheckbox
}
/>
<
input
type=
"text"
value=
{
item
.
text
}
value=
{
text
}
onChange=
{
(
e
)
=>
setText
(
e
.
target
.
value
)
}
className=
{
`${styles.todoContent} ${item.completed ? styles.todoContentCompleted : ""}`
}
onChange=
{
(
e
)
=>
handleUpdate
(
item
.
id
,
e
.
target
.
value
)
}
/>
{
error
&&
<
div
className=
{
styles
.
error
}
>
{
error
}
</
div
>
}
<
button
onClick=
{
()
=>
handleDelete
(
item
.
id
)
}
className=
{
styles
.
listButton
}
>
<
button
onClick=
{
()
=>
setShowConfirm
(
true
)
}
className=
{
styles
.
listButton
}
>
<
TiDelete
className=
{
styles
.
deletebutton
}
/>
</
button
>
{
showConfirm
&&
(
<
div
className=
{
styles
.
modalOverlay
}
>
<
div
className=
{
styles
.
modal
}
>
<
p
>
Are you sure you want to delete this todo?
</
p
>
<
div
className=
{
styles
.
modalButtons
}
>
<
button
onClick=
{
confirmDelete
}
className=
{
styles
.
confirmButton
}
>
OK
</
button
>
<
button
onClick=
{
()
=>
setShowConfirm
(
false
)
}
className=
{
styles
.
cancelButton
}
>
Cancel
</
button
>
</
div
>
</
div
>
</
div
>
)
}
</
li
>
);
);
};
export
default
TodoItem
;
src/db.json
View file @
69a4433d
{
"todos"
:
[
{
"id"
:
"
9a22
"
,
"text"
:
"
Buy Groceries Tomorrow
"
,
"id"
:
"
f87f
"
,
"text"
:
"
vjbdcbdxcvfdvdvfvfxvfrgrv
"
,
"completed"
:
false
},
{
"id"
:
"
58ea
"
,
"text"
:
"
Travel to Head Office
"
,
"id"
:
"
ed2b
"
,
"text"
:
"
bbbzdfbdfff
"
,
"completed"
:
false
},
{
"id"
:
"
1ad0
"
,
"text"
:
"
Get phone from the repair shop
"
,
"id"
:
"
f779
"
,
"text"
:
"
qwdhmm
"
,
"completed"
:
false
}
]
...
...
src/pages/Todo.jsx
View file @
69a4433d
...
...
@@ -13,14 +13,21 @@ function Todo() {
useEffect
(()
=>
{
getTodos
().
then
((
res
)
=>
setTodos
(
res
.
data
));
},
[]);
const
handleInputChange
=
(
e
)
=>
{
setInput
(
e
.
target
.
value
);
if
(
e
.
target
.
value
.
trim
()
!==
""
){
setError
(
""
);
}
};
const
handleSubmit
=
async
(
e
)
=>
{
e
.
preventDefault
();
if
(
input
.
trim
()
===
""
)
{
setError
(
"Please fill this field"
);
setTimeout
(()
=>
setError
(
""
),
3000
);
return
;
}
setError
(
""
);
try
{
const
newTodo
=
{
text
:
input
,
completed
:
false
};
const
res
=
await
addTodo
(
newTodo
);
...
...
@@ -74,6 +81,7 @@ const handleSubmit = async (e) => {
};
return
(
<
div
className=
{
styles
.
wrapper
}
>
<
div
className=
{
styles
.
container
}
>
<
h1
className=
{
styles
.
title
}
>
You have
{
todos
.
length
}
{
todos
.
length
===
1
?
"Todo"
:
"Todos"
}
...
...
@@ -83,7 +91,8 @@ const handleSubmit = async (e) => {
)
:
(
<
TodoList
todos=
{
todos
}
handleToggleComplete=
{
handleToggleComplete
}
handleUpdate=
{
handleUpdate
}
handleDelete=
{
handleDelete
}
updateErrors=
{
updateErrors
}
/>
)
}
<
TodoForm
input=
{
input
}
error=
{
error
}
setInput=
{
setInput
}
handleSubmit=
{
handleSubmit
}
/>
<
TodoForm
input=
{
input
}
error=
{
error
}
handleInputChange=
{
handleInputChange
}
handleSubmit=
{
handleSubmit
}
/>
</
div
>
</
div
>
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment