Commit 4b660503 by Sujeeth AV

Index.jsx

parent df7f13da
import React, { createContext, useState, useRef, useEffect, useCallback } from 'react'; import React, { createContext, useState, useRef, useEffect, useCallback } from 'react';
import { getTodo, addTodo, delTodo, uptTodo } from '../../API/Api' import { getTodo, addTodo, delTodo, uptTodo } from '../../API/Api';
import { Header } from '../../Layout/card/Index'; import { Header } from '../../Layout/card/Index';
import styles from'./styles.module.css'; import styles from './styles.module.css';
import List from '../../todo/List/Index'; import List from '../../todo/List/Index';
export const MyTask = createContext();
const debounce = (func, delay) => { export const MyTask = createContext();
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
};
export const Input = () => { export const Input = () => {
const [task, setTask] = useState(""); const [task, setTask] = useState("");
...@@ -21,9 +12,13 @@ export const Input = () => { ...@@ -21,9 +12,13 @@ export const Input = () => {
const [editIndex, setEditIndex] = useState(null); const [editIndex, setEditIndex] = useState(null);
const [editedTask, setEditedTask] = useState(""); const [editedTask, setEditedTask] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isNewTodoAdded, setIsNewTodoAdded] = useState(false);
const editableRef = useRef(null); const editableRef = useRef(null);
const lastCursorPos = useRef(0); const lastCursorPos = useRef(0);
const debounceTimeout = useRef(null);
const fetchTodos = useCallback(async () => { const fetchTodos = useCallback(async () => {
try { try {
setLoading(true); setLoading(true);
...@@ -62,7 +57,7 @@ export const Input = () => { ...@@ -62,7 +57,7 @@ export const Input = () => {
if (editableRef.current) { if (editableRef.current) {
const range = document.createRange(); const range = document.createRange();
const selection = window.getSelection(); const selection = window.getSelection();
let found = false; let found = false;
const findPosition = (node, remainingPos) => { const findPosition = (node, remainingPos) => {
if (node.nodeType === Node.TEXT_NODE) { if (node.nodeType === Node.TEXT_NODE) {
...@@ -108,43 +103,42 @@ export const Input = () => { ...@@ -108,43 +103,42 @@ export const Input = () => {
} }
}, [editIndex, editedTask]); }, [editIndex, editedTask]);
const debouncedSave = useCallback(
debounce(async (id, newTask) => {
try {
const todo = store.find(item => item.id === id);
if (todo && todo.task !== newTask) {
await uptTodo(id, {
id: todo.id,
task: newTask,
completed: todo.completed
});
}
} catch (error) {
console.error("Error saving todo:", error);
}
}, 500),
[store]
);
const handleChange = (e) => setTask(e.target.value);
const handleEdit = (e) => { const handleEdit = (e) => {
try { try {
saveCursorPosition(); saveCursorPosition();
const newValue = e.currentTarget.textContent; const newValue = e.currentTarget.textContent;
setEditedTask(newValue); setEditedTask(newValue);
const newStore = [...store]; const updatedStore = [...store];
newStore[editIndex] = { ...newStore[editIndex], task: newValue }; const original = updatedStore[editIndex];
setStore(newStore); updatedStore[editIndex] = { ...original, task: newValue };
setStore(updatedStore);
debouncedSave(store[editIndex].id, newValue);
if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current);
}
debounceTimeout.current = setTimeout(() => {
uptTodo(original.id, {
id: original.id,
task: newValue,
completed: original.completed,
}).catch((error) => {
console.error("Error saving todo:", error);
});
}, 1000);
} catch (error) { } catch (error) {
console.error("Error during edit:", error); console.error("Error during edit:", error);
setEditIndex(null); setEditIndex(null);
} }
}; };
const handleChange = (e) => setTask(e.target.value);
const startEdit = (index) => { const startEdit = (index) => {
try { try {
setEditIndex(index); setEditIndex(index);
...@@ -162,14 +156,16 @@ export const Input = () => { ...@@ -162,14 +156,16 @@ export const Input = () => {
const Add = async () => { const Add = async () => {
if (task.trim() === '') return; if (task.trim() === '') return;
try { try {
setIsNewTodoAdded(true);
const res = await addTodo(task); const res = await addTodo(task);
setStore([...store, res.data]); setStore([...store, res.data]);
setTask(""); setTask("");
} catch (error) { } catch (error) {
console.error("Error adding todo:", error); console.error("Error adding todo:", error);
} finally {
setTimeout(() => setIsNewTodoAdded(false), 500);
} }
}; };
const Delete = async (id) => { const Delete = async (id) => {
const confirmDelete = window.confirm("Are you sure you want to delete?"); const confirmDelete = window.confirm("Are you sure you want to delete?");
if (confirmDelete) { if (confirmDelete) {
...@@ -190,7 +186,7 @@ export const Input = () => { ...@@ -190,7 +186,7 @@ export const Input = () => {
completed: !newStore[index].completed completed: !newStore[index].completed
}; };
setStore(newStore); setStore(newStore);
await uptTodo(newStore[index].id, newStore[index]); await uptTodo(newStore[index].id, newStore[index]);
} catch (error) { } catch (error) {
console.error("Error toggling complete:", error); console.error("Error toggling complete:", error);
...@@ -214,6 +210,11 @@ export const Input = () => { ...@@ -214,6 +210,11 @@ export const Input = () => {
} }
}} }}
className={`${styles.task} ${store[editIndex]?.completed ? 'completed' : ''}`} className={`${styles.task} ${store[editIndex]?.completed ? 'completed' : ''}`}
style={{
display: 'inline-block',
width:'100%',
boxSizing:'border-box'
}}
> >
{editedTask} {editedTask}
</div> </div>
...@@ -222,8 +223,7 @@ export const Input = () => { ...@@ -222,8 +223,7 @@ export const Input = () => {
console.error("Error rendering editable content:", error); console.error("Error rendering editable content:", error);
return ( return (
<span <span
className={`${styles.task} ${store[editIndex]?.completed ? styles.completed : ''}`} className={`${styles.task} ${store[editIndex]?.completed ? styles.completed : ''}`}
onClick={() => startEdit(editIndex)} onClick={() => startEdit(editIndex)}
> >
{typeof store[editIndex]?.task === 'string' {typeof store[editIndex]?.task === 'string'
...@@ -237,15 +237,16 @@ export const Input = () => { ...@@ -237,15 +237,16 @@ export const Input = () => {
return ( return (
<MyTask.Provider value={{ store, setStore }}> <MyTask.Provider value={{ store, setStore }}>
<div className="todo-container"> <div className="todo-container">
<Header/> <Header />
<List <List
store={store} store={store}
editIndex={editIndex} editIndex={editIndex}
renderEditableContent={renderEditableContent} renderEditableContent={renderEditableContent}
startEdit={startEdit} startEdit={startEdit}
toggleComplete={toggleComplete} toggleComplete={toggleComplete}
Delete={Delete} Delete={Delete}
/> isNewTodoAdded={isNewTodoAdded}
/>
<form onSubmit={(e) => e.preventDefault()}> <form onSubmit={(e) => e.preventDefault()}>
<div className={styles.merge}> <div className={styles.merge}>
<input <input
...@@ -256,12 +257,12 @@ export const Input = () => { ...@@ -256,12 +257,12 @@ export const Input = () => {
onChange={handleChange} onChange={handleChange}
disabled={loading} disabled={loading}
/> />
<button <button
onClick={Add} onClick={Add}
className={styles.button} className={styles.button}
disabled={loading || !task.trim()} disabled={loading || !task.trim()}
> >
Submit Submit
</button> </button>
</div> </div>
</form> </form>
......
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