In short
Every real product has an admin side: tables of users, edit forms, delete buttons and pages only some people can open. This project brings tables, forms and protected routes together.
A management interface for CRUD operations across multiple resources (users, products, orders) — practice for forms, tables, and role-based UI.

Think of it like this
The hostel warden's office
Students can read the notice board, but only the warden opens the register to add, edit or remove names. An admin panel is that office: powerful pages behind a locked door, and only the right people get the key.
Watch it happen
Who gets past the guard
open /admin/users
1/5A student types /admin/users into the address bar.
The big ideas
What you need to know
Data tables
List users with search, sorting and pagination, because real tables have hundreds of rows.
One form, two jobs
The same form component handles both 'add user' and 'edit user'.
Protected routes
Redirect anyone who isn't logged in or isn't an admin. And check it on the server too.
Confirm dangerous actions
Deleting asks 'Are you sure?' in a modal before anything happens.
How it works
Build plan
- 1
Layout
A sidebar with Users, Courses and Settings, and an Outlet for the pages.
- 2
Users table
Mock or fetch users and show them in a paginated table.
- 3
Forms
Add and edit users with one shared form component.
- 4
Guard routes
Wrap admin routes in a component that checks the user's role.
See it in code
Walk through the code
1import { Navigate, Outlet } from "react-router";2import { useAuth } from "./auth"; // your own hook3 4export function RequireAdmin() {5 const { user } = useAuth();6 7 if (!user) return <Navigate to="/login" replace />;8 if (user.role !== "admin") return <p>You don't have access to this page.</p>;9 10 return <Outlet />;11}12 13// <Route element={<RequireAdmin />}>14// <Route path="/admin/users" element={<Users />} />15// </Route>1/5Read the current user from your auth hook.
Every route nested inside RequireAdmin is guarded in one place. This only hides pages, so the API must still reject requests from non-admins.
Save yourself the pain
Common mistakes
Oops
Protecting admin pages only in the frontend.
Do this instead
Anyone can call your API directly. The server must check the role on every admin request too.
Oops
Deleting a row the moment the button is clicked.
Do this instead
Ask for confirmation first, and name the exact item that's about to be deleted.
Your mission
First milestone: a guarded users table
Quick check
A logged-in student opens /admin/users, and their role is "student". What does RequireAdmin render?
Go deeper
- 1Build a reusable data table component used across multiple resource types.
- 2Add create/edit forms that share validation logic.
- 3Practice conditionally rendering UI based on a mock user role.
More projects at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.