From d97cc41ee235906c8ebe9fb442ffc6308ca376c8 Mon Sep 17 00:00:00 2001 From: jeremy bayse Date: Sun, 2 Aug 2026 11:16:44 +0200 Subject: [PATCH] Add mobile bottom tab bar and redesign mobile dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- resources/css/app.css | 14 +++ .../views/components/bottom-tab-bar.blade.php | 41 ++++++++ resources/views/layouts/app.blade.php | 4 +- .../views/livewire/dashboard/index.blade.php | 98 +++++++++++++++---- .../livewire/layout/navigation.blade.php | 25 +---- 5 files changed, 142 insertions(+), 40 deletions(-) create mode 100644 resources/views/components/bottom-tab-bar.blade.php diff --git a/resources/css/app.css b/resources/css/app.css index 54c430e..90bb12f 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -51,6 +51,20 @@ --color-negative-fill: 214 127 72; /* #d67f48: 3.2:1 white text (large/bold header use only) */ --color-info-fill: 71 66 56; /* #474238: 9.8:1 white text */ --color-danger-fill: 166 45 45; /* 5.4:1 white text */ + + /* "Organic" tonal ramps — mode-invariant, used for mobile category dots + * and progress bars where a spread of same-hue shades tells categories + * apart (WCAG 1.4.11 graphical-object contrast), not for text-on-surface. */ + --color-accent-400: #f6a06b; + --color-accent-500: #d67f48; + --color-accent-600: #b2622d; + --color-accent-700: #8c491a; + --color-accent-800: #643312; + --color-accent-2-400: #aebf92; + --color-accent-2-500: #8fa073; + --color-accent-2-600: #728157; + --color-accent-2-700: #56633f; + --color-accent-2-800: #3d472b; } .dark { diff --git a/resources/views/components/bottom-tab-bar.blade.php b/resources/views/components/bottom-tab-bar.blade.php new file mode 100644 index 0000000..5ed2406 --- /dev/null +++ b/resources/views/components/bottom-tab-bar.blade.php @@ -0,0 +1,41 @@ +@php + $tabs = [ + ['route' => 'dashboard', 'label' => 'Accueil', 'icon' => 'home'], + ['route' => 'plan', 'label' => 'Plan', 'icon' => 'grid'], + ['route' => 'suivi', 'label' => 'Suivi', 'icon' => 'list'], + ['route' => 'sankey', 'label' => 'Flux', 'icon' => 'chart'], + ]; +@endphp + + diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 07c1f7b..2f4ca9a 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -19,7 +19,7 @@ @vite(['resources/css/app.css', 'resources/js/app.js']) -
+
@@ -39,6 +39,8 @@
+ + @stack('scripts') diff --git a/resources/views/livewire/dashboard/index.blade.php b/resources/views/livewire/dashboard/index.blade.php index 6c17319..736894c 100644 --- a/resources/views/livewire/dashboard/index.blade.php +++ b/resources/views/livewire/dashboard/index.blade.php @@ -1,4 +1,84 @@ -
+@php + $colors = [ + 'revenu' => ['bg' => 'bg-positive-fill', 'row' => 'bg-positive-surface/40'], + 'depense' => ['bg' => 'bg-negative-fill', 'row' => 'bg-negative-surface/40'], + 'epargne' => ['bg' => 'bg-info-fill', 'row' => 'bg-info-surface/40'], + ]; + + // Ordered to alternate light/dark shades so adjacent donut slices stay distinguishable + // even without relying on the border stroke (WCAG 1.4.11 graphical-object contrast). + $chartPalettes = [ + 'revenu' => ['#15803d', '#4ade80', '#166534', '#86efac', '#16a34a', '#22c55e'], + 'depense' => ['#991b1b', '#fb923c', '#c2410c', '#fdba74', '#dc2626', '#f97316'], + 'epargne' => ['#1e40af', '#93c5fd', '#1d4ed8', '#bfdbfe', '#2563eb', '#60a5fa'], + ]; + + // Mobile category dots cycle through a same-hue tonal ramp so adjacent rows + // stay distinguishable (WCAG 1.4.11), independent of the desktop chart palette. + $mobileDotRamp = ['#8c491a', '#b2622d', '#d67f48', '#f6a06b']; + $depenseRows = $sections['depense']['rows']->sortByDesc('tracked')->values(); +@endphp + +
+{{-- Mobile: hero "reste à dépenser" card + tiles + spending-by-category list --}} +
+
+

Bonjour {{ Str::of(auth()->user()->name)->before(' ') }}

+ + {{ Str::of(auth()->user()->name)->explode(' ')->map(fn ($p) => mb_substr($p, 0, 1))->take(2)->implode('') }} + +
+ +
+ Reste à dépenser · {{ \Illuminate\Support\Carbon::create($year, (int) ($period === 'year' ? now()->month : $period))->translatedFormat('F') }} + {{ number_format($sections['depense']['totals']['reste'], 2, ',', ' ') }} € + @php + $depTotals = $sections['depense']['totals']; + $spentPct = $depTotals['budget'] > 0 ? min(100, round($depTotals['tracked'] / $depTotals['budget'] * 100)) : 0; + @endphp + + {{ number_format($depTotals['tracked'], 2, ',', ' ') }} € dépensés sur {{ number_format($depTotals['budget'], 2, ',', ' ') }} € prévus +
+ +
+
+ Revenus + {{ number_format($sections['revenu']['totals']['tracked'], 2, ',', ' ') }} € +
+
+ Épargne + {{ number_format($sections['epargne']['totals']['tracked'], 2, ',', ' ') }} € +
+
+ +
+

Dépenses par catégorie

+
+ + @if ($depenseRows->isEmpty()) +

Aucune catégorie de dépenses.

+ @else +
+ @foreach ($depenseRows as $i => $row) +
+ +
+
{{ $row['category']->name }}
+ +
+ {{ number_format($row['tracked'], 0, ',', ' ') }} € +
+ @endforeach +
+ @endif +
+ +{{-- Desktop / tablet: full analysis tables + donut charts --}} +