66 lines
3.2 KiB
PHP
66 lines
3.2 KiB
PHP
@props([
|
|
// [[route, icon, translation key], …] or [['label' => …, 'items' => [...]], …]
|
|
'groups',
|
|
// dot-prefix for the labels, e.g. 'dashboard.nav' or 'admin.nav'
|
|
'prefix',
|
|
// console routes are matched through AdminArea so recovery hostnames still
|
|
// highlight; the portal uses the router directly
|
|
'console' => false,
|
|
'footer' => null,
|
|
])
|
|
{{--
|
|
The sidebar, shared by both shells.
|
|
|
|
Light, like everything else. The console used to be dark, which made it a
|
|
second product: two ideas of what a card is, two oranges, two status
|
|
palettes. What actually differs between an operator and a customer is
|
|
density, and that lives in the tokens — not here.
|
|
--}}
|
|
<aside
|
|
class="fixed inset-y-0 left-0 z-50 flex w-[15.5rem] flex-col overflow-y-auto border-r border-line bg-surface px-3 py-4 shadow-md transition-transform lg:static lg:h-screen lg:translate-x-0 lg:shadow-none"
|
|
:class="nav ? 'translate-x-0' : '-translate-x-full'"
|
|
>
|
|
<div class="flex items-center justify-between gap-2 px-2.5 pb-5">
|
|
<a href="{{ $console ? \App\Support\AdminArea::home() : route('dashboard') }}" class="flex items-center gap-2.5">
|
|
<x-ui.logo class="size-7" />
|
|
{{-- One element: as separate flex children the gap lands inside the
|
|
word and reads as "Clu Pilot". --}}
|
|
<span class="whitespace-nowrap text-lg font-bold tracking-tight text-ink">Clu<span class="text-accent-text">Pilot</span></span>
|
|
@if ($console)
|
|
<span class="rounded-sm bg-accent-subtle px-1.5 py-0.5 font-mono text-[9.5px] font-semibold uppercase tracking-[0.1em] text-accent-text">{{ __('admin.badge') }}</span>
|
|
@endif
|
|
</a>
|
|
<button type="button" class="lg:hidden -mr-1 inline-flex min-h-11 min-w-11 items-center justify-center rounded text-muted"
|
|
@click="nav = false" aria-label="{{ __('dashboard.close_nav') }}">
|
|
<x-ui.icon name="x" />
|
|
</button>
|
|
</div>
|
|
|
|
@foreach ($groups as $group)
|
|
@if (! empty($group['label']))
|
|
<p class="px-3 pb-2 pt-5 font-mono text-[11px] uppercase tracking-[0.07em] text-muted">{{ $group['label'] }}</p>
|
|
@endif
|
|
<nav class="space-y-0.5">
|
|
@foreach ($group['items'] as [$route, $icon, $key, $capability])
|
|
@continue($capability !== null && ! auth()->user()?->can($capability))
|
|
<x-ui.nav-item
|
|
:href="route($route)"
|
|
:active="$console ? \App\Support\AdminArea::routeIs($route) : request()->routeIs($route)"
|
|
@click="nav = false"
|
|
>
|
|
<x-slot:icon><x-ui.icon :name="$icon" class="size-[1.15rem]" /></x-slot:icon>
|
|
{{ __($prefix.'.'.$key) }}
|
|
</x-ui.nav-item>
|
|
@endforeach
|
|
</nav>
|
|
@endforeach
|
|
|
|
@if ($footer)
|
|
<p class="mt-auto px-3 pt-6 font-mono text-[11px] leading-relaxed text-muted">{{ $footer }}</p>
|
|
@endif
|
|
</aside>
|
|
|
|
{{-- Backdrop. Tapping it closes the drawer, which is the behaviour every
|
|
phone user tries first. --}}
|
|
<div x-show="nav" x-cloak @click="nav = false" class="fixed inset-0 z-40 bg-[color-mix(in_srgb,var(--plate)_42%,transparent)] lg:hidden"></div>
|