Forms and API Basics
Introduction: Welcome to Part 2 — Real CRUD Starts Here
Welcome to Vibe Coding the Frontend: Task Manager CRUD & UX Polish (Part 2) 🎉
In Part 1, you built a strong UI foundation. You now have a dashboard shell with navigation, reusable components like TaskRow and Button, URL-driven filtering, polished stub routes, and a lightweight toast system that already makes the app feel more interactive.
In Unit 1: Forms and API Basics, you’ll start building the pieces that make real CRUD flows clean and consistent. Instead of jumping straight into large create and edit pages, you’ll first build the reusable primitives those pages depend on. That includes a reusable Input primitive with label, error handling, and ref forwarding, a reusable TaskForm that defines the shape and validation of task data, and a small API client wrapper so fetch(...) logic is not scattered across the codebase.
These building blocks matter because the next two units will use them repeatedly. Once they exist, you can implement full task creation and editing more cleanly, and then move into delete flow and UX polish without rewriting form and request logic in every page. This is the same philosophy you used in Part 1: build small reusable pieces first, then use them to make the app feel real.
Previously: Where We Left Off (End of Part 1)
In the previous unit, you let the URL drive the UI. Filter buttons updated /tasks/filter?completed=true|false, the filter page validated query params and rendered filtered lists using TaskRow, stub routes were upgraded so they felt intentional instead of broken, and a toast system added friendly feedback across the dashboard.
That matters because Part 2 keeps the same overall philosophy. You are still aiming for small reusable primitives, predictable data flow, and clear boundaries between frontend and backend. The frontend consumes src/app/api/**, but it does not rewrite it. The goal is not just to make CRUD “work,” but to make it work in a way that stays organized as the project grows.
Practice 1: Reusable Input Primitive
