Skip to main content

Admin Dashboard Integration

Integrate your plugin with the AutoDeployBase admin dashboard.

Adding Menu Items

Basic Menu

await sdk.registerAdminMenu({
id: 'my-plugin',
label: 'My Plugin',
icon: 'Plug',
href: '/admin/my-plugin'
});

With Submenu

await sdk.registerAdminMenu({
id: 'my-plugin',
label: 'My Plugin',
icon: 'Plug',
children: [
{
id: 'my-plugin-dashboard',
label: 'Dashboard',
href: '/admin/my-plugin'
},
{
id: 'my-plugin-settings',
label: 'Settings',
href: '/admin/my-plugin/settings'
},
{
id: 'my-plugin-logs',
label: 'Logs',
href: '/admin/my-plugin/logs'
}
]
});

With Permissions

await sdk.registerAdminMenu({
id: 'my-plugin-admin',
label: 'Plugin Admin',
icon: 'Shield',
href: '/admin/my-plugin/admin',
permission: 'super_admin'
});

Available Icons

AutoDeployBase uses Lucide Icons. Common icons:

IconUse Case
LayoutDashboardDashboard
UsersUser management
SettingsSettings
CreditCardPayments
MailEmail
BarChartAnalytics
PackageProducts
ShoppingCartCart/Orders
FileTextContent
BellNotifications
ShieldSecurity
PlugPlugins

Admin Pages

Page Template (Next.js)

templates/next/app/admin/my-plugin/page.tsx
import { getPluginSettings } from '@/lib/settings';
import { MyPluginDashboard } from '@/plugins/my-plugin/components';

export default async function MyPluginPage() {
const settings = await getPluginSettings('my-plugin');

return (
<div className="admin-page">
<header className="admin-page-header">
<h1>My Plugin Dashboard</h1>
</header>

<main className="admin-page-content">
<MyPluginDashboard settings={settings} />
</main>
</div>
);
}

Settings Page

templates/next/app/admin/my-plugin/settings/page.tsx
import { PluginSettingsForm } from '@/components/admin/PluginSettingsForm';

export default function MyPluginSettingsPage() {
return (
<div className="admin-page">
<header className="admin-page-header">
<h1>My Plugin Settings</h1>
</header>

<main className="admin-page-content">
<PluginSettingsForm pluginId="my-plugin" />
</main>
</div>
);
}

Admin Components

Using Built-in Components

import { AdminCard, AdminTable, AdminForm, AdminStats, AdminChart } from '@/components/admin';

export function MyPluginDashboard() {
return (
<div className="grid gap-6">
<AdminStats
stats={[
{ label: 'Total', value: 1234 },
{ label: 'Active', value: 856 },
{ label: 'Pending', value: 42 }
]}
/>

<AdminCard title="Recent Activity">
<AdminTable
columns={[
{ key: 'date', label: 'Date' },
{ key: 'action', label: 'Action' },
{ key: 'user', label: 'User' }
]}
data={activityData}
/>
</AdminCard>
</div>
);
}

Custom Components

templates/shared/components/MyPluginStats.tsx
interface StatsProps {
totalItems: number;
activeItems: number;
growth: number;
}

export function MyPluginStats({ totalItems, activeItems, growth }: StatsProps) {
return (
<div className="grid grid-cols-3 gap-4">
<div className="stat-card">
<span className="stat-label">Total Items</span>
<span className="stat-value">{totalItems}</span>
</div>
<div className="stat-card">
<span className="stat-label">Active</span>
<span className="stat-value">{activeItems}</span>
</div>
<div className="stat-card">
<span className="stat-label">Growth</span>
<span className="stat-value text-green-500">+{growth}%</span>
</div>
</div>
);
}

API Routes for Admin

CRUD Endpoints

templates/next/app/api/admin/my-plugin/route.ts
import { NextResponse } from 'next/server';
import { requireAdmin } from '@/lib/auth';
import { prisma } from '@/lib/db';

export async function GET(request: Request) {
const user = await requireAdmin(request);
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}

const items = await prisma.myPluginItem.findMany({
orderBy: { createdAt: 'desc' }
});

return NextResponse.json(items);
}

export async function POST(request: Request) {
const user = await requireAdmin(request);
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}

const body = await request.json();

