Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions src\App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useState, useEffect } from 'react'
import { TodoForm, TodoItem } from './components'
import { TodoProvider } from './context'

function App() {
const [todos, setTodos] = useState([])

const addTodos = (todo) => {
setTodos((prev) => [{ id: Date.now(), ...todo }, ...prev])
}

const updateTodo = (id, todo) => {
setTodos((prev) =>
prev.map((prevTodo) => (prevTodo.id === id ? todo : prevTodo))
)
}

const deleteTodo = (id) => {
setTodos((prev) => prev.filter((todo) => todo.id !== id))
}

const toggleComplete = (id) => {
setTodos((prev) =>
prev.map((prevTodo) =>
prevTodo.id === id
? { ...prevTodo, completed: !prevTodo.completed }
: prevTodo
)
)
}

// Load todos from localStorage on initial render
useEffect(() => {
const savedTodos = JSON.parse(localStorage.getItem('todos'))
if (savedTodos && savedTodos.length > 0) {
setTodos(savedTodos)
}
Comment on lines +33 to +37
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard localStorage deserialization to prevent mount-time crash.

At Line 34, JSON.parse(...) is unguarded. Invalid or manually-corrupted localStorage data will throw and crash the app on initial render.

Proposed fix
   useEffect(() => {
-    const savedTodos = JSON.parse(localStorage.getItem('todos'))
-    if (savedTodos && savedTodos.length > 0) {
-      setTodos(savedTodos)
-    }
+    const raw = localStorage.getItem('todos')
+    if (!raw) return
+    try {
+      const savedTodos = JSON.parse(raw)
+      if (Array.isArray(savedTodos)) {
+        setTodos(savedTodos)
+      }
+    } catch {
+      localStorage.removeItem('todos')
+    }
   }, [])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
const savedTodos = JSON.parse(localStorage.getItem('todos'))
if (savedTodos && savedTodos.length > 0) {
setTodos(savedTodos)
}
useEffect(() => {
const raw = localStorage.getItem('todos')
if (!raw) return
try {
const savedTodos = JSON.parse(raw)
if (Array.isArray(savedTodos)) {
setTodos(savedTodos)
}
} catch {
localStorage.removeItem('todos')
}
}, [])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src`\App.jsx around lines 33 - 37, Protect the localStorage deserialization
in the useEffect that initializes state: instead of calling JSON.parse(...)
directly, first read the raw value with localStorage.getItem('todos'), then wrap
JSON.parse in a try/catch and only call setTodos(savedTodos) if parsing succeeds
and the result is an array (or otherwise valid). Update the useEffect in App.jsx
(the effect that reads 'todos' and calls setTodos) to handle null/invalid data
and log or ignore parse errors rather than letting them throw on mount.

}, [])

// Save todos to localStorage whenever todos change
useEffect(() => {
localStorage.setItem('todos', JSON.stringify(todos))
}, [todos])

return (
<TodoProvider value={{ todos, addTodos, updateTodo, deleteTodo, toggleComplete }}>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Context value key mismatch breaks toggle completion.

At Line 46, TodoProvider exposes toggleComplete, but TodoItem consumes toggleCompleted (src/components/TodoItem.jsx Line 5). This can make toggle calls fail at runtime.

Proposed fix
-    <TodoProvider value={{ todos, addTodos, updateTodo, deleteTodo, toggleComplete }}>
+    <TodoProvider value={{ todos, addTodos, updateTodo, deleteTodo, toggleComplete, toggleCompleted: toggleComplete }}>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<TodoProvider value={{ todos, addTodos, updateTodo, deleteTodo, toggleComplete }}>
<TodoProvider value={{ todos, addTodos, updateTodo, deleteTodo, toggleComplete, toggleCompleted: toggleComplete }}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src`\App.jsx at line 46, The context provided by TodoProvider exposes a key
named toggleComplete but the consumer in TodoItem expects toggleCompleted,
causing runtime failure; update either the provider or the consumer so the keys
match—rename the provider's context value to toggleCompleted or change TodoItem
to call toggleComplete, ensuring the property name used in the value object
passed to TodoProvider and the one imported/used in TodoItem.jsx are identical
(refer to TodoProvider, TodoItem, toggleComplete, toggleCompleted).

<div className="bg-[#172842] min-h-screen py-8">
<div className="w-full max-w-2xl mx-auto shadow-md rounded-lg px-4 py-3 text-white">
<h1 className="text-2xl font-bold text-center mb-8 mt-2">Manage Your Todos</h1>
<div className="mb-4">
{/* Todo form goes here */}
<TodoForm />
</div>
<div className="flex flex-wrap gap-y-3">
{/* Loop and Add TodoItem here */}
{todos.map((todo) => (
<div key={todo.id} className="w-full">
<TodoItem todo={todo} />
</div>
))}
</div>
</div>
</div>
</TodoProvider>
)
}

export default App