From 62a56f3fc919f7dd2d7b2fcfc11510e53b71bbc8 Mon Sep 17 00:00:00 2001 From: CCS Admin Date: Thu, 26 Feb 2026 16:11:47 +0000 Subject: [PATCH] feat: add disclosure request UI and field visibility for dak_mitarbeiter Co-Authored-By: Claude Opus 4.6 --- frontend/src/pages/CasesPage.tsx | 109 ++++++++++++++++++++---- frontend/src/pages/cases/fieldConfig.ts | 9 +- 2 files changed, 98 insertions(+), 20 deletions(-) diff --git a/frontend/src/pages/CasesPage.tsx b/frontend/src/pages/CasesPage.tsx index 493ec44..f848161 100644 --- a/frontend/src/pages/CasesPage.tsx +++ b/frontend/src/pages/CasesPage.tsx @@ -22,6 +22,7 @@ import { Alert, AlertDescription } from '@/components/ui/alert' import { CASE_SECTIONS } from './cases/fieldConfig' import { useInlineEdit } from './cases/useInlineEdit' import { EditableField } from './cases/EditableField' +import { requestDisclosure } from '@/services/disclosureService' const FALLGRUPPEN_LABELS: Record = { onko: 'Onkologie', @@ -396,6 +397,18 @@ function CaseDetail({ + {/* Disclosure status / request */} + {!isAdmin && caseData.disclosure_granted && caseData.disclosure_expires_at && ( + + + Personendaten sichtbar bis {formatDateTime(caseData.disclosure_expires_at)} + + + )} + {!isAdmin && !caseData.disclosure_granted && ( + + )} + {/* Static metadata (always read-only) */}
@@ -405,23 +418,30 @@ function CaseDetail({
{/* Editable sections from config */} - {CASE_SECTIONS.map((section) => ( -
-

{section.title}

-
- {section.fields.map((field) => ( -
- -
- ))} + {CASE_SECTIONS.map((section) => { + const visibleFields = section.fields.filter((field) => { + if (field.visibleTo === 'admin' && !isAdmin && !caseData.disclosure_granted) return false + return true + }) + if (visibleFields.length === 0) return null + return ( +
+

{section.title}

+
+ {visibleFields.map((field) => ( +
+ +
+ ))} +
-
- ))} + ) + })} {/* ICD section — own endpoint with validation */}
@@ -474,6 +494,63 @@ function CaseDetail({ ) } +function DisclosureRequestButton({ caseId }: { caseId: number }) { + const [open, setOpen] = useState(false) + const [reason, setReason] = useState('') + const [loading, setLoading] = useState(false) + const [error, setError] = useState('') + const [success, setSuccess] = useState(false) + + const submit = async () => { + if (!reason.trim()) return + setLoading(true) + setError('') + try { + await requestDisclosure(caseId, reason.trim()) + setSuccess(true) + setOpen(false) + } catch (err: any) { + const detail = err.response?.data?.detail + setError(typeof detail === 'string' ? detail : 'Fehler beim Senden der Anfrage') + } finally { + setLoading(false) + } + } + + if (success) { + return

Freigabe-Anfrage gesendet.

+ } + + return ( + <> + + {open && ( +
+

+ Begründung für die Einsicht in Personendaten: +

+ setReason(e.target.value)} + placeholder="z.B. KVNR-Fehler, Identifikation nötig" + /> + {error &&

{error}

} +
+ + +
+
+ )} + + ) +} + function ReadOnlyField({ label, value }: { label: string; value: string | null | undefined }) { return (
diff --git a/frontend/src/pages/cases/fieldConfig.ts b/frontend/src/pages/cases/fieldConfig.ts index fbab4d6..72c83d5 100644 --- a/frontend/src/pages/cases/fieldConfig.ts +++ b/frontend/src/pages/cases/fieldConfig.ts @@ -8,6 +8,7 @@ export interface FieldConfig { type: FieldType colSpan?: 1 | 2 editableBy: 'admin' | 'all' + visibleTo?: 'admin' | 'all' placeholder?: string options?: { value: string; label: string }[] } @@ -28,10 +29,10 @@ export const CASE_SECTIONS: SectionConfig[] = [ { title: 'Persönliche Daten', fields: [ - { key: 'anrede', label: 'Anrede', type: 'select', editableBy: 'admin', options: ANREDE_OPTIONS }, - { key: 'vorname', label: 'Vorname', type: 'text', editableBy: 'admin', placeholder: 'Vorname' }, - { key: 'nachname', label: 'Nachname', type: 'text', editableBy: 'admin', placeholder: 'Nachname' }, - { key: 'geburtsdatum', label: 'Geburtsdatum', type: 'date', editableBy: 'admin' }, + { key: 'anrede', label: 'Anrede', type: 'select', editableBy: 'admin', visibleTo: 'admin', options: ANREDE_OPTIONS }, + { key: 'vorname', label: 'Vorname', type: 'text', editableBy: 'admin', visibleTo: 'admin', placeholder: 'Vorname' }, + { key: 'nachname', label: 'Nachname', type: 'text', editableBy: 'admin', visibleTo: 'admin', placeholder: 'Nachname' }, + { key: 'geburtsdatum', label: 'Geburtsdatum', type: 'date', editableBy: 'admin', visibleTo: 'admin' }, { key: 'kvnr', label: 'KVNR', type: 'text', editableBy: 'all', placeholder: 'z.B. A123456789' }, { key: 'versicherung', label: 'Versicherung', type: 'text', editableBy: 'admin', placeholder: 'z.B. DAK' }, ],