Skip to content

Panels

A Panel is the root grouping of an Arqel instance — a set of Resources, Widgets, middleware, branding, and path. You can have a single /admin panel (the typical case), or multiple panels per persona — /admin, /staff, /partners — each with its own Resources and auth.

The minimum

In app/Providers/ArqelServiceProvider.php (created by php artisan arqel:install):

php
namespace App\Providers;

use App\Arqel\Resources\UserResource;
use Arqel\Core\Panel\PanelRegistry;
use Illuminate\Support\ServiceProvider;

final class ArqelServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->afterResolving(PanelRegistry::class, function (PanelRegistry $panels): void {
            $panels->panel('admin')
                ->path('admin')
                ->brand('Acme Admin')
                ->resources([UserResource::class])
                ->middleware(['web', 'auth']);
        });
    }
}

This registers an admin panel at /admin with 1 Resource and auth enabled.

Fluent API

MethodTypeDescription
path(string)stringPanel root path (no leading slash)
brand(string)stringText/title shown in the Topbar
theme(string)stringPrimary color or custom theme ID
primaryColor(string)stringShortcut for --primary
darkMode(bool)boolEnables the dark mode toggle in the Topbar
middleware(array)arrayMiddleware applied to all panel routes
resources(array)array<class-string>List of Resource classes
widgets(array)array<class-string>Widgets shown on the dashboard
navigationGroups(array)array<NavigationGroup>Customizes the sidebar
authGuard(string)stringAlternative guard (default web)
tenant(class-string)class-stringTenant resolver (Phase 2)

Multi-panel

php
$panels->panel('admin')
    ->path('admin')
    ->brand('Acme — Internal')
    ->resources([UserResource::class, OrderResource::class])
    ->middleware(['web', 'auth', 'role:staff']);

$panels->panel('partners')
    ->path('partners')
    ->brand('Acme — Partner Portal')
    ->resources([CommissionResource::class])
    ->middleware(['web', 'auth', 'role:partner']);

Each panel is independent — separate Resources, sidebar, theme, and middleware. arqel:install only creates admin by default; add more as needed.

How the panel is resolved

Arqel\Core\Panel\PanelRegistry is a singleton populated at boot. At runtime, the HandleArqelInertiaRequests middleware calls PanelRegistry::setCurrent($id) based on the request path, and panel appears as a shared prop in usePage().props.panel on the React side.

tsx
import { usePage } from '@inertiajs/react';
import type { SharedProps } from '@arqel-dev/types';

const { panel } = usePage<SharedProps>().props;
console.log(panel.id);    // 'admin'
console.log(panel.brand); // 'Acme Admin'
console.log(panel.path);  // 'admin'

Anti-patterns

  • Hardcoding URLs on the front-end — use route('arqel.resources.index', { resource: 'users' }) (Ziggy) or the links generated by the Sidebar automatically
  • Sharing Resources between panels — instead, declare Resource::canBeSeenIn(panel) (Phase 2) or duplicate the class to differentiate behavior

Next steps

MIT License — built with Inertia + React + Laravel.