feat(ui) : refonte du menu latéral et de la navigation téléphone (#569)

Menu PC et navigation téléphone tirés d'une configuration unique
(client/src/lib/navigation.ts), selon docs/PLAN-OPTIMISATION-WEBUI.md
(P1 § 2.1 et § 2.6).

- menu regroupé par usage (Au quotidien, Fournisseurs, Planning et infos,
  Administration), libellés clarifiés, chaque icône une seule fois ;
  droits d'accès PC inchangés
- l'envoi de BAP quitte le menu : bouton « Envoyer un BAP » (admin) dans
  l'en-tête du Rapprochement BL / factures
- téléphone : 4 raccourcis selon le rôle + « Menu » avec tous les modules
  autorisés, magasin, profil et déconnexion ; pages sans version mobile
  affichées dans le cadre téléphone
- titre de l'onglet du navigateur tiré du menu
- onglets du Rapprochement lisibles sur téléphone
- suppression de PhoneBottomNav.tsx (inutilisé)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrRFddV2BaqDCxGY1j52UJ
This commit is contained in:
LogiFlowandClaude Opus 5.5 authored and GitHub committed 2026-10-10 09:35:35 +02:00
1 parent bd3bb5e64a
commit b964e137bf
9 files changed
+826 -1205

No files matched your search

+42 -11
View File
@@ -1,4 +1,4 @@
import { lazy, useEffect } from "react";
import { lazy, Suspense, useEffect, type ComponentType } from "react";
import { Switch, Route, Redirect, useLocation } from "wouter";
import { useAuthUnified } from "@/hooks/useAuthUnified";
import { useScreenSize } from "@/hooks/use-screen-size";
@@ -10,6 +10,7 @@ import Layout from "@/components/Layout";
// Mobile : coque et page d'accueil chargées immédiatement
import MobileApp from "@/pages/mobile/MobileApp";
import MobileDashboardPage from "@/pages/mobile/DashboardPage";
import MobileLayout from "@/pages/mobile/MobileLayout";
// Les autres pages sont chargées à la demande (un fichier JS par page) : l'écran
// de connexion et le tableau de bord n'attendent plus le code de toutes les pages
@@ -44,6 +45,36 @@ const MobileDlcPage = lazy(() => import("@/pages/mobile/DlcPage"));
const MobileSavPage = lazy(() => import("@/pages/mobile/SavPage"));
const MobileAvoirsPage = lazy(() => import("@/pages/mobile/AvoirsPage"));
// Pages sans version mobile : affichées dans le cadre téléphone (en-tête, barre
// du bas et menu) pour ne jamais laisser une page sans navigation
function withMobileFrame(Page: ComponentType) {
return function MobileFramedPage() {
return (
<MobileLayout>
<div className="p-3">
<Suspense fallback={
<div className="flex items-center justify-center py-16">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
</div>
}>
<Page />
</Suspense>
</div>
</MobileLayout>
);
};
}
const MobileFramedContacts = withMobileFrame(Contacts);
const MobileFramedSuppliers = withMobileFrame(Suppliers);
const MobileFramedGroups = withMobileFrame(Groups);
const MobileFramedUsers = withMobileFrame(Users);
const MobileFramedBLReconciliation = withMobileFrame(BLReconciliation);
const MobileFramedUtilities = withMobileFrame(Utilities);
const MobileFramedAnalytics = withMobileFrame(Analytics);
const MobileFramedPaymentSchedule = withMobileFrame(PaymentSchedulePage);
const MobileFramedNotFound = withMobileFrame(NotFound);
// Helper component to handle redirection
const RedirectToAuth = () => {
const [, setLocation] = useLocation();
@@ -92,20 +123,20 @@ function RouterProduction() {
<Route path="/deliveries" component={MobileDeliveriesPage} />
<Route path="/tasks" component={MobileTasksPage} />
{/* Pages sans version mobile - utiliser version desktop pour l'instant */}
<Route path="/contacts" component={Contacts} />
<Route path="/suppliers" component={Suppliers} />
<Route path="/groups" component={Groups} />
<Route path="/users" component={Users} />
<Route path="/bl-reconciliation" component={BLReconciliation} />
{/* Pages sans version mobile : version PC dans le cadre téléphone */}
<Route path="/contacts" component={MobileFramedContacts} />
<Route path="/suppliers" component={MobileFramedSuppliers} />
<Route path="/groups" component={MobileFramedGroups} />
<Route path="/users" component={MobileFramedUsers} />
<Route path="/bl-reconciliation" component={MobileFramedBLReconciliation} />
<Route path="/publicities" component={MobilePublicitiesPage} />
<Route path="/customer-orders" component={MobileCustomerOrdersPage} />
<Route path="/dlc" component={MobileDlcPage} />
<Route path="/utilities" component={Utilities} />
<Route path="/utilities" component={MobileFramedUtilities} />
<Route path="/sav" component={MobileSavPage} />
<Route path="/avoirs" component={MobileAvoirsPage} />
<Route path="/analytics" component={Analytics} />
<Route path="/payment-schedule" component={PaymentSchedulePage} />
<Route path="/analytics" component={MobileFramedAnalytics} />
<Route path="/payment-schedule" component={MobileFramedPaymentSchedule} />
{/* Redirection /auth vers dashboard (navigation interne, sans rechargement) */}
<Route path="/auth">
@@ -113,7 +144,7 @@ function RouterProduction() {
</Route>
<Route path="/" component={MobileDashboardPage} />
<Route component={NotFound} />
<Route component={MobileFramedNotFound} />
</Switch>
</MobileApp>
);