← back to all projects
Freelancer Client Portal
Part 7 — React Router, Styles
Why This Project
This is the project where everything from Parts 0–7 comes together into one polished
full stack app. A client portal has natural multi-page structure (dashboard, clients,
projects, invoices), protected routes, nested layouts, and enough visual complexity
to justify a real styling approach. It's the first app in this roadmap that could
pass as a real product.
What to Build
A portal where a freelancer manages their clients and projects. Each client has
contact info and a list of projects. Each project has a name, status (active,
completed, on-hold), hourly rate, and logged hours. The portal calculates total
earnings per project and per client. There's a dashboard showing active projects,
total earnings this month, and recent activity. Backend is Express + MongoDB.
Requirements
- React Router v6 routes: /dashboard, /clients, /clients/:id, /clients/:id/projects/:projectId, /login
- Nested layout: sidebar nav + main content area that changes per route
- Protected routes: redirect to /login if not authenticated
- Dashboard: aggregate data (total active projects, earnings this month, recent time entries)
- Client detail page: contact info + list of their projects using
useParams
- Project detail page: log time entries (date, hours, description), see total hours and earnings
- Programmatic navigation: after creating a client, navigate to their page (
useNavigate)
- Pick ONE styling approach and use it consistently (CSS Modules, styled-components, or Tailwind)
- React Query for data fetching; context or Redux for auth state
- Backend: Express + MongoDB with JWT auth, models for User, Client, Project, TimeEntry
- Responsive: usable on mobile (collapsed sidebar or bottom nav)
Skills Practiced
React Router v6
nested routes
useParams
useNavigate
protected routes
layout components
CSS Modules / styled-components / Tailwind
React Query
full stack integration
aggregation
Pain Point to Notice
This is the first time you're juggling routing, auth, data fetching, state management,
and styling all at once. It will feel chaotic. The key skill being practiced isn't
any single tool — it's the ability to debug across layers. When something breaks,
your first job is figuring out WHICH layer is broken: is it a routing issue (wrong URL)?
A data issue (API returning wrong shape)? An auth issue (token expired)? A rendering
issue (component not re-rendering)? Learn to isolate problems by layer.