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" }).
| Surface | Current status |
|---|---|
dashboard.vue | Example/UI starter — hardcoded table rows and chart/summary data |
admin/users.vue | Integrated read path — fetches real users from a role-guarded API |
account/subscription.vue | Integrated read path — loads the current database subscription |
setting/profile.vue | Integrated basic update — reads session data and updates name/avatar URL |
account/order.vue | Placeholder — text only |
setting/billing.vue | Placeholder — text only |
setting/security.vue | Placeholder — 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.vueprovides summary cards with static example figures.ChartAreaInteractive.vueuses@unovis/vuewith a hardcoded time series.DataTable.vue,DraggableRow.vue, andDragHandle.vueuse@tanstack/vue-tableand dnd-kit for a sortable example table.UsersTable.vuerenders 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
| API | Backing behavior |
|---|---|
GET/PUT /api/user/profile | Real authenticated profile read/update |
GET /api/user/subscription | Real Drizzle subscription record plus plan lookup |
GET /api/user/settings | Authenticated, but returns example preference/security data |
GET /api/user/billing | Authenticated, 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.
