React SPA for tracking project budgets and associated service costs. Users can create projects, assign budgets by category, add services, and monitor remaining budget.
In scope:
- CRUD operations for projects and services
- Budget validation (service cost cannot exceed remaining budget)
- Category-based project organization
- Client-side routing with feedback messages
Non-goals:
- Authentication / authorization
- Persistent database (uses json-server mock)
- Production deployment configuration
- Comprehensive error handling
- Form validation beyond budget constraints
┌─────────────────┐ fetch ┌─────────────────┐
│ React SPA │ ◄────────────► │ json-server │
│ (port 3000) │ REST API │ (port 5000) │
└─────────────────┘ └────────┬────────┘
│
┌────────▼────────┐
│ db.json │
│ (file-based) │
└─────────────────┘
Components:
src/App.js— Route definitions (React Router v6)src/components/pages/— Route handlers (Projects, ProjectEdit, NewProject)src/components/project/— Project-specific UI (ProjectForm, ProjectCard)src/components/services/— Service management (ServiceForm, ServiceCard)src/components/form/— Reusable form primitives (Input, Select, SubmitButton)src/components/layout/— Layout components (Container, Navbar, Message, Loading)db.json— Mock database with projects and categories
- React functional components with hooks (
useState,useEffect) - Component composition and prop drilling
- Controlled form inputs with dynamic field binding (
[e.target.name]) - CSS Modules for scoped styling
- React Router v6 navigation with state passing
- REST API consumption with fetch
- Conditional rendering patterns
- UUID generation for service IDs
| Decision | Rationale |
|---|---|
| json-server instead of real backend | Focus on frontend patterns, not API development |
| No TypeScript | Learning project prioritizing React fundamentals |
Hardcoded API URL (localhost:5000) |
Simplicity; no environment configuration |
| Services embedded in project object | Matches json-server limitations; avoids relations |
| Simulated loading delay (setTimeout) | Demonstrates loading state patterns |
| No form validation library | Manual validation shows underlying logic |
Entry points:
src/App.js— Route structure and page componentssrc/components/pages/ProjectEdit.js— Most complex component; shows CRUD, validation, state managementdb.json— Data model structure
Data flow example (adding a service):
ServiceForm.submit()
→ pushes service to project.services array
→ calls ProjectEdit.createService()
→ validates against budget
→ PATCH to json-server
→ updates local state
Key patterns to observe:
src/components/form/Input.js— Reusable controlled input patternsrc/components/layout/Message.js— Auto-dismiss notification with useEffect cleanupsrc/components/pages/Projects.js— List fetching with loading state
npm install
npm run backend # Terminal 1: json-server on port 5000
npm start # Terminal 2: React dev server on port 3000