CluPilotCloud/resources/views/components/shell/nav.blade.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>