'use client' /** * DraftingEngineWidget - Erweitert den ComplianceAdvisor um 4 Modi * * Mode-Indicator Pills: Explain / Ask / Draft / Validate * Document-Type Selector aus requiredDocuments der ScopeDecision * Feature-Flag enableDraftingEngine fuer schrittweises Rollout */ import { useState, useEffect, useRef, useCallback } from 'react' import { useSDK } from '@/lib/sdk/context' import { useDraftingEngine } from '@/lib/sdk/drafting-engine/use-drafting-engine' import { DOCUMENT_TYPE_LABELS } from '@/lib/sdk/compliance-scope-types' import type { AgentMode } from '@/lib/sdk/drafting-engine/types' import type { ScopeDocumentType } from '@/lib/sdk/compliance-scope-types' import { DraftEditor } from './DraftEditor' import { ValidationReport } from './ValidationReport' interface DraftingEngineWidgetProps { currentStep?: string enableDraftingEngine?: boolean } const MODE_CONFIG: Record = { explain: { label: 'Explain', color: 'bg-gray-100 text-gray-600', activeColor: 'bg-purple-100 text-purple-700 ring-1 ring-purple-300', icon: 'M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z' }, ask: { label: 'Ask', color: 'bg-gray-100 text-gray-600', activeColor: 'bg-amber-100 text-amber-700 ring-1 ring-amber-300', icon: 'M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z' }, draft: { label: 'Draft', color: 'bg-gray-100 text-gray-600', activeColor: 'bg-blue-100 text-blue-700 ring-1 ring-blue-300', icon: 'M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z' }, validate: { label: 'Validate', color: 'bg-gray-100 text-gray-600', activeColor: 'bg-green-100 text-green-700 ring-1 ring-green-300', icon: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z' }, } const EXAMPLE_QUESTIONS: Record = { explain: [ 'Was ist ein Verarbeitungsverzeichnis?', 'Wann brauche ich eine DSFA?', 'Was sind TOM nach Art. 32 DSGVO?', ], ask: [ 'Welche Luecken hat mein Compliance-Profil?', 'Was fehlt noch fuer die Zertifizierung?', 'Welche Dokumente muss ich noch erstellen?', ], draft: [ 'Erstelle einen VVT-Eintrag fuer unseren Hauptprozess', 'Erstelle TOM fuer unsere Cloud-Infrastruktur', 'Erstelle eine Datenschutzerklaerung', ], validate: [ 'Pruefe die Konsistenz meiner Dokumente', 'Stimmen VVT und TOM ueberein?', 'Gibt es Luecken bei den Loeschfristen?', ], } export function DraftingEngineWidget({ currentStep = 'default', enableDraftingEngine = true, }: DraftingEngineWidgetProps) { const { state } = useSDK() const engine = useDraftingEngine() const [isOpen, setIsOpen] = useState(false) const [isExpanded, setIsExpanded] = useState(false) const [inputValue, setInputValue] = useState('') const [showDraftEditor, setShowDraftEditor] = useState(false) const [showValidationReport, setShowValidationReport] = useState(false) const messagesEndRef = useRef(null) // Available document types from scope decision const availableDocumentTypes: ScopeDocumentType[] = state.complianceScope?.decision?.requiredDocuments ?.filter(d => d.required) .map(d => d.documentType as ScopeDocumentType) ?? ['vvt', 'tom', 'lf'] // Auto-scroll useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }) }, [engine.messages]) // Open draft editor when a new draft arrives useEffect(() => { if (engine.currentDraft) { setShowDraftEditor(true) } }, [engine.currentDraft]) // Open validation report when new results arrive useEffect(() => { if (engine.validationResult) { setShowValidationReport(true) } }, [engine.validationResult]) const handleSendMessage = useCallback( (content: string) => { if (!content.trim()) return setInputValue('') engine.sendMessage(content) }, [engine] ) const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault() handleSendMessage(inputValue) } } const exampleQuestions = EXAMPLE_QUESTIONS[engine.currentMode] if (!isOpen) { return ( ) } // Draft Editor full-screen overlay if (showDraftEditor && engine.currentDraft) { return ( { engine.acceptDraft() setShowDraftEditor(false) }} onValidate={() => { engine.validateDraft() }} onClose={() => setShowDraftEditor(false)} onRefine={(instruction: string) => { engine.requestDraft(instruction) }} validationResult={engine.validationResult} isTyping={engine.isTyping} /> ) } return (
{/* Header */}
Drafting Engine
Compliance-Dokumententwurf
{/* Mode Pills */}
{(Object.keys(MODE_CONFIG) as AgentMode[]).map((mode) => { const config = MODE_CONFIG[mode] const isActive = engine.currentMode === mode return ( ) })}
{/* Document Type Selector (visible in draft/validate mode) */} {(engine.currentMode === 'draft' || engine.currentMode === 'validate') && (
Dokument:
)} {/* Error Banner */} {engine.error && (
{engine.error}
)} {/* Validation Report Inline */} {showValidationReport && engine.validationResult && (
setShowValidationReport(false)} compact />
)} {/* Messages Area */}
{engine.messages.length === 0 ? (

{engine.currentMode === 'explain' && 'Fragen beantworten'} {engine.currentMode === 'ask' && 'Luecken erkennen'} {engine.currentMode === 'draft' && 'Dokumente entwerfen'} {engine.currentMode === 'validate' && 'Konsistenz pruefen'}

{engine.currentMode === 'explain' && 'Stellen Sie Fragen zu DSGVO, AI Act und Compliance.'} {engine.currentMode === 'ask' && 'Identifiziert Luecken in Ihrem Compliance-Profil.'} {engine.currentMode === 'draft' && 'Erstellt strukturierte Compliance-Dokumente.'} {engine.currentMode === 'validate' && 'Prueft Cross-Dokument-Konsistenz.'}

Beispiele:

{exampleQuestions.map((q, idx) => ( ))}
{/* Quick Actions for Draft/Validate */} {engine.currentMode === 'draft' && engine.activeDocumentType && ( )} {engine.currentMode === 'validate' && ( )}
) : ( <> {engine.messages.map((message, idx) => (

{message.content}

{/* Draft ready indicator */} {message.metadata?.hasDraft && engine.currentDraft && ( )} {/* Validation ready indicator */} {message.metadata?.hasValidation && engine.validationResult && ( )}
))} {engine.isTyping && (
)}
)}
{/* Input Area */}
setInputValue(e.target.value)} onKeyDown={handleKeyDown} placeholder={ engine.currentMode === 'draft' ? 'Anweisung fuer den Entwurf...' : engine.currentMode === 'validate' ? 'Validierungsfrage...' : 'Frage eingeben...' } disabled={engine.isTyping} className="flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent disabled:opacity-50" /> {engine.isTyping ? ( ) : ( )}
) }