import React, { useState, useEffect } from 'react'; import { TextareaControl } from "../ui/textarea-control"; import { Card, CardHeader, CardBody, CardDivider } from '../ui/wp-card'; import { Elevation } from '../ui/elevation'; import { InputControl } from '../ui/input-control'; import { Divider } from '../ui/divider'; import { DismissibleAlert } from '../ui/dismissible-alert'; import { Heading } from '../ui/heading'; import { Flex, FlexItem } from '../ui/flex'; import { Spacer } from '../ui/spacer'; import { TabPanel } from '../ui/tab-panel'; import { Disabled } from '../ui/disabled'; import { DropdownMenu, DropdownMenuItem } from '../ui/dropdown-menu'; import { useFormContext, Controller, useFieldArray } from 'react-hook-form'; import { IValueSet, useAuthServiceContext, useValueSetServiceContext } from '../../services'; import { FhirAge, FhirAnnotation, FhirCodeableConcept, FhirPeriod, FhirRange, FhirReference, FhirReferenceCollection, FhirValueSetSearch, TypeSelector } from '../../components'; import { useFhirClinicalImpressions, useFhirConditionBroadcast, useFhirConditions, useFhirEncounters, useFhirObservations } from '../../hooks'; import { PlusCircle, Trash2 } from 'lucide-react'; import { ChartBar } from 'lucide-react'; import { FhirResource } from 'fhir/r4'; const StageAssessmentReferences: React.FC<{ index: number; disabled: boolean; enableInlineActions: boolean; }> = ({ index, disabled, enableInlineActions = true }) => { const { control } = useFormContext(); const itemReferenceFieldArray = useFieldArray({ control, name: `stage.${index}.assessment` }); const { observationsList } = useFhirObservations(); const { clinicalImpressionsList } = useFhirClinicalImpressions(); return ( { switch (referenceType) { case 'ClinicalImpression': return clinicalImpressionsList; case 'Observation': return observationsList; default: return []; } }} required={false} disabled={disabled} multiple={true} enableInlineActions={enableInlineActions}/> ); }; interface FhirConditionProps { isNew: boolean; conditionProfile: string | undefined; onConditionProfileSelect: (conditionProfile: string) => void; elevated?: boolean; disabled?: boolean; enableInlineActions?: boolean; } export const FhirCondition: React.FC = ({ conditionProfile, onConditionProfileSelect, isNew, elevated = true, disabled = false, enableInlineActions = true }) => { const { control, watch } = useFormContext(); const { fetchValueSet, valueSetUrls } = useValueSetServiceContext(); const { userRole, USER_ROLES } = useAuthServiceContext(); const isPatientRole = [USER_ROLES.PATIENT, USER_ROLES.RELATED_PERSON].includes(userRole as string); const [loading, setLoading] = useState(false); const [isCategoryMutable, setIsCategoryMutable] = useState(false); const [categoryCodes, setCategoryCodes] = useState([]); // value sets const [conditionClinical, setConditionClinical] = useState([]); const [conditionVerStatus, setConditionVerStatus] = useState([]); const [conditionCategory, setConditionCategory] = useState([]); const [conditionSeverity, setConditionSeverity] = useState([]); const [usCoreProblemOrHealthConcern, setUsCoreProblemOrHealthConcern] = useState([]); const [usCoreSimpleObservationCategory, setUsCoreSimpleObservationCategory] = useState([]); const spacerMargin = '24px'; useFhirConditions(); useFhirConditionBroadcast(); const { encountersList } = useFhirEncounters(); const onsetType = watch('onsetType'); const abatementType = watch('abatementType'); const stageFieldArray = useFieldArray({ control, name: 'stage' }); const evidenceFieldArray = useFieldArray({ control, name: 'evidence' }); useEffect(() => { const loadValueSets = async () => { setLoading(true); try { const [ conditionClinicalValueSet, conditionVerStatusValueSet, conditionSeverityValueSet, conditionCategoryValueSet, usCoreProblemOrHealthConcernValueSet, usCoreSimpleObservationCategoryValueSet ] = await Promise.all([ fetchValueSet(valueSetUrls.conditionClinical), fetchValueSet(valueSetUrls.conditionVerStatus), fetchValueSet(valueSetUrls.conditionSeverity), fetchValueSet(valueSetUrls.conditionCategory), fetchValueSet(valueSetUrls.usCoreProblemOrHealthConcern), fetchValueSet(valueSetUrls.usCoreSimpleObservationCategory) ]); setConditionClinical(conditionClinicalValueSet); setConditionVerStatus(conditionVerStatusValueSet); setConditionSeverity(conditionSeverityValueSet); setConditionCategory(conditionCategoryValueSet); setUsCoreProblemOrHealthConcern(usCoreProblemOrHealthConcernValueSet); setUsCoreSimpleObservationCategory(usCoreSimpleObservationCategoryValueSet); } catch (err) { console.error('Error loading value sets:', err); } finally { setLoading(false); } }; loadValueSets(); }, [fetchValueSet, valueSetUrls]); useEffect(() => { if (conditionProfile === 'us-core-condition-encounter-diagnosis') { setIsCategoryMutable(false); setCategoryCodes(conditionCategory); } else if (conditionProfile === 'us-core-condition-problems-health-concerns') { setIsCategoryMutable(true); setCategoryCodes([ ...usCoreProblemOrHealthConcern, ...usCoreSimpleObservationCategory ]) } }, [conditionProfile, setIsCategoryMutable, setIsCategoryMutable, conditionCategory, usCoreProblemOrHealthConcern, usCoreSimpleObservationCategory]); const addStage = () => { stageFieldArray.append({ type: null, summary: null, assessment: [] }); }; const removeStage = (index: number) => { stageFieldArray.remove(index); }; const addEvidence = () => { evidenceFieldArray.append({ code: [] }); }; const removeEvidence = (index: number) => { evidenceFieldArray.remove(index); }; const getSelectedConditionProfile = () => { switch (conditionProfile) { case 'us-core-condition-encounter-diagnosis': return 'Encounter Diagnosis'; case 'us-core-condition-problems-health-concerns': return 'Problems and Health Concerns'; } return ''; }; return ( {elevated && } Details {conditionProfile && (`: ${getSelectedConditionProfile()}`)} {/* Radix closes the menu on select, so WP's manual onClose() is gone. */} {isNew && ( )} {!conditionProfile && ( No condition profile selected. )} {(isNew && conditionProfile || !isNew) && ( <> {/* code */} {/* category */} {/* severity */} {/* clinicalStatus */} {/* verificationStatus */} {/* bodySite */} {/* encounter */} {!isPatientRole && <> } {/* recordedDate */} ( )}/> When did the condition begin? {/* onsetType */} {onsetType === 'dateTime' && ( <> {/* onsetDateTime */} ( )}/> )} {onsetType === 'age' && ( <> {/* onsetAge */} )} {onsetType === 'period' && ( <> {/* onsetPeriod */} )} {onsetType === 'range' && ( <> {/* onsetRange */} )} {onsetType === 'string' && ( <> {/* onsetString */} ( )}/> )} When did the condition resolve? {/* abatementType */} {abatementType === 'dateTime' && ( <> {/* abatementDateTime */} ( )}/> )} {abatementType === 'age' && ( <> {/* abatementAge */} )} {abatementType === 'period' && ( <> {/* abatementPeriod */} )} {abatementType === 'range' && ( <> {/* abatementRange */} )} {abatementType === 'string' && ( <> {/* abatementString */} ( )}/> )} {(tab) => { // stages if (tab.name === 'stages') { return (
{stageFieldArray.fields.length === 0 && ( <> Clinical stage or grade of a condition No stage added yet. )} {stageFieldArray.fields.map((field, index) => (

Stage {index + 1}

{/* stage.type */} {/* stage.summary */} {/* stage.assessment */}
))} {stageFieldArray.fields.length > 0 && ( )}
); } // evidences if (tab.name === 'evidences') { return (
{evidenceFieldArray.fields.length === 0 && ( <> Supporting evidence No evidence added yet. )} {evidenceFieldArray.fields.map((field, index) => (

Evidence {index + 1}

{/* evidence.code */}
))} {evidenceFieldArray.fields.length > 0 && ( )}
); } // notes if (tab.name === 'notes') { return (
{/* note */}
); } }}
)}
); }; export default FhirCondition;