Skip to content

Admin Panel Demo

The @saas/admin module provides a user management admin panel, gated by the admin role.

Module: @saas/admin · Route: /dashboard/admin · Docs · Install Guide

Live Demo

Sign in as admin@example.com / Admin123! to access the admin panel.

https://your-app.zeabur.app/dashboard/admin Open ↗
🖥️
Admin Panel — Live Demo

Configure your deployed Next.js app URL via the VITEPRESS_DEMO_BASE environment variable, then rebuild to enable live iframe embeds.

View demo at https://your-app.zeabur.app/dashboard/admin

Features

FeatureComponentServer Action (actions/admin.ts)
User Tableadmin-user-table.tsxgetAllUsers()
Role Selectoradmin-role-selector.tsxsetUserRole(userId, role)
Delete Useradmin-delete-user-button.tsxdeleteUser(userId)

RBAC Gate

The admin panel is protected at three levels:

  1. Edge middleware (proxy.ts) — non-authenticated users are redirected to /login
  2. Page level — the page calls requireAdmin(), which re-reads the role from the DB and redirects non-admins to /dashboard
  3. Server Action level — each action in actions/admin.ts calls requireAdmin() independently

This defense-in-depth ensures no admin operation can be performed without the correct role, even if the page-level check is bypassed. Because the guard re-reads the role from the database (not the JWT snapshot), a demotion takes effect immediately.

Server Actions

User management runs entirely through Server Actions in actions/admin.ts (getAllUsers, setUserRole, deleteUser) — not HTTP endpoints — so there is nothing cross-origin to call. Each action re-reads the caller's role from the DB via requireAdmin(). See the API Reference for signatures.

Live App

GET/api/health
Base URL (your deployed Next.js app)
Authorization Header (optional)
Try in Live App →

Note: The admin panel requires an admin session. Sign in as admin@example.com first.

Released under the MIT License.