Awn Awn
Back to Awn
Documentation menu — Organization dashboard surfaces
Build / Organization dashboard surfaces
Version
1.0
Last verified
2026-08-09

Organization dashboard surfaces

Organization surfaces belong to one tenant and run under a resolved CurrentOrganization. A plugin may contribute management links, home widgets, both, or neither.

Management pages and submenu

Implement ContributesDashboard:

public function dashboards(): array
{
    return [
        new PluginDashboard(
            id: 'orders-overview',
            title: 'Overview',
            description: 'Tenant order metrics.',
            routeName: 'plugin.orders.dashboard.overview',
            icon: DashboardIcon::Chart,
            order: 40,
            requiresEnabled: true,
        ),
        new PluginDashboard(
            id: 'orders',
            title: 'Orders',
            description: 'Manage tenant orders.',
            routeName: 'plugin.orders.dashboard.orders.index',
            icon: DashboardIcon::Inbox,
            order: 41,
            requiresEnabled: true,
        ),
    ];
}

All contributions from one plugin become one sidebar submenu. The manifest name labels the parent; the first ordered item supplies its icon. Add overview/index and useful fixed-path shortcuts. Keep parameterized show/edit/delete routes contextual.

Use this route pattern:

Route::middleware([
    'web',
    'auth',
    'organization.route',
    'organization.member',
    'plugin.available:orders',
])
    ->prefix('/charity/{organization:slug}/plugins/orders/manage')
    ->name('plugin.orders.dashboard.')
    ->group(function (): void {
        Route::get('/', OverviewController::class)->name('overview');
        Route::get('/orders', [OrderController::class, 'index'])->name('orders.index');
    });

requiresEnabled: true requires plugin.available:{slug}. false requires plugin.available:{slug},installed; definition validation enforces the pairing. Settings remain at /charity/{organization}/plugins/{slug}, so management must use /manage.

Organization-home widgets

Implement ContributesDashboardWidgets:

public function dashboardWidgets(Organization $organization): array
{
    return [
        new PluginDashboardWidget(
            id: 'orders-overview',
            view: view('plugin.orders::widgets.overview', [
                'organization' => $organization,
                'openOrders' => Order::query()->where('status', 'open')->count(),
            ]),
            order: 20,
        ),
    ];
}

Widgets render on charity.dashboard, are globally sorted by order, and contain only ID, pre-built View, and order. Keep them summary-oriented and link to the full management page.

Tenant safety

  • Every tenant model uses BelongsToOrganization.
  • Never accept organization_id from a form.
  • Resolve organization.route before model binding or queries.
  • Authorize direct routes; hiding a link is not authorization.
  • Test two organizations, guessed ULIDs, disabled/unavailable state, and direct requests.

Fundraising is the complete reference: seven submenu pages and one organization-home widget.