--- name: filament-dashboard description: Create FilamentPHP v4 dashboard pages with single-tab or multi-tab layouts, message callouts, and widget integration --- # FilamentPHP Dashboard Page Generation Skill ## Overview This skill generates FilamentPHP v4 dashboard pages that follow a consistent pattern: - Extends `Filament\Pages\Page` - Supports single-tab (no tabs UI) or multi-tab layouts - Includes optional color-coded message callouts - Renders widgets using the standard Filament widgets component - Uses Livewire reactive tabs with `$activeTab` state ## Documentation Reference **CRITICAL:** Before generating dashboard pages, read: - `/home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/filament-docs/references/general/06-navigation/` - `/home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/filament-docs/references/widgets/` ## Pattern Architecture A dashboard page in this style has 3 pieces: 1. **Filament Page class** (PHP) - Extends `Filament\Pages\Page` - Sets `$view` - Declares navigation metadata (icon/label/group/sort) - Stores Livewire public state: `$activeTab` - Provides `getTabs(): array` and `getActiveTabData(): ?array` 2. **Blade view** (`resources/views/filament/{panel}/pages/{slug}.blade.php`) - Renders tabs navigation (optional, for multi-tab) - Renders optional message callout (color-coded) - Renders widgets using: `` 3. **Widgets** (Filament Widgets) - Each tab is basically "a widget list" - Widgets are referenced as `::class` strings ## Tab Schema Contract Each tab must follow this array schema: ```php [ 'key' => 'overview', // Required: unique identifier 'title' => 'Overview', // Required: display title 'icon' => 'heroicon-o-chart-bar', // Optional: Heroicon name 'message' => 'Note: ...', // Optional: HTML message 'messageColor' => 'blue', // Optional: blue|green|purple|orange|indigo|gray 'widgets' => [ // Optional: widget class references \App\Filament\Admin\Widgets\SomeWidget::class, \App\Filament\Admin\Widgets\AnotherWidget::class, ], ], ``` ## Multi-Tab Dashboard Page Template ### PHP Class Template ```php * }> */ public function getTabs(): array { return [ [ 'key' => '__TAB_KEY__', 'icon' => '__TAB_ICON__', 'title' => '__TAB_TITLE__', 'message' => '__TAB_MESSAGE_HTML__', 'messageColor' => '__TAB_COLOR__', 'widgets' => [ // \App\Filament\__PANEL__\Widgets\ExampleWidget::class, ], ], // Additional tabs... ]; } /** * Get the data for the currently active tab. */ public function getActiveTabData(): ?array { return collect($this->getTabs())->firstWhere('key', $this->activeTab); } } ``` ### Blade View Template (Multi-Tab) ```blade @php $tabs = $this->getTabs(); $activeTabData = $this->getActiveTabData(); // If activeTab is invalid, fall back to first tab to avoid empty page. if (! $activeTabData && count($tabs) > 0) { $this->activeTab = $tabs[0]['key']; $activeTabData = $tabs[0]; } @endphp
{{-- Tabs Navigation --}}
{{-- Tab Content --}} @if($activeTabData)
@if(!empty($activeTabData['message'])) @php $color = $activeTabData['messageColor'] ?? 'gray'; @endphp
$color === 'blue', 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800' => $color === 'green', 'bg-purple-50 dark:bg-purple-900/20 border-purple-200 dark:border-purple-800' => $color === 'purple', 'bg-orange-50 dark:bg-orange-900/20 border-orange-200 dark:border-orange-800' => $color === 'orange', 'bg-indigo-50 dark:bg-indigo-900/20 border-indigo-200 dark:border-indigo-800' => $color === 'indigo', 'bg-gray-50 dark:bg-gray-900/20 border-gray-200 dark:border-gray-800' => $color === 'gray', ])>

$color === 'blue', 'text-green-700 dark:text-green-300' => $color === 'green', 'text-purple-700 dark:text-purple-300' => $color === 'purple', 'text-orange-700 dark:text-orange-300' => $color === 'orange', 'text-indigo-700 dark:text-indigo-300' => $color === 'indigo', 'text-gray-700 dark:text-gray-300' => $color === 'gray', ])> {!! $activeTabData['message'] !!}

