import { useState } from 'react'; import { Mail, MailOpen, Star, Paperclip, ChevronRight, Trash2, X } from 'lucide-react'; import { CachedEmail, cachedEmailApi } from '../../services/api'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useAuth } from '../../context/AuthContext'; import Button from '../ui/Button'; import toast from 'react-hot-toast'; interface EmailListProps { emails: CachedEmail[]; selectedEmailId?: number; onSelectEmail: (email: CachedEmail) => void; onEmailDeleted?: (emailId: number) => void; isLoading?: boolean; folder?: 'INBOX' | 'SENT'; accountId?: number | null; // Für Folder-Count-Aktualisierung bei Lesen/Ungelesen } export default function EmailList({ emails, selectedEmailId, onSelectEmail, onEmailDeleted, isLoading, folder = 'INBOX', accountId, }: EmailListProps) { const isSentFolder = folder === 'SENT'; const [deleteConfirmId, setDeleteConfirmId] = useState(null); const { hasPermission } = useAuth(); // Für gesendete E-Mails: Empfänger extrahieren const getDisplayName = (email: CachedEmail) => { if (isSentFolder) { // Bei gesendeten E-Mails: Ersten Empfänger anzeigen try { const toAddresses = JSON.parse(email.toAddresses); if (toAddresses.length > 0) { return `An: ${toAddresses[0]}${toAddresses.length > 1 ? ` (+${toAddresses.length - 1})` : ''}`; } } catch { return 'An: (Unbekannt)'; } } // Bei empfangenen E-Mails: Absender anzeigen return email.fromName || email.fromAddress; }; const queryClient = useQueryClient(); const toggleStarMutation = useMutation({ mutationFn: (emailId: number) => cachedEmailApi.toggleStar(emailId), onSuccess: (_data, emailId) => { queryClient.invalidateQueries({ queryKey: ['emails'] }); queryClient.invalidateQueries({ queryKey: ['email', emailId] }); }, }); const toggleReadMutation = useMutation({ mutationFn: ({ emailId, isRead }: { emailId: number; isRead: boolean }) => cachedEmailApi.markAsRead(emailId, isRead), onSuccess: (_data, variables) => { queryClient.invalidateQueries({ queryKey: ['emails'] }); queryClient.invalidateQueries({ queryKey: ['email', variables.emailId] }); // Folder-Counts aktualisieren für Badge-Update if (accountId) { queryClient.invalidateQueries({ queryKey: ['folder-counts', accountId] }); } }, }); const deleteMutation = useMutation({ mutationFn: (emailId: number) => cachedEmailApi.delete(emailId), onSuccess: (_data, emailId) => { queryClient.invalidateQueries({ queryKey: ['emails'] }); // Folder-Counts aktualisieren if (accountId) { queryClient.invalidateQueries({ queryKey: ['folder-counts', accountId] }); } toast.success('E-Mail in Papierkorb verschoben'); setDeleteConfirmId(null); onEmailDeleted?.(emailId); }, onError: (error: Error) => { console.error('Delete error:', error); toast.error(error.message || 'Fehler beim Löschen der E-Mail'); setDeleteConfirmId(null); }, }); const unassignMutation = useMutation({ mutationFn: (emailId: number) => cachedEmailApi.unassignFromContract(emailId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['emails'] }); toast.success('Vertragszuordnung aufgehoben'); }, onError: (error: Error) => { console.error('Unassign error:', error); toast.error(error.message || 'Fehler beim Aufheben der Zuordnung'); }, }); const handleUnassign = (e: React.MouseEvent, emailId: number) => { e.stopPropagation(); unassignMutation.mutate(emailId); }; const handleDeleteClick = (e: React.MouseEvent, emailId: number) => { e.stopPropagation(); setDeleteConfirmId(emailId); }; const handleDeleteConfirm = (e: React.MouseEvent) => { e.stopPropagation(); if (deleteConfirmId) { deleteMutation.mutate(deleteConfirmId); } }; const handleDeleteCancel = (e: React.MouseEvent) => { e.stopPropagation(); setDeleteConfirmId(null); }; const formatDate = (dateStr: string) => { const date = new Date(dateStr); const now = new Date(); const isToday = date.toDateString() === now.toDateString(); if (isToday) { return date.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }); } return date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }); }; const handleStarClick = (e: React.MouseEvent, emailId: number) => { e.stopPropagation(); toggleStarMutation.mutate(emailId); }; const handleReadToggle = (e: React.MouseEvent, email: CachedEmail) => { e.stopPropagation(); toggleReadMutation.mutate({ emailId: email.id, isRead: !email.isRead }); }; const handleSelectEmail = (email: CachedEmail) => { // E-Mail als gelesen markieren wenn noch nicht gelesen if (!email.isRead) { toggleReadMutation.mutate({ emailId: email.id, isRead: true }); } onSelectEmail(email); }; if (isLoading) { return (
); } if (emails.length === 0) { return (

Keine E-Mails vorhanden

); } return (
{emails.map((email) => (
handleSelectEmail(email)} className={[ 'flex items-start gap-3 p-3 cursor-pointer transition-colors', selectedEmailId === email.id ? 'bg-blue-100' : ['hover:bg-gray-100', !email.isRead ? 'bg-white' : 'bg-gray-50/50'].join(' ') ].join(' ')} style={{ borderLeft: selectedEmailId === email.id ? '4px solid #2563eb' : '4px solid transparent' }} > {/* Read Status */} {/* Star */} {/* Delete (nur für User mit emails:delete Permission) */} {hasPermission('emails:delete') && ( )} {/* Email Content */}
{/* From/To & Date */}
{getDisplayName(email)} {formatDate(email.receivedAt)}
{/* Subject */}
{email.subject || '(Kein Betreff)'} {email.hasAttachments && ( )}
{/* Contract Badge */} {email.contract && (
{email.contract.contractNumber} {/* X-Button nur für INBOX oder manuell zugeordnete gesendete E-Mails */} {(folder === 'INBOX' || (folder === 'SENT' && !email.isAutoAssigned)) && ( )}
)}
{/* Chevron */}
))} {/* Lösch-Bestätigung Modal */} {deleteConfirmId && (

E-Mail löschen?

Die E-Mail wird in den Papierkorb verschoben.

)}
); }