Commit f6b189c6 by Sujeeth AV

Index.jsx

parent 2e8c0bf3
...@@ -10,14 +10,11 @@ export const Input = () => { ...@@ -10,14 +10,11 @@ export const Input = () => {
const [task, setTask] = useState(""); const [task, setTask] = useState("");
const [store, setStore] = useState([]); const [store, setStore] = useState([]);
const [editIndex, setEditIndex] = useState(null); const [editIndex, setEditIndex] = useState(null);
const [editedTask, setEditedTask] = useState("");
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isNewTodoAdded, setIsNewTodoAdded] = useState(false); const [isNewTodoAdded, setIsNewTodoAdded] = useState(false);
const editableRef = useRef(null); const editableRef = useRef(null);
const lastCursorPos = useRef(0);
const debounceTimeout = useRef(null); const debounceTimeout = useRef(null);
const lastClickEvent = useRef(null);
const fetchTodos = useCallback(async () => { const fetchTodos = useCallback(async () => {
try { try {
...@@ -35,118 +32,72 @@ export const Input = () => { ...@@ -35,118 +32,72 @@ export const Input = () => {
fetchTodos(); fetchTodos();
}, [fetchTodos]); }, [fetchTodos]);
const saveCursorPosition = () => { const placeCaretAtClick = () => {
try { const el = editableRef.current;
if (editableRef.current) { const event = lastClickEvent.current;
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(editableRef.current);
preCaretRange.setEnd(range.endContainer, range.endOffset);
lastCursorPos.current = preCaretRange.toString().length;
}
}
} catch (error) {
console.error("Error saving cursor position:", error);
}
};
const restoreCursorPosition = () => {
try {
if (editableRef.current) {
const range = document.createRange();
const selection = window.getSelection();
let found = false;
const findPosition = (node, remainingPos) => {
if (node.nodeType === Node.TEXT_NODE) {
const length = node.nodeValue.length;
if (remainingPos <= length) {
range.setStart(node, remainingPos);
found = true;
return;
}
remainingPos -= length;
} else {
for (let i = 0; i < node.childNodes.length && !found; i++) {
findPosition(node.childNodes[i], remainingPos);
}
}
};
findPosition(editableRef.current, lastCursorPos.current); if (el && event) {
if (!found) { let range, sel;
range.selectNodeContents(editableRef.current); if (document.caretRangeFromPoint) {
range.collapse(false); range = document.caretRangeFromPoint(event.clientX, event.clientY);
} else { } else if (document.caretPositionFromPoint) {
range.collapse(true); const pos = document.caretPositionFromPoint(event.clientX, event.clientY);
range = document.createRange();
range.setStart(pos.offsetNode, pos.offset);
} }
selection.removeAllRanges(); if (range) {
selection.addRange(range); sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} }
} catch (error) {
console.error("Error restoring cursor position:", error);
} }
}; };
useEffect(() => {
if (editableRef.current && editIndex !== null) {
try {
editableRef.current.focus();
setTimeout(restoreCursorPosition, 0);
} catch (error) {
console.error("Error focusing editable element:", error);
setEditIndex(null);
}
}
}, [editIndex, editedTask]);
const handleEdit = (e) => { const handleEdit = (e) => {
try {
saveCursorPosition();
const newValue = e.currentTarget.textContent; const newValue = e.currentTarget.textContent;
setEditedTask(newValue);
const updatedStore = [...store];
const original = updatedStore[editIndex];
updatedStore[editIndex] = { ...original, task: newValue };
setStore(updatedStore);
setStore(prevStore => {
const updatedStore = [...prevStore];
if (updatedStore[editIndex]) {
updatedStore[editIndex] = {
...updatedStore[editIndex],
task: newValue
};
}
return updatedStore;
});
if (debounceTimeout.current) { if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current); clearTimeout(debounceTimeout.current);
} }
debounceTimeout.current = setTimeout(() => { debounceTimeout.current = setTimeout(() => {
uptTodo(original.id, { const currentItem = store[editIndex];
id: original.id, if (currentItem) {
uptTodo(currentItem.id, {
id: currentItem.id,
task: newValue, task: newValue,
completed: original.completed, completed: currentItem.completed,
}).catch((error) => { }).catch(console.error);
console.error("Error saving todo:", error);
});
}, 1000);
} catch (error) {
console.error("Error during edit:", error);
setEditIndex(null);
} }
}, 1000);
}; };
const handleChange = (e) => setTask(e.target.value); const handleChange = (e) => setTask(e.target.value);
const startEdit = (index) => { const startEdit = (index, clickEvent = null) => {
try {
setEditIndex(index); setEditIndex(index);
setEditedTask(store[index].task); lastClickEvent.current = clickEvent;
} catch (error) {
console.error("Error starting edit:", error); setTimeout(() => {
setEditIndex(null); if (editableRef.current) {
const actualText = store[index]?.task || "";
editableRef.current.innerText = actualText;
editableRef.current.focus();
placeCaretAtClick();
} }
}, 0);
}; };
const endEdit = () => { const endEdit = () => {
...@@ -158,7 +109,7 @@ export const Input = () => { ...@@ -158,7 +109,7 @@ export const Input = () => {
try { try {
setIsNewTodoAdded(true); setIsNewTodoAdded(true);
const res = await addTodo(task); const res = await addTodo(task);
setStore([...store, res.data]); setStore(prev => [...prev, res.data]);
setTask(""); setTask("");
} catch (error) { } catch (error) {
console.error("Error adding todo:", error); console.error("Error adding todo:", error);
...@@ -166,12 +117,13 @@ export const Input = () => { ...@@ -166,12 +117,13 @@ export const Input = () => {
setTimeout(() => setIsNewTodoAdded(false), 500); 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) {
try { try {
await delTodo(id); await delTodo(id);
setStore(store.filter(item => item.id !== id)); setStore(prev => prev.filter(item => item.id !== id));
} catch (error) { } catch (error) {
console.error("Error deleting todo:", error); console.error("Error deleting todo:", error);
} }
...@@ -180,59 +132,38 @@ export const Input = () => { ...@@ -180,59 +132,38 @@ export const Input = () => {
const toggleComplete = async (index) => { const toggleComplete = async (index) => {
try { try {
const newStore = [...store]; const updated = [...store];
newStore[index] = { updated[index].completed = !updated[index].completed;
...newStore[index], setStore(updated);
completed: !newStore[index].completed
};
setStore(newStore);
await uptTodo(newStore[index].id, newStore[index]); await uptTodo(updated[index].id, updated[index]);
} catch (error) { } catch (error) {
console.error("Error toggling complete:", error); console.error("Error toggling complete:", error);
fetchTodos(); fetchTodos();
} }
}; };
const renderEditableContent = () => { const renderEditableContent = () => (
try {
return (
<div <div
ref={editableRef} ref={editableRef}
contentEditable contentEditable
suppressContentEditableWarning suppressContentEditableWarning
onBlur={endEdit} onBlur={endEdit}
onInput={handleEdit} onInput={handleEdit}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
e.currentTarget.blur();
}
}}
className={`${styles.task} ${store[editIndex]?.completed ? 'completed' : ''}`} className={`${styles.task} ${store[editIndex]?.completed ? 'completed' : ''}`}
style={{ style={{
display: 'inline-block', display: 'inline-block',
width:'100%', width: '100%',
boxSizing:'border-box' boxSizing: 'border-box',
outline: 'none',
whiteSpace: 'pre-wrap',
// margin: 0,
marginscreenLeft:'0.2rem',
padding: '4px 0',
userSelect: 'text'
}} }}
> />
{editedTask}
</div>
);
} catch (error) {
console.error("Error rendering editable content:", error);
return (
<span
className={`${styles.task} ${store[editIndex]?.completed ? styles.completed : ''}`}
onClick={() => startEdit(editIndex)}
>
{typeof store[editIndex]?.task === 'string'
? store[editIndex].task
: JSON.stringify(store[editIndex]?.task)}
</span>
); );
}
};
return ( return (
<MyTask.Provider value={{ store, setStore }}> <MyTask.Provider value={{ store, setStore }}>
...@@ -242,7 +173,7 @@ export const Input = () => { ...@@ -242,7 +173,7 @@ export const Input = () => {
store={store} store={store}
editIndex={editIndex} editIndex={editIndex}
renderEditableContent={renderEditableContent} renderEditableContent={renderEditableContent}
startEdit={startEdit} startEdit={(index, e) => startEdit(index, e)}
toggleComplete={toggleComplete} toggleComplete={toggleComplete}
Delete={Delete} Delete={Delete}
isNewTodoAdded={isNewTodoAdded} isNewTodoAdded={isNewTodoAdded}
......
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