nuxt-x-app-admin
nuxt-x-app-admin
Admin portal layer for Nuxt 4 apps. Extends nuxt-x-app with 43 XAdmin-prefixed components and 10 composables organized by domain: Dashboard, Users (Better Auth), Stripe, Content, Support, AI, Roles & Permissions, Tenants, Audit Logs, and Impersonation. The layer provides UI and composables only — your backend provides the API endpoints.
Installation
npm install @xenterprises/nuxt-x-app-admin
// nuxt.config.ts
export default defineNuxtConfig({
extends: [
"nuxt-x-app-admin", // automatically includes nuxt-x-app
"nuxt-x-auth", // Better Auth for admin sessions
],
});
Components
All components use the XAdmin prefix and are auto-imported.
Dashboard
| Component | Description |
|---|---|
XAdminDashboard | Complete dashboard layout with all widgets. |
XAdminDashboardMetrics | Configurable metrics grid. |
XAdminDashboardRevenueChart | Revenue trends with area chart. |
XAdminDashboardActivityChart | User activity line chart. |
XAdminDashboardUsageChart | Resource usage donut chart. |
XAdminDashboardSystemChart | CPU/Memory/Disk metrics. |
XAdminDashboardSystemHealth | System health status monitor. |
XAdminDashboardActiveUsers | Real-time active users count. |
XAdminDashboardErrorLog | Recent error log viewer. |
User Management
| Component | Description |
|---|---|
XAdminUsersDirectory | Searchable user directory with filters. |
XAdminUsersProfile | User profile management. |
XAdminUsersDetail | Full user detail with tabs. |
XAdminUsersSessions | Active session management. |
XAdminUsersAccounts | Linked OAuth accounts. |
Stripe Management
| Component | Description |
|---|---|
XAdminStripeCustomers | Customer list with search and filters. |
XAdminStripeCustomersDetail | Customer detail view with subscriptions. |
XAdminStripeCharges | Charge/payment history table. |
XAdminStripeChargesDetail | Charge detail with refund actions. |
XAdminStripeInvoices | Invoice management list. |
XAdminStripeInvoicesDetail | Invoice detail with refund/void actions. |
XAdminStripeSubscriptions | Subscription management. |
XAdminStripeSubscriptionsDetail | Subscription detail with cancel options. |
XAdminStripePaymentMethods | Payment method list. |
XAdminStripeWebhookLogs | Webhook event audit trail. |
Content Management
| Component | Description |
|---|---|
XAdminContentPosts | Blog/content post list with filters. |
XAdminContentPostsEditor | Rich post editor with SEO settings. |
XAdminContentMedia | Media library with grid/list views. |
Support Queue
| Component | Description |
|---|---|
XAdminSupportTickets | Support ticket queue with stats. |
XAdminSupportTicketsDetail | Ticket conversation view with reply. |
AI / Agents
| Component | Description |
|---|---|
XAdminAIChat | AI chat interface. |
XAdminAIAgents | Agent management list. |
XAdminAIAgentEditor | Agent configuration editor. |
Roles & Permissions
| Component | Description |
|---|---|
XAdminRolesList | Role list with user counts. |
XAdminRolesEditor | Role creation/edit with permissions. |
XAdminRolesPermissionMatrix | Visual permission grid. |
XAdminRolesAssignModal | Assign roles to users. |
Tenant Management
| Component | Description |
|---|---|
XAdminTenantsDirectory | Tenant list with search and filters. |
XAdminTenantsDetail | Tenant detail view with tabs. |
XAdminTenantsSettings | Tenant settings and feature flags. |
XAdminTenantsBilling | Tenant billing and usage metrics. |
Audit & Security
| Component | Description |
|---|---|
XAdminAuditLog | System-wide activity log viewer. |
XAdminImpersonationBanner | Warning banner when impersonating a user. |
XAdminImpersonationSwitcher | Modal to select a user to impersonate. |
Composables
useXAdminDashboard(options?)
const dashboard = useXAdminDashboard({ refreshInterval: 30000 });
dashboard.health.value
dashboard.metrics.value
dashboard.activeUsers.value
dashboard.revenueHistory.value
await dashboard.refreshAll();
useXAdminUsers()
const admin = useXAdminUsers();
await admin.updateRole(userId, "editor");
await admin.suspendUser(userId, "Violation of TOS");
await admin.unsuspendUser(userId);
await admin.resetPassword(userId);
await admin.deleteUser(userId, { hardDelete: false });
useXAdminStripe()
const stripe = useXAdminStripe();
stripe.customers.data
stripe.subscriptions.data
await stripe.syncCustomer(customerId);
await stripe.cancelSubscription(subscriptionId, { immediately: false });
await stripe.refundInvoice(invoiceId, { amount: 1000 });
await stripe.voidInvoice(invoiceId);
useXAdminContent()
const content = useXAdminContent();
await content.publishPost(postId);
await content.unpublishPost(postId);
await content.duplicatePost(postId);
await content.uploadMedia(files, { folder: "images" });
useXAdminSupport()
const support = useXAdminSupport();
await support.assignTicket(ticketId, agentId);
await support.closeTicket(ticketId, "Resolved");
await support.replyToTicket(ticketId, "Hello!", { close: true });
useXAdminAI()
const ai = useXAdminAI();
await ai.selectAgent(agentId);
await ai.sendMessage("Hello!");
await ai.streamMessage("Generate a report", (chunk) => console.log(chunk));
await ai.createAgent({ name: "Support Bot", systemPrompt: "..." });
useXAdminRoles()
const roles = useXAdminRoles();
await roles.updatePermissions(roleId, ["perm1", "perm2"]);
await roles.assignRole(userId, roleId);
await roles.revokeRole(userId, roleId);
roles.hasPermission(roleId, "users:delete");
useXAdminTenants()
const tenants = useXAdminTenants();
await tenants.suspend(tenantId, "Violation reason");
await tenants.activate(tenantId);
await tenants.updatePlan(tenantId, "enterprise");
await tenants.updateSettings(tenantId, { maxUsers: 100 });
useXAdminAuditLog()
const auditLog = useXAdminAuditLog();
await auditLog.getLogsByUser(userId);
await auditLog.getLogsByResource("users", userId);
await auditLog.exportLogs("csv");
useXAdminImpersonation()
const impersonation = useXAdminImpersonation();
impersonation.isImpersonating.value
impersonation.impersonatedUser.value
await impersonation.startImpersonation(userId);
await impersonation.stopImpersonation();
API Endpoints Expected
The layer calls these backend routes — your backend must implement them:
| Domain | Routes |
|---|---|
| Dashboard | GET /api/admin/dashboard/health, /metrics, /active-users, /errors, /charts/* |
| Users | GET/POST /api/admin/users, GET/PUT/DELETE /api/admin/users/:id, ban/unban/reset-password |
| Stripe | Customers, charges, subscriptions, invoices, webhook-logs under /api/admin/stripe/* |
| Content | Posts (publish/unpublish/duplicate), media upload under /api/admin/content/* |
| Support | Tickets (assign/close/reopen/reply), agents, stats under /api/admin/support/* |
| AI | Agents, conversations, chat, stream under /api/admin/ai/* |
| Roles | CRUD, permissions, assign/revoke under /api/admin/roles/* |
| Tenants | CRUD, suspend/activate/plan/settings under /api/admin/tenants/* |
| Audit | GET /api/admin/audit-log, POST /api/admin/audit-log/export |
| Impersonation | POST /api/admin/impersonation/start, /stop, GET .../status |
Environment Variables
This layer does not read env vars directly. The backend API it calls typically needs:
| Variable | Required | Description |
|---|---|---|
STRIPE_SECRET_KEY | Yes (backend) | Stripe API key for billing management. |
STRIPE_WEBHOOK_SECRET | Yes (backend) | Stripe webhook signing secret. |
BETTER_AUTH_SECRET | Yes (backend) | Better Auth session secret. |
NUXT_PUBLIC_API_BASE | No | Override API base URL (default: /api). |
Error Handling
All composables follow a consistent pattern:
| Error Source | Behavior |
|---|---|
$fetch failure | Toast shown (if showToast: true), error re-thrown. |
| Invalid input | Caught by backend, returned as typed error. |
| Network timeout | Toast with "Failed to..." message, error re-thrown. |
Pass showToast: false to suppress toasts and handle errors manually.
How It Works
nuxt-x-app-admin is a Nuxt layer that extends nuxt-x-app. Extending it automatically includes all base-layer components, composables, and utilities.
Components live under app/components/XAdmin/ and are auto-registered with the XAdmin prefix. Each component is self-contained: pass an endpoint prop and it handles fetching, loading states, pagination, and actions using useXCrud from the base layer.
Composables live under app/composables/ and wrap $fetch with toast notifications, error handling, and reactive state. They use useXCrud for list/detail CRUD and raw $fetch for domain-specific actions (suspend, impersonate, refund, stream, etc.).
Types are exported from app/types/index.ts and define shapes for AdminUser, AuditLogEntry, Tenant, Role, Permission, Stripe objects, and more.
The layer's nuxt.config.ts configures extends: ['../nuxt-x-app'], sets up component auto-import from ./app/components, and adds composable auto-import from ./app/composables.
The layer does not include server routes — your backend implements all /api/admin/* endpoints.
