import { ReactNode, useState, useEffect } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Button } from "@/components/ui/button"; import { LogOut, Store, Menu, AlertTriangle } from "lucide-react"; import { useAuthUnified } from "@/hooks/useAuthUnified"; import { useIsMobile } from "@/hooks/use-mobile"; import { useScreenSize } from "@/hooks/use-screen-size"; import { StoreProvider } from "@/contexts/StoreContext"; import Sidebar from "./Sidebar"; import WeatherWidget from "./WeatherWidget"; import DateWidget from "./DateWidget"; import type { Group } from "@shared/schema"; interface LayoutProps { children: ReactNode; } export default function Layout({ children }: LayoutProps) { const { user } = useAuthUnified(); const queryClient = useQueryClient(); const isMobile = useIsMobile(); const { screenSize, isMobileOrTablet, isTablet } = useScreenSize(); const [selectedStoreId, setSelectedStoreId] = useState(() => { // Restaurer le selectedStoreId depuis localStorage si disponible const saved = localStorage.getItem('selectedStoreId'); const restoredId = saved ? parseInt(saved) : null; console.log('🏪 Layout - Restoring selectedStoreId from localStorage:', { saved, restoredId }); return restoredId; }); const [storeInitialized, setStoreInitialized] = useState(false); const [sidebarCollapsed, setSidebarCollapsed] = useState(() => { // Restaurer l'état de la sidebar depuis localStorage, mais forcer collapsed sur mobile try { const saved = localStorage.getItem('sidebarCollapsed'); console.log('🔧 Layout - Restoring sidebar state:', { saved, isMobile }); return isMobile ? true : (saved ? JSON.parse(saved) : false); } catch (error) { console.error('Error reading sidebar state from localStorage:', error); return isMobile ? true : false; } }); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const { data: stores = [] } = useQuery({ queryKey: ['/api/groups'], enabled: !!user, }); // Effet pour marquer l'initialisation comme terminée useEffect(() => { if (user && stores.length > 0) { let needsUpdate = false; // Pour tous les rôles, vérifier que selectedStoreId est cohérent avec les stores disponibles if (selectedStoreId) { const storeExists = stores.find(store => store.id === selectedStoreId); if (!storeExists) { console.log('🏪 Selected store not found in available stores, clearing selection:', { selectedStoreId, userRole: user.role, availableStores: stores.map(s => s.id) }); setSelectedStoreId(null); localStorage.removeItem('selectedStoreId'); needsUpdate = true; } else { console.log('🏪 Selected store validated successfully:', { selectedStoreId, userRole: user.role, storeName: storeExists.name }); } } // IMPORTANT FIX: Pour les rôles directeur/manager, forcer la sélection d'un magasin spécifique // si aucun n'est sélectionné et qu'ils n'ont accès qu'à un seul magasin if ((user.role === 'directeur' || user.role === 'manager') && !selectedStoreId && stores.length === 1 && !needsUpdate) { console.log('🏪 Auto-selecting single available store for directeur/manager:', { storeId: stores[0].id, storeName: stores[0].name, userRole: user.role, userId: user.id, previousSelectedStoreId: selectedStoreId, timestamp: new Date().toISOString() }); const singleStoreId = stores[0].id; setSelectedStoreId(singleStoreId); localStorage.setItem('selectedStoreId', singleStoreId.toString()); } // VALIDATION CRITIQUE: Pour les directeurs/managers, s'assurer qu'un magasin est toujours sélectionné if ((user.role === 'directeur' || user.role === 'manager') && !selectedStoreId && !needsUpdate) { console.log('🚨 CRITICAL: Directeur/Manager has no store selected, this will cause empty data display:', { userId: user.id, userRole: user.role, availableStores: stores.map(s => ({ id: s.id, name: s.name })) }); } console.log('🏪 Store initialization complete:', { user: user.role, selectedStoreId, storesCount: stores.length, validatedStore: selectedStoreId ? stores.find(s => s.id === selectedStoreId)?.name : 'None', autoSelected: (user.role === 'directeur' || user.role === 'manager') && !selectedStoreId && stores.length === 1 }); setStoreInitialized(true); } }, [user, stores, selectedStoreId]); const handleLogout = () => { window.location.href = "/api/logout"; }; return (
{/* Mobile overlay */} {isMobile && mobileMenuOpen && (
setMobileMenuOpen(false)} /> )}
{/* Header with mobile menu and store selector */}
{/* Mobile menu button */} {isMobile && ( )} {/* Weather and Date widgets - responsive */}
{!isMobile && }
{/* Store selector for admin, directeur, and manager - responsive */} {user && (user.role === 'admin' || user.role === 'directeur' || user.role === 'manager') && stores.length > 0 && (
)}
{/* Alert for directeur/manager without store selection */} {user && (user.role === 'directeur' || user.role === 'manager') && !selectedStoreId && storeInitialized && (

Action requise : Veuillez sélectionner un magasin pour afficher les données. Vos permissions ne permettent pas de voir les données de tous les magasins.

)}
{children}
); }