@php $__siteName = \App\Helpers\BrandingHelper::name(); $__favicon = \App\Models\SystemSetting::get('favicon'); @endphp
{{ $title }} — {{ $__siteName }} Admin
{{-- Favicon --}}
@if($__favicon)
@else
@endif
{{-- Dynamic brand colors from admin settings --}}
@php $__brandColor = \App\Models\SystemSetting::get('primary_color'); $__brandStrong = \App\Models\SystemSetting::get('secondary_color'); $__accentColor = \App\Models\SystemSetting::get('accent_color'); @endphp
@if($__brandColor || $__brandStrong || $__accentColor)
@endif
{{-- Body font (admin-configurable via Settings → General → Body Font) --}}
{!! \App\Helpers\FontHelper::renderHead() !!}
{{-- Vite --}}
@vite(['resources/css/app.css', 'resources/js/app.js'])
@livewireStyles
{{-- Theme Studio runtime variables (light + dark). Loaded AFTER Vite so
these override app.css defaults but BEFORE custom_css so admins can
still override individual properties. --}}
{!! \App\Helpers\ThemeHelper::renderCss() !!}
{{-- Admin-defined custom CSS + head HTML (analytics, custom meta, etc.) --}}
@php $__customCss = \App\Models\SystemSetting::get('custom_css', ''); @endphp
@if(trim($__customCss) !== '')
@endif
{!! \App\Models\SystemSetting::get('head_code', '') !!}
{{-- Progress Bar --}}
{{-- Mobile backdrop — dims content when sidebar is open --}}
{{-- ═══════════════════════════════════════════════
SIDEBAR
═══════════════════════════════════════════════ --}}
{{-- Mobile sidebar overlay --}}
{{-- ═══════════════════════════════════════════════
MAIN CONTENT
═══════════════════════════════════════════════ --}}
{{-- Fullscreen toggle (pointless on phone, hidden below sm) --}}
{{-- Language switcher (hidden on mobile — available in sidebar/profile on small screens) --}}
{{-- Notification bell.
Counts cached for 30s — these run on EVERY admin page render
and were the root cause of "Maximum execution time exceeded" and
the "Add Ticket continues loading" hang on installs with large
tickets / users / payments / sessions tables. 30s is short enough
that a fresh ticket / signup still shows up almost immediately. --}}
@php
$__notifCounts = \Illuminate\Support\Facades\Cache::remember(
'admin.notification_counts',
30,
function () {
return [
'openTickets' => (int) \Illuminate\Support\Facades\DB::table('tickets')->where('status', 'open')->count(),
'recentUsers' => (int) \App\Models\User::where('created_at', '>=', now()->subDay())->count(),
'failedPayments' => (int) \Illuminate\Support\Facades\DB::table('payments')->where('status', 'failed')->where('created_at', '>=', now()->subDays(7))->count(),
'pendingJobs' => (int) \Illuminate\Support\Facades\DB::table('failed_jobs')->count(),
'newWorkspaces' => (int) \Illuminate\Support\Facades\DB::table('workspaces')->where('created_at', '>=', now()->subDay())->count(),
'activeNow' => (int) \Illuminate\Support\Facades\DB::table('sessions')->where('last_activity', '>=', now()->subMinutes(5)->timestamp)->count(),
];
}
);
$openTickets = $__notifCounts['openTickets'];
$recentUsers = $__notifCounts['recentUsers'];
$failedPayments = $__notifCounts['failedPayments'];
$pendingJobs = $__notifCounts['pendingJobs'];
$newWorkspaces = $__notifCounts['newWorkspaces'];
$activeNow = $__notifCounts['activeNow'];
$notifCount = $openTickets + $recentUsers + $failedPayments + $pendingJobs;
@endphp