Files
suivicpt/resources/views/livewire/layout/navigation.blade.php
T
jeremy bayseandClaude Sonnet 5 d97cc41ee2 Add mobile bottom tab bar and redesign mobile dashboard
Import the Finlio Mobile design: a fixed bottom tab bar
(Accueil/Plan/Suivi/Flux) replaces the duplicated links in the mobile
hamburger menu, and the dashboard gets a mobile-first layout — hero
"reste à dépenser" card, revenus/épargne tiles, and a spending-by-
category list with progress bars — built from the same $sections data
the desktop tables use. Desktop dashboard is untouched.

The hero card uses a fixed dark background (independent of the
light/dark token swap) so its white text holds contrast in both
themes, matching how the existing -fill tokens are documented.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-02 11:16:44 +02:00

165 lines
8.0 KiB
PHP

<?php
use App\Livewire\Actions\Logout;
use Livewire\Volt\Component;
new class extends Component
{
/**
* Log the current user out of the application.
*/
public function logout(Logout $logout): void
{
$logout();
$this->redirect('/', navigate: true);
}
}; ?>
<nav x-data="{ open: false }" class="bg-surface rounded-full shadow-sm">
<!-- Primary Navigation Menu -->
<div class="px-2.5 py-2">
<div class="flex justify-between items-center">
<div class="flex items-center">
<!-- Logo -->
<div class="shrink-0 flex items-center gap-2.5 mr-2">
<a href="{{ route('dashboard') }}" wire:navigate aria-label="{{ config('app.name', 'Laravel') }} — Tableau de bord" class="flex items-center gap-2.5 rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface">
<span class="w-9 h-9 rounded-full bg-brand flex items-center justify-center shrink-0">
<x-application-logo class="block h-5 w-auto text-surface" />
</span>
<span class="hidden sm:inline font-display text-lg text-text">{{ config('app.name', 'SuiviCPT') }}</span>
</a>
</div>
<!-- Navigation Links -->
<div class="hidden sm:flex sm:items-center sm:gap-1">
<x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')" wire:navigate>
{{ __('Tableau de bord') }}
</x-nav-link>
@if (Route::has('plan'))
<x-nav-link :href="route('plan')" :active="request()->routeIs('plan')" wire:navigate>
{{ __('Plan') }}
</x-nav-link>
@endif
@if (Route::has('suivi'))
<x-nav-link :href="route('suivi')" :active="request()->routeIs('suivi')" wire:navigate>
{{ __('Suivi') }}
</x-nav-link>
@endif
@if (Route::has('sankey'))
<x-nav-link :href="route('sankey')" :active="request()->routeIs('sankey')" wire:navigate>
{{ __('Flux') }}
</x-nav-link>
@endif
</div>
</div>
<!-- Settings Dropdown -->
<div class="hidden sm:flex sm:items-center sm:ms-6 gap-2">
<x-theme-toggle />
<x-dropdown align="right" width="48">
<x-slot name="trigger">
<button class="inline-flex items-center gap-2 pl-1 pr-3 py-1 rounded-full text-sm leading-4 font-medium text-text hover:bg-surface-alt focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface transition ease-in-out duration-150">
<span class="w-8 h-8 rounded-full bg-positive-fill text-surface flex items-center justify-center text-xs font-bold shrink-0">{{ Str::of(auth()->user()->name)->explode(' ')->map(fn ($p) => mb_substr($p, 0, 1))->take(2)->implode('') }}</span>
<div x-data="{{ json_encode(['name' => auth()->user()->name]) }}" x-text="name" x-on:profile-updated.window="name = $event.detail.name"></div>
<div class="text-text-muted text-[10px]">⌄</div>
</button>
</x-slot>
<x-slot name="content">
<x-dropdown-link :href="route('profile')" wire:navigate>
{{ __('Profile') }}
</x-dropdown-link>
<x-dropdown-link :href="route('household.settings')" wire:navigate>
{{ __('Foyer') }}
</x-dropdown-link>
@if (Route::has('categories'))
<x-dropdown-link :href="route('categories')" wire:navigate>
{{ __('Catégories') }}
</x-dropdown-link>
@endif
@if (Route::has('recurring'))
<x-dropdown-link :href="route('recurring')" wire:navigate>
{{ __('Récurrences') }}
</x-dropdown-link>
@endif
<!-- Authentication -->
<button wire:click="logout" class="w-full text-start">
<x-dropdown-link>
{{ __('Log Out') }}
</x-dropdown-link>
</button>
</x-slot>
</x-dropdown>
</div>
<!-- Hamburger -->
<div class="-me-2 flex items-center sm:hidden">
<button
@click="open = ! open"
:aria-expanded="open.toString()"
aria-label="Menu"
class="inline-flex items-center justify-center p-2 rounded-md text-text-muted hover:text-text hover:bg-surface-alt focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring transition duration-150 ease-in-out"
>
<svg class="h-6 w-6" aria-hidden="true" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<path :class="{'hidden': open, 'inline-flex': ! open }" class="inline-flex" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
<path :class="{'hidden': ! open, 'inline-flex': open }" class="hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
</div>
{{-- Primary routes (Tableau de bord/Plan/Suivi/Flux) live in the bottom tab
bar on mobile now — this menu only needs account/settings links. --}}
<!-- Responsive Navigation Menu -->
<div :class="{'block': open, 'hidden': ! open}" class="hidden sm:hidden mt-2 bg-surface rounded-3xl shadow-sm px-2">
<!-- Responsive Settings Options -->
<div class="pt-2 pb-1">
<div class="px-4">
<div class="font-medium text-base text-text" x-data="{{ json_encode(['name' => auth()->user()->name]) }}" x-text="name" x-on:profile-updated.window="name = $event.detail.name"></div>
<div class="font-medium text-sm text-text-muted">{{ auth()->user()->email }}</div>
</div>
<div class="px-4 py-2">
<x-theme-toggle />
</div>
<div class="mt-3 space-y-1">
<x-responsive-nav-link :href="route('profile')" wire:navigate>
{{ __('Profile') }}
</x-responsive-nav-link>
<x-responsive-nav-link :href="route('household.settings')" wire:navigate>
{{ __('Foyer') }}
</x-responsive-nav-link>
@if (Route::has('categories'))
<x-responsive-nav-link :href="route('categories')" wire:navigate>
{{ __('Catégories') }}
</x-responsive-nav-link>
@endif
@if (Route::has('recurring'))
<x-responsive-nav-link :href="route('recurring')" wire:navigate>
{{ __('Récurrences') }}
</x-responsive-nav-link>
@endif
<!-- Authentication -->
<button wire:click="logout" class="w-full text-start">
<x-responsive-nav-link>
{{ __('Log Out') }}
</x-responsive-nav-link>
</button>
</div>
</div>
</div>
</nav>