/** * Patient Dashboard Page * E2.S3: Default view showing patient overview and status */ import Link from 'next/link'; import { User, ClipboardList, FileText, ArrowRight, AlertCircle, Calendar, Clock, } from 'lucide-react'; import { getIntakesByPatientId } from './intakes/actions'; import type { Intake } from '@/lib/types/intake'; import { format } from 'date-fns'; import { nl } from 'date-fns/locale'; import { getPatientEncounters } from '@/app/epd/agenda/actions'; import { getActiveCarePlan, getPatientIntakes } from './behandelplan/actions'; import type { SmartGoal, Intervention, Behandelstructuur, Evaluatiemoment } from '@/lib/types/behandelplan'; function extractHulpvraag(notes: string | null): string | null { if (!notes) return null; const firstSentence = notes.split(/[.!?]/)[0]; return firstSentence.length > 150 ? firstSentence.slice(0, 150) + '...' : firstSentence; } export default async function PatientDashboardPage({ params, }: { params: Promise<{ id: string }>; }) { const { id } = await params; // Fetch recent intakes (optional) let recentIntakes: Intake[] = []; try { const intakes = await getIntakesByPatientId(id); recentIntakes = intakes.slice(0, 3); // Get up to 3 most recent } catch (error) { // Silently fail - intakes are optional for dashboard console.error('Failed to fetch intakes for dashboard:', error); } // Fetch encounters (vandaag, toekomst en recente) let upcomingEncounters: any[] = []; let recentEncounters: any[] = []; try { const allEncounters = await getPatientEncounters(id); const now = new Date(); const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()); // Split into upcoming (vandaag + toekomst) and recent (verleden) const upcoming = allEncounters.filter(e => new Date(e.period_start) >= todayStart); const recent = allEncounters.filter(e => new Date(e.period_start) < todayStart); // Take 5 most relevant: prioritize upcoming, then recent upcomingEncounters = upcoming.slice(0, 5); if (upcomingEncounters.length < 5) { recentEncounters = recent.slice(0, 5 - upcomingEncounters.length); } } catch (error) { console.error('Failed to fetch encounters:', error); } // Fetch active care plan let activeCarePlan: any = null; let hulpvraag: string | null = null; try { activeCarePlan = await getActiveCarePlan(id); // Get hulpvraag from linked intake if (activeCarePlan?.based_on_intake_id) { const intakes = await getPatientIntakes(id); const linkedIntake = intakes.find(i => i.id === activeCarePlan.based_on_intake_id); if (linkedIntake?.notes) { hulpvraag = extractHulpvraag(linkedIntake.notes); } } } catch (error) { console.error('Failed to fetch care plan:', error); } return (
{/* Page Header */}

Dashboard

Overzicht van cliëntgegevens en voortgang

{/* Quick Actions Grid */}
{/* Basisgegevens Card */}

Basisgegevens

NAW & contactgegevens

{/* Screening Card */}

Screening

Activiteiten & besluit

{/* Intake Card */}

Intake

Gesprekken & registraties

{/* Recent Intakes Section */} {recentIntakes.length > 0 && (

Recente Intakes

Bekijk alle →
{recentIntakes.map((intake) => (

{intake.title}

{intake.department}
{format(new Date(intake.start_date), 'd MMM yyyy', { locale: nl })}
{intake.status}
))}
)} {/* Agenda Afspraken Section */} {(upcomingEncounters.length > 0 || recentEncounters.length > 0) && (

Agenda Afspraken

Bekijk agenda →
{[...upcomingEncounters, ...recentEncounters].slice(0, 5).map((encounter) => { const encounterDate = new Date(encounter.period_start); const isPast = encounterDate < new Date(); const isToday = encounterDate.toDateString() === new Date().toDateString(); return (

{encounter.type_display || 'Afspraak'}

{format(encounterDate, 'd MMM yyyy HH:mm', { locale: nl })} {encounter.period_end && ( <> {format(new Date(encounter.period_end), 'HH:mm', { locale: nl })} )}
{encounter.status === 'planned' ? 'Gepland' : encounter.status === 'arrived' ? 'Aangekomen' : encounter.status === 'finished' ? 'Afgerond' : encounter.status}
); })}
)} {/* Behandelplan Section */} {activeCarePlan && (

Actief Behandelplan

Bekijk volledig plan →
{/* Hulpvraag */} {hulpvraag && (

Hulpvraag

“{hulpvraag}”

)} {/* Behandelstructuur */} {activeCarePlan.behandelstructuur && (

Behandelstructuur

Duur: {activeCarePlan.behandelstructuur.duur}
Frequentie: {activeCarePlan.behandelstructuur.frequentie}
Aantal sessies: {activeCarePlan.behandelstructuur.aantalSessies}
Vorm: {activeCarePlan.behandelstructuur.vorm}
)} {/* Doelen Overzicht */} {activeCarePlan.goals && Array.isArray(activeCarePlan.goals) && activeCarePlan.goals.length > 0 && (

Doelen ({activeCarePlan.goals.length})

{activeCarePlan.goals.slice(0, 3).map((goal: SmartGoal) => (

{goal.title}

{goal.status === 'bezig' ? 'Bezig' : goal.status === 'gehaald' ? 'Gehaald' : goal.status === 'niet_gestart' ? 'Niet gestart' : goal.status}
{goal.progress > 0 && (

{goal.progress}% voltooid

)}
))} {activeCarePlan.goals.length > 3 && (

+{activeCarePlan.goals.length - 3} meer doelen

)}
)} {/* Interventies Overzicht */} {activeCarePlan.activities && Array.isArray(activeCarePlan.activities) && activeCarePlan.activities.length > 0 && (

Interventies ({activeCarePlan.activities.length})

{activeCarePlan.activities.slice(0, 5).map((intervention: Intervention) => ( {intervention.name} ))} {activeCarePlan.activities.length > 5 && ( +{activeCarePlan.activities.length - 5} meer )}
)} {/* Aankomende Evaluatiemomenten */} {activeCarePlan.evaluatiemomenten && Array.isArray(activeCarePlan.evaluatiemomenten) && activeCarePlan.evaluatiemomenten.length > 0 && (

Aankomende evaluatiemomenten

{activeCarePlan.evaluatiemomenten .filter((evaluatie: Evaluatiemoment) => evaluatie.status === 'gepland') .slice(0, 2) .map((evaluatie: Evaluatiemoment) => (

{evaluatie.type === 'tussentijds' ? 'Tussentijdse evaluatie' : evaluatie.type === 'eind' ? 'Eindevaluatie' : 'Crisis evaluatie'}

{evaluatie.plannedDate && (

Week {evaluatie.weekNumber} • {format(new Date(evaluatie.plannedDate), 'd MMM yyyy', { locale: nl })}

)}
Gepland
))}
)}
)} {/* Next Steps Section */}

Volgende stappen

  • • Controleer en vul basisgegevens aan indien nodig
  • • Start screening door activiteiten te loggen
  • • Upload relevante documenten (verwijsbrief, etc.)
  • • Neem screeningsbesluit om door te gaan naar intake
  • • Start een nieuwe intake via de{' '} Intake module
); }