A modern, full-stack admin dashboard built with React, TypeScript, and Vite. Features a responsive layout with navigation, user management, assessment tracking, and analytics dashboard with mock API integration. Optimized with lazy-loaded routes, virtualized lists, and Web Vitals monitoring.
- Responsive Design β Mobile-first layout with collapsible navigation
- User Management β View and manage user accounts
- Assessment Tracking β Create, view, and manage assessments with paginated tables
- Dashboard Analytics β Overview of key metrics and statistics
- Lazy-Loaded Routes β Code splitting for optimal initial load performance
- Efficient Tables β Paginated tables for assessments and users
- Mock API β Built-in Express server for development
- React Query β Efficient data fetching and caching
- Toast Notifications β User-friendly feedback system
- Dark/Light Theme Toggle β Switch between dark and light themes from the header; Tailwind configured for
class-based dark mode
- React 18 β UI library
- TypeScript β Type-safe development
- Vite β Fast build tool and dev server
- React Router β Client-side routing with lazy-loaded components
- TanStack Query (React Query) β Server state management
- Tailwind CSS β Utility-first CSS framework
- (note)
react-windowwas explored but removed from the assessments table due totable/tbodycompatibility; the app uses paginated standard tables.
- Express.js β Node.js web framework
- CORS β Cross-origin resource sharing
- TypeScript β Type-safe backend
- Vitest β Unit testing framework
- Testing Library β React component testing
- ESLint β Code linting (flat config)
- Prettier β Code formatting
- Husky β Git hooks
- lint-staged β Pre-commit checks
- Docker β Containerization
- Fly.io β Platform for deployment
- Node.js 18+ and npm
- (Optional) Docker for containerized deployment
-
Clone the repository
git clone <repository-url> cd admin-dashboard
-
Install dependencies
npm install
-
Start the development server (Vite dev server on port 5173)
npm run dev
The app will open at
http://localhost:5173 -
Start the mock API server (in a separate terminal on port 3001)
npm run api
API endpoints:
http://localhost:3001 -
Verify the setup
- Frontend should be running at
http://localhost:5173 - API should be running at
http://localhost:3001 - Navigation menu shows Dashboard, Assessments, and Users routes
- Lazy-loaded routes will show loading spinner on first navigation
- Frontend should be running at
npm run devβ Start Vite dev server with HMRnpm run apiβ Start mock Express API servernpm run buildβ Create optimized production buildnpm run previewβ Preview production build locally
npm testβ Run Vitest once with verbose reporter (suitable for CI, equivalent tonpx vitest run --reporter verbose)npm run test:watchβ Run Vitest in interactive watch mode (developer workflow)
Vitest is configured to only include project tests β src/**/*.test.{ts,tsx} β and explicitly excludes node_modules and e2e/.
npm run coverageβ Run tests with coverage reportnpm run lintβ Run ESLint on all filesnpm run typecheckβ Run TypeScript type checkingnpm run formatβ Check Prettier formattingnpm run format:writeβ Apply Prettier formatting fixes
npm run storybookβ Start Storybook dev servernpm run build-storybookβ Build Storybook static site
npm run test:e2eβ Run Playwright end-to-end tests
# Install and run everything
npm install
# Terminal 1: Frontend dev server
npm run dev
# Terminal 2: Mock API server
npm run api
# Terminal 3 (optional): Watch tests
npm testThen navigate to http://localhost:5173 in your browser.
Routes are code-split using React.lazy() and Suspense:
- Dashboard β Loads on demand at
/dashboard - Assessments β Loads on demand at
/assessments - Users β Loads on demand at
/users
This reduces initial bundle size and improves Time to Interactive (TTI).
The Assessments page renders a paginated, sortable table with create/edit/delete flows and server-driven pagination. Note: react-window was explored for virtualization but removed after it proved incompatible with <table>/<tbody> semantics β pagination and standard rendering are used for compatibility and accessibility.
Key behaviors:
- Sorting by column headers
- Pagination controls for navigating pages
- Modal form for create & edit actions (
AssessmentForm) - Confirmation-driven deletes and toast notifications
The production build automatically splits code into:
index.jsβ Main app shellDashboard.jsβ Dashboard page chunkAssessments.jsβ Assessments page chunkUsers.jsβ Users page chunk
admin-dashboard/
βββ api/
β βββ server.ts # Express mock API server
βββ src/
β βββ api/ # API client functions
β β βββ assessments.ts
β β βββ client.ts
β β βββ dashboard.ts
β β βββ health.ts
β β βββ users.ts
β βββ assets/ # Static assets
β βββ components/ # Reusable components
β β βββ AssessmentForm.tsx
β β βββ Layout.tsx # Main layout with nav
β β βββ Modal.tsx
β β βββ ToastContainer.tsx
β βββ contexts/ # React context providers
β β βββ ToastContext.tsx
β βββ lib/ # Libraries and utilities
β β βββ queryClient.ts
β β βββ performanceMetrics.ts (optional)
β βββ pages/ # Page components (lazy-loaded)
β β βββ Dashboard.tsx
β β βββ Assessments.tsx # Virtualized table
β β βββ Users.tsx
β βββ App.tsx # Main app component
β βββ main.tsx # Entry point with routing
β βββ index.css
βββ e2e/ # Playwright E2E tests
βββ Dockerfile # Docker configuration
βββ fly.toml # Fly.io deployment config
βββ vite.config.ts # Vite + Vitest config
βββ package.json # Dependencies and scripts
npm test- Tests located in
src/alongside components - Uses Vitest and Testing Library
- Accessibility checks using axe-core (see
src/App.a11y.test.tsx) β axe runs in the Vitest environment and the color-contrast rule is disabled by default to avoid jsdom false positives - Jest-DOM matchers in
src/setupTests.ts - Watch mode enabled by default
npm run coverageGenerates coverage reports in coverage/ directory.
npm run test:e2ePlaywright tests are located in the e2e/ directory and include flows for Dashboard, Assessments (listing, create modal, error handling) and Users (listing and filters). The Playwright config includes a webServer entry so the dev server (npm run dev) is started automatically when running npm run test:e2e locally; you don't need to start the dev server manually. Use npx playwright show-report to open the last HTML report.
Husky automatically enforces quality checks:
# Pre-commit hook runs:
- ESLint (zero warnings)
- Prettier format check
- lint-staged on staged filesAll checks must pass before committing.
Build and run containerized:
# Build image
docker build -t admin-dashboard .
# Run container
docker run -p 5173:5173 -p 3001:3001 admin-dashboardAccess at http://localhost:5173
Configuration in fly.toml. Deploy with:
# Install Fly CLI: https://fly.io/docs/getting-started/installing-flyctl/
fly deployConfiguration in vercel.json. Deploy from Git or:
# Install Vercel CLI
npm i -g vercel
vercel- ESLint uses modern flat config (
eslint.config.mts) - Vitest configured in
vite.config.ts - TailwindCSS dark theme with custom color tokens
- React Query client in
src/lib/queryClient.ts - Lazy routes with loading UI in
src/main.tsx - Paginated tables with standard rendering (react-window removed from
src/pages/Assessments.tsxfor compatibility)
- Create a feature branch
- Make changes
- Ensure all tests pass:
npm test - Ensure no lint errors:
npm run lint - Format code:
npm run format:write - Commit (git hooks will validate)
- Open a pull request
This project is private and not licensed for public use.