@endif @if(!empty($activeTabData['widgets'])) @endif
@endif
``` ## Single-Tab Dashboard Page Template Use this when you want a page that behaves like "one tab" without showing navigation. ### PHP Class Template (Single-Tab) ```php * }> */ public function getTabs(): array { return [ [ 'key' => 'main', 'title' => '__PAGE_TITLE__', 'message' => '__MESSAGE_HTML__', 'messageColor' => '__COLOR__', 'widgets' => [ // \App\Filament\__PANEL__\Widgets\ExampleWidget::class, ], ], ]; } /** * Get the data for the active tab (always the single main tab). */ public function getActiveTabData(): ?array { return $this->getTabs()[0] ?? null; } } ``` ### Blade View Template (Single-Tab) ```blade @php $activeTabData = $this->getActiveTabData(); @endphp
@if($activeTabData) @if(!empty($activeTabData['message'])) @php $color = $activeTabData['messageColor'] ?? 'gray'; @endphp
$color === 'blue', 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800' => $color === 'green', 'bg-purple-50 dark:bg-purple-900/20 border-purple-200 dark:border-purple-800' => $color === 'purple', 'bg-orange-50 dark:bg-orange-900/20 border-orange-200 dark:border-orange-800' => $color === 'orange', 'bg-indigo-50 dark:bg-indigo-900/20 border-indigo-200 dark:border-indigo-800' => $color === 'indigo', 'bg-gray-50 dark:bg-gray-900/20 border-gray-200 dark:border-gray-800' => $color === 'gray', ])>

$color === 'blue', 'text-green-700 dark:text-green-300' => $color === 'green', 'text-purple-700 dark:text-purple-300' => $color === 'purple', 'text-orange-700 dark:text-orange-300' => $color === 'orange', 'text-indigo-700 dark:text-indigo-300' => $color === 'indigo', 'text-gray-700 dark:text-gray-300' => $color === 'gray', ])> {!! $activeTabData['message'] !!}

@endif @if(!empty($activeTabData['widgets'])) @endif @endif
``` ## Inputs Required for Generation When creating a dashboard page, collect or assume defaults for: | Input | Description | Example | |-------|-------------|---------| | Page class name | PascalCase class name | `BillingDashboard` | | Panel | Panel name (Admin, Support, etc.) | `Admin` | | View slug | Kebab-case slug for blade file | `billing-dashboard` | | Navigation label | Display text in sidebar | `Billing` | | Navigation group | Group in sidebar | `Analytics` | | Navigation icon | Heroicon name | `heroicon-o-chart-bar` | | Navigation sort | Numeric sort order | `10` | | Mode | `single` or `multi` tab | `multi` | | Tabs | Array of tab definitions | See schema above | | Default tab key | First active tab | `overview` | ## Generation Workflow ### 1. Parse Requirements - Identify page name and panel - Determine single-tab vs multi-tab mode - List tabs with their widgets ### 2. Generate PHP Class - Use appropriate template (single or multi) - Replace all placeholders - Add widget class references ### 3. Generate Blade View - Use appropriate template (single or multi) - Match view path to class `$view` property ### 4. Verify Output - [ ] `$view` matches the Blade path - [ ] `activeTab` key exists in `getTabs()` - [ ] Each tab has `key` and `title` - [ ] Widgets are valid class strings - [ ] Blade falls back if `activeTab` invalid - [ ] Message uses `{!! !!}` only with trusted HTML ## Complete Example: Analytics Dashboard ### PHP Class ```php * }> */ public function getTabs(): array { return [ [ 'key' => 'overview', 'icon' => 'heroicon-o-home', 'title' => 'Overview', 'message' => 'Overview: Key metrics and performance indicators at a glance.', 'messageColor' => 'blue', 'widgets' => [ \App\Filament\Admin\Widgets\StatsOverview::class, \App\Filament\Admin\Widgets\RevenueChart::class, ], ], [ 'key' => 'users', 'icon' => 'heroicon-o-users', 'title' => 'Users', 'message' => 'User Analytics: Track user growth, engagement, and retention metrics.', 'messageColor' => 'green', 'widgets' => [ \App\Filament\Admin\Widgets\UserGrowthChart::class, \App\Filament\Admin\Widgets\ActiveUsersWidget::class, ], ], [ 'key' => 'revenue', 'icon' => 'heroicon-o-currency-dollar', 'title' => 'Revenue', 'message' => 'Revenue Analytics: Monitor income streams and financial performance.', 'messageColor' => 'purple', 'widgets' => [ \App\Filament\Admin\Widgets\RevenueBreakdown::class, \App\Filament\Admin\Widgets\TopProducts::class, ], ], ]; } public function getActiveTabData(): ?array { return collect($this->getTabs())->firstWhere('key', $this->activeTab); } } ``` ## Conventions - Tab keys should use **snake_case** or **kebab-case** (be consistent) - `$activeTab` must match a `key` from `getTabs()` - `message` is rendered with `{!! !!}` — **only use trusted HTML** - Widgets are referenced as `::class` strings - Navigation icons use Heroicon names (e.g., `heroicon-o-chart-bar`) - Available message colors: `blue`, `green`, `purple`, `orange`, `indigo`, `gray` ## Output Generated dashboard pages include: 1. Complete PHP Page class 2. Complete Blade view file 3. Proper namespace and imports 4. Navigation configuration 5. Tab definitions with widgets 6. Color-coded message callouts 7. Fallback handling for invalid tabs