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:
| Icon | Use Case |
|---|---|
LayoutDashboard | Dashboard |
Users | User management |
Settings | Settings |
CreditCard | Payments |
Mail | |
BarChart | Analytics |
Package | Products |
ShoppingCart | Cart/Orders |
FileText | Content |
Bell | Notifications |
Shield | Security |
Plug | Plugins |
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');
Menu with Permissions
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 }
}
});
}