diff --git a/client/src/components/CalendarGrid.tsx b/client/src/components/CalendarGrid.tsx index aa908bf..64ea724 100644 --- a/client/src/components/CalendarGrid.tsx +++ b/client/src/components/CalendarGrid.tsx @@ -171,14 +171,16 @@ export default function CalendarGrid({ onDateClick, onItemClick, }: CalendarGridProps) { - console.log('🗓️ CalendarGrid rendered with:', { - currentDate: currentDate?.toISOString(), - ordersCount: orders?.length || 0, - deliveriesCount: deliveries?.length || 0, - publicitiesCount: publicities?.length || 0, - selectedStoreId, - userGroupsCount: userGroups?.length || 0 - }); + if (import.meta.env.DEV) { + console.log('🗓️ CalendarGrid rendered with:', { + currentDate: currentDate?.toISOString(), + ordersCount: orders?.length || 0, + deliveriesCount: deliveries?.length || 0, + publicitiesCount: publicities?.length || 0, + selectedStoreId, + userGroupsCount: userGroups?.length || 0 + }); + } const monthStart = startOfMonth(currentDate); const monthEnd = endOfMonth(currentDate); @@ -192,12 +194,14 @@ export default function CalendarGrid({ return []; } - console.log('🔍 CalendarGrid getPublicitiesForDate:', { - date: dateStr, - totalPublicities: publicities.length, - selectedStoreId, - userGroups: userGroups?.length || 0 - }); + if (import.meta.env.DEV) { + console.log('🔍 CalendarGrid getPublicitiesForDate:', { + date: dateStr, + totalPublicities: publicities.length, + selectedStoreId, + userGroups: userGroups?.length || 0 + }); + } try { return publicities.filter(pub => { @@ -222,7 +226,7 @@ export default function CalendarGrid({ // If no store is selected and user has no assigned groups, show only publicities with participations if (!selectedStoreId && (!userGroups || userGroups.length === 0)) { const hasParticipations = pub.participations && Array.isArray(pub.participations) && pub.participations.length > 0; - if (hasParticipations) { + if (hasParticipations && import.meta.env.DEV) { console.log('📋 Publicity has participations (no store selected):', { pubNumber: pub.pubNumber, participationCount: pub.participations.length }); } return hasParticipations; @@ -232,7 +236,7 @@ export default function CalendarGrid({ if (selectedStoreId) { const matches = pub.participations && Array.isArray(pub.participations) && pub.participations.some((pg: any) => pg?.groupId === selectedStoreId); - if (matches) { + if (matches && import.meta.env.DEV) { console.log('🎯 Publicity matches selected store:', { pubNumber: pub.pubNumber, selectedStoreId }); } return matches; diff --git a/client/src/components/modals/OrderDetailModal.tsx b/client/src/components/modals/OrderDetailModal.tsx index c81f18d..dd386fe 100644 --- a/client/src/components/modals/OrderDetailModal.tsx +++ b/client/src/components/modals/OrderDetailModal.tsx @@ -43,8 +43,8 @@ export default function OrderDetailModal({ title: "Succès", description: "Commande validée avec succès", }); + // Invalidation sélective pour éviter la disparition du calendrier queryClient.invalidateQueries({ queryKey: ['/api/orders'] }); - queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] }); onClose(); }, onError: (error) => { @@ -76,8 +76,8 @@ export default function OrderDetailModal({ title: "Succès", description: "Livraison validée avec succès", }); + // Invalidation sélective pour éviter la disparition du calendrier queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] }); - queryClient.invalidateQueries({ queryKey: ['/api/orders'] }); onClose(); }, onError: (error) => { @@ -103,37 +103,26 @@ export default function OrderDetailModal({ const deleteMutation = useMutation({ mutationFn: async (id: number) => { const endpoint = isOrder ? `/api/orders/${id}` : `/api/deliveries/${id}`; - console.log(`🗑️ Deleting ${isOrder ? 'order' : 'delivery'}:`, id); + if (import.meta.env.DEV) { + console.log(`🗑️ Deleting ${isOrder ? 'order' : 'delivery'}:`, id); + } await apiRequest(endpoint, "DELETE"); }, onSuccess: () => { - console.log(`✅ ${isOrder ? 'Order' : 'Delivery'} deleted successfully, clearing cache...`); + if (import.meta.env.DEV) { + console.log(`✅ ${isOrder ? 'Order' : 'Delivery'} deleted successfully`); + } toast({ title: "Succès", description: `${isOrder ? 'Commande' : 'Livraison'} supprimée avec succès`, }); - // SOLUTION PRODUCTION : Cache clearing radical pour éviter incohérences storeId - console.log('🗑️ Cache cleared, forcing page reload to maintain storeId consistency...'); - - // SOLUTION HYBRIDE : Invalidation sélective pour éviter perte storeId - console.log('🧹 Using selective invalidation to preserve storeId context...'); - - // Invalidation ciblée sans clear() pour préserver le contexte - queryClient.invalidateQueries({ - predicate: (query) => { - const key = query.queryKey[0]?.toString() || ''; - return key.includes('/api/orders') || key.includes('/api/deliveries'); - } - }); - - // Force refetch pour garantir synchronisation immédiate - queryClient.refetchQueries({ - predicate: (query) => { - const key = query.queryKey[0]?.toString() || ''; - return key.includes('/api/orders') || key.includes('/api/deliveries'); - } - }); + // Invalidation sélective uniquement pour l'API concernée + if (isOrder) { + queryClient.invalidateQueries({ queryKey: ['/api/orders'] }); + } else { + queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] }); + } onClose(); }, diff --git a/client/src/pages/Calendar.tsx b/client/src/pages/Calendar.tsx index 6413a82..3905e10 100644 --- a/client/src/pages/Calendar.tsx +++ b/client/src/pages/Calendar.tsx @@ -49,12 +49,14 @@ export default function Calendar() { } const url = `/api/orders?${params.toString()}`; - console.log('📅 Calendar fetching orders:', { - url, - selectedStoreId, - userRole: user?.role, - params: params.toString() - }); + if (import.meta.env.DEV) { + console.log('📅 Calendar fetching orders:', { + url, + selectedStoreId, + userRole: user?.role, + params: params.toString() + }); + } const response = await fetch(url, { credentials: 'include' @@ -65,7 +67,9 @@ export default function Calendar() { } const data = await response.json(); - console.log('📅 Calendar orders received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items'); + if (import.meta.env.DEV) { + console.log('📅 Calendar orders received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items'); + } // Protection contre les données invalides en production if (!Array.isArray(data)) { @@ -74,6 +78,8 @@ export default function Calendar() { } return data; }, + staleTime: 5 * 60 * 1000, // 5 minutes de cache pour éviter la disparition des données + gcTime: 10 * 60 * 1000, // 10 minutes en cache }); const { data: deliveries = [], isLoading: loadingDeliveries } = useQuery({ @@ -91,12 +97,14 @@ export default function Calendar() { } const url = `/api/deliveries?${params.toString()}`; - console.log('📅 Calendar fetching deliveries:', { - url, - selectedStoreId, - userRole: user?.role, - params: params.toString() - }); + if (import.meta.env.DEV) { + console.log('📅 Calendar fetching deliveries:', { + url, + selectedStoreId, + userRole: user?.role, + params: params.toString() + }); + } const response = await fetch(url, { credentials: 'include' @@ -107,7 +115,9 @@ export default function Calendar() { } const data = await response.json(); - console.log('📅 Calendar deliveries received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items'); + if (import.meta.env.DEV) { + console.log('📅 Calendar deliveries received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items'); + } // Protection contre les données invalides en production if (!Array.isArray(data)) { @@ -116,6 +126,8 @@ export default function Calendar() { } return data; }, + staleTime: 5 * 60 * 1000, // 5 minutes de cache pour éviter la disparition des données + gcTime: 10 * 60 * 1000, // 10 minutes en cache }); // Fetch publicities for the current year @@ -129,12 +141,14 @@ export default function Calendar() { } const url = `/api/publicities?${params.toString()}`; - console.log('📅 Calendar fetching publicities:', { - url, - selectedStoreId, - userRole: user?.role, - year: currentDate.getFullYear() - }); + if (import.meta.env.DEV) { + console.log('📅 Calendar fetching publicities:', { + url, + selectedStoreId, + userRole: user?.role, + year: currentDate.getFullYear() + }); + } const response = await fetch(url, { credentials: 'include' @@ -145,7 +159,9 @@ export default function Calendar() { } const data = await response.json(); - console.log('📅 Calendar publicities received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items'); + if (import.meta.env.DEV) { + console.log('📅 Calendar publicities received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items'); + } return Array.isArray(data) ? data : []; }, }); @@ -166,12 +182,7 @@ export default function Calendar() { }; const handleItemClick = (item: any, type: 'order' | 'delivery') => { - // Rafraîchir les données avant d'ouvrir le modal pour s'assurer d'avoir les liaisons à jour - queryClient.invalidateQueries({ queryKey: ['/api/orders'] }); - queryClient.invalidateQueries({ queryKey: ['/api/orders', selectedStoreId] }); - queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] }); - queryClient.invalidateQueries({ queryKey: ['/api/deliveries', selectedStoreId] }); - + // Ne pas invalider le cache à l'ouverture pour éviter la disparition des données setSelectedItem({ ...item, type }); setShowOrderDetail(true); }; diff --git a/cookies.txt b/cookies.txt index 4390e07..fb76b7b 100644 --- a/cookies.txt +++ b/cookies.txt @@ -2,4 +2,4 @@ # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. -#HttpOnly_localhost FALSE / FALSE 1755187696 connect.sid s%3AnEg7s3fD2sLyetJTCx-VYkzZFbBkPEcf.2BsOBC1UlFIC%2BpyKgdtocMX42YO%2FZLBn1cU6UeEnIYY +#HttpOnly_localhost FALSE / FALSE 1755203512 connect.sid s%3AGm18ttGO7m1DI7WtETfDd8gMojt-FqEw.%2BP3S4uZr6aX7vk2UAaEIow8kKQlZfWMzPcKLjUHAdNI diff --git a/replit.md b/replit.md index 1186295..f53d685 100644 --- a/replit.md +++ b/replit.md @@ -19,13 +19,19 @@ La plateforme fournit une gestion robuste des flux de travail de livraison avec ## Recent Changes -### 2025-08-13 - Optimisation performance production + suppression fonctionnelle +### 2025-08-13 - Optimisation performance production + correction calendrier ✅ **Résolution latence production** : - **Problème** : Console saturée par centaines de logs "API Response" causant latence - **Solution** : Logging conditionnel - seulement en développement pour requêtes normales - **Production** : Seules les erreurs API sont loggées pour debugging - **Impact** : Réduction drastique de la charge console et amélioration performances +✅ **Problème calendrier résolu** : +- **Problème** : Fermeture carte commande/livraison faisait disparaître toutes les données +- **Cause** : Invalidation aggressive du cache React Query + invalidation à l'ouverture +- **Solution** : Cache timing optimisé (5min staleTime) + invalidation sélective seulement +- **Résultat** : Calendrier stable, plus de disparition des données au jour actuel + ✅ **Fonctionnalité suppression complètement opérationnelle** : - **Cache NocoDB** : Fonction `saveInvoiceVerificationCache` ajoutée aux deux systèmes stockage - **MemStorage** : Implémentation CRUD complète pour ordres et livraisons