A production-like admin dashboard that demonstrates senior-level UI architecture and API design: server-side pagination/filtering/sorting, accessible interactions, strong loading/empty/error states, tests, and CI.
Built with Next.js, TypeScript, Postgres, Prisma, TanStack Table, and Zod.
- Live: https://admin-workbench.vercel.app/
- Demo GIF:
- Production-like data UI: server-side pagination, filtering, sorting (not “toy app” client filtering)
- UX that holds up: URL-persisted state, responsive layout, clear empty/error/loading states
- Accessibility: keyboard navigation, focus management, aria labels
- Contracts: validated input and consistent API responses
- Quality: tests that prove behavior + CI that enforces it
- Deployment: GitHub → Vercel + Neon Postgres
- KPI cards (7/30 day views)
- Charts: events over time, errors by type
- Global filters (date range, environment) persisted in the URL
- Server-side pagination (
page,pageSize) - Server-side filtering (status/type/source/date range/search)
- Server-side sorting (
sort=occurredAt:desc) - Row details drawer with JSON payload viewer + copy
- Roles:
admin,analyst,viewer - Admin can create/deactivate users and manage roles
- Audit log records admin actions
- Paginated + filterable log of admin actions
- Useful for demonstrating “operational thinking”
- Next.js (App Router) + React + TypeScript
- Tailwind CSS + shadcn/ui
- Postgres (Neon for production, Docker for local)
- Prisma (schema + migrations + seed)
- TanStack Table (data table UX)
- Recharts (charts)
- Zod (API input validation)
- iron-session (signed-cookie sessions, demo auth)
- Jest / RTL (unit + component tests)
- Playwright (E2E tests)
- GitHub Actions (CI)
graph LR
U[Browser] --> N[Nextjs app]
N --> A[Route handlers]
A --> D[Postgres]
N --> C[React UI]
- Server-side data operations: pagination/filtering/sorting happens in the API to keep the UI scalable.
- URL-driven state: filters and table state are encoded in query params for shareable links.
- Consistent API shape for list endpoints:
{ (data, page, pageSize, total, totalPages); }
- Demo auth with RBAC: minimal implementation that still enforces roles server-side.
events: time-series operational/admin data (status/type/source/payload)users,roles,user_roles: access controlaudit_log: records administrative actions
See: prisma/schema.prisma
This is a Next.js project bootstrapped with
create-next-app.
- Node 18+ (20+ recommended)
- Docker Desktop (for local Postgres)
git clone https://github.com/<your-handle>/admin-workbench.git
cd admin-workbench
npm installdocker compose up -dCreate .env.local (use .env.example as a starting point):
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/admin_workbench"
SESSION_PASSWORD="change-me-to-32+chars-min"npm run db:migrate
npm run db:seednpm run dev
# or
yarn dev
# or
pnpm dev
# or
bun devYou can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
npm run dev # run locally
npm run build # production build
npm run start # run production server
npm run lint # lint
npm run typecheck # TS checks
npm run format # prettier
npm run test # unit/component tests (Jest)
npm run test:e2e # Playwright
npm run db:migrate # prisma migrate dev
npm run db:deploy # prisma migrate deploy
npm run db:seed # seed sample data
npm run db:studio # prisma studionpm run testnpm run test:e2eSuggested E2E flows:
- Filter events to
status=error→ open details drawer → copy payload - Change date range → KPIs and charts update
This project aims to be keyboard-usable and screen-reader friendly:
- Visible focus states
- Table controls labeled with aria attributes
- Drawer focus trap + escape handling
- Logical heading structure and tab order
Checklist: docs/a11y-checklist.md
GitHub Actions runs on PR:
- Lint
- Typecheck
- Unit tests
- Build
- (Optional) E2E tests
Add badge once CI is set up:
- Create a Neon database and copy the connection string.
- Create a Vercel project from this GitHub repo.
- Add env vars in Vercel:
DATABASE_URLSESSION_PASSWORD
- Deploy.
To learn more about Next.js, take a look at:
- Next.js Documentation - features and API
- Learn Next.js - interactive tutorial
- Next.js GitHub repository - feedback and contributions welcome
This project uses next/font to automatically optimize and load Geist.
You can also review Next.js deployment guidance here:
- Saved views (named filter presets)
- CSV export (server-generated)
- Cursor-based pagination for large datasets
- Rate limiting + security headers
- Observability (structured logs and dashboards)
MIT
