'use client'; import { useState, useEffect, useMemo } from 'react'; import { Check, ChevronsUpDown } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '@/components/ui/command'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover'; import icd10CodesData from '@/lib/data/icd10-ggz-codes.json'; import { type ICD10Code, type FlatICD10Code, flattenICD10Codes, searchICD10Codes, getFrequentCodes, type ICD10CodeList, } from '@/lib/types/icd10'; interface ICD10ComboboxProps { value: string; onSelect: (code: ICD10Code) => void; placeholder?: string; disabled?: boolean; } // Debounce hook function useDebounce(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue; } export function ICD10Combobox({ value, onSelect, placeholder = 'Zoek ICD-10 code...', disabled = false, }: ICD10ComboboxProps) { const [open, setOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); // Flatten ICD-10 codes once const flatCodes = useMemo(() => { return flattenICD10Codes(icd10CodesData as ICD10CodeList); }, []); // Debounce search query (200ms) const debouncedQuery = useDebounce(searchQuery, 200); // Get search results or frequent codes const displayCodes = useMemo(() => { if (debouncedQuery.trim()) { // Search mode: max 8 results return searchICD10Codes(flatCodes, debouncedQuery, 8); } else { // Empty field: show top 5 frequent codes return getFrequentCodes(flatCodes, icd10CodesData.frequentCodes).slice(0, 5); } }, [debouncedQuery, flatCodes]); // Find selected code object const selectedCode = useMemo(() => { if (!value) return null; return flatCodes.find((code) => code.code === value) || null; }, [value, flatCodes]); const handleSelect = (code: FlatICD10Code) => { onSelect({ code: code.code, display: code.display, keywords: code.keywords, }); setOpen(false); setSearchQuery(''); }; return ( {debouncedQuery.trim() ? 'Geen codes gevonden.' : 'Begin met typen om te zoeken...'} {!debouncedQuery.trim() && ( {displayCodes.map((code) => ( handleSelect(code)} >
{code.code} {code.display}
))}
)} {debouncedQuery.trim() && ( {displayCodes.map((code) => ( handleSelect(code)} >
{code.code} {code.display} {code.category}
))}
)}
); }