CC
0 XP
0

Chapter 2: Build Core Todo

Chapter 2 Review

practice5 min

Chapter 2 Review

You just built a fully-featured todo application using Claude Code as your AI pair programmer. Let's take stock of what you accomplished and the patterns you learned.

What you built

Starting from an empty Next.js project, you constructed a complete todo app with:

  1. CLAUDE.md -- Persistent project context for Claude Code
  2. Data model -- TypeScript interfaces for Todo, Category, and Priority
  3. Layout -- Clean, centered app shell with header
  4. CRUD operations -- Create, Read, Update, Delete todos with inline editing
  5. Categories -- Organize todos with colored tags (Work, Personal, Shopping, Health, Other)
  6. Category filter -- View todos from a single category or all at once
  7. Due dates -- Date picker with overdue and "due today" highlighting
  8. Priorities -- Three-level system (Low, Medium, High) with traffic-light color coding
  9. Search -- Real-time text filtering across your todo list
  10. Local storage -- Todos survive page refreshes via a custom hook
  11. Sorting -- Five different sort options (newest, oldest, alphabetical, priority, due date)
  12. Empty states -- Context-aware messages when the list is empty

The final file structure

File StructureYour structure may look different — that's OK

src/ app/ page.tsx -- Main page, state management, data pipeline layout.tsx -- App shell and metadata globals.css -- Global styles components/ AddTodo.tsx -- Form with title, category, date, priority inputs TodoList.tsx -- Renders todos with checkbox, edit, delete CategoryFilter.tsx -- Pill buttons for category filtering SearchBar.tsx -- Text search with clear button SortSelect.tsx -- Dropdown for sort order EmptyState.tsx -- Context-aware empty state messages hooks/ useLocalStorage.ts -- Custom hook for persistent state types/ todo.ts -- Todo, Category, Priority types and constants data/ sample-todos.ts -- Starter data for first-time users utils/ generateId.ts -- UUID generation

Key patterns you practiced

These patterns will serve you well beyond this project:

💡Info

Derived state -- You computed filteredTodos and sortedTodos from source state instead of storing them separately. The rule: if a value can be calculated from existing state, calculate it during render. This eliminates an entire category of synchronization bugs.

💡Info

Immutable updates -- Every state update created a new array or object. map() for updates, filter() for deletes, spread operator for new items. React depends on reference changes to detect updates, so mutation causes silent bugs.

💡Info

Callback props -- Components like TodoList and AddTodo do not manage state themselves. They receive callbacks (onToggle, onDelete, onEdit, onAdd) and call them when the user acts. This keeps components reusable and testable.

💡Info

Custom hooks -- The useLocalStorage hook wraps complexity (SSR checks, error handling, JSON serialization) behind a simple useState-like API. Custom hooks are how React developers share and reuse logic.

💡Info

Composable data pipeline -- Your filter-then-sort pipeline (todos -> filter category -> filter search -> sort -> render) is clean and extensible. Adding a new filter or sort option means adding one line, not rewriting the whole flow.

Review questions

Test your understanding of the key concepts. Think through each question before reading the answer.

Quiz • 10 XP

Why do we use [...todos].sort() instead of todos.sort() when sorting?

Quiz • 10 XP

What is 'derived state' and why is it preferred over storing filtered results in a separate useState?

Quiz • 10 XP

Why does the useLocalStorage hook check typeof window === 'undefined'?

Quiz • 10 XP

In the AddTodo component, why is the onAdd callback defined in the parent (page.tsx) instead of having AddTodo manage the todos array directly?

Quiz • 10 XP

What is the most effective way to use Claude Code when building features?

Prompting patterns to remember

Important

Be specific about interactions. When building the inline editor, you specified double-click to edit, Enter to save, Escape to cancel, blur to save. The more interaction details you provide, the more complete the first result.

Important

Name the component and its file path. Telling Claude Code "Create a SearchBar component at src/components/SearchBar.tsx" removes ambiguity about what to build and where to put it. In prompt engineering terms, this is called output formatting — the more specific your output expectations, the less Claude has to guess.

Important

Describe the visual result. Phrases like "colored pill badges," "red left border for high priority," and "magnifying glass icon on the left" give Claude Code the context it needs to generate appropriate styles.

Important

Mention constraints and defaults. "Don't allow saving empty titles" and "default to Medium priority" prevent edge cases. Claude Code implements validation when you mention it, but may skip it if you do not.

The prompt engineering framework

These patterns map to what Anthropic's research calls the prompt engineering framework. Every effective Claude Code prompt has some combination of:

ElementExample from this chapter
ContextYour CLAUDE.md (loaded automatically)
Task"Create a SearchBar component"
Constraints"Don't allow saving empty titles"
ExamplesSample data, reference apps
Output expectationsFile path, component name, visual description
Thinking time/plan before building

You don't need all of these every time — a simple task needs only a clear instruction. But the more complex the feature, the more elements help. By the end of this course, you'll have internalized these patterns and apply them instinctively.

Challenge yourself

Before moving to the next chapter, try extending the app on your own with Claude Code:

Tip

Challenge 1: Bulk actions. Ask Claude Code to add "Select All" and "Delete Completed" buttons. This exercises the filter and map patterns on multiple items at once.

Tip

Challenge 2: Dark mode. Ask Claude Code to add a dark mode toggle using Tailwind's dark: variant classes. This is a great exercise in understanding CSS theming.

Tip

Challenge 3: Drag and drop reordering. Ask Claude Code to add drag-and-drop. This is harder and might require a library. See how Claude Code handles the integration and dependency management.

⚠️Warning

These challenges are optional. If you want to keep moving forward, head straight to Chapter 3. You can always come back to extend the todo app later.

What is next

In Chapter 3, we'll transform your functional prototype into a polished, beautiful application with a cohesive color system, typography, animations, dark mode, and responsive design. You'll learn how to give Claude Code a design direction and iterate on visual details — the skills that turn a project into a product.

You now have a real, working application. Every feature was built by giving Claude Code clear, specific instructions. That skill -- communicating your intent precisely to an AI -- is the core competency this course teaches. And you are getting good at it.