"use client"; import { useEffect, useState } from "react"; import { useSession } from "next-auth/react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { RefreshCw, MessageSquare, Mail, MailOpen, Loader2 } from "lucide-react"; import Link from 'next/link'; import { useUnifiedRefresh } from "@/hooks/use-unified-refresh"; import { REFRESH_INTERVALS } from "@/lib/constants/refresh-intervals"; import { Badge } from "@/components/ui/badge"; interface Email { id: string; subject: string; from: string; fromName?: string; date: string; read: boolean; starred: boolean; folder: string; } interface EmailResponse { emails: Email[]; mailUrl: string; error?: string; } export function Email() { const { data: session, status } = useSession(); const [emails, setEmails] = useState([]); const [loading, setLoading] = useState(false); const [refreshing, setRefreshing] = useState(false); const [error, setError] = useState(null); const [mailUrl, setMailUrl] = useState(null); const [accounts, setAccounts] = useState>([]); const [unreadCount, setUnreadCount] = useState(0); const [accountErrors, setAccountErrors] = useState>({}); useEffect(() => { if (status === 'authenticated') { loadAccounts(); } }, [status]); useEffect(() => { if (accounts.length > 0 && status === 'authenticated') { fetchEmails(false); fetchUnreadCount(); } }, [accounts, status]); const loadAccounts = async () => { try { const response = await fetch('/api/courrier/accounts'); if (response.ok) { const data = await response.json(); if (data.accounts) { setAccounts(data.accounts.map((acc: any) => ({ id: acc.id || acc.email, email: acc.email }))); } } } catch (err) { console.error('Error loading accounts:', err); } }; const fetchEmails = async (forceRefresh = false) => { // Only show loading spinner on initial load, not on auto-refresh if (!emails.length) { setLoading(true); } setRefreshing(true); setError(null); setAccountErrors({}); try { // Fetch emails from all accounts in parallel const emailPromises = accounts.map(async (account) => { try { const url = `/api/courrier?folder=INBOX&page=1&perPage=5&accountId=${encodeURIComponent(account.id)}${forceRefresh ? '&refresh=true' : ''}`; const response = await fetch(url); if (!response.ok) { const errorMsg = `Failed to fetch emails for ${account.email}`; console.warn(errorMsg); setAccountErrors(prev => ({ ...prev, [account.id]: errorMsg })); return []; } const data = await response.json(); if (data.error || !data.emails) { const errorMsg = data.error || `No emails returned for ${account.email}`; setAccountErrors(prev => ({ ...prev, [account.id]: errorMsg })); return []; } // Add accountId to each email for proper identification return data.emails.map((email: any) => ({ ...email, accountId: account.id })); } catch (err) { const errorMsg = `Error fetching emails for ${account.email}: ${err instanceof Error ? err.message : 'Unknown error'}`; console.error(errorMsg, err); setAccountErrors(prev => ({ ...prev, [account.id]: errorMsg })); return []; } }); const allEmailsArrays = await Promise.allSettled(emailPromises); const allEmails = allEmailsArrays .filter((result): result is PromiseFulfilledResult => result.status === 'fulfilled') .flatMap(result => result.value); // Transform and sort all emails const transformedEmails = allEmails .map((email: any) => ({ id: email.id, subject: email.subject, from: email.from[0]?.address || '', fromName: email.from[0]?.name || '', date: email.date, read: email.flags.seen, starred: email.flags.flagged, folder: email.folder, accountId: email.accountId })) // Sort emails by date (most recent first) .sort((a: Email, b: Email) => new Date(b.date).getTime() - new Date(a.date).getTime()) .slice(0, 5); // Only show the first 5 emails setEmails(transformedEmails); setMailUrl('/courrier'); // Show error only if all accounts failed if (allEmails.length === 0 && accounts.length > 0 && Object.keys(accountErrors).length === accounts.length) { setError('Failed to load emails from all accounts'); } } catch (error) { console.error('Error fetching emails:', error); setError(error instanceof Error ? error.message : 'Failed to load emails'); setEmails([]); } finally { setLoading(false); setRefreshing(false); } }; const fetchUnreadCount = async () => { try { const response = await fetch('/api/courrier/unread-counts'); if (response.ok) { const data = await response.json(); if (data && typeof data === 'object') { // Sum up unread counts from all accounts and folders let totalUnread = 0; Object.values(data).forEach((accountCounts: any) => { if (typeof accountCounts === 'object') { Object.values(accountCounts).forEach((count: any) => { if (typeof count === 'number') { totalUnread += count; } }); } }); setUnreadCount(totalUnread); } } } catch (err) { console.error('Error fetching unread count:', err); // Don't set error state for unread count failures } }; // Integrate unified refresh for automatic polling const { refresh } = useUnifiedRefresh({ resource: 'email', interval: REFRESH_INTERVALS.EMAIL, // 1 minute enabled: status === 'authenticated', onRefresh: async () => { await fetchEmails(false); // Use cache for auto-refresh await fetchUnreadCount(); }, priority: 'medium', }); // Manual refresh handler (bypasses cache) const handleManualRefresh = async () => { await fetchEmails(true); // Force refresh, bypass cache await fetchUnreadCount(); }; const formatDate = (dateString: string) => { try { const date = new Date(dateString); return new Intl.DateTimeFormat('fr-FR', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }).format(date); } catch (e) { return ''; } }; return ( Courrier {unreadCount > 0 && ( {unreadCount} )} {error ? (

{error}

{Object.keys(accountErrors).length > 0 && (
{Object.entries(accountErrors).map(([accountId, errMsg]) => (

{errMsg}

))}
)}
) : loading && emails.length === 0 ? (

Chargement des emails...

) : emails.length === 0 ? (

Aucun email

) : (
{emails.map((email) => (
{email.read ? : }

{email.fromName || email.from.split('@')[0]}

{formatDate(email.date)}

{email.subject}

))} {mailUrl && (
Voir tous les emails →
)}
)}
); }