Spaces:
Runtime error
Runtime error
File size: 9,456 Bytes
5752a28 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | import { ComplianceReport } from '../types/analysis';
import { Shield, AlertCircle, CheckCircle2, FileCheck } from 'lucide-react';
import { Progress } from './ui/progress';
import { Card } from './ui/card';
import { Badge } from './ui/badge';
interface CompliancePanelProps {
report: ComplianceReport;
}
export function CompliancePanel({ report }: CompliancePanelProps) {
const getComplianceColor = () => {
if (report.cfpbAlignment >= 80) return 'text-emerald-400';
if (report.cfpbAlignment >= 60) return 'text-amber-400';
if (report.cfpbAlignment >= 45) return 'text-orange-400';
return 'text-rose-400';
};
const getComplianceBg = () => {
if (report.cfpbAlignment >= 80) return 'from-emerald-500/10 via-emerald-500/5 to-transparent border-emerald-500/30';
if (report.cfpbAlignment >= 60) return 'from-amber-500/10 via-amber-500/5 to-transparent border-amber-500/30';
if (report.cfpbAlignment >= 45) return 'from-orange-500/10 via-orange-500/5 to-transparent border-orange-500/30';
return 'from-rose-500/10 via-rose-500/5 to-transparent border-rose-500/30';
};
const getComplianceStatus = () => {
if (report.cfpbAlignment >= 80) return 'Compliant';
if (report.cfpbAlignment >= 60) return 'Needs Improvement';
if (report.cfpbAlignment >= 45) return 'Non-Compliant';
return 'Critically Non-Compliant';
};
const getBadgeVariantClass = () => {
if (report.cfpbAlignment >= 80) return 'bg-emerald-500/10 text-emerald-400 border border-emerald-500/20';
if (report.cfpbAlignment >= 60) return 'bg-amber-500/10 text-amber-400 border border-amber-500/20';
if (report.cfpbAlignment >= 45) return 'bg-orange-500/10 text-orange-400 border border-orange-500/20';
return 'bg-rose-500/10 text-rose-400 border border-rose-500/20';
};
return (
<div className="space-y-6">
{/* Overall Compliance Score */}
<Card className={`p-6 border bg-gradient-to-br ${getComplianceBg()} rounded-2xl relative overflow-hidden`}>
<div className="absolute top-0 right-0 w-32 h-32 bg-white/5 rounded-full blur-3xl pointer-events-none" />
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-4 mb-4 justify-between">
<div className="flex items-center gap-4">
<div className={`p-3 rounded-xl bg-slate-950/20 border border-white/5`}>
<Shield className={`w-8 h-8 ${getComplianceColor()}`} />
</div>
<div>
<h3 className="text-lg font-extrabold text-slate-100">
CFPB Compliance Score: {report.cfpbAlignment}%
</h3>
<p className={`text-xs font-semibold mt-0.5 ${getComplianceColor()}`}>
Status: {getComplianceStatus()}
</p>
</div>
</div>
<Badge className={`${getBadgeVariantClass()} text-xs px-3 py-1 font-bold rounded-lg`}>
{getComplianceStatus()}
</Badge>
</div>
<Progress value={report.cfpbAlignment} className="h-3 bg-slate-900 border border-white/5" />
<p className="text-xs text-slate-400 mt-4 leading-relaxed">
This score reflects alignment with the Consumer Financial Protection Bureau (CFPB) guidelines
against deceptive practices in financial services, calculated by deducting points based on the severity of issues found.
</p>
</Card>
{/* Issues Found */}
{report.issues.length > 0 && (
<Card className="p-6 bg-slate-900/30 border border-border rounded-2xl">
<div className="flex items-center gap-3 mb-4">
<AlertCircle className="w-5 h-5 text-rose-400" />
<h4 className="font-bold text-sm text-slate-200">Compliance Issues Identified</h4>
</div>
<div className="space-y-3">
{report.issues.map((issue, index) => (
<div
key={index}
className="flex items-start gap-3 p-3.5 bg-rose-500/5 border border-rose-500/10 rounded-xl"
>
<div className="w-5 h-5 rounded-md bg-rose-500/20 text-rose-400 border border-rose-500/30 flex items-center justify-center text-xs font-bold shrink-0 mt-0.5">
{index + 1}
</div>
<p className="text-xs text-rose-200/90 leading-relaxed flex-1">{issue}</p>
</div>
))}
</div>
</Card>
)}
{/* Recommendations */}
{report.recommendations.length > 0 && (
<Card className="p-6 bg-slate-900/30 border border-border rounded-2xl">
<div className="flex items-center gap-3 mb-4">
<CheckCircle2 className="w-5 h-5 text-emerald-400" />
<h4 className="font-bold text-sm text-slate-200">Compliance Recommendations</h4>
</div>
<div className="space-y-3">
{report.recommendations.map((recommendation, index) => (
<div
key={index}
className="flex items-start gap-3 p-3.5 bg-emerald-500/5 border border-emerald-500/10 rounded-xl"
>
<div className="w-5 h-5 rounded-md bg-emerald-500/20 text-emerald-400 border border-emerald-500/30 flex items-center justify-center text-xs font-bold shrink-0 mt-0.5">
{index + 1}
</div>
<p className="text-xs text-emerald-200/90 leading-relaxed flex-1">{recommendation}</p>
</div>
))}
</div>
</Card>
)}
{/* CFPB Guidelines Reference */}
<Card className="p-6 bg-slate-900/30 border border-border rounded-2xl">
<div className="flex items-center gap-3 mb-4">
<FileCheck className="w-5 h-5 text-indigo-400" />
<h4 className="font-bold text-sm text-slate-200">CFPB Guidelines Reference</h4>
</div>
<div className="grid sm:grid-cols-2 gap-4">
<div className="bg-slate-950/20 rounded-xl p-4 border border-white/5">
<h5 className="font-bold text-xs text-slate-200 mb-1">Deceptive Practices (12 CFR 1041)</h5>
<p className="text-xs text-slate-400 leading-relaxed">
Prohibits unfair, deceptive, or abusive acts or practices (UDAAP) in connection with
consumer financial products or services.
</p>
</div>
<div className="bg-slate-950/20 rounded-xl p-4 border border-white/5">
<h5 className="font-bold text-xs text-slate-200 mb-1">Truth in Lending Act (TILA)</h5>
<p className="text-xs text-slate-400 leading-relaxed">
Requires clear disclosure of key terms and costs of consumer credit, ensuring
transparency in lending practices.
</p>
</div>
<div className="bg-slate-950/20 rounded-xl p-4 border border-white/5">
<h5 className="font-bold text-xs text-slate-200 mb-1">Electronic Fund Transfer Act (EFTA)</h5>
<p className="text-xs text-slate-400 leading-relaxed">
Protects consumers engaging in electronic fund transfers, requiring clear
disclosure of terms and conditions.
</p>
</div>
<div className="bg-slate-950/20 rounded-xl p-4 border border-white/5">
<h5 className="font-bold text-xs text-slate-200 mb-1">Fair Debt Collection Practices Act</h5>
<p className="text-xs text-slate-400 leading-relaxed">
Prohibits abusive, unfair, or deceptive practices by debt collectors,
including manipulative communication tactics.
</p>
</div>
</div>
</Card>
{/* Action Items */}
<Card className="p-6 bg-indigo-500/5 border border-indigo-500/10 rounded-2xl">
<h4 className="font-bold text-sm text-indigo-300 mb-3">📋 Compliance Action Items</h4>
<ol className="list-decimal list-inside space-y-2 text-xs text-indigo-200/80 leading-relaxed">
<li>Address critical violations immediately to avoid regulatory action</li>
<li>Implement recommended design changes in order of severity</li>
<li>Conduct user testing to validate improved experience</li>
<li>Schedule follow-up compliance audit after changes are made</li>
<li>Document all changes for regulatory review</li>
<li>Train design and product teams on ethical UI principles</li>
</ol>
</Card>
{/* AI Explanation */}
<div className="bg-indigo-500/5 border border-indigo-500/10 rounded-xl p-4">
<h4 className="font-bold text-xs text-indigo-300 mb-2">🤖 XAI Compliance Analysis</h4>
<p className="text-xs text-slate-400 leading-relaxed">
Our compliance engine uses natural language processing to match detected dark patterns
against CFPB regulation text. Each violation is cross-referenced with specific guideline
sections to provide actionable, legally-grounded recommendations. The compliance score
is calculated using a weighted severity model that prioritizes consumer protection.
</p>
</div>
</div>
);
}
|