Display notifications for pending client calls and improve data caching

Add an alert component to display pending client calls and adjust query invalidation logic for pending calls.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 95e8aab4-f39f-4b48-aa57-a759ec15ba3d
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/95e8aab4-f39f-4b48-aa57-a759ec15ba3d/IFoerZ5
This commit is contained in:
michaelschal committed 2025-09-11 11:13:28 +00:00
1 parent 7745a75928
commit 367e09c234
3 files changed
+54 -7

No files matched your search

+4 -4
View File
@@ -15,10 +15,6 @@ run = ["npm", "run", "start"]
localPort = 5000
externalPort = 80
[[ports]]
localPort = 38145
externalPort = 3003
[[ports]]
localPort = 38451
externalPort = 3002
@@ -27,6 +23,10 @@ externalPort = 3002
localPort = 41343
externalPort = 3001
[[ports]]
localPort = 45663
externalPort = 3000
[workflows]
runButton = "Project"
@@ -33,8 +33,12 @@ export default function ClientCallsModal({ isOpen, onClose, pendingCalls }: Clie
description: "L'appel a été enregistré avec succès",
});
// Invalider les caches
queryClient.invalidateQueries({ queryKey: ['/api/customer-orders/pending-calls'] });
// Invalider les caches avec la bonne stratégie
queryClient.invalidateQueries({
predicate: (query) => {
return query.queryKey[0] === '/api/customer-orders/pending-calls';
}
});
queryClient.invalidateQueries({ queryKey: ['/api/customer-orders'] });
},
onError: (error, customerOrderId) => {
+44 -1
View File
@@ -5,6 +5,7 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Alert, AlertDescription } from "@/components/ui/alert";
import {
Dialog,
DialogContent,
@@ -28,7 +29,7 @@ import {
SelectValue,
} from "@/components/ui/select";
import { Pagination, usePagination } from "@/components/ui/pagination";
import { Plus, Edit, Trash2, Phone, PhoneCall, Printer, Eye, Package } from "lucide-react";
import { Plus, Edit, Trash2, Phone, PhoneCall, Printer, Eye, Package, AlertCircle } from "lucide-react";
import JsBarcode from 'jsbarcode';
import { safeFormat, safeDate } from "@/lib/dateUtils";
import { format } from "date-fns";
@@ -39,6 +40,7 @@ import type { CustomerOrderWithRelations, Group } from "@shared/schema";
import { CustomerOrderForm } from "@/components/CustomerOrderForm";
import { CustomerOrderDetails } from "@/components/CustomerOrderDetails";
import { ConfirmationModal } from "@/components/ConfirmationModal";
import ClientCallsModal from "@/components/modals/ClientCallsModal";
import { useStore } from "@/contexts/StoreContext";
import { usePermissions } from "@shared/permissions";
@@ -52,6 +54,7 @@ export default function CustomerOrders() {
const [showDetailsModal, setShowDetailsModal] = useState(false);
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [showStatusModal, setShowStatusModal] = useState(false);
const [showClientCallsModal, setShowClientCallsModal] = useState(false);
const [selectedOrder, setSelectedOrder] = useState<CustomerOrderWithRelations | null>(null);
const [searchTerm, setSearchTerm] = useState("");
const [sortBy, setSortBy] = useState<"date" | "status" | "supplier">("date");
@@ -64,6 +67,22 @@ export default function CustomerOrders() {
queryKey: ['/api/groups'],
});
// Query pour les appels clients en attente
const { data: pendingCalls = [], isLoading: isPendingCallsLoading } = useQuery<CustomerOrderWithRelations[]>({
queryKey: ['/api/customer-orders/pending-calls', selectedStoreId],
queryFn: async () => {
const pendingCallsUrl = `/api/customer-orders/pending-calls${selectedStoreId ? `?storeId=${selectedStoreId}` : ''}`;
const response = await fetch(pendingCallsUrl, { credentials: 'include' });
if (!response.ok) {
throw new Error('Failed to fetch pending calls');
}
const data = await response.json();
console.log('📞 Customer Orders - Pending calls received:', Array.isArray(data) ? data.length : 'NOT_ARRAY', 'items');
return data;
},
refetchInterval: 30000, // Refetch every 30 seconds
});
// Fetch suppliers for filter
const { data: suppliers = [] } = useQuery<any[]>({
queryKey: ['/api/suppliers'],
@@ -688,6 +707,23 @@ export default function CustomerOrders() {
return (
<div className="p-6 space-y-6">
{/* Alerte pour les appels clients en attente */}
{!isPendingCallsLoading && pendingCalls.length > 0 && (
<Alert
className="sticky top-0 z-50 bg-orange-50 border-orange-200 cursor-pointer hover:bg-orange-100 transition-colors"
onClick={() => setShowClientCallsModal(true)}
data-testid="alert-client-calls"
>
<Phone className="h-4 w-4 text-orange-600" />
<AlertDescription className="text-orange-700">
<strong>📞 {pendingCalls.length} client{pendingCalls.length > 1 ? 's' : ''} à appeler</strong>
<span className="block text-sm mt-1">
Produits disponibles - Cliquez pour voir la liste des clients à contacter
</span>
</AlertDescription>
</Alert>
)}
{/* Header */}
<div className="bg-white border-b border-gray-200 p-6 shadow-sm -m-6 mb-6">
<div className="flex items-center justify-between">
@@ -996,6 +1032,13 @@ export default function CustomerOrders() {
confirmText="Supprimer"
isLoading={deleteMutation.isPending}
/>
{/* Modal pour les appels clients */}
<ClientCallsModal
isOpen={showClientCallsModal}
onClose={() => setShowClientCallsModal(false)}
pendingCalls={pendingCalls}
/>
</div>
);
}