'use client'; /** * RisicoBlock * * Shows risk assessments for an intake: level indicators, categories. * Uses Cortex shared components and hooks. * * Epic: E2.S2 - Intake Blocks */ import { useCortexStore } from '@/stores/cortex-store'; import { BlockContainer } from './block-container'; import { BLOCK_CONFIGS } from '@/lib/cortex/types'; import { AlertTriangle, User, ExternalLink, Shield, AlertCircle, } from 'lucide-react'; // Use extracted hooks and components import { useBlockData, useIntakeContext, type IntakePrefillData } from '@/lib/cortex/hooks'; import { BlockLoading, BlockError, BlockEmpty, BlockSection, BlockItem, BlockFooter, getRiskBadgeVariant, } from '@/components/cortex/shared'; // Import response type from API import type { IntakeRisicoResponse, RiskAssessmentItem } from '@/app/api/cortex/intake/risico/route'; // ============================================================================ // Types // ============================================================================ interface RisicoBlockProps { prefill?: IntakePrefillData; } // ============================================================================ // Sub-components // ============================================================================ function RiskSummaryCard({ summary }: { summary: IntakeRisicoResponse['summary'] }) { const getLevelColor = (level: string | null) => { if (!level) return 'bg-slate-100 border-slate-200'; switch (level) { case 'acuut': return 'bg-red-100 border-red-300'; case 'hoog': return 'bg-red-50 border-red-200'; case 'matig': return 'bg-amber-50 border-amber-200'; case 'laag': return 'bg-green-50 border-green-200'; default: return 'bg-slate-100 border-slate-200'; } }; const getLevelLabel = (level: string | null) => { if (!level) return 'Geen'; return level.charAt(0).toUpperCase() + level.slice(1); }; return (
Risico-overzicht
Hoogste: {getLevelLabel(summary.highestLevel)}
{/* Risk indicators */}
{summary.hasSuicideRisk && ( Suïcide )} {summary.hasSelfHarmRisk && ( Zelfbeschadiging )} {summary.hasAggressionRisk && ( Agressie )} {!summary.hasSuicideRisk && !summary.hasSelfHarmRisk && !summary.hasAggressionRisk && summary.total === 0 && ( Geen specifieke risico's geregistreerd )}
{summary.total} risicotaxatie{summary.total !== 1 ? 's' : ''} geregistreerd
); } function RiskItem({ risk }: { risk: RiskAssessmentItem }) { const formatDate = (dateStr: string) => { return new Date(dateStr).toLocaleDateString('nl-NL', { day: 'numeric', month: 'short', year: 'numeric', }); }; return ( ); } // ============================================================================ // Main Component // ============================================================================ export function RisicoBlock({ prefill }: RisicoBlockProps) { const config = BLOCK_CONFIGS.risico_query; const { closeBlock } = useCortexStore(); // Get patient context (from prefill or activePatient) const { patientId, patientName, hasPatientContext } = useIntakeContext(prefill); // Fetch risk data const { data, isLoading, error, refetch } = useBlockData({ endpoint: '/api/cortex/intake/risico', params: { patientId: patientId || undefined, intakeId: prefill?.intakeId, }, enabled: hasPatientContext, operationName: 'Risicotaxaties laden', }); // No patient context if (!hasPatientContext) { return ( { closeBlock(); // TODO: Open zoeken block }, }} /> ); } // Loading state if (isLoading) { return ( ); } // Error state if (error) { return ( ); } // No data if (!data) { return ( ); } return (
{/* Patient name header */} {patientName && (
Patiënt: {patientName}
)} {/* Risk summary */} {/* Risk assessments list */} {data.risks.length > 0 ? (
{data.risks.map((risk) => ( ))}
) : (

Nog geen risicotaxaties geregistreerd

)} {/* Footer with actions */} { // Navigate to risk page const url = `/epd/patients/${data.patientId}/intakes/${data.intakeId}/risk`; window.location.href = url; }, }} />
); }