Ensure all users can view relevant data by filtering it by their selected store

Fix data fetching logic to correctly apply store filtering for all user roles, and add an alert for managers/directors if no store is selected.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 15f19c36-9aac-46a4-a181-3dc5f496fabd
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/15f19c36-9aac-46a4-a181-3dc5f496fabd/H1nJA1b
This commit is contained in:
michaelschal committed 2025-08-20 08:58:29 +00:00
1 parent 46de48f459
commit 20efd9251e
4 files changed
+53 -9

No files matched your search

+45 -5
View File
@@ -2,7 +2,7 @@ import { ReactNode, useState, createContext, useContext, 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 } from "lucide-react";
import { LogOut, Store, Menu, AlertTriangle } from "lucide-react";
import { useAuthUnified } from "@/hooks/useAuthUnified";
import { useIsMobile } from "@/hooks/use-mobile";
import Sidebar from "./Sidebar";
@@ -72,29 +72,52 @@ export default function Layout({ children }: LayoutProps) {
// Effet pour marquer l'initialisation comme terminée
useEffect(() => {
if (user && stores.length > 0) {
// Pour les admins, vérifier que selectedStoreId est cohérent avec les stores disponibles
if (user.role === 'admin' && selectedStoreId) {
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');
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) {
if ((user.role === 'directeur' || user.role === 'manager') && !selectedStoreId && stores.length === 1 && !needsUpdate) {
console.log('🏪 Auto-selecting single available store for directeur/manager:', stores[0].id);
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);
@@ -206,6 +229,23 @@ export default function Layout({ children }: LayoutProps) {
)}
</header>
{/* Alert for directeur/manager without store selection */}
{user && (user.role === 'directeur' || user.role === 'manager') && !selectedStoreId && storeInitialized && (
<div className="bg-red-50 border-l-4 border-red-400 p-4 m-4">
<div className="flex">
<div className="flex-shrink-0">
<AlertTriangle className="h-5 w-5 text-red-400" />
</div>
<div className="ml-3">
<p className="text-sm text-red-700">
<strong>Action requise :</strong> Veuillez sélectionner un magasin pour afficher les données.
Vos permissions ne permettent pas de voir les données de tous les magasins.
</p>
</div>
</div>
</div>
)}
<div className="flex-1 bg-gray-50 p-6 h-full overflow-y-auto">
{children}
</div>
+2 -1
View File
@@ -71,7 +71,8 @@ export default function Deliveries() {
const [deliveryToDelete, setDeliveryToDelete] = useState<DeliveryWithRelations | null>(null);
// Construire l'URL pour l'historique complet sans filtrage par date
const deliveriesUrl = `/api/deliveries${selectedStoreId && user?.role === 'admin' ? `?storeId=${selectedStoreId}` : ''}`;
// CRITICAL FIX: Appliquer le filtrage par storeId pour TOUS les rôles, pas seulement admin
const deliveriesUrl = `/api/deliveries${selectedStoreId ? `?storeId=${selectedStoreId}` : ''}`;
const { data: deliveriesData = [], isLoading } = useQuery<DeliveryWithRelations[]>({
queryKey: ['/api/deliveries', selectedStoreId, user?.role],
+2 -1
View File
@@ -69,7 +69,8 @@ export default function Orders() {
const [orderToDelete, setOrderToDelete] = useState<OrderWithRelations | null>(null);
// Construire l'URL pour l'historique complet sans filtrage par date
const ordersUrl = `/api/orders${selectedStoreId && user?.role === 'admin' ? `?storeId=${selectedStoreId}` : ''}`;
// CRITICAL FIX: Appliquer le filtrage par storeId pour TOUS les rôles, pas seulement admin
const ordersUrl = `/api/orders${selectedStoreId ? `?storeId=${selectedStoreId}` : ''}`;
const { data: ordersData = [], isLoading } = useQuery<OrderWithRelations[]>({
queryKey: [ordersUrl, selectedStoreId],
+4 -2
View File
@@ -339,14 +339,16 @@ export default function Tasks() {
queryFn: async () => {
try {
const params = new URLSearchParams();
if (selectedStoreId && user?.role === 'admin') {
// CRITICAL FIX: Appliquer le filtrage par storeId pour TOUS les rôles, pas seulement admin
if (selectedStoreId) {
params.append('storeId', selectedStoreId.toString());
}
console.log('📋 TASKS QUERY - Fetching with params:', {
selectedStoreId,
userRole: user?.role,
storeInitialized,
url: `/api/tasks?${params.toString()}`
url: `/api/tasks?${params.toString()}`,
willFilterByStore: !!selectedStoreId
});
const response = await fetch(`/api/tasks?${params.toString()}`, {