'use client'; import { useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Sparkles, FileText, Clock, CheckCircle2, AlertCircle, ChevronRight, Calendar, Target, Stethoscope, CalendarDays, ClipboardCheck, Shield, Phone, AlertTriangle, } from 'lucide-react'; import type { GeneratedPlan, SmartGoal, Intervention, Sessie, Evaluatiemoment, Veiligheidsplan } from '@/lib/types/behandelplan'; import type { LifeDomainScore } from '@/lib/types/leefgebieden'; import { LeefgebiedenScoresCard } from './leefgebieden-scores'; import { LeefgebiedenBadge } from './leefgebieden-badge'; import { FHIR_STATUS_LABELS, GOAL_STATUS_LABELS, type FhirCarePlanStatus, type Behandelstructuur } from '@/lib/types/behandelplan'; import { EditableSection, ItemActions } from './editable-section'; import { BehandelstructuurForm } from './sections/behandelstructuur-form'; import { GoalForm } from './sections/goal-form'; import { InterventionForm } from './sections/intervention-form'; import { Plus } from 'lucide-react'; interface CarePlan { id: string; title: string; status: 'draft' | 'active' | 'on-hold' | 'completed' | 'revoked' | 'entered-in-error' | 'unknown'; version: number | null; goals: SmartGoal[] | null; activities: Intervention[] | null; behandelstructuur: GeneratedPlan['behandelstructuur'] | null; sessie_planning: Sessie[] | null; evaluatiemomenten: Evaluatiemoment[] | null; veiligheidsplan: Veiligheidsplan | null; created_at: string | null; published_at: string | null; period_start: string | null; } interface Intake { id: string; title: string; status: string; start_date: string; life_domains: LifeDomainScore[] | null; notes: string | null; } interface Condition { id: string; category: string; code_display: string; severity_code: string | null; severity_display: string | null; } interface BehandelplanViewProps { patientId: string; carePlan: CarePlan | null; intakes: Intake[]; conditions: Condition[]; onGenerate: (intakeId: string) => Promise; onStatusChange: (status: CarePlan['status']) => Promise; onCreateManual: (intakeId?: string) => Promise; // Edit callbacks onUpdateBehandelstructuur?: (data: Behandelstructuur) => Promise; onAddGoal?: (goal: SmartGoal) => Promise; onUpdateGoal?: (goalId: string, goal: SmartGoal) => Promise; onDeleteGoal?: (goalId: string) => Promise; onAddIntervention?: (intervention: Intervention) => Promise; onUpdateIntervention?: (interventionId: string, intervention: Intervention) => Promise; onDeleteIntervention?: (interventionId: string) => Promise; } export function BehandelplanView({ carePlan, intakes, conditions, onGenerate, onStatusChange, onCreateManual, onUpdateBehandelstructuur, onAddGoal, onUpdateGoal, onDeleteGoal, onAddIntervention, onUpdateIntervention, onDeleteIntervention, }: BehandelplanViewProps) { const [isGenerating, setIsGenerating] = useState(false); const [isCreatingManual, setIsCreatingManual] = useState(false); const [selectedIntakeId, setSelectedIntakeId] = useState( intakes[0]?.id || null ); const [error, setError] = useState(null); // Edit state const [editingBehandelstructuur, setEditingBehandelstructuur] = useState(false); const [editingGoalId, setEditingGoalId] = useState(null); const [addingGoal, setAddingGoal] = useState(false); const [editingInterventionId, setEditingInterventionId] = useState(null); const [addingIntervention, setAddingIntervention] = useState(false); // Temp data for forms const [tempBehandelstructuur, setTempBehandelstructuur] = useState(null); const [tempGoal, setTempGoal] = useState(null); const [tempIntervention, setTempIntervention] = useState(null); const selectedIntake = intakes.find((i) => i.id === selectedIntakeId); const hasLifeDomains = selectedIntake?.life_domains && selectedIntake.life_domains.length > 0; const latestCondition = conditions[0]; const handleGenerate = async () => { if (!selectedIntakeId) { setError('Selecteer eerst een intake'); return; } // Leefgebieden zijn aanbevolen maar niet verplicht if (!hasLifeDomains) { // Toon waarschuwing maar blokkeer niet console.warn('Leefgebieden niet ingevuld - AI generatie mogelijk minder nauwkeurig'); } setIsGenerating(true); setError(null); try { await onGenerate(selectedIntakeId); } catch (err) { setError(err instanceof Error ? err.message : 'Er ging iets mis'); } finally { setIsGenerating(false); } }; const handleCreateManual = async () => { setIsCreatingManual(true); setError(null); try { await onCreateManual(selectedIntakeId || undefined); } catch (err) { setError(err instanceof Error ? err.message : 'Er ging iets mis'); } finally { setIsCreatingManual(false); } }; // No care plan exists - show generation UI if (!carePlan) { return (
{/* Header */}

Behandelplan

Genereer een behandelplan op basis van de intake en diagnose

{/* Context Cards */}
{/* Intake Selection */} Intake selecteren {intakes.length === 0 ? (

Geen intakes gevonden. Maak eerst een intake aan.

) : (
{intakes.map((intake) => ( ))}
)}
{/* Diagnosis Info */} Diagnose {latestCondition ? (

{latestCondition.code_display}

{latestCondition.category} {latestCondition.severity_display && ( {latestCondition.severity_display} )}
) : (

Geen diagnose gevonden. Voeg eerst een diagnose toe.

)}
{/* Leefgebieden Preview */} {selectedIntake && hasLifeDomains && ( )} {/* Create Options */}
{/* AI Generate Option */}

AI Genereren

Automatisch SMART doelen en interventies genereren

{!hasLifeDomains && (

Tip: vul leefgebieden in voor betere AI resultaten

)}
{/* Manual Create Option */}

Handmatig Aanmaken

Zelf doelen en interventies invoeren

{/* Error Display */} {error && (
{error}
)}
); } // Care plan exists - show plan view const goals = (carePlan.goals as SmartGoal[]) || []; const interventions = (carePlan.activities as Intervention[]) || []; const behandelstructuur = carePlan.behandelstructuur as GeneratedPlan['behandelstructuur'] | null; const sessiePlanning = (carePlan.sessie_planning as Sessie[]) || []; const evaluatiemomenten = (carePlan.evaluatiemomenten as Evaluatiemoment[]) || []; const veiligheidsplan = carePlan.veiligheidsplan as Veiligheidsplan | null; const statusInfo = FHIR_STATUS_LABELS[carePlan.status as FhirCarePlanStatus] || { label: carePlan.status, color: '#6b7280', }; return (
{/* Header with Status */}

