Files
breakpilot-compliance/admin-compliance/app/sdk/training/_components/MatrixTab.tsx
Sharang Parnerkar 375b34a0d8 refactor(admin): split consent-management, control-library, incidents, training pages
Agent-completed splits committed after agents hit rate limits before
committing their work. All 4 pages now under 500 LOC:

- consent-management: 1303 -> 193 LOC (+ 7 _components, _hooks, _data, _types)
- control-library: 1210 -> 298 LOC (+ _components, _types)
- incidents: 1150 -> 373 LOC (+ _components)
- training: 1127 -> 366 LOC (+ _components)

Verification: next build clean (142 pages generated).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 15:52:45 +02:00

69 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import type { MatrixResponse } from '@/lib/sdk/training/types'
import { ROLE_LABELS, ALL_ROLES } from '@/lib/sdk/training/types'
interface MatrixTabProps {
matrix: MatrixResponse
onDeleteEntry: (roleCode: string, moduleId: string) => void
onAddEntry: (roleCode: string) => void
}
export function MatrixTab({ matrix, onDeleteEntry, onAddEntry }: MatrixTabProps) {
return (
<div className="space-y-4">
<p className="text-sm text-gray-600">Compliance Training Matrix (CTM): Welche Rollen benoetigen welche Schulungsmodule</p>
<div className="overflow-x-auto">
<table className="w-full text-sm border-collapse">
<thead>
<tr className="bg-gray-50">
<th className="text-left p-2 border font-medium text-gray-700 w-48">Rolle</th>
<th className="text-left p-2 border font-medium text-gray-700">Module</th>
<th className="text-center p-2 border font-medium text-gray-700 w-20">Anzahl</th>
</tr>
</thead>
<tbody>
{ALL_ROLES.map(role => {
const entries = matrix.entries[role] || []
return (
<tr key={role} className="border-b hover:bg-gray-50">
<td className="p-2 border font-medium">
<span className="text-gray-900">{role}</span>
<span className="text-gray-500 ml-1 text-xs">{ROLE_LABELS[role]}</span>
</td>
<td className="p-2 border">
<div className="flex flex-wrap gap-2 items-center">
{entries.map(e => (
<span
key={e.id || e.module_id}
className={`inline-flex items-center gap-1 px-2 py-1 text-xs rounded-full ${e.is_mandatory ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 text-gray-600'}`}
title={`${e.module_title} (${e.is_mandatory ? 'Pflicht' : 'Optional'})`}
>
{e.is_mandatory ? '🔴' : '🔵'} {e.module_code}
<button
onClick={() => onDeleteEntry(role, e.module_id)}
className="ml-1 text-gray-400 hover:text-red-500 font-bold leading-none"
title="Zuordnung entfernen"
>×</button>
</span>
))}
{entries.length === 0 && <span className="text-gray-400 text-xs">Keine Module</span>}
<button
onClick={() => onAddEntry(role)}
className="px-2 py-1 text-xs text-blue-600 border border-blue-300 rounded-full hover:bg-blue-50 transition-colors"
>
+ Hinzufuegen
</button>
</div>
</td>
<td className="p-2 border text-center">{entries.length}</td>
</tr>
)
})}
</tbody>
</table>
</div>
</div>
)
}