From edd230712a9d6736dc8da0410ba3e5d7ac86cfc1 Mon Sep 17 00:00:00 2001 From: alma Date: Thu, 15 Jan 2026 23:51:35 +0100 Subject: [PATCH] widget courrier refactor --- components/parole.tsx | 87 ++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/components/parole.tsx b/components/parole.tsx index 6aba04a..998ecba 100644 --- a/components/parole.tsx +++ b/components/parole.tsx @@ -3,11 +3,14 @@ import { useEffect, useState, useRef } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; -import { RefreshCw, MessageSquare } from "lucide-react"; +import { RefreshCw, MessageSquare, Loader2 } from "lucide-react"; import { useRouter } from "next/navigation"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { signIn, useSession } from "next-auth/react"; import { useTriggerNotification } from "@/hooks/use-trigger-notification"; +import { useUnifiedRefresh } from "@/hooks/use-unified-refresh"; +import { REFRESH_INTERVALS } from "@/lib/constants/refresh-intervals"; +import { Badge } from "@/components/ui/badge"; interface Message { id: string; @@ -40,19 +43,23 @@ export function Parole() { const [error, setError] = useState(null); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); + const [unreadCount, setUnreadCount] = useState(0); const router = useRouter(); const { data: session, status } = useSession(); const { triggerNotificationRefresh } = useTriggerNotification(); const lastUnreadCountRef = useRef(-1); // Initialize to -1 to detect first load const isInitializedRef = useRef(false); - const fetchMessages = async (isRefresh = false) => { - try { - if (isRefresh) { - setRefreshing(true); - } + const fetchMessages = async (forceRefresh = false) => { + // Only show loading spinner on initial load, not on auto-refresh + if (!messages.length) { + setLoading(true); + } + setRefreshing(true); + setError(null); - const response = await fetch('/api/rocket-chat/messages' + (isRefresh ? '?refresh=true' : ''), { + try { + const response = await fetch('/api/rocket-chat/messages' + (forceRefresh ? '?refresh=true' : ''), { cache: 'no-store', next: { revalidate: 0 }, credentials: 'include', @@ -68,6 +75,9 @@ export function Parole() { // Utiliser le totalUnreadCount de l'API (plus fiable) const currentUnreadCount = data.totalUnreadCount || 0; + // Update unread count state for badge display + setUnreadCount(currentUnreadCount); + // On initialise le count au premier chargement if (!isInitializedRef.current) { isInitializedRef.current = true; @@ -110,15 +120,32 @@ export function Parole() { } }; + // Initial fetch on mount useEffect(() => { if (status === 'authenticated') { - fetchMessages(); - // Set up polling every 30 seconds with force refresh to bypass cache - const interval = setInterval(() => fetchMessages(true), 30000); - return () => clearInterval(interval); + fetchMessages(false); // Use cache on initial load } }, [status]); + // Integrate unified refresh for automatic polling + const { refresh } = useUnifiedRefresh({ + resource: 'parole', + interval: REFRESH_INTERVALS.PAROLE, // 30 seconds + enabled: status === 'authenticated', + onRefresh: async () => { + await fetchMessages(false); // Use cache for auto-refresh + }, + priority: 'high', + }); + + // Manual refresh handler (bypasses cache) + const handleManualRefresh = async (e?: React.MouseEvent) => { + if (e) { + e.stopPropagation(); + } + await fetchMessages(true); // Force refresh, bypass cache + }; + if (status === 'loading') { return ( @@ -172,41 +199,43 @@ export function Parole() { Parole + {unreadCount > 0 && ( + + {unreadCount} + + )} - {loading &&

Loading messages...

} - {error && ( -
-

Error: {error}

+ {loading && messages.length === 0 ? ( +
+ +

Chargement des messages...

+
+ ) : error ? ( +
+

{error}

- )} - {!loading && !error && ( + ) : (
{messages.length === 0 ? ( -

No messages found

+

Aucun message

) : ( messages.map((message) => (