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):
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
| Method | Type | Description |
|---|---|---|
path(string) | string | Panel root path (no leading slash) |
brand(string) | string | Text/title shown in the Topbar |
theme(string) | string | Primary color or custom theme ID |
primaryColor(string) | string | Shortcut for --primary |
darkMode(bool) | bool | Enables the dark mode toggle in the Topbar |
middleware(array) | array | Middleware 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) | string | Alternative guard (default web) |
tenant(class-string) | class-string | Tenant resolver (Phase 2) |
Multi-panel
$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.
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 theSidebarautomatically - Sharing Resources between panels — instead, declare
Resource::canBeSeenIn(panel)(Phase 2) or duplicate the class to differentiate behavior
Next steps
- Resources — declare models as CRUDs
- Auth — Policies + panel middleware
- API reference: PHP overview