Commit 69a4433d by Manivasagam S

new code update

parent 63cb6e09
...@@ -5,6 +5,12 @@ ...@@ -5,6 +5,12 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title> <title>Vite + React</title>
<style>
#root{
display: flex;
justify-content: center;
}
</style>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
......
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import Todo from "./pages/Todo"; import Todo from "./pages/Todo";
function App() { function App() {
return <Todo />; return (
<Todo/>
)
} }
export default App; export default App;
...@@ -2,17 +2,25 @@ ...@@ -2,17 +2,25 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
body { body {
background-color: #f5f5f5; background-color: #f5f5f5;
background-image: radial-gradient(#ccc 0.5px, transparent 1px); background-image: radial-gradient(#ccc 0.5px, transparent 1px);
background-size: 10px 10px; background-size: 10px 10px;
}
}
.wrapper {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
width: 90%;
box-sizing: border-box;
}
.container { .container {
max-width: 34.375rem; max-width: 34.375rem;
width: 90%; width: 90%;
margin: 200px auto; /* margin: 200px auto; */
background: #fff; background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
box-sizing: border-box; box-sizing: border-box;
......
.form { .form {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 12px; gap: 15px;
justify-content: space-evenly; padding: 1rem;
padding: 0.438rem; }
padding-bottom: 1.5rem;
padding-top: 5px; .input-wrapper {
padding-left: 1rem; box-sizing: border-box;
padding-right: 1.1rem;
} }
.input { .input {
border-radius: 3px; border-radius: 3px;
border: 1px solid #dbd8d8; 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); box-shadow: inset 0 0 4px rgba(93, 81, 81, 0.2), 0 0 4px rgba(233, 228, 228, 0.1);
height: 2.063rem; font-size: 1rem;
width: 100%; padding: 1rem 0.7rem;
max-width: 24rem;
font-size: 1.063rem;
padding: 6px 10px;
transition: all 0.3s ease; transition: all 0.3s ease;
padding-left: rem; box-sizing: border-box;
width: 100%;
max-width: 100%;
} }
.input:focus { .input:focus {
...@@ -28,9 +27,9 @@ ...@@ -28,9 +27,9 @@
border: 1px solid #acbbcb; border: 1px solid #acbbcb;
} }
.inputError { .inputError {
border-color: rgb(216, 76, 76); border-color: rgb(216, 76, 76);
} }
.button { .button {
border: 1px solid #ccc; border: 1px solid #ccc;
...@@ -38,30 +37,38 @@ ...@@ -38,30 +37,38 @@
background: #fff; background: #fff;
cursor: pointer; cursor: pointer;
color: #333; color: #333;
padding: 10px ; padding: 1rem 2rem;
font-size: 0.938rem; font-size: 0.938rem;
width: 5.625rem; max-height: 3.25rem;
height: 2.940rem; /* min-width: 150px; */
max-width: 100%;
flex-grow: 1; flex-grow: 1;
} }
.errorText { .errorText {
display: flex; display: block;
color: rgb(216, 76, 76); color: rgb(216, 76, 76);
font-size: 0.875rem; font-size: 0.875rem;
padding:1px 0px 10px 20px; padding-block: 10px;
width: 100%; width: 100%;
max-width: 25rem; max-width: 25rem;
margin-top: -13px; padding-left: 2px;
} }
::placeholder { ::placeholder {
font-size: 0.938rem; font-size: 0.938rem;
} }
.input-wrapper{
@media (max-width:768px) { max-width: 100%;
.input{ width: 100%;
max-width: 35rem;
} }
} @media (min-width:540px) {
\ No newline at end of file .input-wrapper{
max-width: auto;
width: auto;
flex-grow: 1;
}
.button{
flex-grow: 0;
}
}
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
height: 1.125rem; height: 1.125rem;
min-width: 2.25rem; min-width: 2.25rem;
cursor: pointer; cursor: pointer;
margin-top:2px
} }
.listButton { .listButton {
...@@ -59,12 +60,11 @@ ...@@ -59,12 +60,11 @@
cursor: pointer; cursor: pointer;
color: #999; color: #999;
transition: color 0.2s ease; transition: color 0.2s ease;
margin-top: 4px;
} }
.deletebutton:hover { .deletebutton:hover {
color: #e74c3c; color: #e74c3c;
} }
.error { .error {
color: red; color: red;
font-size: 0.9rem; font-size: 0.9rem;
...@@ -73,3 +73,53 @@ ...@@ -73,3 +73,53 @@
margin-right: auto; margin-right: auto;
width: 790rem; 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
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
ul { ul {
margin: 0; margin: 0;
padding: 0; padding: 0;
max-height: 15.625rem; max-height: 84vh;
overflow-y: auto; overflow-y: auto;
scroll-behavior: smooth; scroll-behavior: smooth;
} }
import axios from "axios"; import axios from "axios";
const URL = "http://192.168.1.59:4000/todos"; const URL = "http://192.168.1.59:3000/todos";
export const getTodos = () => axios.get(URL); export const getTodos = () => axios.get(URL);
export const addTodo = (newTodo) => axios.post(URL, newTodo); export const addTodo = (newTodo) => axios.post(URL, newTodo);
export const deleteTodo = (id) => axios.delete(`${URL}/${id}`); export const deleteTodo = (id) => axios.delete(`${URL}/${id}`);
......
import React from "react"; import React from "react";
import styles from "../styles/TodoForm.module.css"; import styles from "../styles/TodoForm.module.css";
const TodoForm = ({ input, error, setInput, handleSubmit }) => { const TodoForm = ({ input, error, handleInputChange, handleSubmit }) => {
return ( return (
<div> <div>
<form className={styles.form} onSubmit={handleSubmit}> <form className={styles.form} onSubmit={handleSubmit}>
<div className={styles['input-wrapper']}>
<input <input
type="text" type="text"
value={input} value={input}
className={`${styles.input} ${error ? styles.inputError : ""}`} className={`${styles.input} ${error ? styles.inputError : ""}`}
placeholder="Enter Item" 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> <button type="submit" className={styles.button}>Submit</button>
</form> </form>
{error && <div className={styles.errorText}>{error}</div>}
</div> </div>
); );
}; };
......
import React from "react"; import React, { useState, useEffect } from "react";
import { TiDelete } from "react-icons/ti"; import { TiDelete } from "react-icons/ti";
import styles from "../styles/TodoItem.module.css"; import styles from "../styles/TodoItem.module.css";
const TodoItem = ({ item, handleToggleComplete, handleUpdate, handleDelete, error }) => ( const TodoItem = ({ item, handleToggleComplete, handleUpdate, handleDelete, error }) => {
<li className={styles.list}> const [showConfirm, setShowConfirm] = useState(false);
<input const [text, setText] = useState(item.text);
type="checkbox"
checked={item.completed}
onChange={() => handleToggleComplete(item.id,!item.completed)} useEffect(() => {
className={styles.listCheckbox} const handler = setTimeout(() => {
/> if (text !== item.text) {
<input handleUpdate(item.id, text);
type="text" }
value={item.text} }, 1000);
className={`${styles.todoContent} ${item.completed ? styles.todoContentCompleted : ""}`}
onChange={(e) => handleUpdate(item.id, e.target.value)} return () => {
/> clearTimeout(handler);
{error && <div className={styles.error}>{error}</div>} };
<button onClick={() => handleDelete(item.id)} className={styles.listButton}> }, [text, item.id, item.text, handleUpdate]);
<TiDelete className={styles.deletebutton} />
</button> const confirmDelete = () => {
</li> handleDelete(item.id);
); setShowConfirm(false);
};
return (
<li className={styles.list}>
<input
type="checkbox"
checked={item.completed}
onChange={() => handleToggleComplete(item.id, !item.completed)}
className={styles.listCheckbox}
/>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
className={`${styles.todoContent} ${item.completed ? styles.todoContentCompleted : ""}`}
/>
{error && <div className={styles.error}>{error}</div>}
<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; export default TodoItem;
{ {
"todos": [ "todos": [
{ {
"id": "9a22", "id": "f87f",
"text": "Buy Groceries Tomorrow", "text": "vjbdcbdxcvfdvdvfvfxvfrgrv",
"completed": false "completed": false
}, },
{ {
"id": "58ea", "id": "ed2b",
"text": "Travel to Head Office", "text": " bbbzdfbdfff",
"completed": false "completed": false
}, },
{ {
"id": "1ad0", "id": "f779",
"text": "Get phone from the repair shop", "text": "qwdhmm",
"completed": false "completed": false
} }
] ]
......
...@@ -13,14 +13,21 @@ function Todo() { ...@@ -13,14 +13,21 @@ function Todo() {
useEffect(() => { useEffect(() => {
getTodos().then((res) => setTodos(res.data)); getTodos().then((res) => setTodos(res.data));
}, []); }, []);
const handleInputChange=(e)=>{
setInput(e.target.value);
if(e.target.value.trim()!==""){
setError("");
}
};
const handleSubmit = async (e) => { const handleSubmit = async (e) => {
e.preventDefault(); e.preventDefault();
if (input.trim() === "") { if (input.trim() === "") {
setError("Please fill this field"); setError("Please fill this field");
setTimeout(() => setError(""), 3000); return;
return;
} }
setError("");
try { try {
const newTodo = { text: input, completed: false }; const newTodo = { text: input, completed: false };
const res = await addTodo(newTodo); const res = await addTodo(newTodo);
...@@ -74,6 +81,7 @@ const handleSubmit = async (e) => { ...@@ -74,6 +81,7 @@ const handleSubmit = async (e) => {
}; };
return ( return (
<div className={styles.wrapper}>
<div className={styles.container}> <div className={styles.container}>
<h1 className={styles.title}> <h1 className={styles.title}>
You have {todos.length} {todos.length === 1 ? "Todo" : "Todos"} You have {todos.length} {todos.length === 1 ? "Todo" : "Todos"}
...@@ -83,7 +91,8 @@ const handleSubmit = async (e) => { ...@@ -83,7 +91,8 @@ const handleSubmit = async (e) => {
) : ( ) : (
<TodoList todos={todos} handleToggleComplete={handleToggleComplete} handleUpdate={handleUpdate} handleDelete={handleDelete} updateErrors={updateErrors}/> <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> </div>
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment