A production-ready, fully-featured admin dashboard template built with React 18, Node.js, and MySQL. Clone it once, configure it in minutes, and ship any client project on top of it β without rewriting the core.
Clean centered card, show/hide password toggle, Zod validation, dark mode ready.
KPI cards, AI insights banner, 4 interactive charts (area, bar, line, donut), sortable data table, quick actions, live activity feed, and system status with 90-day uptime history.
Searchable, paginated user table. Add / Edit / Delete with role-based button visibility. Reset password action per user.
Card grid layout. Each card shows user count, permission count, and an expandable permission chip view. Add/edit roles with a permission matrix picker.
Role filter chips (Viewer Β· Admin Β· Editor Β· Moderator) with live permission counts. Full-width search with amber highlight. Module cards with toggle switches, progress bars, and Grant all / Revoke all actions. Unsaved changes banner with Save / Discard.
Server-side filtered, paginated log table. Filter by module, status, date range. Expandable rows show raw JSON meta. CSV export. Auto-refresh toggle (30 s).
Expands to show label + icon. Collapses to icon-only mode. User Management group shows a flyout submenu in collapsed mode. Active-route detection auto-opens the correct group.
| Feature | Detail |
|---|---|
| RBAC | Dynamic role/permission system β no hardcoded role names anywhere |
| JWT Auth | Access token (15 min, memory only) + Refresh token (7 days, httpOnly cookie) |
| Silent refresh | Axios interceptor refreshes expired token and retries the original request |
| Audit logging | Every write operation is automatically logged via middleware β no manual calls needed |
| Module system | Add a module by editing one config file β sidebar, router, API routes, and seed all update automatically |
| Dark mode | System-aware default, persisted to localStorage, smooth transition |
| Setup script | node scripts/setup.js β installs deps, migrates DB, seeds data in one command |
| Feature | Detail |
|---|---|
| KPI cards | Revenue, Active Users, New Signups, System Uptime with trend indicators |
| AI Insights | Auto-generated insight cards with icon + description |
| Charts | User Growth (area), Traffic Sources (donut), Sales by Region (bar), Login Activity (line) β all via Recharts |
| DataTable | Client-side sort, filter, pagination β reusable component |
| Quick Actions | 6 shortcut buttons to key pages |
| System Status | Per-service health + 90-day uptime history bar |
| Auto Refresh | Live-polls analytics every 30 s when enabled |
| Feature | Detail |
|---|---|
| Collapsible | Toggle button on edge, smooth CSS transition |
| Groups | Modules can be grouped under a parent (e.g. User Management) |
| Flyout | In collapsed mode, clicking a group opens a fixed flyout submenu |
| Auto-open | Active child route automatically opens its parent group |
| RBAC-aware | Nav items hidden if user lacks the module's primary permission |
| Feature | Detail |
|---|---|
| Role chips | Filter by role, shows granted permission count badge |
| Search | Real-time filter with amber text highlight, result count |
| Module cards | 2-column grid, progress bar, Grant all / Revoke all per module |
| Toggle switches | Replaces checkboxes, smooth animation |
| Unsaved changes | Accumulates changes, shows count banner, batch-saves on confirm |
| Layer | Technology | Version |
|---|---|---|
| Frontend framework | React | 18 |
| Build tool | Vite | 5 |
| Styling | Tailwind CSS | 3 |
| Component library | shadcn/ui (Radix primitives) | latest |
| Global state | Zustand | 4 |
| Server state + cache | TanStack React Query | 5 |
| Forms | React Hook Form + Zod | 7 + 3 |
| Charts | Recharts | 2 |
| Routing | React Router | 6 |
| Icons | Lucide React | latest |
| Toast notifications | Sonner | latest |
| HTTP client | Axios | latest |
| Backend | Node.js + Express | 18+ / 4 |
| Database ORM | Prisma | 5 |
| Database | MySQL | 8+ |
| Auth | JWT (jsonwebtoken + bcryptjs) | latest |
| Validation (backend) | Zod | 3 |
dashboard/
βββ frontend/ # React + Vite app
β βββ src/
β β βββ api/
β β β βββ axiosClient.js # Axios instance + auth interceptors
β β β βββ tokenStore.js # In-memory access token (no localStorage)
β β βββ components/
β β β βββ charts/ # UserGrowth, LoginActivity, RoleDistribution, ModuleUsage
β β β βββ common/ # KPICard, DataTable, Badge, Modal, ConfirmDialog,
β β β β # StatCard, PageHeader, SystemStatus, QuickActions
β β β βββ layout/ # AppLayout, Sidebar (collapsible + groups), Topbar
β β βββ config/
β β β βββ app.config.js # Branding, theme, API URL, pagination
β β β βββ modules.config.js # Module definitions (sidebar, routes, permissions)
β β βββ guards/
β β β βββ AuthGuard.jsx # Redirect to /login if unauthenticated
β β β βββ PermissionGuard.jsx # Hide/show based on permission name
β β βββ hooks/
β β β βββ useDebounce.js
β β β βββ usePermission.js # Returns boolean from permission store
β β βββ pages/
β β β βββ auth/ # LoginPage
β β β βββ audit-logs/ # AuditLogsPage
β β β βββ dashboard/ # DashboardPage (full featured)
β β β βββ permissions/ # PermissionsPage (redesigned)
β β β βββ roles/ # RolesPage + RoleFormModal
β β β βββ settings/ # SettingsPage (profile, password, theme)
β β β βββ users/ # UsersPage + UserFormModal
β β βββ router/index.jsx # Dynamic routes from modules.config
β β βββ stores/
β β β βββ authStore.js # User, isAuthenticated, isLoading, init/login/logout
β β β βββ permissionStore.js # Permission list + hasPermission()
β β β βββ uiStore.js # Dark mode, sidebar collapsed state
β β βββ utils/
β β βββ exportCsv.js
β β βββ formatDate.js # formatDate, formatDateTime, formatRelativeTime
β βββ .env # VITE_API_URL (empty = use Vite proxy)
β βββ .env.example
β βββ vite.config.js # Proxy /api β localhost:5001
β βββ tailwind.config.js
β
βββ backend/ # Node.js + Express API
β βββ prisma/
β β βββ schema.prisma # User, Role, Permission, RolePermission,
β β β # RefreshToken, AuditLog
β β βββ seed.js # Seeds roles, permissions, admin user
β βββ src/
β βββ app.js # Express app entry point
β βββ config/
β β βββ modules.config.js # Mirror of frontend modules config
β βββ middleware/
β β βββ auth.middleware.js # JWT verification β req.user
β β βββ permission.middleware.js # requirePermission() factory
β β βββ audit.middleware.js # Auto-logs all write operations
β βββ modules/
β β βββ analytics/ # 5 aggregation endpoints for dashboard charts
β β βββ audit-logs/ # Paginated log query + CSV export
β β βββ auth/ # Login, refresh, logout, forgot/reset password
β β βββ permissions/ # Permission list + role-permission matrix
β β βββ roles/ # Role CRUD + toggle permission endpoint
β β βββ users/ # User CRUD + /me self-service endpoints
β βββ routes/index.js # Auto-loads module routes from modules.config
β
βββ scripts/
β βββ setup.js # One-command project setup
βββ docs/
β βββ GETTING_STARTED.md
β βββ ADDING_A_MODULE.md
β βββ RBAC_GUIDE.md
β βββ CONFIG_REFERENCE.md
β βββ DEPLOYMENT.md
βββ package.json # Root: npm run setup / npm run dev
βββ Promot.md # Master AI prompt file (10 build prompts)
| Requirement | Version |
|---|---|
| Node.js | 18 or higher |
| MySQL | 8 or higher |
| npm | 9 or higher |
macOS users: Port 5000 is used by AirPlay Receiver. This project uses port 5001 for the backend. If you need to change it, update
backend/.envβPORT=andfrontend/vite.config.jsβtarget:.
git clone https://github.com/yourteam/admin-template.git my-project
cd my-project
# Remove template git history and start fresh
rm -rf .git
git init && git add . && git commit -m "initial: from admin-template v1.0"Open backend/.env (copy from .env.example if it doesn't exist):
DATABASE_URL=mysql://root:your-password@localhost:3306/admin_db
JWT_ACCESS_SECRET=<generate a 64-char random string>
JWT_REFRESH_SECRET=<generate a different 64-char random string>
JWT_ACCESS_EXPIRY=15m
JWT_REFRESH_EXPIRY=7d
PORT=5001
CLIENT_URL=http://localhost:5173
NODE_ENV=developmentGenerate secrets:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"node scripts/setup.jsThis automatically:
- β Checks Node.js version
- β Copies
.env.exampleβ.envfor both frontend and backend - β Runs
npm installinfrontend/andbackend/ - β Generates Prisma client
- β Runs database migrations
- β Seeds default roles, permissions, and admin user
npm run devThis starts both servers concurrently:
| Server | URL |
|---|---|
| Frontend (Vite) | http://localhost:5173 |
| Backend (Express) | http://localhost:5001 |
Open http://localhost:5173 and sign in with:
| Field | Value |
|---|---|
admin@admin.com |
|
| Password | Admin@1234 |
| Role | Access |
|---|---|
| Admin | Full access to all modules and actions |
| Editor | View + Create + Edit on most modules. No delete, no role management |
| Viewer | Read-only (.view permissions only) |
| Moderator | View + Edit on most modules |
Permissions follow the module.action naming convention:
users.view users.create users.edit users.delete users.reset_password
roles.view roles.create roles.edit roles.delete
permissions.view permissions.edit
logs.view logs.export
settings.view settings.edit
analytics.view
Adding a module touches one config file β everything else wires up automatically.
# Step 1: Add to modules.config.js (frontend + backend)
{
key: 'products',
label: 'Products',
icon: 'Package',
path: '/products',
core: false,
permissions: ['products.view', 'products.create', 'products.edit', 'products.delete'],
}
# Step 2: Create 3 frontend files
frontend/src/pages/products/
βββ productsApi.js # Axios wrappers
βββ ProductsPage.jsx # Table + search + pagination
βββ ProductFormModal.jsx # Add/Edit form (React Hook Form + Zod)
# Step 3: Create 4 backend files
backend/src/modules/products/
βββ products.schema.js # Zod validation
βββ products.service.js # Prisma queries
βββ products.controller.js # HTTP handlers
βββ products.routes.js # Express routes + middleware
# Step 4: Add Prisma model + migrate
cd backend
npx prisma migrate dev --name add_products
# Step 5: Seed new permissions
npm run seedSee docs/ADDING_A_MODULE.md for the full guide with complete working code.
To group modules under a collapsible parent in the sidebar:
// modules.config.js β add group: 'key' to any module
{ key: 'users', group: 'user-management', ... }
{ key: 'roles', group: 'user-management', ... }
{ key: 'permissions', group: 'user-management', ... }
// Sidebar.jsx β define the group label and icon
const GROUP_META = {
'user-management': {
label: 'User Management',
icon: 'UsersRound',
},
}The sidebar automatically:
- Renders a collapsible section for the group
- Opens it when a child route is active
- Shows a flyout submenu in collapsed mode
export const appConfig = {
appName: 'Admin Dashboard', // Sidebar header + browser tab
appLogo: '/logo.svg',
theme: {
primaryColor: '#3b82f6', // Change accent color per project
darkMode: false, // Default theme
},
pagination: { defaultPageSize: 10 },
api: {
baseUrl: '', // Empty = use Vite proxy (recommended in dev)
// Set to https://api.yourdomain.com in production
},
}VITE_API_URL= # Leave empty in dev (Vite proxy handles it)
# Set to https://api.yourdomain.com in production
VITE_APP_NAME=Admin Dashboard# Build
cd frontend && npm run build
# Set environment variable in Vercel/Netlify dashboard:
VITE_API_URL=https://your-api-domain.comAdd frontend/public/_redirects for Netlify SPA routing:
/* /index.html 200
npm install -g pm2
pm2 start backend/src/app.js --name admin-api
pm2 save && pm2 startupProduction .env checklist:
NODE_ENV=production
JWT_ACCESS_SECRET=<64-char random> # NOT the dev default
JWT_REFRESH_SECRET=<64-char random> # Different from access secret
DATABASE_URL=mysql://user:pass@host/db
CLIENT_URL=https://your-frontend.comSee docs/DEPLOYMENT.md for full Nginx config and SSL setup.
| File | Description |
|---|---|
| docs/GETTING_STARTED.md | Prerequisites, clone, setup, common errors |
| docs/ADDING_A_MODULE.md | Step-by-step with full working code example |
| docs/RBAC_GUIDE.md | How to guard pages, buttons, and API endpoints |
| docs/CONFIG_REFERENCE.md | Every config field documented with examples |
| docs/DEPLOYMENT.md | Vercel, Netlify, VPS, PM2, Nginx, SSL |
| Promot.md | Master AI prompt file β 10 prompts that built this template |
Every new project follows this exact sequence:
Plan β Configure β Setup β Database β Backend β Frontend
β Permissions β Dashboard β QA β Deploy
Every new module follows:
Config β Database β Backend β Frontend β Permissions β Test
Golden rule: Never skip phases. Building out of order breaks the template's assumptions.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m 'add: my feature' - Push:
git push origin feature/my-feature - Open a Pull Request
MIT License β free for personal and commercial use.
Built with React 18 Β· Tailwind CSS Β· shadcn/ui Β· Node.js Β· Express Β· MySQL Β· Prisma Auth: JWT Β· State: Zustand Β· Charts: Recharts Β· Forms: React Hook Form + Zod






