refactor(admin): split control-library, iace/mitigations, iace/components, controls pages
All 4 page.tsx files reduced well below 500 LOC (235/181/158/262) by extracting components and hooks into colocated _components/ and _hooks/ subdirectories. Zero behavior changes — logic relocated verbatim. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
'use client'
|
||||
|
||||
import { ExternalLink, Scale } from 'lucide-react'
|
||||
import type { CanonicalControl } from './helpers'
|
||||
|
||||
export function ControlSourceCitation({ ctrl }: { ctrl: CanonicalControl }) {
|
||||
if (!ctrl.source_citation) return null
|
||||
|
||||
const stype = ctrl.source_citation.source_type
|
||||
const colorSet = stype === 'law'
|
||||
? { bg: 'bg-blue-50 border-blue-200', icon: 'text-blue-600', title: 'text-blue-900', badge: 'bg-blue-100 text-blue-700' }
|
||||
: stype === 'guideline'
|
||||
? { bg: 'bg-indigo-50 border-indigo-200', icon: 'text-indigo-600', title: 'text-indigo-900', badge: 'bg-indigo-100 text-indigo-700' }
|
||||
: { bg: 'bg-teal-50 border-teal-200', icon: 'text-teal-600', title: 'text-teal-900', badge: 'bg-teal-100 text-teal-700' }
|
||||
|
||||
const sectionTitle = stype === 'law' ? 'Gesetzliche Grundlage'
|
||||
: stype === 'guideline' ? 'Behoerdliche Leitlinie'
|
||||
: 'Standard / Best Practice'
|
||||
|
||||
const badgeText = stype === 'law' ? 'Direkte gesetzliche Pflicht'
|
||||
: stype === 'guideline' ? 'Aufsichtsbehoerdliche Empfehlung'
|
||||
: stype === 'standard' || (!stype && ctrl.license_rule === 2) ? 'Freiwilliger Standard'
|
||||
: !stype && ctrl.license_rule === 1 ? 'Noch nicht klassifiziert' : null
|
||||
|
||||
return (
|
||||
<section className={`border rounded-lg p-4 ${colorSet.bg}`}>
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<Scale className={`w-4 h-4 ${colorSet.icon}`} />
|
||||
<h3 className={`text-sm font-semibold ${colorSet.title}`}>{sectionTitle}</h3>
|
||||
{badgeText && <span className={`text-xs px-2 py-0.5 rounded-full ${colorSet.badge}`}>{badgeText}</span>}
|
||||
</div>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="flex-1">
|
||||
{ctrl.source_citation.source ? (
|
||||
<p className="text-sm font-medium text-blue-900 mb-1">
|
||||
{ctrl.source_citation.source}
|
||||
{ctrl.source_citation.article && ` — ${ctrl.source_citation.article}`}
|
||||
{ctrl.source_citation.paragraph && ` ${ctrl.source_citation.paragraph}`}
|
||||
</p>
|
||||
) : ctrl.generation_metadata?.source_regulation ? (
|
||||
<p className="text-sm font-medium text-blue-900 mb-1">{String(ctrl.generation_metadata.source_regulation)}</p>
|
||||
) : null}
|
||||
{ctrl.source_citation.license && <p className="text-xs text-blue-600">Lizenz: {ctrl.source_citation.license}</p>}
|
||||
{ctrl.source_citation.license_notice && <p className="text-xs text-blue-600 mt-0.5">{ctrl.source_citation.license_notice}</p>}
|
||||
</div>
|
||||
{ctrl.source_citation.url && (
|
||||
<a href={ctrl.source_citation.url} target="_blank" rel="noopener noreferrer"
|
||||
className="flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800 whitespace-nowrap">
|
||||
<ExternalLink className="w-3.5 h-3.5" />Quelle
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
{ctrl.source_original_text && (
|
||||
<details className="mt-3">
|
||||
<summary className="text-xs text-blue-600 cursor-pointer hover:text-blue-800">Originaltext anzeigen</summary>
|
||||
<p className="text-xs text-gray-600 mt-2 p-2 bg-white rounded border border-blue-100 leading-relaxed max-h-40 overflow-y-auto whitespace-pre-wrap">
|
||||
{ctrl.source_original_text}
|
||||
</p>
|
||||
</details>
|
||||
)}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user