T

TechIdea

Ecosystem

Back to nextjs Projects
Advanced Level

Next.js Admin Dashboard

Build an enterprise Admin Dashboard in Next.js demonstrating nested layouts, data fetching from mock APIs, chart rendering, metrics cards, and user table filtering.

The Problem

Build an enterprise Admin Dashboard in Next.js demonstrating nested layouts, data fetching from mock APIs, chart rendering, metrics cards, and user table filtering.

Real-World Use Case

Build an enterprise Admin Dashboard in Next.js demonstrating nested layouts, data fetching from mock APIs, chart rendering, metrics cards, and user table filtering.

Technology Stack

Understanding of Next.js nested layouts

Prerequisite

Familiarity with data fetching patterns

Prerequisite

Architecture & Design

Folder Structure

admin_dashboard/
├── app/
│   ├── dashboard/
│   │   ├── layout.tsx
│   │   └── page.tsx
│   └── layout.tsx
└── package.json

Step-by-Step Implementation

1

Create shared dashboard layout with navigation sidebar.

### Step 1: Project Setup Initialize Next.js project and setup dashboard folder routing.

nextjs
import { useState } from 'react';

const INITIAL_USERS = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com', role: 'Admin', status: 'Active' },
  { id: '2', name: 'Bob Jones', email: 'bob@example.com', role: 'Editor', status: 'Active' },
  { id: '3', name: 'Charlie Brown', email: 'charlie@example.com', role: 'Viewer', status: 'Inactive' },
  { id: '4', name: 'Diana Prince', email: 'diana@example.com', role: 'Editor', status: 'Active' },
];

