'use client'; /** * LogList Component * E3.S1: Lijst van dagnotities met real-time updates * E3.S2: Inclusief quick entry form * E3.S3: Edit/Delete functionality */ import { useState, useCallback, useTransition } from 'react'; import { format } from 'date-fns'; import { nl } from 'date-fns/locale'; import { Pill, Utensils, User, AlertTriangle, FileText, Clock, CheckCircle2, Pencil, Trash2, X, Check, Loader2, } from 'lucide-react'; import type { NursingLog, NursingLogCategory } from '@/lib/types/nursing-log'; import { CATEGORY_CONFIG, NURSING_LOG_CATEGORIES } from '@/lib/types/nursing-log'; import { LogForm } from './log-form'; interface LogListProps { patientId: string; initialLogs: NursingLog[]; date: string; } // Icon mapping const CATEGORY_ICONS: Record> = { medicatie: Pill, adl: Utensils, gedrag: User, incident: AlertTriangle, observatie: FileText, }; export function LogList({ patientId, initialLogs, date }: LogListProps) { const [logs, setLogs] = useState(initialLogs); // Refresh logs from API const refreshLogs = useCallback(async () => { try { const response = await fetch( `/api/nursing-logs?patientId=${patientId}&date=${date}` ); if (response.ok) { const data = await response.json(); setLogs(data.logs); } } catch (error) { console.error('Failed to refresh logs:', error); } }, [patientId, date]); // Group logs by category for summary const logsByCategory = logs.reduce( (acc, log) => { acc[log.category] = (acc[log.category] || 0) + 1; return acc; }, {} as Record ); const markedForHandover = logs.filter((l) => l.include_in_handover).length; return (
{/* Quick Entry Form */} {/* Summary Cards */}
{logs.length}
Notities vandaag
{markedForHandover}
Voor overdracht
{logsByCategory['incident'] > 0 && (
{logsByCategory['incident']}
Incidenten
)}
{/* Log List */}

Notities ({logs.length})

{logs.length === 0 ? (

Nog geen notities vandaag

Voeg een notitie toe via het formulier hieronder

) : (
{logs.map((log) => ( ))}
)}
); } interface LogCardProps { log: NursingLog; onUpdate: () => void; } function LogCard({ log, onUpdate }: LogCardProps) { const [isEditing, setIsEditing] = useState(false); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [editContent, setEditContent] = useState(log.content); const [editCategory, setEditCategory] = useState( log.category as NursingLogCategory ); const [editHandover, setEditHandover] = useState(log.include_in_handover); const [isPending, startTransition] = useTransition(); const [error, setError] = useState(null); const config = CATEGORY_CONFIG[log.category as NursingLogCategory]; const Icon = CATEGORY_ICONS[log.category as NursingLogCategory] || FileText; const handleSave = () => { if (!editContent.trim()) { setError('Notitie mag niet leeg zijn'); return; } setError(null); startTransition(async () => { try { const response = await fetch(`/api/nursing-logs/${log.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: editContent.trim(), category: editCategory, include_in_handover: editHandover, }), }); if (!response.ok) { const data = await response.json(); throw new Error(data.error || 'Opslaan mislukt'); } setIsEditing(false); onUpdate(); } catch (err) { setError(err instanceof Error ? err.message : 'Opslaan mislukt'); } }); }; const handleDelete = () => { startTransition(async () => { try { const response = await fetch(`/api/nursing-logs/${log.id}`, { method: 'DELETE', }); if (!response.ok && response.status !== 204) { const data = await response.json(); throw new Error(data.error || 'Verwijderen mislukt'); } setShowDeleteConfirm(false); onUpdate(); } catch (err) { setError(err instanceof Error ? err.message : 'Verwijderen mislukt'); } }); }; const handleCancelEdit = () => { setIsEditing(false); setEditContent(log.content); setEditCategory(log.category as NursingLogCategory); setEditHandover(log.include_in_handover); setError(null); }; // Delete confirmation dialog if (showDeleteConfirm) { return (

Notitie verwijderen?

Deze actie kan niet ongedaan worden gemaakt.

); } // Edit mode if (isEditing) { return (
{/* Category selector */}
{NURSING_LOG_CATEGORIES.map((cat) => { const catConfig = CATEGORY_CONFIG[cat]; const isSelected = editCategory === cat; return ( ); })}
{/* Content textarea */}