X Enterprises

nuxt-x-app-admin

Nuxt layer for admin portals — user management, Stripe billing, content, support ticketing, AI assistants, roles, tenants, audit logs, and impersonation. Extends nuxt-x-app.

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

ComponentDescription
XAdminDashboardComplete dashboard layout with all widgets.
XAdminDashboardMetricsConfigurable metrics grid.
XAdminDashboardRevenueChartRevenue trends with area chart.
XAdminDashboardActivityChartUser activity line chart.
XAdminDashboardUsageChartResource usage donut chart.
XAdminDashboardSystemChartCPU/Memory/Disk metrics.
XAdminDashboardSystemHealthSystem health status monitor.
XAdminDashboardActiveUsersReal-time active users count.
XAdminDashboardErrorLogRecent error log viewer.

User Management

ComponentDescription
XAdminUsersDirectorySearchable user directory with filters.
XAdminUsersProfileUser profile management.
XAdminUsersDetailFull user detail with tabs.
XAdminUsersSessionsActive session management.
XAdminUsersAccountsLinked OAuth accounts.

Stripe Management

ComponentDescription
XAdminStripeCustomersCustomer list with search and filters.
XAdminStripeCustomersDetailCustomer detail view with subscriptions.
XAdminStripeChargesCharge/payment history table.
XAdminStripeChargesDetailCharge detail with refund actions.
XAdminStripeInvoicesInvoice management list.
XAdminStripeInvoicesDetailInvoice detail with refund/void actions.
XAdminStripeSubscriptionsSubscription management.
XAdminStripeSubscriptionsDetailSubscription detail with cancel options.
XAdminStripePaymentMethodsPayment method list.
XAdminStripeWebhookLogsWebhook event audit trail.

Content Management

ComponentDescription
XAdminContentPostsBlog/content post list with filters.
XAdminContentPostsEditorRich post editor with SEO settings.
XAdminContentMediaMedia library with grid/list views.

Support Queue

ComponentDescription
XAdminSupportTicketsSupport ticket queue with stats.
XAdminSupportTicketsDetailTicket conversation view with reply.

AI / Agents

ComponentDescription
XAdminAIChatAI chat interface.
XAdminAIAgentsAgent management list.
XAdminAIAgentEditorAgent configuration editor.

Roles & Permissions

ComponentDescription
XAdminRolesListRole list with user counts.
XAdminRolesEditorRole creation/edit with permissions.
XAdminRolesPermissionMatrixVisual permission grid.
XAdminRolesAssignModalAssign roles to users.

Tenant Management

ComponentDescription
XAdminTenantsDirectoryTenant list with search and filters.
XAdminTenantsDetailTenant detail view with tabs.
XAdminTenantsSettingsTenant settings and feature flags.
XAdminTenantsBillingTenant billing and usage metrics.

Audit & Security

ComponentDescription
XAdminAuditLogSystem-wide activity log viewer.
XAdminImpersonationBannerWarning banner when impersonating a user.
XAdminImpersonationSwitcherModal 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:

DomainRoutes
DashboardGET /api/admin/dashboard/health, /metrics, /active-users, /errors, /charts/*
UsersGET/POST /api/admin/users, GET/PUT/DELETE /api/admin/users/:id, ban/unban/reset-password
StripeCustomers, charges, subscriptions, invoices, webhook-logs under /api/admin/stripe/*
ContentPosts (publish/unpublish/duplicate), media upload under /api/admin/content/*
SupportTickets (assign/close/reopen/reply), agents, stats under /api/admin/support/*
AIAgents, conversations, chat, stream under /api/admin/ai/*
RolesCRUD, permissions, assign/revoke under /api/admin/roles/*
TenantsCRUD, suspend/activate/plan/settings under /api/admin/tenants/*
AuditGET /api/admin/audit-log, POST /api/admin/audit-log/export
ImpersonationPOST /api/admin/impersonation/start, /stop, GET .../status

Environment Variables

This layer does not read env vars directly. The backend API it calls typically needs:

VariableRequiredDescription
STRIPE_SECRET_KEYYes (backend)Stripe API key for billing management.
STRIPE_WEBHOOK_SECRETYes (backend)Stripe webhook signing secret.
BETTER_AUTH_SECRETYes (backend)Better Auth session secret.
NUXT_PUBLIC_API_BASENoOverride API base URL (default: /api).

Error Handling

All composables follow a consistent pattern:

Error SourceBehavior
$fetch failureToast shown (if showToast: true), error re-thrown.
Invalid inputCaught by backend, returned as typed error.
Network timeoutToast 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.

Copyright © 2026