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 readsuseSession()for the user name, email, and avatar and callssignOut().- Dashboard, admin, account, profile, security, and billing navigation.
What is connected today
| Surface | Status | Current behavior |
|---|---|---|
| Dashboard shell/user menu | Integrated | Session-backed identity and sign-out; responsive shell |
/api/user/profile | Integrated | Authenticated GET/PUT against the user table with Zod validation |
/api/user/subscription | Integrated | Authenticated read from the subscription table |
/api/user/settings | Example | Reads real sessions but returns static preference/security defaults |
/api/user/billing | Example | Authenticated, but subscription/billing/usage payload is static |
/api/admin/users | Integrated | Auth + admin role check, filters, pagination, database reads |
| Payment records | Integrated | Creem 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/component | Status | Work remaining |
|---|---|---|
| Dashboard cards/chart/table | Example | Values and rows are constants inside SectionCards, ChartAreaInteractive, and DataTable |
/admin/users page | Example | Uses mockUsers; actions do not call the real admin API |
/account/subscription | Example | Displays mockSubscription (including a Stripe label), not the Creem subscription table/API |
/account/order | UI starter | Static empty state; does not query orders |
/setting/billing | UI starter | “Coming soon” empty state |
/setting/security | UI starter | “Coming soon” empty state; no password/2FA/session actions |
/setting/profile | UI starter | Reads 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/subscriptionand map real Creem product/status fields instead ofmockSubscription. - Orders: query the order table by the authenticated user ID, never a client- supplied user ID.
- Profile: call
PUT /api/user/profilefor 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/billingpayload 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.idor 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.
