Dashboard & Admin

Dashboard and admin surfaces in the Nuxt template.

The template combines dashboard Examples, partially connected account pages, and a real admin users foundation under the authenticated user layout. Treat each surface according to its status rather than assuming the whole area is wired.

Layout and surfaces

app/layouts/user.vue provides the responsive sidebar, breadcrumb, theme and language controls, and the main content slot. Pages opt into it with definePageMeta({ layout: "user", middleware: "auth" }).

SurfaceCurrent status
dashboard.vueExample/UI starter — hardcoded table rows and chart/summary data
admin/users.vueIntegrated read path — fetches real users from a role-guarded API
account/subscription.vueIntegrated read path — loads the current database subscription
setting/profile.vueIntegrated basic update — reads session data and updates name/avatar URL
account/order.vuePlaceholder — text only
setting/billing.vuePlaceholder — text only
setting/security.vuePlaceholder — text only

The user sidebar exposes dashboard, admin, order/subscription, profile, and security entries. Menu role filtering is presentation logic; API authorization remains authoritative.

Dashboard components

  • SectionCards.vue provides summary cards with static example figures.
  • ChartAreaInteractive.vue uses @unovis/vue with a hardcoded time series.
  • DataTable.vue, DraggableRow.vue, and DragHandle.vue use @tanstack/vue-table and dnd-kit for a sortable example table.
  • UsersTable.vue renders and filters real admin user data.

Replace the example arrays in both dashboard.vue and ChartAreaInteractive.vue; changing only the table does not make the chart live.

Admin users

admin/users.vue declares middleware: ["auth", "admin"], fetches GET /api/admin/users, and renders loading/error/retry states. The server route independently calls requireAuth, returns 403 unless role === "admin", and supports page, page size, search, role, and banned filters.

Both layers are intentional: client middleware prevents confusing navigation, while the API role check protects data if the page guard is bypassed.

The page currently requests the first 50 users and UsersTable performs local filtering. Wire its controls to the server query/pagination fields for larger datasets.

Connected user APIs

APIBacking behavior
GET/PUT /api/user/profileReal authenticated profile read/update
GET /api/user/subscriptionReal Drizzle subscription record plus plan lookup
GET /api/user/settingsAuthenticated, but returns example preference/security data
GET /api/user/billingAuthenticated, but returns example billing/usage data

The session-backed sidebar user menu uses useSession() for name, email, avatar, and logout. The profile page's “Upload Avatar” action currently prompts for a URL; it is not a file-upload workflow.

Connect live product data

Use useFetch for SSR-friendly initial reads or $fetch for event-driven refresh/mutations. Put sensitive aggregation and ownership checks in Nitro routes, not in the browser.

Define dashboard metrics

Choose product-specific cards, chart series, table columns, time ranges, and roles. Add authenticated aggregation routes with bounded queries.

Replace example data

Fetch metrics in dashboard.vue, pass typed props into the card/chart/table components, and add loading, empty, error, and refresh states.

Finish account/settings pages

Build order history from payment tables, connect real billing/settings state, implement security actions, and replace the avatar prompt with the chosen storage workflow.

Add mutations safely

Zod-validate server inputs, check ownership/role, return stable errors, prevent duplicate submissions, refresh cached data, and record sensitive admin actions.

Verify

  • Logged-out dashboard visits redirect to login and APIs return 401.
  • Non-admin users cannot open the admin page or fetch /api/admin/users.
  • Profile updates and subscription reads operate on the current user only.
  • Mock cards/charts/table rows have been replaced before product launch.
  • Placeholder order, billing, and security pages are implemented or removed.
  • Loading, empty, error, pagination, and mutation states are tested.

On this page