Dashboard & Admin

Turn the template's dashboard examples into connected product surfaces.

The template provides a polished dashboard shell and several Example or UI starter pages. The shell is connected to authentication; most business data and mutations are intentionally left for your product.

Dashboard shell

The client layout at src/app/[locale]/(dashboard)/layout.tsx composes:

  • A collapsible shadcn sidebar and route config from src/config/user-sidebar-config.ts.
  • A sticky header with sidebar trigger, path-derived breadcrumbs, language toggle, and theme toggle.
  • DashboardSideUser, which reads useSession() for the user name, email, and avatar and calls signOut().
  • Dashboard, admin, account, profile, security, and billing navigation.

What is connected today

SurfaceStatusCurrent behavior
Dashboard shell/user menuIntegratedSession-backed identity and sign-out; responsive shell
/api/user/profileIntegratedAuthenticated GET/PUT against the user table with Zod validation
/api/user/subscriptionIntegratedAuthenticated read from the subscription table
/api/user/settingsExampleReads real sessions but returns static preference/security defaults
/api/user/billingExampleAuthenticated, but subscription/billing/usage payload is static
/api/admin/usersIntegratedAuth + admin role check, filters, pagination, database reads
Payment recordsIntegratedCreem webhooks can populate order/subscription tables

Every user API performs an authoritative Better Auth session check. The admin API additionally requires session.user.role === "admin" and returns 401 or 403 before querying users.

What is sample UI

Page/componentStatusWork remaining
Dashboard cards/chart/tableExampleValues and rows are constants inside SectionCards, ChartAreaInteractive, and DataTable
/admin/users pageExampleUses mockUsers; actions do not call the real admin API
/account/subscriptionExampleDisplays mockSubscription (including a Stripe label), not the Creem subscription table/API
/account/orderUI starterStatic empty state; does not query orders
/setting/billingUI starter“Coming soon” empty state
/setting/securityUI starter“Coming soon” empty state; no password/2FA/session actions
/setting/profileUI starterReads useSession, but Save and Upload have no handlers

Do not treat the /admin/users page as role-gated. src/proxy.ts only checks for a Better Auth session cookie on /admin; it does not validate the session or role. The page itself uses mock data, and DashboardSideContent currently does not apply the roles metadata from the sidebar config. Only /api/admin/users performs the authoritative admin check.

The proxy check is an early navigation convenience, not authorization. Protect Server Component reads, Route Handlers, and mutations at the data boundary.

Connecting real data

Dashboard metrics

Keep the interactive chart/table as Client Components, but fetch/aggregate data in a Server Component parent and pass plain serializable arrays as props. Move the stats, chartData, and initialData constants out of the components. Parallelize independent database queries with Promise.all.

Admin users

Replace mockUsers with a request to /api/admin/users?page=...&search=..., or move the same query into a server-only data function used by a role-checked Server Component. Keep the API's server-side role check for client requests. Wire ban/edit actions to authenticated, role-checked mutation endpoints; the current dropdown actions are visual only (apart from copying an email).

Account and settings

  • Subscription: read /api/user/subscription and map real Creem product/status fields instead of mockSubscription.
  • Orders: query the order table by the authenticated user ID, never a client- supplied user ID.
  • Profile: call PUT /api/user/profile for Save; upload an avatar through your durable storage flow, then save the returned URL.
  • Security: use Better Auth APIs for password, sessions, and 2FA if enabled.
  • Billing: replace the static /api/user/billing payload with your provider's portal, invoices, payment method, and real usage model.

Implementation checklist

  • Define which metrics, tables, roles, and account actions your product actually needs.
  • Add server-only query functions scoped to session.user.id or tenant ID.
  • Validate a full server session in every protected read and mutation.
  • Add an authoritative admin check to the admin page/layout as well as APIs.
  • Filter unauthorized navigation items for usability (without relying on that filtering for security).
  • Replace constants and mock records with database/API data.
  • Add Zod schemas, mutation handlers, loading/error/empty states, and toast feedback.
  • Implement pagination/filter parameters on the server for large tables.
  • Add audit logging for role, ban, billing, and security changes.
  • Test logged-out, normal-user, admin, empty-data, and provider-failure cases.

On this page