From 5e910c3053f2482f52857f209bc6f4741f625bea Mon Sep 17 00:00:00 2001 From: colinislit Date: Tue, 14 Jul 2026 22:39:58 +0200 Subject: [PATCH] chore(strip): verwijder dubbele diagnosemodule op patientniveau MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit De intake-variant (intakes/[intakeId]/diagnosis) is de meest complete en blijft. Sidebar-items Diagnose en Behandelplan (level 2) verwijderd — behandelplan-module zelf volgt in de volgende commit. Co-Authored-By: Claude Fable 5 --- app/epd/components/epd-sidebar.tsx | 4 - app/epd/patients/[id]/diagnose/actions.ts | 201 -------- .../components/diagnosis-detail-form.tsx | 435 ------------------ .../components/diagnosis-list-item.tsx | 64 --- .../components/diagnosis-master-detail.tsx | 133 ------ .../components/diagnosis-overview-card.tsx | 182 -------- app/epd/patients/[id]/diagnose/page.tsx | 54 --- 7 files changed, 1073 deletions(-) delete mode 100644 app/epd/patients/[id]/diagnose/actions.ts delete mode 100644 app/epd/patients/[id]/diagnose/components/diagnosis-detail-form.tsx delete mode 100644 app/epd/patients/[id]/diagnose/components/diagnosis-list-item.tsx delete mode 100644 app/epd/patients/[id]/diagnose/components/diagnosis-master-detail.tsx delete mode 100644 app/epd/patients/[id]/diagnose/components/diagnosis-overview-card.tsx delete mode 100644 app/epd/patients/[id]/diagnose/page.tsx diff --git a/app/epd/components/epd-sidebar.tsx b/app/epd/components/epd-sidebar.tsx index fcb5035..a6acdf4 100644 --- a/app/epd/components/epd-sidebar.tsx +++ b/app/epd/components/epd-sidebar.tsx @@ -17,8 +17,6 @@ import { LayoutDashboard, User, ClipboardList, - Stethoscope, - Calendar, FileBarChart, PenLine, Zap @@ -70,8 +68,6 @@ const level2NavigationItems: NavigationItem[] = [ { id: "basisgegevens", name: "Basisgegevens", icon: User, href: "/basisgegevens" }, { id: "screening", name: "Screening", icon: ClipboardList, href: "/screening" }, { id: "intake", name: "Intake", icon: FileText, href: "/intakes" }, - { id: "diagnose", name: "Diagnose", icon: Stethoscope, href: "/diagnose" }, - { id: "behandelplan", name: "Behandelplan", icon: Calendar, href: "/behandelplan" }, { id: "rapportage", name: "Rapportage", icon: FileBarChart, href: "/rapportage" }, ]; diff --git a/app/epd/patients/[id]/diagnose/actions.ts b/app/epd/patients/[id]/diagnose/actions.ts deleted file mode 100644 index 31cfcb5..0000000 --- a/app/epd/patients/[id]/diagnose/actions.ts +++ /dev/null @@ -1,201 +0,0 @@ -'use server'; - -import { revalidatePath } from 'next/cache'; -import { createClient } from '@/lib/auth/server'; -import type { Database } from '@/lib/supabase/database.types'; - -export type Condition = Database['public']['Tables']['conditions']['Row']; -type ClinicalStatus = 'active' | 'recurrence' | 'relapse' | 'inactive' | 'remission' | 'resolved'; - -export type IntakeInfo = { - id: string; - title: string | null; - department: string | null; - start_date: string | null; -}; - -export type DiagnosisWithIntake = Condition & { - intake?: IntakeInfo | null; -}; - -/** - * Haal alle diagnoses op voor een patiënt (uit alle intakes) - */ -export async function getPatientDiagnoses(patientId: string): Promise { - const supabase = await createClient(); - - // Haal eerst alle diagnoses op - const { data: conditions, error: conditionsError } = await supabase - .from('conditions') - .select('*') - .eq('patient_id', patientId) - .order('recorded_date', { ascending: false }); - - if (conditionsError) { - console.error('getPatientDiagnoses error', conditionsError); - throw new Error('Kon diagnoses niet ophalen'); - } - - if (!conditions || conditions.length === 0) { - return []; - } - - // Haal de intake IDs op - const intakeIds = [...new Set(conditions.map((c) => c.encounter_id).filter((id): id is string => id !== null))]; - - if (intakeIds.length === 0) { - return conditions.map((c) => ({ ...c, intake: null })); - } - - // Haal intake informatie op - const { data: intakes, error: intakesError } = await supabase - .from('intakes') - .select('id, title, department, start_date') - .in('id', intakeIds); - - if (intakesError) { - console.error('getPatientDiagnoses intakes error', intakesError); - // Return conditions zonder intake info als de query faalt - return conditions.map((c) => ({ ...c, intake: null })); - } - - // Maak lookup map - const intakeMap = new Map(); - intakes?.forEach((intake) => { - intakeMap.set(intake.id, intake); - }); - - // Combineer data - return conditions.map((condition) => ({ - ...condition, - intake: condition.encounter_id ? intakeMap.get(condition.encounter_id) || null : null, - })); -} - -/** - * Haal alle intakes op voor een patiënt (voor intake selectie dropdown) - */ -export async function getPatientIntakes(patientId: string) { - const supabase = await createClient(); - const { data, error } = await supabase - .from('intakes') - .select('id, title, department, start_date') - .eq('patient_id', patientId) - .order('start_date', { ascending: false }); - - if (error) { - console.error('getPatientIntakes error', error); - throw new Error('Kon intakes niet ophalen'); - } - return data || []; -} - -// ---------------- CRUD Actions ---------------- - -export interface CreateDiagnosisPayload { - patientId: string; - intakeId: string; - code: string; - description: string; - severity?: string; - status?: ClinicalStatus; - notes?: string; - diagnosisType?: 'primary' | 'secondary'; -} - -export async function createPatientDiagnosis(payload: CreateDiagnosisPayload) { - const supabase = await createClient(); - - const insertData = { - patient_id: payload.patientId, - encounter_id: payload.intakeId, - code_code: payload.code, - code_display: payload.description, - code_system: 'ICD-10', - clinical_status: payload.status || 'active', - severity_display: payload.severity || null, - category: payload.diagnosisType === 'primary' ? 'primary-diagnosis' : 'encounter-diagnosis', - note: payload.notes || null, - recorded_date: new Date().toISOString(), - }; - - console.log('createPatientDiagnosis payload:', JSON.stringify(insertData, null, 2)); - - const { error } = await supabase.from('conditions').insert(insertData); - - if (error) { - console.error('createPatientDiagnosis error:', error.message, error.details, error.hint); - throw new Error(`Diagnose opslaan mislukt: ${error.message}`); - } - - revalidatePath(`/epd/patients/${payload.patientId}/diagnose`); -} - -export interface UpdateDiagnosisPayload { - code?: string; - description?: string; - severity?: string; - status?: string; - notes?: string; - diagnosisType?: 'primary' | 'secondary'; -} - -export async function updatePatientDiagnosis( - patientId: string, - diagnosisId: string, - payload: UpdateDiagnosisPayload -): Promise<{ success: boolean; error?: string }> { - const supabase = await createClient(); - - const updateData: Record = { - updated_at: new Date().toISOString(), - }; - - if (payload.code !== undefined) { - updateData.code_code = payload.code; - } - if (payload.description !== undefined) { - updateData.code_display = payload.description; - } - if (payload.status !== undefined) { - updateData.clinical_status = payload.status; - } - if (payload.severity !== undefined) { - updateData.severity_display = payload.severity; - } - if (payload.notes !== undefined) { - updateData.note = payload.notes; - } - if (payload.diagnosisType !== undefined) { - updateData.category = payload.diagnosisType === 'primary' ? 'primary-diagnosis' : 'encounter-diagnosis'; - } - - const { error } = await supabase - .from('conditions') - .update(updateData) - .eq('id', diagnosisId); - - if (error) { - console.error('updatePatientDiagnosis error', error); - return { success: false, error: 'Diagnose bijwerken mislukt' }; - } - - revalidatePath(`/epd/patients/${patientId}/diagnose`); - return { success: true }; -} - -export async function deletePatientDiagnosis( - patientId: string, - diagnosisId: string -): Promise<{ success: boolean; error?: string }> { - const supabase = await createClient(); - const { error } = await supabase.from('conditions').delete().eq('id', diagnosisId); - - if (error) { - console.error('deletePatientDiagnosis error', error); - return { success: false, error: 'Diagnose verwijderen mislukt' }; - } - - revalidatePath(`/epd/patients/${patientId}/diagnose`); - return { success: true }; -} diff --git a/app/epd/patients/[id]/diagnose/components/diagnosis-detail-form.tsx b/app/epd/patients/[id]/diagnose/components/diagnosis-detail-form.tsx deleted file mode 100644 index 7f310a4..0000000 --- a/app/epd/patients/[id]/diagnose/components/diagnosis-detail-form.tsx +++ /dev/null @@ -1,435 +0,0 @@ -'use client'; - -import { useState, useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { Loader2, Stethoscope, Trash2 } from 'lucide-react'; -import { Button } from '@/components/ui/button'; -import { Label } from '@/components/ui/label'; -import { Textarea } from '@/components/ui/textarea'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; -import { toast } from '@/hooks/use-toast'; -import { ICD10Combobox } from '@/app/epd/patients/[id]/intakes/[intakeId]/diagnosis/components/icd10-combobox'; -import { - diagnosisSchema, - diagnosisDefaults, - type DiagnosisFormData, - DIAGNOSIS_SEVERITIES, - DIAGNOSIS_TYPES, - DIAGNOSIS_STATUSES, -} from '@/lib/schemas/diagnosis'; -import { - createPatientDiagnosis, - updatePatientDiagnosis, - deletePatientDiagnosis, - type DiagnosisWithIntake, - type IntakeInfo, -} from '../actions'; -import type { ICD10Code } from '@/lib/types/icd10'; - -interface DiagnosisDetailFormProps { - patientId: string; - intakes: IntakeInfo[]; - diagnosis: DiagnosisWithIntake | null; - isNew: boolean; - onSaved: () => void; - onDeleted: () => void; -} - -const STATUS_LABELS: Record = { - active: 'Actief', - remission: 'In remissie', - resolved: 'Opgelost', - inactive: 'Inactief', -}; - -const SEVERITY_LABELS: Record = { - licht: 'Licht', - matig: 'Matig', - ernstig: 'Ernstig', -}; - -const DIAGNOSIS_TYPE_LABELS: Record = { - primary: 'Hoofddiagnose', - secondary: 'Nevendiagnose', -}; - -export function DiagnosisDetailForm({ - patientId, - intakes, - diagnosis, - isNew, - onSaved, - onDeleted, -}: DiagnosisDetailFormProps) { - const [isSubmitting, setIsSubmitting] = useState(false); - const [isDeleting, setIsDeleting] = useState(false); - const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); - const [selectedICD10Code, setSelectedICD10Code] = useState(null); - const [selectedIntakeId, setSelectedIntakeId] = useState( - diagnosis?.encounter_id || intakes[0]?.id || '' - ); - - const { - register, - handleSubmit, - formState: { errors }, - reset, - setValue, - watch, - } = useForm({ - resolver: zodResolver(diagnosisSchema), - defaultValues: diagnosisDefaults, - }); - - const diagnosisType = watch('diagnosisType'); - const severity = watch('severity'); - const status = watch('status'); - - // Reset form wanneer diagnosis wijzigt - useEffect(() => { - if (diagnosis) { - setValue('code', diagnosis.code_code || ''); - setValue('description', diagnosis.code_display || ''); - setValue('severity', (diagnosis.severity_display as 'licht' | 'matig' | 'ernstig') || 'matig'); - setValue('status', (diagnosis.clinical_status as 'active' | 'remission' | 'resolved' | 'inactive') || 'active'); - setValue('diagnosisType', diagnosis.category === 'primary-diagnosis' ? 'primary' : 'secondary'); - setValue('notes', diagnosis.note || ''); - - if (diagnosis.code_code && diagnosis.code_display) { - setSelectedICD10Code({ - code: diagnosis.code_code, - display: diagnosis.code_display, - keywords: [], - }); - } - setSelectedIntakeId(diagnosis.encounter_id || intakes[0]?.id || ''); - } else { - reset(diagnosisDefaults); - setSelectedICD10Code(null); - setSelectedIntakeId(intakes[0]?.id || ''); - } - setShowDeleteConfirm(false); - }, [diagnosis, reset, setValue, intakes]); - - const handleICD10Select = (code: ICD10Code) => { - setSelectedICD10Code(code); - setValue('code', code.code); - setValue('description', code.display); - }; - - const onSubmit = async (data: DiagnosisFormData) => { - if (!selectedIntakeId) { - toast({ - variant: 'destructive', - title: 'Intake vereist', - description: 'Selecteer een intake om de diagnose aan te koppelen.', - }); - return; - } - - setIsSubmitting(true); - - try { - if (isNew) { - await createPatientDiagnosis({ - patientId, - intakeId: selectedIntakeId, - code: data.code, - description: data.description, - severity: data.severity, - status: data.status, - notes: data.notes || undefined, - diagnosisType: data.diagnosisType, - }); - - toast({ - title: 'Diagnose toegevoegd', - description: `${data.code} — ${data.description}`, - }); - } else if (diagnosis) { - const result = await updatePatientDiagnosis(patientId, diagnosis.id, { - code: data.code, - description: data.description, - severity: data.severity, - status: data.status, - notes: data.notes || undefined, - diagnosisType: data.diagnosisType, - }); - - if (!result.success) { - toast({ - variant: 'destructive', - title: 'Bijwerken mislukt', - description: result.error || 'Er ging iets mis.', - }); - return; - } - - toast({ - title: 'Diagnose bijgewerkt', - description: `${data.code} — ${data.description}`, - }); - } - - onSaved(); - } catch (error) { - toast({ - variant: 'destructive', - title: 'Opslaan mislukt', - description: error instanceof Error ? error.message : 'Er ging iets mis.', - }); - } finally { - setIsSubmitting(false); - } - }; - - const handleDelete = async () => { - if (!diagnosis) return; - - setIsDeleting(true); - - try { - const result = await deletePatientDiagnosis(patientId, diagnosis.id); - - if (!result.success) { - toast({ - variant: 'destructive', - title: 'Verwijderen mislukt', - description: result.error || 'Er ging iets mis.', - }); - return; - } - - toast({ - title: 'Diagnose verwijderd', - description: `${diagnosis.code_code} is verwijderd.`, - }); - - onDeleted(); - } catch (error) { - toast({ - variant: 'destructive', - title: 'Verwijderen mislukt', - description: error instanceof Error ? error.message : 'Er ging iets mis.', - }); - } finally { - setIsDeleting(false); - setShowDeleteConfirm(false); - } - }; - - // Empty state - if (!isNew && !diagnosis) { - return ( -
-
- -
-

Geen diagnose geselecteerd

-

- Selecteer een diagnose uit de lijst of voeg een nieuwe toe. -

-
- ); - } - - const selectedIntake = intakes.find((i) => i.id === selectedIntakeId); - - return ( -
- {/* Header */} -
-

- {isNew ? 'Nieuwe diagnose' : 'Diagnose bewerken'} -

- {!isNew && diagnosis && ( -

- Gekoppeld aan: {diagnosis.intake?.title || diagnosis.intake?.department || 'Intake'} -

- )} -
- - {/* Intake selectie (alleen bij nieuwe diagnose) */} - {isNew && intakes.length > 0 && ( -
- - -
- )} - - {/* ICD-10 Code */} -
- - - {errors.code &&

{errors.code.message}

} - {errors.description &&

{errors.description.message}

} -
- - {/* Ernst en Type */} -
-
- - - {errors.severity &&

{errors.severity.message}

} -
- -
- -
- {DIAGNOSIS_TYPES.map((type) => ( - - ))} -
- {errors.diagnosisType &&

{errors.diagnosisType.message}

} -
-
- - {/* Status */} -
- - - {errors.status &&

{errors.status.message}

} -
- - {/* Onderbouwing */} -
- -