refactor(admin): split loeschfristen and vvt pages
Reduce both page.tsx files below the 500-LOC hard cap by extracting all inline tab components and API helpers into colocated _components/. - loeschfristen/page.tsx: 2720 → 467 LOC - vvt/page.tsx: 2297 → 256 LOC New files: LoeschkonzeptTab, loeschfristen/api, TabDokument, TabProcessor Updated: TabVerzeichnis (template picker + badge), vvt/api (template helpers) Fixed: VVTLinkSection wrong field name (linkedVVTActivityIds), VendorLinkSection added Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -370,18 +370,18 @@ export function VVTLinkSection({
|
||||
Verknuepfen Sie diese Loeschfrist mit einer Verarbeitungstaetigkeit aus Ihrem VVT.
|
||||
</p>
|
||||
<div className="space-y-2">
|
||||
{policy.linkedVvtIds && policy.linkedVvtIds.length > 0 && (
|
||||
{policy.linkedVVTActivityIds && policy.linkedVVTActivityIds.length > 0 && (
|
||||
<div className="mb-3">
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Verknuepfte Taetigkeiten:</label>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{policy.linkedVvtIds.map((vvtId: string) => {
|
||||
{policy.linkedVVTActivityIds.map((vvtId: string) => {
|
||||
const activity = vvtActivities.find((a: any) => a.id === vvtId)
|
||||
return (
|
||||
<span key={vvtId} className="inline-flex items-center gap-1 bg-blue-100 text-blue-800 text-xs font-medium px-2 py-0.5 rounded-full">
|
||||
{activity?.name || vvtId}
|
||||
<button type="button"
|
||||
onClick={() => updatePolicy(pid, (p) => ({
|
||||
...p, linkedVvtIds: (p.linkedVvtIds || []).filter((id: string) => id !== vvtId),
|
||||
...p, linkedVVTActivityIds: (p.linkedVVTActivityIds || []).filter((id: string) => id !== vvtId),
|
||||
}))}
|
||||
className="text-blue-600 hover:text-blue-900">x</button>
|
||||
</span>
|
||||
@@ -393,15 +393,15 @@ export function VVTLinkSection({
|
||||
<select
|
||||
onChange={(e) => {
|
||||
const val = e.target.value
|
||||
if (val && !(policy.linkedVvtIds || []).includes(val)) {
|
||||
updatePolicy(pid, (p) => ({ ...p, linkedVvtIds: [...(p.linkedVvtIds || []), val] }))
|
||||
if (val && !(policy.linkedVVTActivityIds || []).includes(val)) {
|
||||
updatePolicy(pid, (p) => ({ ...p, linkedVVTActivityIds: [...(p.linkedVVTActivityIds || []), val] }))
|
||||
}
|
||||
e.target.value = ''
|
||||
}}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500">
|
||||
<option value="">Verarbeitungstaetigkeit verknuepfen...</option>
|
||||
{vvtActivities
|
||||
.filter((a: any) => !(policy.linkedVvtIds || []).includes(a.id))
|
||||
.filter((a: any) => !(policy.linkedVVTActivityIds || []).includes(a.id))
|
||||
.map((a: any) => (<option key={a.id} value={a.id}>{a.name || a.id}</option>))}
|
||||
</select>
|
||||
</div>
|
||||
@@ -415,6 +415,70 @@ export function VVTLinkSection({
|
||||
)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sektion 5b: Auftragsverarbeiter-Verknuepfung
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export function VendorLinkSection({
|
||||
policy, pid, vendorList, updatePolicy,
|
||||
}: {
|
||||
policy: LoeschfristPolicy; pid: string; vendorList: Array<{id: string; name: string}>
|
||||
updatePolicy: (id: string, updater: (p: LoeschfristPolicy) => LoeschfristPolicy) => void
|
||||
}) {
|
||||
return (
|
||||
<div className="bg-white rounded-xl border border-gray-200 p-6 space-y-4">
|
||||
<h3 className="text-lg font-semibold text-gray-900">5b. Verknuepfte Auftragsverarbeiter</h3>
|
||||
{vendorList.length > 0 ? (
|
||||
<div>
|
||||
<p className="text-sm text-gray-500 mb-3">
|
||||
Verknuepfen Sie diese Loeschfrist mit relevanten Auftragsverarbeitern.
|
||||
</p>
|
||||
<div className="space-y-2">
|
||||
{policy.linkedVendorIds && policy.linkedVendorIds.length > 0 && (
|
||||
<div className="mb-3">
|
||||
<label className="block text-xs font-medium text-gray-500 mb-1">Verknuepfte Auftragsverarbeiter:</label>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{policy.linkedVendorIds.map((vendorId: string) => {
|
||||
const vendor = vendorList.find((v) => v.id === vendorId)
|
||||
return (
|
||||
<span key={vendorId} className="inline-flex items-center gap-1 bg-orange-100 text-orange-800 text-xs font-medium px-2 py-0.5 rounded-full">
|
||||
{vendor?.name || vendorId}
|
||||
<button type="button"
|
||||
onClick={() => updatePolicy(pid, (p) => ({
|
||||
...p, linkedVendorIds: (p.linkedVendorIds || []).filter((id: string) => id !== vendorId),
|
||||
}))}
|
||||
className="text-orange-600 hover:text-orange-900">x</button>
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<select
|
||||
onChange={(e) => {
|
||||
const val = e.target.value
|
||||
if (val && !(policy.linkedVendorIds || []).includes(val)) {
|
||||
updatePolicy(pid, (p) => ({ ...p, linkedVendorIds: [...(p.linkedVendorIds || []), val] }))
|
||||
}
|
||||
e.target.value = ''
|
||||
}}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-purple-500">
|
||||
<option value="">Auftragsverarbeiter verknuepfen...</option>
|
||||
{vendorList
|
||||
.filter((v) => !(policy.linkedVendorIds || []).includes(v.id))
|
||||
.map((v) => (<option key={v.id} value={v.id}>{v.name || v.id}</option>))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-gray-400">
|
||||
Keine Auftragsverarbeiter gefunden. Erstellen Sie zuerst Auftragsverarbeiter im Vendor-Compliance-Modul, um hier Verknuepfungen herstellen zu koennen.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sektion 6: Review-Einstellungen
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user