An internal admin dashboard for ops and support teams — search and filter 100,000 users, invite with role and account assignment, suspend or delete in bulk, read a global audit log, and pull reports. Everything is client-side. MSW intercepts all fetch calls and responds from in-memory seed data. The network tab shows real requests because MSW operates at the Service Worker level.
How It Was Built
The user list has 100,000 records. @tanstack/react-virtual renders only the visible rows — the DOM never holds more than ~20 nodes regardless of the total count. Pagination runs on top of it: MSW handles offset and limit, and the total count from the response sizes the scroll container so the scrollbar feels correct. placeholderData: keepPreviousData keeps the current page visible while the next one loads so the layout never jumps.
Filters, search query, role, account, and status all live in useSearchParams. The URL is the source of truth — not component state, not Zustand. Refreshing restores the exact view, the back button navigates filter history, and sharing a link sends someone to the right filtered state.
Auth uses an adaptiveStorage object that routes Zustand's persist middleware to localStorage or sessionStorage based on whether "remember me" was checked — the decision is made at write time. ProtectedRoute reads isAuthenticated and redirects to /login if false.
Every form shares the same Zod schema for its TypeScript type, runtime validation, and error messages. Adding a field means updating one object.
Architecture
MSW (Service Worker)
└─ intercepts fetch()
└─ returns mock JSON from in-memory seed
└─ API layer (src/api/)
└─ React Query hooks (src/hooks/)
└─ components via useQuery / useMutation
├─ server state: cached by React Query
└─ UI state: sidebar, modals, theme in Zustand
Mutation path:
Component calls mutateAsync()
→ API function fires fetch()
→ MSW intercepts, updates in-memory seed
→ React Query invalidates cache key
→ hook re-fetches, UI updates
Stack
| Tool | Version | Role |
|---|---|---|
| React | 19 | UI layer |
| TypeScript | 5 | Strict mode, zero any |
| Vite | 5 | Dev server + build |
| Tailwind CSS | v4 | Styling, dark mode via class strategy |
| shadcn/ui | latest | Accessible UI primitives |
| TanStack Query | 5 | Server state, caching, pagination |
| Zustand | 4 | Auth state + UI state |
| MSW | 2 | API simulation at Service Worker level |
| React Virtual | 3 | Virtual scrolling for 100k row list |
| React Hook Form | 7 | Form state |
| Zod | 3 | Schema validation + TypeScript types |
| React Router | v6 | Nested routes + URL-as-state |
| Playwright | latest | E2E tests |
| Vitest | latest | Unit + integration tests |