Stop 22 · Build Portfolio ProjectsProjects · 9/15

Admin Dashboard

Part of the Frontend Developer Roadmap

In short

Most frontend jobs involve building internal tools, not shiny landing pages. A clean admin dashboard with real tables and charts says 'I can do the work you actually need'.

A polished, data-dense admin interface — charts, tables with sorting/filtering, and role-based views — demonstrating you can build 'boring but essential' enterprise UI well.

The jaadu watches a row of screens with charts and train icons in a station control room.

Think of it like this

The station master's control room

Screens show which trains are on time, which are late and which platform is free. One glance, and the station master knows what to do. A good dashboard gives that same quick picture.

Watch it happen

Turning 500 rows into one page

Rows
Filter
Sort
Slice
URL

1/5500 user rows come in. With real data, the server would run these same steps.

The big ideas

What you need to know

Tables that do real work

Sort, filter, search and paginate thousands of rows. This is everyday enterprise frontend.

Filters live in the URL

?status=active&page=2 lets admins share and bookmark views. Shows senior-level thinking.

Charts and KPI cards

Clear numbers at the top, trends below. Proves you can present data, not just fetch it.

Role-based views

An admin sees delete buttons, a viewer doesn't, and the server checks too.

How it works

Build plan

  1. 1

    Layout shell

    Sidebar, top bar and responsive content area.

  2. 2

    Users table

    Fake data for 500 users with sort, filter and pagination.

  3. 3

    Sync with the URL

    Read and write filters as search params.

  4. 4

    Charts and KPIs

    Summary cards and two or three charts.

  5. 5

    Roles and polish

    Login with roles, dark mode, loading skeletons.

See it in code

Walk through the code

js
1function getPage(rows, { search = "", sortBy = "name", dir = "asc", page = 1, size = 20 }) {2  const q = search.toLowerCase();3  const filtered = rows.filter((r) => r.name.toLowerCase().includes(q));4 5  const sorted = [...filtered].sort((a, b) => {6    const cmp = String(a[sortBy]).localeCompare(String(b[sortBy]), undefined, { numeric: true });7    return dir === "asc" ? cmp : -cmp;8  });9 10  const start = (page - 1) * size;11  return { total: sorted.length, rows: sorted.slice(start, start + size) };12}

1/3Keep rows whose name contains the search text, ignoring case.

Filter, then sort, then slice. For real data with lakhs of rows, do the same steps on the server and send back one page at a time.

Save yourself the pain

Common mistakes

Oops

Fetching all 50,000 rows and paginating in the browser.

Do this instead

Paginate on the server with page and limit params. Send only what's on screen.

Oops

Hiding the delete button and calling it 'role-based access'.

Do this instead

Hiding is UI only. The API must also reject actions the user's role doesn't allow.

Your mission

Milestone 1: a table that does its job

~45 min

Quick check

Why keep table filters and page number in the URL instead of only in React state?

Go deeper

  1. 1Add real charts (not placeholders) summarizing key metrics.
  2. 2Implement a data table with sorting, filtering and pagination from scratch or a library.
  3. 3Add at least two distinct user roles with different visible sections.

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