Stop 08 · ReactProjects · 6/6

Admin Panel

Part of the Frontend Developer Roadmap

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.

The jaadu mascot as a warden sits at a desk with a big key and an open register.

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

Student
RequireAdmin
useAuth
Users page

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. 1

    Layout

    A sidebar with Users, Courses and Settings, and an Outlet for the pages.

  2. 2

    Users table

    Mock or fetch users and show them in a paginated table.

  3. 3

    Forms

    Add and edit users with one shared form component.

  4. 4

    Guard routes

    Wrap admin routes in a component that checks the user's role.

See it in code

Walk through the code

tsx
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

~45 min

Quick check

A logged-in student opens /admin/users, and their role is "student". What does RequireAdmin render?

Go deeper

  1. 1Build a reusable data table component used across multiple resource types.
  2. 2Add create/edit forms that share validation logic.
  3. 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.

Download
InsideEdge