diff --git a/client/src/components/RouterProduction.tsx b/client/src/components/RouterProduction.tsx
index 06d4f79..225106b 100644
--- a/client/src/components/RouterProduction.tsx
+++ b/client/src/components/RouterProduction.tsx
@@ -30,6 +30,7 @@ import PaymentSchedulePage from "@/pages/PaymentSchedulePage";
import Layout from "@/components/Layout";
// Mobile pages
+import MobileApp from "@/pages/mobile/MobileApp";
import MobileDashboardPage from "@/pages/mobile/DashboardPage";
import MobileOrdersPage from "@/pages/mobile/OrdersPage";
import MobileDeliveriesPage from "@/pages/mobile/DeliveriesPage";
@@ -85,44 +86,46 @@ function RouterProduction() {
);
}
- // ===== MOBILE ROUTES (sans Layout standard) =====
+ // ===== MOBILE ROUTES (avec MobileApp pour StoreProvider) =====
if (isMobile) {
return (
-
-
-
-
-
-
+
+
+
+
+
+
+
- {/* Pages sans version mobile - utiliser version desktop dans Layout pour l'instant */}
-
-
-
-
-
-
-
-
-
-
-
-
-
+ {/* Pages sans version mobile - utiliser version desktop pour l'instant */}
+
+
+
+
+
+
+
+
+
+
+
+
+
- {/* Redirection /auth vers dashboard */}
-
- {() => {
- if (typeof window !== 'undefined') {
- window.location.href = '/dashboard';
- }
- return ;
- }}
-
+ {/* Redirection /auth vers dashboard */}
+
+ {() => {
+ if (typeof window !== 'undefined') {
+ window.location.href = '/dashboard';
+ }
+ return ;
+ }}
+
-
-
-
+
+
+
+
);
}
diff --git a/client/src/pages/mobile/MobileApp.tsx b/client/src/pages/mobile/MobileApp.tsx
new file mode 100644
index 0000000..70c1c07
--- /dev/null
+++ b/client/src/pages/mobile/MobileApp.tsx
@@ -0,0 +1,71 @@
+/**
+ * MobileApp - Wrapper pour l'application mobile avec StoreProvider
+ * Fournit le contexte Store à toutes les pages mobiles
+ */
+import { ReactNode, useState, useEffect } from "react";
+import { useQuery } from "@tanstack/react-query";
+import { useAuthUnified } from "@/hooks/useAuthUnified";
+import { StoreProvider } from "@/contexts/StoreContext";
+import type { Group } from "@shared/schema";
+
+interface MobileAppProps {
+ children: ReactNode;
+}
+
+export default function MobileApp({ children }: MobileAppProps) {
+ const { user } = useAuthUnified();
+
+ // Store state management
+ const [selectedStoreId, setSelectedStoreId] = useState(() => {
+ if (typeof window === 'undefined') return null;
+ const saved = localStorage.getItem('selectedStoreId');
+ return saved ? parseInt(saved) : null;
+ });
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+ const [storeInitialized, setStoreInitialized] = useState(false);
+
+ // Fetch stores
+ const { data: stores = [] } = useQuery({
+ queryKey: ['/api/groups'],
+ enabled: !!user,
+ });
+
+ // Initialize store selection
+ useEffect(() => {
+ if (user && stores.length > 0) {
+ if ((user.role === 'directeur' || user.role === 'manager') && !selectedStoreId && stores.length === 1) {
+ const singleStoreId = stores[0].id;
+ setSelectedStoreId(singleStoreId);
+ localStorage.setItem('selectedStoreId', singleStoreId.toString());
+ }
+ setStoreInitialized(true);
+ }
+ }, [user, stores, selectedStoreId]);
+
+ // Sync selectedStoreId to localStorage
+ useEffect(() => {
+ if (selectedStoreId) {
+ localStorage.setItem('selectedStoreId', selectedStoreId.toString());
+ } else {
+ localStorage.removeItem('selectedStoreId');
+ }
+ }, [selectedStoreId]);
+
+ const storeContextValue = {
+ selectedStoreId,
+ setSelectedStoreId,
+ stores,
+ sidebarCollapsed,
+ setSidebarCollapsed,
+ mobileMenuOpen,
+ setMobileMenuOpen,
+ storeInitialized
+ };
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/client/src/pages/mobile/MobileLayout.tsx b/client/src/pages/mobile/MobileLayout.tsx
index 1937781..6e1532a 100644
--- a/client/src/pages/mobile/MobileLayout.tsx
+++ b/client/src/pages/mobile/MobileLayout.tsx
@@ -1,13 +1,12 @@
/**
* MobileLayout - Layout dédié pour l'application mobile
* Affiche le magasin sélectionné de manière visible et une navigation bottom
- * Inclut son propre StoreProvider
+ * Note: Le StoreProvider est fourni par MobileApp au niveau supérieur
*/
-import { ReactNode, useState, useEffect } from "react";
-import { useQuery } from "@tanstack/react-query";
+import { ReactNode, useState } from "react";
import { Menu, Store, ChevronDown, LogOut } from "lucide-react";
import { useAuthUnified } from "@/hooks/useAuthUnified";
-import { StoreProvider } from "@/contexts/StoreContext";
+import { useStore } from "@/contexts/StoreContext";
import { Button } from "@/components/ui/button";
import { Sheet, SheetContent, SheetHeader, SheetTitle } from "@/components/ui/sheet";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
@@ -19,15 +18,9 @@ interface MobileLayoutProps {
title?: string;
}
-// Inner component that uses the store context
-function MobileLayoutInner({ children, title, selectedStoreId, setSelectedStoreId, stores, user }: {
- children: ReactNode;
- title?: string;
- selectedStoreId: number | null;
- setSelectedStoreId: (id: number | null) => void;
- stores: Group[];
- user: any;
-}) {
+export default function MobileLayout({ children, title }: MobileLayoutProps) {
+ const { user } = useAuthUnified();
+ const { selectedStoreId, setSelectedStoreId, stores } = useStore();
const [menuOpen, setMenuOpen] = useState(false);
// Get selected store name
@@ -183,61 +176,3 @@ function MobileLayoutInner({ children, title, selectedStoreId, setSelectedStoreI
);
}
-
-// Main MobileLayout component with StoreProvider
-export default function MobileLayout({ children, title }: MobileLayoutProps) {
- const { user } = useAuthUnified();
-
- // Store state management
- const [selectedStoreId, setSelectedStoreId] = useState(() => {
- const saved = localStorage.getItem('selectedStoreId');
- return saved ? parseInt(saved) : null;
- });
- const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
- const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
- const [storeInitialized, setStoreInitialized] = useState(false);
-
- // Fetch stores
- const { data: stores = [] } = useQuery({
- queryKey: ['/api/groups'],
- enabled: !!user,
- });
-
- // Initialize store selection
- useEffect(() => {
- if (user && stores.length > 0) {
- if ((user.role === 'directeur' || user.role === 'manager') && !selectedStoreId && stores.length === 1) {
- const singleStoreId = stores[0].id;
- setSelectedStoreId(singleStoreId);
- localStorage.setItem('selectedStoreId', singleStoreId.toString());
- }
- setStoreInitialized(true);
- }
- }, [user, stores, selectedStoreId]);
-
- const storeContextValue = {
- selectedStoreId,
- setSelectedStoreId,
- stores,
- sidebarCollapsed,
- setSidebarCollapsed,
- mobileMenuOpen,
- setMobileMenuOpen,
- storeInitialized
- };
-
- return (
-
-
- {children}
-
-
- );
-}
-