{carePlan.title}

{statusInfo.label}

{carePlan.created_at && ( <>Aangemaakt op {new Date(carePlan.created_at).toLocaleDateString('nl-NL')} )} {carePlan.published_at && ( <> • Gepubliceerd op {new Date(carePlan.published_at).toLocaleDateString('nl-NL')} )}

{/* Status Actions */}
{carePlan.status === 'draft' && ( )} {carePlan.status === 'active' && ( )}
{/* Behandelstructuur */} } isEditing={editingBehandelstructuur} onEditChange={(editing) => { setEditingBehandelstructuur(editing); if (editing) { setTempBehandelstructuur(behandelstructuur || { duur: '8 weken', frequentie: 'Wekelijks', aantalSessies: 8, vorm: 'Individueel', }); } }} canEdit={!!onUpdateBehandelstructuur} onSave={async () => { if (tempBehandelstructuur && onUpdateBehandelstructuur) { await onUpdateBehandelstructuur(tempBehandelstructuur); setEditingBehandelstructuur(false); } }} onCancel={() => { setEditingBehandelstructuur(false); setTempBehandelstructuur(null); }} editForm={ } > {behandelstructuur ? (

Duur

{behandelstructuur.duur}

Frequentie

{behandelstructuur.frequentie}

Sessies

{behandelstructuur.aantalSessies}

Vorm

{behandelstructuur.vorm}

) : (

Nog geen behandelstructuur ingesteld

)}
{/* Goals Section */}
SMART Doelen ({goals.length}) Behandeldoelen gekoppeld aan leefgebieden
{onAddGoal && ( )}
{/* Add Goal Form */} {addingGoal && (

Nieuw doel toevoegen

)} {goals.map((goal) => { const goalStatus = GOAL_STATUS_LABELS[goal.status] || { label: goal.status, color: '#6b7280', }; const isEditing = editingGoalId === goal.id; if (isEditing) { return (
); } return (
{goalStatus.label}

{goal.title}

{goal.description}

{/* Client version */} {goal.clientVersion && (
Voor cliënt: {goal.clientVersion}
)} {/* Progress bar */}
Voortgang {goal.progress}%
{(onUpdateGoal || onDeleteGoal) && ( { setEditingGoalId(goal.id); setTempGoal(goal); } : undefined} onDelete={onDeleteGoal ? () => onDeleteGoal(goal.id) : undefined} /> )}
); })} {goals.length === 0 && !addingGoal && (

Geen doelen gevonden

)}
{/* Interventions Section */}
Interventies ({interventions.length}) Evidence-based behandelmethoden
{onAddIntervention && ( )}
{/* Add Intervention Form */} {addingIntervention && (

Nieuwe interventie toevoegen

)} {interventions.map((intervention) => { const isEditing = editingInterventionId === intervention.id; if (isEditing) { return (
); } return (

{intervention.name}

{intervention.description}

{intervention.rationale && (
Rationale: {intervention.rationale}
)} {intervention.linkedGoalIds.length > 0 && (
Gekoppeld aan: {intervention.linkedGoalIds.map((goalId) => { const goal = goals.find((g) => g.id === goalId); return goal ? ( ) : null; })}
)}
{(onUpdateIntervention || onDeleteIntervention) && ( { setEditingInterventionId(intervention.id); setTempIntervention(intervention); } : undefined} onDelete={onDeleteIntervention ? () => onDeleteIntervention(intervention.id) : undefined} /> )}
); })} {interventions.length === 0 && !addingIntervention && (

Geen interventies gevonden

)}
{/* Sessie Planning Section */} {sessiePlanning.length > 0 && ( Sessie Planning ({sessiePlanning.length}) Overzicht van geplande en afgeronde sessies
{sessiePlanning.map((sessie) => { const statusColors: Record = { gepland: 'bg-blue-100 text-blue-800', afgerond: 'bg-green-100 text-green-800', no_show: 'bg-red-100 text-red-800', verzet: 'bg-amber-100 text-amber-800', geannuleerd: 'bg-slate-100 text-slate-800', }; return (
{sessie.nummer}

{sessie.focus}

{sessie.datum && (

{new Date(sessie.datum).toLocaleDateString('nl-NL', { weekday: 'short', day: 'numeric', month: 'short', })}

)}
{sessie.status === 'no_show' ? 'No-show' : sessie.status}
); })}
)} {/* Evaluatiemomenten Section */} {evaluatiemomenten.length > 0 && ( Evaluatiemomenten ({evaluatiemomenten.length}) Geplande evaluaties en voortgangsmomenten
{evaluatiemomenten.map((evaluatie) => { const typeLabels: Record = { tussentijds: { label: 'Tussentijds', color: 'bg-blue-100 text-blue-800' }, eind: { label: 'Eindevaluatie', color: 'bg-green-100 text-green-800' }, crisis: { label: 'Crisis', color: 'bg-red-100 text-red-800' }, }; const statusLabels: Record = { gepland: 'Gepland', afgerond: 'Afgerond', overgeslagen: 'Overgeslagen', }; const typeInfo = typeLabels[evaluatie.type] || { label: evaluatie.type, color: 'bg-slate-100' }; return (
W{evaluatie.weekNumber}
{typeInfo.label} {statusLabels[evaluatie.status] || evaluatie.status}

{new Date(evaluatie.plannedDate).toLocaleDateString('nl-NL', { day: 'numeric', month: 'long', year: 'numeric', })}

{evaluatie.status === 'afgerond' && ( )}
); })}
)} {/* Veiligheidsplan Section */} {veiligheidsplan && ( Veiligheidsplan Crisisplan en veiligheidsafspraken {/* Waarschuwingssignalen */}

Waarschuwingssignalen

    {veiligheidsplan.waarschuwingssignalen.map((signaal, i) => (
  • {signaal}
  • ))}
{/* Coping Strategieën */}

Coping Strategieën

    {veiligheidsplan.copingStrategieen.map((strategie, i) => (
  • {strategie}
  • ))}
{/* Contactpersonen */}

Noodcontacten

{veiligheidsplan.contacten.map((contact, i) => (

{contact.naam}

{contact.rol}

{contact.telefoon}

))}
{/* Restricties */} {veiligheidsplan.restricties && veiligheidsplan.restricties.length > 0 && (

Afspraken/Restricties

    {veiligheidsplan.restricties.map((restrictie, i) => (
  • {restrictie}
  • ))}
)}
)}
); }