import { useState } from 'react'; import { FileText, User, CreditCard, IdCard, AlertTriangle, Check, ChevronDown, ChevronRight, Receipt } from 'lucide-react'; import Modal from '../ui/Modal'; import Button from '../ui/Button'; import Input from '../ui/Input'; import Select from '../ui/Select'; import { cachedEmailApi, AttachmentTargetSlot, AttachmentEntityWithSlots } from '../../services/api'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import toast from 'react-hot-toast'; import type { InvoiceType } from '../../types'; interface SaveEmailAsPdfModalProps { isOpen: boolean; onClose: () => void; emailId: number; onSuccess?: () => void; } type SelectedTarget = { entityType: 'customer' | 'identityDocument' | 'bankCard' | 'contract'; entityId?: number; targetKey: string; hasDocument: boolean; label: string; }; type SaveMode = 'document' | 'invoice'; export default function SaveEmailAsPdfModal({ isOpen, onClose, emailId, onSuccess, }: SaveEmailAsPdfModalProps) { const [selectedTarget, setSelectedTarget] = useState(null); const [expandedSections, setExpandedSections] = useState>(new Set(['customer'])); const [saveMode, setSaveMode] = useState('document'); const [invoiceData, setInvoiceData] = useState({ invoiceDate: new Date().toISOString().split('T')[0], invoiceType: 'INTERIM' as InvoiceType, notes: '', }); const queryClient = useQueryClient(); // Ziele laden (gleiche wie bei Anhängen) const { data: targetsData, isLoading, error } = useQuery({ queryKey: ['attachment-targets', emailId], queryFn: () => cachedEmailApi.getAttachmentTargets(emailId), enabled: isOpen, }); const targets = targetsData?.data; // Prüfen ob es ein Energievertrag ist const isEnergyContract = targets?.contract?.type === 'ELECTRICITY' || targets?.contract?.type === 'GAS'; const saveMutation = useMutation({ mutationFn: () => { if (!selectedTarget) throw new Error('Kein Ziel ausgewählt'); return cachedEmailApi.saveEmailAsPdf(emailId, { entityType: selectedTarget.entityType, entityId: selectedTarget.entityId, targetKey: selectedTarget.targetKey, }); }, onSuccess: () => { toast.success('E-Mail als PDF gespeichert'); queryClient.invalidateQueries({ queryKey: ['attachment-targets', emailId] }); queryClient.invalidateQueries({ queryKey: ['customers'] }); queryClient.invalidateQueries({ queryKey: ['contracts'] }); // Spezifische Ansichten aktualisieren if (targets?.customer?.id) { queryClient.invalidateQueries({ queryKey: ['customer', targets.customer.id.toString()] }); } if (targets?.contract?.id) { queryClient.invalidateQueries({ queryKey: ['contract', targets.contract.id.toString()] }); } onSuccess?.(); handleClose(); }, onError: (error: Error) => { toast.error(error.message || 'Fehler beim Speichern'); }, }); const saveInvoiceMutation = useMutation({ mutationFn: () => { return cachedEmailApi.saveEmailAsInvoice(emailId, { invoiceDate: invoiceData.invoiceDate, invoiceType: invoiceData.invoiceType, notes: invoiceData.notes || undefined, }); }, onSuccess: () => { toast.success('E-Mail als Rechnung gespeichert'); queryClient.invalidateQueries({ queryKey: ['attachment-targets', emailId] }); queryClient.invalidateQueries({ queryKey: ['customers'] }); queryClient.invalidateQueries({ queryKey: ['contracts'] }); if (targets?.contract?.id) { queryClient.invalidateQueries({ queryKey: ['contract', targets.contract.id.toString()] }); } onSuccess?.(); handleClose(); }, onError: (error: Error) => { toast.error(error.message || 'Fehler beim Speichern der Rechnung'); }, }); const handleClose = () => { setSelectedTarget(null); setSaveMode('document'); setInvoiceData({ invoiceDate: new Date().toISOString().split('T')[0], invoiceType: 'INTERIM', notes: '', }); onClose(); }; const toggleSection = (section: string) => { const newExpanded = new Set(expandedSections); if (newExpanded.has(section)) { newExpanded.delete(section); } else { newExpanded.add(section); } setExpandedSections(newExpanded); }; const handleSelectSlot = ( entityType: 'customer' | 'identityDocument' | 'bankCard' | 'contract', slot: AttachmentTargetSlot, entityId?: number, parentLabel?: string ) => { setSelectedTarget({ entityType, entityId, targetKey: slot.key, hasDocument: slot.hasDocument, label: parentLabel ? `${parentLabel} → ${slot.label}` : slot.label, }); }; const renderSlots = ( slots: AttachmentTargetSlot[], entityType: 'customer' | 'identityDocument' | 'bankCard' | 'contract', entityId?: number, parentLabel?: string ) => { return slots.map((slot) => { const isSelected = selectedTarget?.entityType === entityType && selectedTarget?.entityId === entityId && selectedTarget?.targetKey === slot.key; return (
handleSelectSlot(entityType, slot, entityId, parentLabel)} className={` flex items-center gap-3 p-3 cursor-pointer transition-colors rounded-lg ml-4 ${isSelected ? 'bg-blue-100 ring-2 ring-blue-500' : 'hover:bg-gray-100'} `} >
{slot.label} {slot.hasDocument && ( Vorhanden )}
{isSelected && }
); }); }; const renderEntityWithSlots = ( entity: AttachmentEntityWithSlots, entityType: 'identityDocument' | 'bankCard' ) => { return (
{entity.label}
{renderSlots(entity.slots, entityType, entity.id, entity.label)}
); }; const renderSection = ( title: string, sectionKey: string, icon: React.ReactNode, children: React.ReactNode, isEmpty: boolean = false ) => { const isExpanded = expandedSections.has(sectionKey); return (
{isExpanded && (
{isEmpty ? (

Keine Einträge vorhanden

) : ( children )}
)}
); }; const isPending = saveMutation.isPending || saveInvoiceMutation.isPending; return (
{/* Info */}

Die E-Mail wird als PDF exportiert (inkl. Absender, Empfänger, Datum und Inhalt) und im gewählten Dokumentenfeld gespeichert.

{/* Loading */} {isLoading && (
)} {/* Error */} {error && (
Fehler beim Laden der Dokumentziele
)} {targets && ( <> {/* Mode Toggle für Energieverträge */} {isEnergyContract && (
)} {/* Document Mode */} {saveMode === 'document' && (
{/* Kunde */} {renderSection( `Kunde: ${targets.customer.name}`, 'customer', , renderSlots(targets.customer.slots, 'customer'), targets.customer.slots.length === 0 )} {/* Ausweise */} {renderSection( 'Ausweisdokumente', 'identityDocuments', , targets.identityDocuments.map((doc) => renderEntityWithSlots(doc, 'identityDocument') ), targets.identityDocuments.length === 0 )} {/* Bankkarten */} {renderSection( 'Bankkarten', 'bankCards', , targets.bankCards.map((card) => renderEntityWithSlots(card, 'bankCard')), targets.bankCards.length === 0 )} {/* Vertrag */} {targets.contract && renderSection( `Vertrag: ${targets.contract.contractNumber}`, 'contract', , renderSlots(targets.contract.slots, 'contract'), targets.contract.slots.length === 0 )} {!targets.contract && (
E-Mail ist keinem Vertrag zugeordnet. Ordnen Sie die E-Mail einem Vertrag zu, um Vertragsdokumente als Ziel auswählen zu können.
)}
)} {/* Invoice Mode */} {saveMode === 'invoice' && isEnergyContract && (

Die E-Mail wird als Rechnung für den Vertrag {targets.contract?.contractNumber} gespeichert.

setInvoiceData({ ...invoiceData, invoiceDate: e.target.value })} required /> setInvoiceData({ ...invoiceData, notes: e.target.value })} placeholder="Optionale Anmerkungen..." />
)} )} {/* Warning if replacing */} {saveMode === 'document' && selectedTarget?.hasDocument && (
Achtung: An diesem Feld ist bereits ein Dokument hinterlegt. Das vorhandene Dokument wird durch die PDF ersetzt.
)} {/* Actions */}
{saveMode === 'document' ? ( ) : ( )}
); }