Initial commit: breakpilot-compliance - Compliance SDK Platform
Services: Admin-Compliance, Backend-Compliance, AI-Compliance-SDK, Consent-SDK, Developer-Portal, PCA-Platform, DSMS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
'use client';
|
||||
|
||||
import { useControls } from '@breakpilot/compliance-sdk-react';
|
||||
import Link from 'next/link';
|
||||
import {
|
||||
ArrowLeft,
|
||||
CheckCircle,
|
||||
Shield,
|
||||
FileCheck,
|
||||
AlertTriangle,
|
||||
Target,
|
||||
BarChart3,
|
||||
FileText,
|
||||
Download,
|
||||
} from 'lucide-react';
|
||||
|
||||
export default function CompliancePage() {
|
||||
const { controls, evidence, risks, isLoading } = useControls();
|
||||
|
||||
const domains = [
|
||||
{ id: 'access', name: 'Access Control', count: 5 },
|
||||
{ id: 'data', name: 'Data Protection', count: 6 },
|
||||
{ id: 'network', name: 'Network Security', count: 4 },
|
||||
{ id: 'incident', name: 'Incident Response', count: 5 },
|
||||
{ id: 'business', name: 'Business Continuity', count: 4 },
|
||||
{ id: 'vendor', name: 'Vendor Management', count: 4 },
|
||||
{ id: 'training', name: 'Security Training', count: 4 },
|
||||
{ id: 'physical', name: 'Physical Security', count: 6 },
|
||||
{ id: 'governance', name: 'Governance', count: 6 },
|
||||
];
|
||||
|
||||
const controlStats = {
|
||||
total: controls?.length ?? 44,
|
||||
implemented:
|
||||
controls?.filter((c) => c.implementationStatus === 'IMPLEMENTED').length ??
|
||||
32,
|
||||
inProgress:
|
||||
controls?.filter((c) => c.implementationStatus === 'IN_PROGRESS').length ??
|
||||
8,
|
||||
notImplemented:
|
||||
controls?.filter((c) => c.implementationStatus === 'NOT_IMPLEMENTED')
|
||||
.length ?? 4,
|
||||
};
|
||||
|
||||
const implementationRate = Math.round(
|
||||
(controlStats.implemented / controlStats.total) * 100
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Header */}
|
||||
<header className="border-b bg-card">
|
||||
<div className="container mx-auto px-6 py-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link
|
||||
href="/"
|
||||
className="p-2 hover:bg-muted rounded-lg transition-colors"
|
||||
>
|
||||
<ArrowLeft className="h-5 w-5" />
|
||||
</Link>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-2 rounded-lg bg-green-500/10">
|
||||
<CheckCircle className="h-6 w-6 text-green-500" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-xl font-semibold">Compliance Hub</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Controls, Evidence & Obligations
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Link
|
||||
href="/compliance/export"
|
||||
className="inline-flex items-center gap-2 px-4 py-2 border rounded-lg hover:bg-muted transition-colors"
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
Export Report
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="container mx-auto px-6 py-8">
|
||||
{/* Stats Overview */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
|
||||
<div className="bg-card border rounded-xl p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<Shield className="h-8 w-8 text-green-500" />
|
||||
<span className="text-3xl font-bold">{implementationRate}%</span>
|
||||
</div>
|
||||
<div className="text-sm font-medium">Implementation Rate</div>
|
||||
<div className="w-full bg-muted rounded-full h-2 mt-2">
|
||||
<div
|
||||
className="bg-green-500 h-2 rounded-full transition-all"
|
||||
style={{ width: `${implementationRate}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-card border rounded-xl p-6">
|
||||
<div className="text-3xl font-bold text-green-500">
|
||||
{controlStats.implemented}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground mt-1">
|
||||
Controls Implemented
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground mt-2">
|
||||
of {controlStats.total} total
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-card border rounded-xl p-6">
|
||||
<div className="text-3xl font-bold text-blue-500">
|
||||
{evidence?.length ?? 0}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground mt-1">
|
||||
Evidence Items
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground mt-2">
|
||||
Uploaded documents
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-card border rounded-xl p-6">
|
||||
<div className="text-3xl font-bold text-yellow-500">
|
||||
{risks?.filter((r) => r.status !== 'MITIGATED').length ?? 0}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground mt-1">Open Risks</div>
|
||||
<div className="text-xs text-muted-foreground mt-2">
|
||||
Require attention
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Links */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
||||
<Link
|
||||
href="/compliance/controls"
|
||||
className="bg-card border rounded-xl p-6 hover:border-primary/50 transition-colors group"
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="p-3 rounded-lg bg-green-500/10">
|
||||
<Shield className="h-6 w-6 text-green-500" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold">Controls</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
44+ controls in 9 domains
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href="/compliance/evidence"
|
||||
className="bg-card border rounded-xl p-6 hover:border-primary/50 transition-colors group"
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="p-3 rounded-lg bg-blue-500/10">
|
||||
<FileCheck className="h-6 w-6 text-blue-500" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold">Evidence</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{evidence?.length ?? 0} documents uploaded
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href="/compliance/risks"
|
||||
className="bg-card border rounded-xl p-6 hover:border-primary/50 transition-colors group"
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="p-3 rounded-lg bg-yellow-500/10">
|
||||
<AlertTriangle className="h-6 w-6 text-yellow-500" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold">Risk Register</h3>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{risks?.length ?? 0} risks tracked
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Control Domains */}
|
||||
<div className="bg-card border rounded-xl p-6">
|
||||
<h2 className="text-lg font-semibold mb-6">Control Domains</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{domains.map((domain) => {
|
||||
const domainControls = controls?.filter(
|
||||
(c) => c.domain === domain.id
|
||||
);
|
||||
const implemented =
|
||||
domainControls?.filter(
|
||||
(c) => c.implementationStatus === 'IMPLEMENTED'
|
||||
).length ?? 0;
|
||||
const total = domain.count;
|
||||
const percent = Math.round((implemented / total) * 100);
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={domain.id}
|
||||
href={`/compliance/controls?domain=${domain.id}`}
|
||||
className="p-4 border rounded-lg hover:bg-muted/50 transition-colors"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="font-medium">{domain.name}</span>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{implemented}/{total}
|
||||
</span>
|
||||
</div>
|
||||
<div className="w-full bg-muted rounded-full h-2">
|
||||
<div
|
||||
className={`h-2 rounded-full transition-all ${
|
||||
percent === 100
|
||||
? 'bg-green-500'
|
||||
: percent >= 50
|
||||
? 'bg-blue-500'
|
||||
: 'bg-yellow-500'
|
||||
}`}
|
||||
style={{ width: `${percent}%` }}
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user