Extract components and hooks from 4 oversized pages (518–508 LOC each) to bring each page.tsx under 300 LOC (hard cap 500). Zero behavior changes. - dsr/new: TypeSelector, SourceSelector → _components/; useNewDSRForm → _hooks/ - compliance-hub: QuickActions, StatsRow, DomainChart, MappingsAndFindings, RegulationsTable → _components/; useComplianceHub → _hooks/ - iace/[projectId]/monitoring: Badges, EventForm, ResolveModal, TimelineEvent → _components/; useMonitoring → _hooks/ - cookie-banner: BannerPreview, CategoryCard → _components/; useCookieBanner → _hooks/ Result: page.tsx LOC: dsr/new=259, compliance-hub=95, monitoring=157, cookie-banner=212 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
96 lines
3.6 KiB
TypeScript
96 lines
3.6 KiB
TypeScript
'use client'
|
|
|
|
/**
|
|
* Compliance Hub Page (SDK Version - Zusatzmodul)
|
|
*
|
|
* Central compliance management dashboard with:
|
|
* - Compliance Score Overview
|
|
* - Quick Access to all compliance modules (SDK paths)
|
|
* - Control-Mappings with statistics
|
|
* - Audit Findings
|
|
* - Regulations overview
|
|
*/
|
|
|
|
import { useComplianceHub } from './_hooks/useComplianceHub'
|
|
import { QuickActions } from './_components/QuickActions'
|
|
import { StatsRow, DomainChart } from './_components/StatsRow'
|
|
import { MappingsAndFindings } from './_components/MappingsAndFindings'
|
|
import { RegulationsTable } from './_components/RegulationsTable'
|
|
|
|
export default function ComplianceHubPage() {
|
|
const {
|
|
dashboard, regulations, mappings, findings,
|
|
loading, error, seeding,
|
|
loadData, seedDatabase,
|
|
} = useComplianceHub()
|
|
|
|
const score = dashboard?.compliance_score || 0
|
|
const scoreColor = score >= 80 ? 'text-green-600' : score >= 60 ? 'text-yellow-600' : 'text-red-600'
|
|
const scoreBgColor = score >= 80 ? 'bg-green-500' : score >= 60 ? 'bg-yellow-500' : 'bg-red-500'
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Title Card (Zusatzmodul - no StepHeader) */}
|
|
<div className="bg-white rounded-xl shadow-sm border p-6">
|
|
<h1 className="text-2xl font-bold text-slate-900">Compliance Hub</h1>
|
|
<p className="text-slate-500 mt-1">
|
|
Zentrale Verwaltung aller Compliance-Anforderungen nach DSGVO, AI Act, BSI TR-03161 und weiteren Regulierungen.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Error Banner */}
|
|
{error && (
|
|
<div className="bg-red-50 border border-red-200 rounded-lg p-4 flex items-center gap-3">
|
|
<svg className="w-5 h-5 text-red-500 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<span className="text-red-700">{error}</span>
|
|
<button onClick={loadData} className="ml-auto text-red-600 hover:text-red-800 text-sm font-medium">
|
|
Erneut versuchen
|
|
</button>
|
|
</div>
|
|
)}
|
|
|
|
{/* Seed Button if no data */}
|
|
{!loading && (dashboard?.total_controls || 0) === 0 && (
|
|
<div className="p-4 bg-yellow-50 border border-yellow-200 rounded-lg">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<p className="font-medium text-yellow-800">Keine Compliance-Daten vorhanden</p>
|
|
<p className="text-sm text-yellow-700">Initialisieren Sie die Datenbank mit den Seed-Daten.</p>
|
|
</div>
|
|
<button
|
|
onClick={seedDatabase}
|
|
disabled={seeding}
|
|
className="px-4 py-2 bg-yellow-600 text-white rounded-lg hover:bg-yellow-700 disabled:opacity-50"
|
|
>
|
|
{seeding ? 'Initialisiere...' : 'Datenbank initialisieren'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Quick Actions */}
|
|
<QuickActions dashboard={dashboard} />
|
|
|
|
{loading ? (
|
|
<div className="flex items-center justify-center h-64">
|
|
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-purple-600" />
|
|
</div>
|
|
) : (
|
|
<>
|
|
<StatsRow
|
|
dashboard={dashboard}
|
|
scoreColor={scoreColor}
|
|
scoreBgColor={scoreBgColor}
|
|
score={score}
|
|
/>
|
|
<MappingsAndFindings dashboard={dashboard} mappings={mappings} findings={findings} />
|
|
<DomainChart dashboard={dashboard} />
|
|
<RegulationsTable regulations={regulations} onRefresh={loadData} />
|
|
</>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|