export default function AdminDashboard() {
  const [search, setSearch] = useState('');
  const [users] = useState(INITIAL_USERS);

  const filtered = users.filter(user => 
    user.name.toLowerCase().includes(search.toLowerCase()) || 
    user.email.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div className="flex min-h-screen bg-slate-50">
      <aside className="w-64 bg-slate-900 text-white p-6 flex flex-col justify-between">
        <div>
          <span className="font-extrabold text-lg tracking-wider text-blue-400 block mb-10">TECHADMIN</span>
          <nav className="space-y-3 text-xs font-semibold">
            <a href="#" className="block p-3 bg-blue-600 rounded-xl text-white">📊 Analytics Overview</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">👥 User Management</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">⚙️ System Settings</a>
          </nav>
        </div>
        <div className="pt-4 border-t border-slate-800 text-[10px] text-slate-500">
          Admin OS v2.1
        </div>
      </aside>

      <main className="flex-1 p-10 max-w-6xl mx-auto space-y-8">
        <div>
          <h1 className="text-2xl font-bold text-slate-900">Analytics Overview</h1>
          <p className="text-xs text-slate-500">Welcome back, System Administrator</p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Total Revenue</span>
            <span className="text-3xl font-extrabold text-slate-900">$48,295</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +14% from last month</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Active Users</span>
            <span className="text-3xl font-extrabold text-slate-900">2,491</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +5% from last week</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Server Load</span>
            <span className="text-3xl font-extrabold text-slate-900">42%</span>
            <span className="text-[10px] text-slate-500 block mt-2">Normal operating parameters</span>
          </div>
        </div>

        <div className="bg-white p-8 rounded-3xl border border-slate-200 shadow-sm">
          <div className="flex justify-between items-center mb-6">
            <h2 className="font-bold text-lg text-slate-900">User Management Directory</h2>
            <input 
              type="text" 
              value={search} 
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search user by name or email..." 
              className="p-2.5 border border-slate-200 rounded-xl text-xs w-72"
            />
          </div>

          <div className="overflow-x-auto">
            <table className="w-full text-left border-collapse text-xs">
              <thead>
                <tr class="bg-slate-50 border-b border-slate-200 text-slate-600 font-bold">
                  <th className="p-3">Name</th>
                  <th className="p-3">Email</th>
                  <th className="p-3">Role</th>
                  <th className="p-3">Status</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100 text-slate-700">
                {filtered.map(user => (
                  <tr key={user.id} className="hover:bg-slate-50">
                    <td className="p-3 font-semibold text-slate-900">{user.name}</td>
                    <td className="p-3 text-slate-500">{user.email}</td>
                    <td className="p-3 font-medium">{user.role}</td>
                    <td className="p-3">
                      <span className={`px-2 py-1 rounded-full text-[10px] font-bold ${user.status === 'Active' ? 'bg-green-100 text-green-700' : 'bg-slate-100 text-slate-600'}`}>
                        {user.status}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </main>
    </div>
  );
}

Code Explanation

Implementation step

2

Fetch metrics summary data on server component mount.

### Step 2: Layout & Data Fetching Implement dashboard layout sidebar and server data fetching.

nextjs
import { useState } from 'react';

const INITIAL_USERS = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com', role: 'Admin', status: 'Active' },
  { id: '2', name: 'Bob Jones', email: 'bob@example.com', role: 'Editor', status: 'Active' },
  { id: '3', name: 'Charlie Brown', email: 'charlie@example.com', role: 'Viewer', status: 'Inactive' },
  { id: '4', name: 'Diana Prince', email: 'diana@example.com', role: 'Editor', status: 'Active' },
];

export default function AdminDashboard() {
  const [search, setSearch] = useState('');
  const [users] = useState(INITIAL_USERS);

  const filtered = users.filter(user => 
    user.name.toLowerCase().includes(search.toLowerCase()) || 
    user.email.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div className="flex min-h-screen bg-slate-50">
      <aside className="w-64 bg-slate-900 text-white p-6 flex flex-col justify-between">
        <div>
          <span className="font-extrabold text-lg tracking-wider text-blue-400 block mb-10">TECHADMIN</span>
          <nav className="space-y-3 text-xs font-semibold">
            <a href="#" className="block p-3 bg-blue-600 rounded-xl text-white">📊 Analytics Overview</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">👥 User Management</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">⚙️ System Settings</a>
          </nav>
        </div>
        <div className="pt-4 border-t border-slate-800 text-[10px] text-slate-500">
          Admin OS v2.1
        </div>
      </aside>

      <main className="flex-1 p-10 max-w-6xl mx-auto space-y-8">
        <div>
          <h1 className="text-2xl font-bold text-slate-900">Analytics Overview</h1>
          <p className="text-xs text-slate-500">Welcome back, System Administrator</p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Total Revenue</span>
            <span className="text-3xl font-extrabold text-slate-900">$48,295</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +14% from last month</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Active Users</span>
            <span className="text-3xl font-extrabold text-slate-900">2,491</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +5% from last week</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Server Load</span>
            <span className="text-3xl font-extrabold text-slate-900">42%</span>
            <span className="text-[10px] text-slate-500 block mt-2">Normal operating parameters</span>
          </div>
        </div>

        <div className="bg-white p-8 rounded-3xl border border-slate-200 shadow-sm">
          <div className="flex justify-between items-center mb-6">
            <h2 className="font-bold text-lg text-slate-900">User Management Directory</h2>
            <input 
              type="text" 
              value={search} 
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search user by name or email..." 
              className="p-2.5 border border-slate-200 rounded-xl text-xs w-72"
            />
          </div>

          <div className="overflow-x-auto">
            <table className="w-full text-left border-collapse text-xs">
              <thead>
                <tr class="bg-slate-50 border-b border-slate-200 text-slate-600 font-bold">
                  <th className="p-3">Name</th>
                  <th className="p-3">Email</th>
                  <th className="p-3">Role</th>
                  <th className="p-3">Status</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100 text-slate-700">
                {filtered.map(user => (
                  <tr key={user.id} className="hover:bg-slate-50">
                    <td className="p-3 font-semibold text-slate-900">{user.name}</td>
                    <td className="p-3 text-slate-500">{user.email}</td>
                    <td className="p-3 font-medium">{user.role}</td>
                    <td className="p-3">
                      <span className={`px-2 py-1 rounded-full text-[10px] font-bold ${user.status === 'Active' ? 'bg-green-100 text-green-700' : 'bg-slate-100 text-slate-600'}`}>
                        {user.status}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </main>
    </div>
  );
}

Code Explanation

Implementation step

3

Render summary metric cards (Total Revenue, Active Users).

### Step 3: Analytics Table & Filtering Build user data table with search query filtering.

nextjs
import { useState } from 'react';

const INITIAL_USERS = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com', role: 'Admin', status: 'Active' },
  { id: '2', name: 'Bob Jones', email: 'bob@example.com', role: 'Editor', status: 'Active' },
  { id: '3', name: 'Charlie Brown', email: 'charlie@example.com', role: 'Viewer', status: 'Inactive' },
  { id: '4', name: 'Diana Prince', email: 'diana@example.com', role: 'Editor', status: 'Active' },
];

export default function AdminDashboard() {
  const [search, setSearch] = useState('');
  const [users] = useState(INITIAL_USERS);

  const filtered = users.filter(user => 
    user.name.toLowerCase().includes(search.toLowerCase()) || 
    user.email.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div className="flex min-h-screen bg-slate-50">
      <aside className="w-64 bg-slate-900 text-white p-6 flex flex-col justify-between">
        <div>
          <span className="font-extrabold text-lg tracking-wider text-blue-400 block mb-10">TECHADMIN</span>
          <nav className="space-y-3 text-xs font-semibold">
            <a href="#" className="block p-3 bg-blue-600 rounded-xl text-white">📊 Analytics Overview</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">👥 User Management</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">⚙️ System Settings</a>
          </nav>
        </div>
        <div className="pt-4 border-t border-slate-800 text-[10px] text-slate-500">
          Admin OS v2.1
        </div>
      </aside>

      <main className="flex-1 p-10 max-w-6xl mx-auto space-y-8">
        <div>
          <h1 className="text-2xl font-bold text-slate-900">Analytics Overview</h1>
          <p className="text-xs text-slate-500">Welcome back, System Administrator</p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Total Revenue</span>
            <span className="text-3xl font-extrabold text-slate-900">$48,295</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +14% from last month</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Active Users</span>
            <span className="text-3xl font-extrabold text-slate-900">2,491</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +5% from last week</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Server Load</span>
            <span className="text-3xl font-extrabold text-slate-900">42%</span>
            <span className="text-[10px] text-slate-500 block mt-2">Normal operating parameters</span>
          </div>
        </div>

        <div className="bg-white p-8 rounded-3xl border border-slate-200 shadow-sm">
          <div className="flex justify-between items-center mb-6">
            <h2 className="font-bold text-lg text-slate-900">User Management Directory</h2>
            <input 
              type="text" 
              value={search} 
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search user by name or email..." 
              className="p-2.5 border border-slate-200 rounded-xl text-xs w-72"
            />
          </div>

          <div className="overflow-x-auto">
            <table className="w-full text-left border-collapse text-xs">
              <thead>
                <tr class="bg-slate-50 border-b border-slate-200 text-slate-600 font-bold">
                  <th className="p-3">Name</th>
                  <th className="p-3">Email</th>
                  <th className="p-3">Role</th>
                  <th className="p-3">Status</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100 text-slate-700">
                {filtered.map(user => (
                  <tr key={user.id} className="hover:bg-slate-50">
                    <td className="p-3 font-semibold text-slate-900">{user.name}</td>
                    <td className="p-3 text-slate-500">{user.email}</td>
                    <td className="p-3 font-medium">{user.role}</td>
                    <td className="p-3">
                      <span className={`px-2 py-1 rounded-full text-[10px] font-bold ${user.status === 'Active' ? 'bg-green-100 text-green-700' : 'bg-slate-100 text-slate-600'}`}>
                        {user.status}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </main>
    </div>
  );
}

Code Explanation

Implementation step

4

Implement client component data table with search filtering.

### Step 4: Loading & Error States Add loading.tsx and error.tsx files for smooth transitions.

nextjs
import { useState } from 'react';

const INITIAL_USERS = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com', role: 'Admin', status: 'Active' },
  { id: '2', name: 'Bob Jones', email: 'bob@example.com', role: 'Editor', status: 'Active' },
  { id: '3', name: 'Charlie Brown', email: 'charlie@example.com', role: 'Viewer', status: 'Inactive' },
  { id: '4', name: 'Diana Prince', email: 'diana@example.com', role: 'Editor', status: 'Active' },
];

export default function AdminDashboard() {
  const [search, setSearch] = useState('');
  const [users] = useState(INITIAL_USERS);

  const filtered = users.filter(user => 
    user.name.toLowerCase().includes(search.toLowerCase()) || 
    user.email.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div className="flex min-h-screen bg-slate-50">
      <aside className="w-64 bg-slate-900 text-white p-6 flex flex-col justify-between">
        <div>
          <span className="font-extrabold text-lg tracking-wider text-blue-400 block mb-10">TECHADMIN</span>
          <nav className="space-y-3 text-xs font-semibold">
            <a href="#" className="block p-3 bg-blue-600 rounded-xl text-white">📊 Analytics Overview</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">👥 User Management</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">⚙️ System Settings</a>
          </nav>
        </div>
        <div className="pt-4 border-t border-slate-800 text-[10px] text-slate-500">
          Admin OS v2.1
        </div>
      </aside>

      <main className="flex-1 p-10 max-w-6xl mx-auto space-y-8">
        <div>
          <h1 className="text-2xl font-bold text-slate-900">Analytics Overview</h1>
          <p className="text-xs text-slate-500">Welcome back, System Administrator</p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Total Revenue</span>
            <span className="text-3xl font-extrabold text-slate-900">$48,295</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +14% from last month</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Active Users</span>
            <span className="text-3xl font-extrabold text-slate-900">2,491</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +5% from last week</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Server Load</span>
            <span className="text-3xl font-extrabold text-slate-900">42%</span>
            <span className="text-[10px] text-slate-500 block mt-2">Normal operating parameters</span>
          </div>
        </div>

        <div className="bg-white p-8 rounded-3xl border border-slate-200 shadow-sm">
          <div className="flex justify-between items-center mb-6">
            <h2 className="font-bold text-lg text-slate-900">User Management Directory</h2>
            <input 
              type="text" 
              value={search} 
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search user by name or email..." 
              className="p-2.5 border border-slate-200 rounded-xl text-xs w-72"
            />
          </div>

          <div className="overflow-x-auto">
            <table className="w-full text-left border-collapse text-xs">
              <thead>
                <tr class="bg-slate-50 border-b border-slate-200 text-slate-600 font-bold">
                  <th className="p-3">Name</th>
                  <th className="p-3">Email</th>
                  <th className="p-3">Role</th>
                  <th className="p-3">Status</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100 text-slate-700">
                {filtered.map(user => (
                  <tr key={user.id} className="hover:bg-slate-50">
                    <td className="p-3 font-semibold text-slate-900">{user.name}</td>
                    <td className="p-3 text-slate-500">{user.email}</td>
                    <td className="p-3 font-medium">{user.role}</td>
                    <td className="p-3">
                      <span className={`px-2 py-1 rounded-full text-[10px] font-bold ${user.status === 'Active' ? 'bg-green-100 text-green-700' : 'bg-slate-100 text-slate-600'}`}>
                        {user.status}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </main>
    </div>
  );
}

Code Explanation

Implementation step

5

Render visual progress bars or chart representations.

### Step 4: Loading & Error States Add loading.tsx and error.tsx files for smooth transitions.

nextjs
import { useState } from 'react';

const INITIAL_USERS = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com', role: 'Admin', status: 'Active' },
  { id: '2', name: 'Bob Jones', email: 'bob@example.com', role: 'Editor', status: 'Active' },
  { id: '3', name: 'Charlie Brown', email: 'charlie@example.com', role: 'Viewer', status: 'Inactive' },
  { id: '4', name: 'Diana Prince', email: 'diana@example.com', role: 'Editor', status: 'Active' },
];

export default function AdminDashboard() {
  const [search, setSearch] = useState('');
  const [users] = useState(INITIAL_USERS);

  const filtered = users.filter(user => 
    user.name.toLowerCase().includes(search.toLowerCase()) || 
    user.email.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div className="flex min-h-screen bg-slate-50">
      <aside className="w-64 bg-slate-900 text-white p-6 flex flex-col justify-between">
        <div>
          <span className="font-extrabold text-lg tracking-wider text-blue-400 block mb-10">TECHADMIN</span>
          <nav className="space-y-3 text-xs font-semibold">
            <a href="#" className="block p-3 bg-blue-600 rounded-xl text-white">📊 Analytics Overview</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">👥 User Management</a>
            <a href="#" className="block p-3 text-slate-400 hover:bg-slate-800 rounded-xl transition">⚙️ System Settings</a>
          </nav>
        </div>
        <div className="pt-4 border-t border-slate-800 text-[10px] text-slate-500">
          Admin OS v2.1
        </div>
      </aside>

      <main className="flex-1 p-10 max-w-6xl mx-auto space-y-8">
        <div>
          <h1 className="text-2xl font-bold text-slate-900">Analytics Overview</h1>
          <p className="text-xs text-slate-500">Welcome back, System Administrator</p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Total Revenue</span>
            <span className="text-3xl font-extrabold text-slate-900">$48,295</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +14% from last month</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Active Users</span>
            <span className="text-3xl font-extrabold text-slate-900">2,491</span>
            <span className="text-[10px] text-green-600 font-bold block mt-2">▲ +5% from last week</span>
          </div>
          <div className="p-6 bg-white rounded-2xl border border-slate-200 shadow-xs">
            <span className="text-xs text-slate-500 font-semibold mb-1 block">Server Load</span>
            <span className="text-3xl font-extrabold text-slate-900">42%</span>
            <span className="text-[10px] text-slate-500 block mt-2">Normal operating parameters</span>
          </div>
        </div>

        <div className="bg-white p-8 rounded-3xl border border-slate-200 shadow-sm">
          <div className="flex justify-between items-center mb-6">
            <h2 className="font-bold text-lg text-slate-900">User Management Directory</h2>
            <input 
              type="text" 
              value={search} 
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search user by name or email..." 
              className="p-2.5 border border-slate-200 rounded-xl text-xs w-72"
            />
          </div>

          <div className="overflow-x-auto">
            <table className="w-full text-left border-collapse text-xs">
              <thead>
                <tr class="bg-slate-50 border-b border-slate-200 text-slate-600 font-bold">
                  <th className="p-3">Name</th>
                  <th className="p-3">Email</th>
                  <th className="p-3">Role</th>
                  <th className="p-3">Status</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100 text-slate-700">
                {filtered.map(user => (
                  <tr key={user.id} className="hover:bg-slate-50">
                    <td className="p-3 font-semibold text-slate-900">{user.name}</td>
                    <td className="p-3 text-slate-500">{user.email}</td>
                    <td className="p-3 font-medium">{user.role}</td>
                    <td className="p-3">
                      <span className={`px-2 py-1 rounded-full text-[10px] font-bold ${user.status === 'Active' ? 'bg-green-100 text-green-700' : 'bg-slate-100 text-slate-600'}`}>
                        {user.status}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </main>
    </div>
  );
}

Code Explanation

Implementation step

Common Errors

Search filter case sensitivity.

Use .toLowerCase() on both query and target strings.

Security & Performance

Test search input by typing user name to verify instant table row filtering.

Confirm metric summary values format cleanly.


Add chart.js integration.

Add user addition modal form.

Interview Questions

Q: Why use nested layouts?

A: Nested layouts keep sidebar navigation persistent across all dashboard sub-routes without re-rendering.

Growth Newsletter

Get practical AI tools, SEO tips, and growth guides weekly.

Join creators, students, and businesses scaling with TechIdea.