import { TextControl } from "../ui/text-control"; import { FormTokenField, type TokenItem } from "../ui/form-token-field"; import { Divider } from '../ui/divider'; import { DismissibleAlert } from '../ui/dismissible-alert'; import { Flex, FlexItem } from '../ui/flex'; import { PlusCircle, Trash2, XCircle } from 'lucide-react'; import { Controller, useWatch, useFormContext, UseFieldArrayReturn, FieldValues } from 'react-hook-form'; import { HumanName } from 'fhir/r4'; interface FhirHumanNameProps { names: UseFieldArrayReturn; required?: boolean; submitting?: boolean; } const FhirHumanName = ({ names, required = false, submitting = false }: FhirHumanNameProps) => { const { control, setValue, getValues } = useFormContext(); const namePrefixes = ['Mr.', 'Mrs.', 'Ms.', 'Dr.', 'Prof.', 'Rev.', 'Hon.', 'Sir', 'Lady']; const nameSuffixes = ['Jr.', 'Sr.', 'II', 'III', 'MD', 'PhD', 'DDS', 'Esq.', 'CPA']; const allNameFields = useWatch({ control, name: 'name', defaultValue: names.fields }); const addName = () => { if (canAddName()) { names.append({ family: '', given: [''], prefix: [], suffix: [], use: 'official' }); } }; const removeName = (index: number) => { names.remove(index); }; const addGivenName = (nameIndex: number) => { if (canAddGivenName(nameIndex)) { const currentGiven = getValues(`name.${nameIndex}.given`) || []; setValue(`name.${nameIndex}.given`, [...currentGiven, '']); } }; const removeGivenName = (nameIndex: number, givenNameIndex: number) => { const currentGiven = getValues(`name.${nameIndex}.given`) || []; if (givenNameIndex > -1 && givenNameIndex < currentGiven.length) { const newGiven = [...currentGiven]; newGiven.splice(givenNameIndex, 1); setValue(`name.${nameIndex}.given`, newGiven); } }; const canAddName = (): boolean => { if (names.fields.length === 0) { return true; } const lastNameIndex = names.fields.length - 1; const lastFamily = getValues(`name.${lastNameIndex}.family`) || ''; const lastGiven = getValues(`name.${lastNameIndex}.given`) || []; return lastFamily.trim() !== '' || lastGiven.some((g: string) => g.trim() !== ''); }; const canAddGivenName = (nameIndex: number): boolean => { const givenNames = getValues(`name.${nameIndex}.given`) || []; if (givenNames.length === 0) { return true; } const lastGivenName = givenNames[givenNames.length - 1]; return lastGivenName.trim() !== ''; }; const tokenText = (tokens: (string | TokenItem)[]) => tokens.map((token) => (typeof token === 'string' ? token : token.value)); const handlePrefixChange = (nameIndex: number, tokens: (string | TokenItem)[]) => { setValue(`name.${nameIndex}.prefix`, tokenText(tokens)); }; const handleSuffixChange = (nameIndex: number, tokens: (string | TokenItem)[]) => { setValue(`name.${nameIndex}.suffix`, tokenText(tokens)); }; return ( <> {names.fields.map((name: HumanName, nameIndex: number) => { const givenNames: string[] = allNameFields?.[nameIndex]?.given ?? ['']; return ( <>
{names.fields.length > 1 && (

Name {nameIndex + 1}

)}
( <> {fieldState.error && ( Family name is required )} )}/>
{givenNames.map((_givenName: string, givenNameIndex: number) => (
( <> {fieldState.error && ( Given name is required )} )}/>
{givenNames.length > 1 && ( )}
))}
( handlePrefixChange(nameIndex, tokens)} disabled={submitting}/> )}/>
( handleSuffixChange(nameIndex, tokens)} disabled={submitting}/> )}/>
{nameIndex === names.fields.length - 1 && ( )} ); })} ); }; export default FhirHumanName;