'use client' import React, { useState, useCallback } from 'react' import { useRouter } from 'next/navigation' import { type UploadedDocument, type DocumentUploadSectionProps, formatFileSize, detectVersionFromFilename, suggestNextVersion, } from './DocumentUploadTypes' import { UploadIcon, QRIcon, DocumentIcon, CheckIcon, EditIcon, CloseIcon, } from './DocumentUploadIcons' import { QRCodeModal } from './DocumentUploadQRModal' export type { UploadedDocument, ExtractedContent, ExtractedSection, DocumentUploadSectionProps, } from './DocumentUploadTypes' // ============================================================================= // MAIN COMPONENT // ============================================================================= export function DocumentUploadSection({ documentType, title, description, acceptedTypes = '.pdf,.docx,.doc', onDocumentProcessed, onOpenInEditor, sessionId, className = '', }: DocumentUploadSectionProps) { const router = useRouter() const [isDragging, setIsDragging] = useState(false) const [uploadedDocs, setUploadedDocs] = useState([]) const [showQRModal, setShowQRModal] = useState(false) const [isExpanded, setIsExpanded] = useState(false) const effectiveSessionId = sessionId || `sdk-${documentType}-${Date.now()}` const defaultTitles: Record = { tom: 'Bestehende TOMs hochladen', dsfa: 'Bestehende DSFA hochladen', vvt: 'Bestehendes VVT hochladen', loeschfristen: 'Bestehende Löschfristen hochladen', consent: 'Bestehende Einwilligungsdokumente hochladen', policy: 'Bestehende Richtlinie hochladen', custom: 'Dokument hochladen', } const defaultDescriptions: Record = { tom: 'Laden Sie Ihre bestehenden technischen und organisatorischen Maßnahmen hoch. Wir erkennen die Version und zeigen Ihnen, was aktualisiert werden sollte.', dsfa: 'Laden Sie Ihre bestehende Datenschutz-Folgenabschätzung hoch. Wir analysieren den Inhalt und schlagen Ergänzungen vor.', vvt: 'Laden Sie Ihr bestehendes Verarbeitungsverzeichnis hoch. Wir erkennen die Struktur und helfen bei der Aktualisierung.', loeschfristen: 'Laden Sie Ihre bestehenden Löschfristen-Dokumente hoch. Wir analysieren die Fristen und prüfen auf Vollständigkeit.', consent: 'Laden Sie Ihre bestehenden Einwilligungsdokumente hoch.', policy: 'Laden Sie Ihre bestehende Richtlinie hoch.', custom: 'Laden Sie ein bestehendes Dokument hoch.', } const displayTitle = title || defaultTitles[documentType] const displayDescription = description || defaultDescriptions[documentType] // Drag & Drop handlers const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault() setIsDragging(true) }, []) const handleDragLeave = useCallback((e: React.DragEvent) => { e.preventDefault() setIsDragging(false) }, []) const processFile = useCallback(async (file: File) => { const docId = `doc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` const newDoc: UploadedDocument = { id: docId, name: file.name, type: file.type, size: file.size, uploadedAt: new Date(), extractedVersion: detectVersionFromFilename(file.name), status: 'uploading', } setUploadedDocs(prev => [...prev, newDoc]) setIsExpanded(true) try { // Upload to API const formData = new FormData() formData.append('file', file) formData.append('documentType', documentType) formData.append('sessionId', effectiveSessionId) const response = await fetch('/api/sdk/v1/documents/upload', { method: 'POST', body: formData, }) if (!response.ok) { throw new Error('Upload fehlgeschlagen') } const result = await response.json() const updatedDoc: UploadedDocument = { ...newDoc, status: 'ready', extractedVersion: result.extractedVersion || newDoc.extractedVersion, extractedContent: result.extractedContent, } setUploadedDocs(prev => prev.map(d => d.id === docId ? updatedDoc : d)) if (onDocumentProcessed) { onDocumentProcessed(updatedDoc) } } catch (error) { setUploadedDocs(prev => prev.map(d => d.id === docId ? { ...d, status: 'error', error: error instanceof Error ? error.message : 'Fehler' } : d )) } }, [documentType, effectiveSessionId, onDocumentProcessed]) const handleDrop = useCallback((e: React.DragEvent) => { e.preventDefault() setIsDragging(false) const files = Array.from(e.dataTransfer.files).filter(f => f.type === 'application/pdf' || f.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || f.type === 'application/msword' ) files.forEach(processFile) }, [processFile]) const handleFileSelect = useCallback((e: React.ChangeEvent) => { if (!e.target.files) return Array.from(e.target.files).forEach(processFile) e.target.value = '' // Reset input }, [processFile]) const removeDocument = useCallback((docId: string) => { setUploadedDocs(prev => prev.filter(d => d.id !== docId)) }, []) const handleOpenInEditor = useCallback((doc: UploadedDocument) => { if (onOpenInEditor) { onOpenInEditor(doc) } else { // Default: navigate to workflow editor router.push(`/sdk/workflow?documentType=${documentType}&documentId=${doc.id}`) } }, [documentType, onOpenInEditor, router]) return (
{/* Header */} {/* Expanded Content */} {isExpanded && (

{displayDescription}

{/* Upload Area */}

{isDragging ? 'Dateien hier ablegen' : 'Dateien hierher ziehen'}

oder klicken zum Auswählen (PDF, DOCX)

{/* QR Upload Button */} {/* Uploaded Documents */} {uploadedDocs.length > 0 && (

Hochgeladene Dokumente:

{uploadedDocs.map(doc => (
{doc.status === 'uploading' || doc.status === 'processing' ? (
) : doc.status === 'ready' ? (
) : (
!
)}

{doc.name}

{formatFileSize(doc.size)} {doc.extractedVersion && ( <> Version {doc.extractedVersion} Vorschlag: v{suggestNextVersion(doc.extractedVersion)} )}
{doc.error && (

{doc.error}

)}
{doc.status === 'ready' && ( )}
))}
)} {/* Extracted Content Preview */} {uploadedDocs.some(d => d.status === 'ready' && d.extractedContent) && (

Erkannte Inhalte

{uploadedDocs .filter(d => d.status === 'ready' && d.extractedContent) .map(doc => (
{doc.extractedContent?.title && (

Titel: {doc.extractedContent.title}

)} {doc.extractedContent?.sections && (

Abschnitte: {doc.extractedContent.sections.length} gefunden

)}
)) }
)}
)} {/* QR Modal */} setShowQRModal(false)} sessionId={effectiveSessionId} />
) } export default DocumentUploadSection