@props(['title' => 'Dashboard']) @php // Defined once, at the top, so both the desktop sidebar and the // mobile offcanvas menu below can use the same list without // duplicating it (and risking the two silently drifting apart). $navItems = [ ['label' => 'Dashboard', 'route' => 'admin.dashboard', 'icon' => 'fa-solid fa-gauge'], ['label' => 'Portfolio', 'route' => 'admin.portfolio-projects.index', 'icon' => 'fa-solid fa-briefcase'], ['label' => 'Blog', 'route' => 'admin.blog-posts.index', 'icon' => 'fa-solid fa-pen-nib'], ['label' => 'Testimonials', 'route' => 'admin.testimonials.index', 'icon' => 'fa-solid fa-quote-left'], ['label' => 'Client Logos', 'route' => 'admin.client-logos.index', 'icon' => 'fa-solid fa-building'], ['label' => 'FAQ', 'route' => 'admin.faqs.index', 'icon' => 'fa-solid fa-circle-question'], ['label' => 'Social Links', 'route' => 'admin.social-links.index', 'icon' => 'fa-solid fa-share-nodes'], ['label' => 'Messages', 'route' => 'admin.contact-messages.index', 'icon' => 'fa-solid fa-envelope'], ['label' => 'Media Library', 'route' => 'admin.media.index', 'icon' => 'fa-solid fa-images'], ['label' => 'Analytics', 'route' => 'admin.analytics.index', 'icon' => 'fa-solid fa-chart-simple'], ['label' => 'SEO', 'route' => 'admin.seo.edit', 'icon' => 'fa-solid fa-magnifying-glass-chart'], ['label' => 'Settings', 'route' => 'admin.settings.edit', 'icon' => 'fa-solid fa-gear'], ]; // Matches "admin.portfolio-projects.index" style route names by their // first two segments ("admin.portfolio-projects*"), so a nav item // stays highlighted across index/create/edit/etc. sub-routes of the // same resource. Computed once per item, up front, so neither the // desktop sidebar nor the mobile menu needs to repeat this logic. foreach ($navItems as &$navItem) { $segments = explode('.', $navItem['route']); $navItem['activePattern'] = implode('.', array_slice($segments, 0, 2)).'*'; } unset($navItem); @endphp {{ $title }} — {{ config('app.name') }} Admin @vite(['resources/css/admin.css', 'resources/js/admin.js']) @stack('styles') {{-- Mobile topbar — the sidebar below is hidden under the lg breakpoint, so this is the only way to reach navigation on a phone or tablet. --}}
{{ config('app.name') }}

Menu

@csrf
@if(session('toast')) @endif {{-- Global validation error summary. Individual fields show their own inline @error() message where the blade partial supports it, but any field missing that markup (or below the fold) would otherwise fail silently with no visible feedback — this guarantees every rejected submission is explained. --}} @if($errors->any()) @endif {{ $slot }}
{{-- Shared destructive-action confirmation (PRD 7.19 — no browser alert()/confirm() dialogs). Rendered once here; any form carrying a data-confirm="…" attribute is routed through it by resources/js/lib/confirm-dialog.js. --}} @stack('scripts')