'use client' import type { ScopeDecision, ApplicableRegulation, SupervisoryAuthorityInfo } from '@/lib/sdk/compliance-scope-types' import { DEPTH_LEVEL_LABELS, DEPTH_LEVEL_DESCRIPTIONS, DEPTH_LEVEL_COLORS, DOCUMENT_TYPE_LABELS } from '@/lib/sdk/compliance-scope-types' // ============================================================================= // Helpers // ============================================================================= export const getScoreColor = (score: number): string => { if (score >= 80) return 'from-red-500 to-red-600' if (score >= 60) return 'from-orange-500 to-orange-600' if (score >= 40) return 'from-yellow-500 to-yellow-600' return 'from-green-500 to-green-600' } export const getSeverityBadge = (severity: string) => { const s = severity.toLowerCase() const colors: Record = { low: 'bg-gray-100 text-gray-800', medium: 'bg-yellow-100 text-yellow-800', high: 'bg-orange-100 text-orange-800', critical: 'bg-red-100 text-red-800', } const labels: Record = { low: 'Niedrig', medium: 'Mittel', high: 'Hoch', critical: 'Kritisch', } return ( {labels[s] || severity} ) } export const ScoreBar = ({ label, score }: { label: string; score: number | undefined }) => { const value = score ?? 0 return (
{label} {value}/100
) } // ============================================================================= // LevelCard // ============================================================================= export function LevelCard({ decision }: { decision: ScopeDecision }) { return (
{decision.determinedLevel}

{DEPTH_LEVEL_LABELS[decision.determinedLevel]}

{DEPTH_LEVEL_DESCRIPTIONS[decision.determinedLevel]}

{decision.reasoning && decision.reasoning.length > 0 && (

{decision.reasoning.map(r => r.description).filter(Boolean).join('. ')}

)}
) } // ============================================================================= // ScoreBreakdown // ============================================================================= export function ScoreBreakdown({ decision }: { decision: ScopeDecision }) { if (!decision.scores) return null return (

Score-Analyse

) } // ============================================================================= // RegulationsPanel // ============================================================================= interface RegulationsPanelProps { applicableRegulations?: ApplicableRegulation[] supervisoryAuthorities?: SupervisoryAuthorityInfo[] regulationAssessmentLoading?: boolean onGoToObligations?: () => void } export function RegulationsPanel({ applicableRegulations, supervisoryAuthorities, regulationAssessmentLoading, onGoToObligations, }: RegulationsPanelProps) { if (!applicableRegulations && !regulationAssessmentLoading) return null return (

Anwendbare Regulierungen

{regulationAssessmentLoading ? (
Regulierungen werden geprueft...
) : applicableRegulations && applicableRegulations.length > 0 ? (
{applicableRegulations.map((reg) => (
{reg.name} {reg.classification && ( {reg.classification} )}
{reg.obligation_count} Pflichten {reg.control_count > 0 && {reg.control_count} Controls}
))} {supervisoryAuthorities && supervisoryAuthorities.length > 0 && (

Zustaendige Aufsichtsbehoerden

{supervisoryAuthorities.map((sa, idx) => (
{sa.authority.abbreviation} ({sa.domain})

{sa.authority.name}

{sa.authority.url && ( Website → )}
))}
)} {onGoToObligations && (
)}
) : (

Keine anwendbaren Regulierungen ermittelt.

)}
) } // ============================================================================= // HardTriggersPanel // ============================================================================= export function HardTriggersPanel({ decision, expandedTrigger, onToggle, }: { decision: ScopeDecision expandedTrigger: number | null onToggle: (idx: number) => void }) { if (!decision.triggeredHardTriggers || decision.triggeredHardTriggers.length === 0) return null return (

Hard-Trigger

{decision.triggeredHardTriggers.map((trigger, idx) => (
{expandedTrigger === idx && (

{trigger.description}

{trigger.legalReference && (

Rechtsgrundlage: {trigger.legalReference}

)} {trigger.mandatoryDocuments && trigger.mandatoryDocuments.length > 0 && (

Pflichtdokumente: {trigger.mandatoryDocuments.join(', ')}

)} {trigger.requiresDSFA && (

DSFA erforderlich

)}
)}
))}
) } // ============================================================================= // RequiredDocumentsPanel // ============================================================================= export function RequiredDocumentsPanel({ decision }: { decision: ScopeDecision }) { if (!decision.requiredDocuments || decision.requiredDocuments.length === 0) return null return (

Erforderliche Dokumente

{decision.requiredDocuments.map((doc, idx) => ( ))}
Dokument Priorität Aufwand Trigger Aktion
{DOCUMENT_TYPE_LABELS[doc.documentType] || doc.documentType} {doc.requirement === 'mandatory' && ( Pflicht )}
{doc.priority} {doc.estimatedEffort ? `${doc.estimatedEffort}h` : '-'} {doc.triggeredBy && doc.triggeredBy.length > 0 && ( {doc.triggeredBy.join(', ')} )} {doc.sdkStepUrl && ( Zum SDK-Schritt → )}
) } // ============================================================================= // RiskFlagsPanel // ============================================================================= export function RiskFlagsPanel({ decision }: { decision: ScopeDecision }) { if (!decision.riskFlags || decision.riskFlags.length === 0) return null return (

Risiko-Flags

{decision.riskFlags.map((flag, idx) => (

{flag.message}

{getSeverityBadge(flag.severity)}
{flag.legalReference &&

{flag.legalReference}

}

Empfehlung: {flag.recommendation}

))}
) } // ============================================================================= // GapAnalysisPanel // ============================================================================= export function GapAnalysisPanel({ decision }: { decision: ScopeDecision }) { if (!decision.gaps || decision.gaps.length === 0) return null return (

Gap-Analyse

{decision.gaps.map((gap, idx) => (

{gap.description}

{getSeverityBadge(gap.severity)}

Ist: {gap.currentState}

Soll: {gap.targetState}

Aufwand: ~{gap.effort}h Level: {gap.requiredFor}
))}
) } // ============================================================================= // NextActionsPanel // ============================================================================= export function NextActionsPanel({ decision }: { decision: ScopeDecision }) { if (!decision.nextActions || decision.nextActions.length === 0) return null return (

Nächste Schritte

{decision.nextActions.map((action, idx) => (
{idx + 1}

{action.title}

{action.description}

{action.estimatedEffort > 0 && ( Aufwand: ~{action.estimatedEffort}h )} {action.sdkStepUrl && ( Zum SDK-Schritt → )}
))}
) } // ============================================================================= // AuditTrailPanel // ============================================================================= export function AuditTrailPanel({ decision, showAuditTrail, onToggle, }: { decision: ScopeDecision showAuditTrail: boolean onToggle: () => void }) { if (!decision.reasoning || decision.reasoning.length === 0) return null return (
{showAuditTrail && (
{decision.reasoning.map((entry, idx) => (

{entry.step}

{entry.description}

{entry.factors && entry.factors.length > 0 && (
    {entry.factors.map((factor, factorIdx) =>
  • • {factor}
  • )}
)} {entry.impact &&

{entry.impact}

}
))}
)}
) }