Files
breakpilot-compliance/admin-compliance/app/sdk/evidence/_components/ReportTab.tsx
Sharang Parnerkar 1fcd8244b1 refactor(admin): split evidence, process-tasks, iace/hazards pages
Extract components and hooks into _components/ and _hooks/ subdirectories
to reduce each page.tsx to under 500 LOC (was 1545/1383/1316).

Final line counts: evidence=213, process-tasks=304, hazards=157.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 17:12:15 +02:00

89 lines
3.6 KiB
TypeScript

'use client'
import type { EvidenceCheck, CoverageReport } from './EvidenceTypes'
export function ReportTab({
coverageReport,
checks,
displayEvidenceLength,
validCount,
expiredCount,
pendingCount,
}: {
coverageReport: CoverageReport | null
checks: EvidenceCheck[]
displayEvidenceLength: number
validCount: number
expiredCount: number
pendingCount: number
}) {
return (
<div className="bg-white rounded-xl shadow-sm border p-6">
<h3 className="text-lg font-semibold text-gray-900 mb-6">Evidence Coverage Report</h3>
{!coverageReport ? (
<div className="flex justify-center py-12">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600" />
</div>
) : (
<>
<div className="mb-8">
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium text-gray-700">Gesamt-Abdeckung</span>
<span className={`text-2xl font-bold ${
coverageReport.coverage_percent >= 80 ? 'text-green-600' :
coverageReport.coverage_percent >= 50 ? 'text-yellow-600' : 'text-red-600'
}`}>
{coverageReport.coverage_percent.toFixed(1)}%
</span>
</div>
<div className="h-4 bg-gray-200 rounded-full overflow-hidden">
<div
className={`h-full transition-all duration-500 ${
coverageReport.coverage_percent >= 80 ? 'bg-green-500' :
coverageReport.coverage_percent >= 50 ? 'bg-yellow-500' : 'bg-red-500'
}`}
style={{ width: `${coverageReport.coverage_percent}%` }}
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
<div className="p-4 bg-gray-50 rounded-lg text-center">
<p className="text-3xl font-bold text-gray-900">{coverageReport.total_controls}</p>
<p className="text-sm text-gray-500">Controls gesamt</p>
</div>
<div className="p-4 bg-green-50 rounded-lg text-center">
<p className="text-3xl font-bold text-green-600">{coverageReport.controls_with_evidence}</p>
<p className="text-sm text-green-600">Mit Nachweis belegt</p>
</div>
<div className="p-4 bg-red-50 rounded-lg text-center">
<p className="text-3xl font-bold text-red-600">{coverageReport.controls_without_evidence}</p>
<p className="text-sm text-red-600">Ohne Nachweis</p>
</div>
</div>
<div className="border-t pt-6">
<h4 className="font-medium text-gray-900 mb-3">Automatische Checks</h4>
<div className="flex items-center gap-4 text-sm text-gray-600">
<span>{checks.length} Check-Definitionen</span>
<span>{checks.filter(c => c.is_active).length} aktiv</span>
<span>{checks.filter(c => c.last_run_at).length} mindestens 1x ausgefuehrt</span>
</div>
</div>
<div className="border-t pt-6 mt-6">
<h4 className="font-medium text-gray-900 mb-3">Nachweise</h4>
<div className="flex items-center gap-4 text-sm text-gray-600">
<span>{displayEvidenceLength} Nachweise gesamt</span>
<span className="text-green-600">{validCount} gueltig</span>
<span className="text-red-600">{expiredCount} abgelaufen</span>
<span className="text-yellow-600">{pendingCount} ausstehend</span>
</div>
</div>
</>
)}
</div>
)
}