{{-- Account dashboard — modular widget grid with shared frame chrome. Per Phase 2B: - Each widget renders inside a single consistent frame that provides the title, description, and (for owner/admin) the management controls. Individual widget components return only their inner content. - Owner/admin sees: Add widget · Move up · Move down · Remove (with confirmation step). - Agents see widgets but no management chrome. Unknown widget types (rows whose `type` doesn't resolve in the registry) render a safe amber fallback so a downgraded / legacy row cannot crash the dashboard. --}}
{{-- Workspace context header --}}
{{ __('Workspace') }}: {{ $account->name }} · {{ $account->slug }}
{{ __('Dashboard') }} {{ __('Operational overview of your support workspace.') }}
@if ($this->canManage) {{ __('Add widget') }} @endif
{{-- Add-widget picker — owner/admin only. Inline panel (modal-free for Phase 2B). Lists only types not already enabled in this account. --}} @if ($this->canManage && $showAddPanel)
{{ __('Add a widget') }} {{ __('Pick a widget type. Duplicates per type are not permitted.') }}
{{ __('Close') }}
@if ($this->availableWidgetTypes->isEmpty())
{{ __('All available widget types are already on your dashboard.') }}
@else
@foreach ($this->availableWidgetTypes as $type) @endforeach
@endif
@endif {{-- Widget grid. 12-col responsive. Each widget renders inside a shared frame (title + description + management controls + content). Widget components return only the content. --}}
@forelse ($this->widgets as $widget) @php // Raw string — bypasses the enum cast so an unknown // DB value cannot throw during attribute access. $rawType = $widget->getRawOriginal('type'); $componentClass = app(\App\Dashboard\WidgetRegistry::class)->resolve($rawType); $typeEnum = \App\Enums\DashboardWidgetType::tryFrom($rawType); $isConfirmingRemoval = $confirmingRemovalOf === $widget->id; @endphp @if ($componentClass)
{{-- Frame header: title + description + controls --}}
{{ $typeEnum?->label() ?? $rawType }} @if ($typeEnum) {{ $typeEnum->description() }} @endif
@if ($this->canManage)
@endif
{{-- Removal confirmation prompt — rendered inside the frame, above the content, so the operator sees which widget is being affected. --}} @if ($this->canManage && $isConfirmingRemoval)
{{ __('Remove this widget from your dashboard?') }}
{{ __('Cancel') }} {{ __('Remove') }}
@endif {{-- Widget content. Components return inner markup only — no card, no title. --}}
@livewire($componentClass, ['dashboardWidgetId' => $widget->id], key('dashboard-widget-'.$widget->id))
@else {{-- Safe fallback: the row exists in the DB but the PHP-side registry doesn't know how to render it. --}}
{{ __('Unknown widget type') }}
{{ __('This dashboard row has type :type, which the current build does not know how to render. Remove or upgrade.', ['type' => $rawType]) }}
@if ($this->canManage) @endif
@if ($this->canManage && $confirmingRemovalOf === $widget->id)
{{ __('Remove this widget from your dashboard?') }}
{{ __('Cancel') }} {{ __('Remove') }}
@endif
@endif @empty
@if ($this->canManage) {{ __('No widgets yet. Use "Add widget" above to start.') }} @else {{ __('No widgets configured for this account yet.') }} @endif
@endforelse