const item = await prisma.myPluginItem.create({
data: body
});

return NextResponse.json(item, { status: 201 });
}

Settings Endpoint

templates/next/app/api/admin/my-plugin/settings/route.ts
import { NextResponse } from 'next/server';
import { requireAdmin } from '@/lib/auth';
import { getPluginSettings, updatePluginSettings } from '@/lib/settings';

export async function GET(request: Request) {
await requireAdmin(request);

const settings = await getPluginSettings('my-plugin');
return NextResponse.json(settings);
}

export async function PUT(request: Request) {
await requireAdmin(request);

const body = await request.json();
const settings = await updatePluginSettings('my-plugin', body);

return NextResponse.json(settings);
}

Permissions

Define Permissions

manifest.json
{
"permissions": [
{
"id": "my-plugin.read",
"label": "View My Plugin"
},
{
"id": "my-plugin.write",
"label": "Manage My Plugin"
},
{
"id": "my-plugin.admin",
"label": "Administer My Plugin"
}
]
}

Check Permissions

import { hasPermission } from '@/lib/auth';

export async function requirePluginAccess(request: Request, permission: string) {
const user = await getUser(request);

if (!user || !hasPermission(user, permission)) {
throw new Error('Permission denied');
}

return user;
}

// Usage
const user = await requirePluginAccess(request, 'my-plugin.write');
await sdk.registerAdminMenu({
id: 'my-plugin',
label: 'My Plugin',
icon: 'Plug',
children: [
{
id: 'view',
label: 'Dashboard',
href: '/admin/my-plugin',
permission: 'my-plugin.read'
},
{
id: 'manage',
label: 'Manage',
href: '/admin/my-plugin/manage',
permission: 'my-plugin.write'
},
{
id: 'settings',
label: 'Settings',
href: '/admin/my-plugin/settings',
permission: 'my-plugin.admin'
}
]
});

Notifications

Show Admin Notifications

import { showNotification } from '@/lib/admin';

// Success
showNotification({
type: 'success',
message: 'Item created successfully'
});

// Error
showNotification({
type: 'error',
message: 'Failed to save changes'
});

// With action
showNotification({
type: 'info',
message: 'New items available',
action: {
label: 'View',
href: '/admin/my-plugin'
}
});

Dashboard Widgets

Register Widget

await sdk.registerDashboardWidget({
id: 'my-plugin-stats',
label: 'My Plugin Stats',
component: '@/plugins/my-plugin/widgets/StatsWidget',
size: 'medium', // 'small' | 'medium' | 'large'
order: 10
});

Widget Component

widgets/StatsWidget.tsx
import useSWR from 'swr';

export default function StatsWidget() {
const { data, error } = useSWR('/api/admin/my-plugin/stats');

if (error) return <div>Failed to load</div>;
if (!data) return <div>Loading...</div>;

return (
<div className="widget">
<h3>My Plugin Stats</h3>
<div className="stats-grid">
<div>
<span className="stat-value">{data.total}</span>
<span className="stat-label">Total</span>
</div>
<div>
<span className="stat-value">{data.today}</span>
<span className="stat-label">Today</span>
</div>
</div>
</div>
);
}

Complete Example

generator.js
import { sdk } from 'autodeploybase';

export default async function generate(context) {
// Copy admin pages
await sdk.copyTemplates({
source: `./templates/${context.framework}/admin`,
destination: `${context.projectPath}/src/app/admin/my-plugin`
});

// Register menu
await sdk.registerAdminMenu({
id: 'my-plugin',
label: 'My Plugin',
icon: 'Plug',
order: 50,
children: [
{ id: 'dashboard', label: 'Dashboard', href: '/admin/my-plugin' },
{ id: 'items', label: 'Items', href: '/admin/my-plugin/items' },
{ id: 'settings', label: 'Settings', href: '/admin/my-plugin/settings' }
]
});

// Register dashboard widget
await sdk.registerDashboardWidget({
id: 'my-plugin-overview',
label: 'My Plugin Overview',
component: '@/plugins/my-plugin/widgets/Overview',
size: 'medium'
});

// Register settings
await sdk.registerSettings({
pluginId: 'my-plugin',
schema: {
enabled: { type: 'boolean', default: true },
apiKey: { type: 'string', secret: true }
}
});
}