'use client' import { useMemo } from 'react' import { TOMGeneratorState, GapAnalysisResult, DerivedTOM } from '@/lib/sdk/tom-generator/types' import { getControlById, getAllControls } from '@/lib/sdk/tom-generator/controls/loader' import { SDM_GOAL_LABELS, SDM_GOAL_DESCRIPTIONS, getSDMCoverageStats, MODULE_LABELS, getModuleCoverageStats, SDMGewaehrleistungsziel, TOMModuleCategory, } from '@/lib/sdk/tom-generator/sdm-mapping' interface TOMGapExportTabProps { state: TOMGeneratorState onRunGapAnalysis: () => void } function getScoreColor(score: number): string { if (score >= 75) return 'text-green-600' if (score >= 50) return 'text-yellow-600' return 'text-red-600' } function getScoreBgColor(score: number): string { if (score >= 75) return 'bg-green-50 border-green-200' if (score >= 50) return 'bg-yellow-50 border-yellow-200' return 'bg-red-50 border-red-200' } function getBarColor(score: number): string { if (score >= 75) return 'bg-green-500' if (score >= 50) return 'bg-yellow-500' return 'bg-red-500' } function downloadJSON(data: unknown, filename: string) { const json = JSON.stringify(data, null, 2) const blob = new Blob([json], { type: 'application/json' }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = filename document.body.appendChild(a) a.click() document.body.removeChild(a) URL.revokeObjectURL(url) } export function TOMGapExportTab({ state, onRunGapAnalysis }: TOMGapExportTabProps) { const gap = state.gapAnalysis as GapAnalysisResult | null | undefined const sdmGoals = useMemo(() => { const goals = Object.keys(SDM_GOAL_LABELS) as SDMGewaehrleistungsziel[] const allStats = getSDMCoverageStats(state.derivedTOMs) return goals.map(key => { const stats = allStats[key] || { total: 0, implemented: 0, partial: 0, missing: 0 } const total = stats.total || 1 const percent = Math.round((stats.implemented / total) * 100) return { key, label: SDM_GOAL_LABELS[key], description: SDM_GOAL_DESCRIPTIONS[key], stats, percent, } }) }, [state.derivedTOMs]) const modules = useMemo(() => { const moduleKeys = Object.keys(MODULE_LABELS) as TOMModuleCategory[] const allStats = getModuleCoverageStats(state.derivedTOMs) return moduleKeys.map(key => { const stats = allStats[key] || { total: 0, implemented: 0 } const total = stats.total || 1 const percent = Math.round((stats.implemented / total) * 100) return { key, label: MODULE_LABELS[key], stats: { ...stats, partial: 0, missing: total - stats.implemented }, percent, } }) }, [state.derivedTOMs]) const handleExportTOMs = () => { downloadJSON(state.derivedTOMs, `tom-export-${new Date().toISOString().slice(0, 10)}.json`) } const handleExportGap = () => { if (!gap) return downloadJSON(gap, `gap-analyse-${new Date().toISOString().slice(0, 10)}.json`) } return (
{/* Gap Analysis */}

Gap-Analyse

{gap ? (
{/* Score Gauge */}
{gap.overallScore}
von 100 Punkten
{/* Missing Controls */} {gap.missingControls && gap.missingControls.length > 0 && (

Fehlende Kontrollen ({gap.missingControls.length})

{gap.missingControls.map((mc, idx) => { const control = getControlById(mc.controlId) return (
{control?.code || mc.controlId} {control?.name?.de || mc.controlId} {mc.reason && {mc.reason}}
) })}
)} {/* Partial Controls */} {gap.partialControls && gap.partialControls.length > 0 && (

Teilweise implementierte Kontrollen ({gap.partialControls.length})

{gap.partialControls.map((pc, idx) => { const control = getControlById(pc.controlId) return (
{control?.code || pc.controlId} {control?.name?.de || pc.controlId}
) })}
)} {/* Missing Evidence */} {gap.missingEvidence && gap.missingEvidence.length > 0 && (

Fehlende Nachweise ({gap.missingEvidence.length})

{gap.missingEvidence.map((item, idx) => { const control = getControlById(item.controlId) return (
{control?.name?.de || item.controlId}: {item.requiredEvidence.join(', ')}
) })}
)} {/* Recommendations */} {gap.recommendations && gap.recommendations.length > 0 && (

Empfehlungen ({gap.recommendations.length})

{gap.recommendations.map((rec, idx) => (
{typeof rec === 'string' ? rec : (rec as { text?: string; message?: string }).text || (rec as { text?: string; message?: string }).message || JSON.stringify(rec)}
))}
)}
) : (

Fuehren Sie die Gap-Analyse aus, um Luecken in Ihren TOMs zu identifizieren.

)}
{/* SDM Gewaehrleistungsziele */}

SDM Gewaehrleistungsziele

{sdmGoals.map(goal => (
{goal.label} {goal.description && ( {goal.description} )}
{goal.stats.implemented}/{goal.stats.total} implementiert {goal.stats.partial > 0 && ` | ${goal.stats.partial} teilweise`} {goal.stats.missing > 0 && ` | ${goal.stats.missing} fehlend`}
))}
{/* Module Coverage */}

Modul-Abdeckung

{modules.map(mod => (
{mod.label}
{mod.percent}% ({mod.stats.implemented}/{mod.stats.total})
{mod.stats.partial > 0 && (
{mod.stats.partial} teilweise
)} {mod.stats.missing > 0 && (
{mod.stats.missing} fehlend
)}
))}
{/* Export Section */}

Export

Vollstaendiger Export (ZIP) Nutzen Sie den TOM Generator fuer den vollstaendigen Export mit DOCX/PDF
) }