Some checks failed
Build + Deploy / build-admin-compliance (push) Failing after 34s
Build + Deploy / build-developer-portal (push) Successful in 56s
Build + Deploy / build-tts (push) Successful in 1m8s
CI/CD / go-lint (push) Has been skipped
Build + Deploy / trigger-orca (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 38s
CI/CD / test-python-backend-compliance (push) Successful in 32s
Build + Deploy / build-backend-compliance (push) Successful in 7s
Build + Deploy / build-ai-sdk (push) Successful in 7s
Build + Deploy / build-document-crawler (push) Successful in 33s
Build + Deploy / build-dsms-gateway (push) Successful in 20s
CI/CD / test-python-dsms-gateway (push) Has been cancelled
CI/CD / validate-canonical-controls (push) Has been cancelled
CI/CD / test-python-document-crawler (push) Has been cancelled
All 8 components imported by app/sdk/training/page.tsx were missing. Docker build was failing with Module not found errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
3.3 KiB
TypeScript
89 lines
3.3 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { setMatrixEntry } from '@/lib/sdk/training/api'
|
|
import type { TrainingModule } from '@/lib/sdk/training/types'
|
|
import { ROLE_LABELS, REGULATION_LABELS } from '@/lib/sdk/training/types'
|
|
|
|
export default function MatrixAddModal({
|
|
roleCode,
|
|
modules,
|
|
onClose,
|
|
onSaved,
|
|
}: {
|
|
roleCode: string
|
|
modules: TrainingModule[]
|
|
onClose: () => void
|
|
onSaved: () => void
|
|
}) {
|
|
const [saving, setSaving] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
|
|
e.preventDefault()
|
|
setSaving(true)
|
|
setError(null)
|
|
const fd = new FormData(e.currentTarget)
|
|
try {
|
|
await setMatrixEntry({
|
|
role_code: roleCode,
|
|
module_id: fd.get('module_id') as string,
|
|
is_mandatory: fd.get('is_mandatory') === 'on',
|
|
priority: parseInt(fd.get('priority') as string) || 1,
|
|
})
|
|
onSaved()
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : 'Fehler beim Hinzufuegen')
|
|
} finally {
|
|
setSaving(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
|
|
<div className="bg-white rounded-xl shadow-xl w-full max-w-md p-6">
|
|
<h3 className="text-base font-semibold mb-1">Modul zuweisen</h3>
|
|
<p className="text-xs text-gray-500 mb-4">
|
|
Rolle: <strong>{ROLE_LABELS[roleCode] ?? roleCode}</strong> ({roleCode})
|
|
</p>
|
|
|
|
{error && (
|
|
<div className="mb-4 text-sm text-red-600 bg-red-50 border border-red-200 rounded p-3">{error}</div>
|
|
)}
|
|
|
|
<form onSubmit={handleSubmit} className="space-y-3">
|
|
<div>
|
|
<label className="text-xs text-gray-600 block mb-1">Modul *</label>
|
|
<select name="module_id" required className="w-full px-3 py-2 text-sm border rounded-lg bg-white">
|
|
<option value="">Modul waehlen...</option>
|
|
{modules.filter(m => m.is_active).map(m => (
|
|
<option key={m.id} value={m.id}>
|
|
{m.module_code} — {m.title} ({REGULATION_LABELS[m.regulation_area] ?? m.regulation_area})
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
<div className="grid grid-cols-2 gap-3">
|
|
<div>
|
|
<label className="text-xs text-gray-600 block mb-1">Prioritaet</label>
|
|
<input name="priority" type="number" defaultValue={1} min={1} max={10} className="w-full px-3 py-2 text-sm border rounded-lg" />
|
|
</div>
|
|
<div className="flex items-center gap-2 mt-5">
|
|
<input name="is_mandatory" type="checkbox" id="mandatory" defaultChecked className="rounded" />
|
|
<label htmlFor="mandatory" className="text-xs text-gray-600">Pflichtmodul</label>
|
|
</div>
|
|
</div>
|
|
<div className="flex gap-3 pt-2">
|
|
<button type="submit" disabled={saving} className="px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50">
|
|
{saving ? 'Speichere...' : 'Zuweisen'}
|
|
</button>
|
|
<button type="button" onClick={onClose} className="px-4 py-2 text-sm bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200">
|
|
Abbrechen
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|