espace-paie-odentas/hooks/usePendingSignatures.ts
odentas 5351456516 feat: Badge signatures en attente avec polling optimisé 30s
- Ajout endpoint API /api/signatures-electroniques/pending-count (COUNT() Supabase)
- Ajout hook usePendingSignatures avec polling 30s et pause en background
- Badge rouge animé dans Sidebar pour signatures employeur en attente
- Optimisé pour ne pas surcharger Supabase (cache 30s, refetch au focus)
- Désactivé en mode démo et pour staff
2025-11-07 18:27:30 +01:00

64 lines
2.1 KiB
TypeScript

import { useQuery } from '@tanstack/react-query';
type PendingSignaturesResponse = {
count: number;
org_id: string | null;
demo?: boolean;
error?: string;
};
/**
* Hook pour récupérer le nombre de signatures employeur en attente
*
* Configuration optimisée pour le temps réel sans surcharger Supabase :
* - Polling toutes les 30 secondes quand l'onglet est actif
* - Pause automatique quand l'onglet est en arrière-plan
* - Refetch immédiat au retour sur l'onglet
* - Cache de 30 secondes pour éviter les requêtes doublons
*
* @param orgId - ID de l'organisation (optionnel, pour les staff)
* @param enabled - Activer ou désactiver le hook (défaut: true)
*/
export function usePendingSignatures(orgId?: string | null, enabled: boolean = true) {
return useQuery<PendingSignaturesResponse>({
queryKey: ['pending-signatures-count', orgId],
queryFn: async () => {
const url = orgId
? `/api/signatures-electroniques/pending-count?org_id=${orgId}`
: `/api/signatures-electroniques/pending-count`;
const res = await fetch(url, {
cache: 'no-store',
headers: {
'Accept': 'application/json',
},
});
if (!res.ok) {
throw new Error('Erreur lors de la récupération du compteur');
}
const data = await res.json();
return data;
},
// Stratégie de cache optimisée
staleTime: 30 * 1000, // 30 secondes - considéré comme "frais"
gcTime: 5 * 60 * 1000, // 5 minutes - conservation en cache
// Polling intelligent
refetchInterval: 30 * 1000, // Polling toutes les 30 secondes
refetchIntervalInBackground: false, // PAUSE quand l'onglet est en arrière-plan
// Refetch automatique
refetchOnWindowFocus: true, // Refetch au retour sur l'onglet
refetchOnMount: true, // Refetch au montage du composant
refetchOnReconnect: true, // Refetch après reconnexion réseau
// Retry strategy
retry: 1, // 1 seul retry en cas d'échec
retryDelay: 1000, // 1 seconde entre les retries
// Activation conditionnelle
enabled: enabled,
});
}