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 { Text } from '../ui/text'; import { Spacer } from '../ui/spacer'; import { TabPanel } from '../ui/tab-panel'; import { Disabled } from '../ui/disabled'; import { useFormContext, Controller, useFieldArray } from 'react-hook-form'; import { IValueSet, useAuthServiceContext, useValueSetServiceContext } from '../../services'; import { FhirAnnotation, FhirCode, FhirCodeableConcept, FhirQuantity, FhirRatio, FhirReference, FhirTiming, FhirValueSetSearch, TypeSelector } from '../../components'; import { useFhirAllergyIntolerances, useFhirEncounters, useFhirNutritionOrderBroadcast, useFhirNutritionOrders } from '../../hooks'; import { PlusCircle, Trash2 } from 'lucide-react'; interface SupplementScheduleProps { index: number; disabled?: boolean; readonly?: boolean; } interface FhirNutritionOrderProps { elevated?: boolean; disabled?: boolean; enableInlineActions?: boolean; } const SupplementSchedule: React.FC = ({ index, disabled = false, readonly = false }) => { const { control } = useFormContext(); const scheduleFieldArray = useFieldArray({ control, name: `supplement.${index}.schedule` }); return ( <> {scheduleFieldArray.fields.length === 0 && ( <> {!readonly && ( )} No schedules added yet. )} {scheduleFieldArray.fields.map((scheduleField, scheduleIndex) => ( Schedule {scheduleIndex + 1} {!readonly && ( )} ))} {!readonly && scheduleFieldArray.fields.length > 0 && ( )} ); }; export const FhirNutritionOrder: React.FC = ({ elevated = true, disabled = false, enableInlineActions = true }) => { const { control, watch } = useFormContext(); const { userRole, USER_ROLES } = useAuthServiceContext(); const { fetchValueSet, valueSetUrls } = useValueSetServiceContext(); const [loading, setLoading] = useState(false); // value sets const [requestStatus, setRequestStatus] = useState([]); const [requestIntent, setRequestIntent] = useState([]); const [encounterDiet, setEncounterDiet] = useState([]); const [dietType, setDietType] = useState([]); const [nutrientCode, setNutrientCode] = useState([]); const [textureCode, setTextureCode] = useState([]); const [modifiedFoodtype, setModifiedFoodtype] = useState([]); const [consistencyType, setConsistencyType] = useState([]); const [supplementType, setSupplementType] = useState([]); const [entformulaType, setEntformulaType] = useState([]); const [entformulaAdditive, setEntformulaAdditive] = useState([]); const [enteralRoute, setEnteralRoute] = useState([]); const isPatient = [USER_ROLES.PATIENT, USER_ROLES.RELATED_PERSON].includes(userRole as string); const spacerMargin = '24px'; useFhirNutritionOrders(); useFhirNutritionOrderBroadcast(); const { encountersList } = useFhirEncounters(); const { allergyIntolerancesList } = useFhirAllergyIntolerances(); const oralDietScheduleFieldArray = useFieldArray({ control, name: 'oralDiet.schedule' }); const oralDietNutrientFieldArray = useFieldArray({ control, name: 'oralDiet.nutrient' }); const oralDietTextureFieldArray = useFieldArray({ control, name: 'oralDiet.texture' }); const supplementFieldArray = useFieldArray({ control, name: 'supplement' }); const enteralFormulaAdministrationFieldArray = useFieldArray({ control, name: 'enteralFormula.administration' }); useEffect(() => { const loadValueSets = async () => { setLoading(true); try { const [ requestStatusValueSet, requestIntentValueSet, encounterDietValueSet, dietTypeValueSet, nutrientCodeValueSet, textureCodeValueSet, modifiedFoodtypeValueSet, consistencyTypeValueSet, supplementTypeValueSet, entformulaTypeValueSet, entformulaAdditiveValueSet, enteralRouteValueSet, ] = await Promise.all([ fetchValueSet(valueSetUrls.requestStatus), fetchValueSet(valueSetUrls.requestIntent), fetchValueSet(valueSetUrls.encounterDiet), fetchValueSet(valueSetUrls.dietType), fetchValueSet(valueSetUrls.nutrientCode), fetchValueSet(valueSetUrls.textureCode), fetchValueSet(valueSetUrls.modifiedFoodtype), fetchValueSet(valueSetUrls.consistencyType), fetchValueSet(valueSetUrls.supplementType), fetchValueSet(valueSetUrls.entformulaType), fetchValueSet(valueSetUrls.entformulaAdditive), fetchValueSet(valueSetUrls.enteralRoute), ]); setRequestStatus(requestStatusValueSet); setRequestIntent(requestIntentValueSet); setEncounterDiet(encounterDietValueSet); setDietType(dietTypeValueSet); setNutrientCode(nutrientCodeValueSet); setTextureCode(textureCodeValueSet); setModifiedFoodtype(modifiedFoodtypeValueSet); setConsistencyType(consistencyTypeValueSet); setSupplementType(supplementTypeValueSet); setEntformulaType(entformulaTypeValueSet); setEntformulaAdditive(entformulaAdditiveValueSet); setEnteralRoute(enteralRouteValueSet); } catch (err) { console.error('Error loading value sets:', err); } finally { setLoading(false); } }; loadValueSets(); }, [fetchValueSet, valueSetUrls]); const addOralDietNutrient = () => { oralDietNutrientFieldArray.append({ modifier: null, amount: null }); }; const removeOralDietNutrient = (index: number) => { oralDietNutrientFieldArray.remove(index); }; const addOralDietTexture = () => { oralDietTextureFieldArray.append({ modifier: null, foodType: null }); }; const removeOralDietTexture = (index: number) => { oralDietTextureFieldArray.remove(index); }; const addOralDietSchedule = () => { oralDietScheduleFieldArray.append({}); }; const removeOralDietSchedule = (index: number) => { oralDietScheduleFieldArray.remove(index); }; const addSupplement = () => { supplementFieldArray.append({ type: null, productName: '', schedule: [], quantity: null, instruction: '' }); }; const removeSupplement = (index: number) => { supplementFieldArray.remove(index); }; const addEnteralFormulaAdministration = () => { enteralFormulaAdministrationFieldArray.append({ schedule: null, quantity: null, rate: null }); }; const removeEnteralFormulaAdministration = (index: number) => { enteralFormulaAdministrationFieldArray.remove(index); }; return ( {elevated && } Details {/* status */} {/* intent */} {/* dateTime */} ( <> {fieldState.error && ( Nutrition order date is required )} )}/> {/* allergyIntolerance */} {/* encounter */} {(tab) => { // oralDiet if (tab.name === 'oralDiet') { return (
{/* oralDiet.type */} Nutrient {oralDietNutrientFieldArray.fields.length === 0 && ( <> {!isPatient && ( )} No nutrients added yet. )} {oralDietNutrientFieldArray.fields.map((field, index) => (

Nutrient {index + 1}

{!isPatient && ( )}
{/* oralDiet.nutrient.modifier */} {/* oralDiet.nutrient.amount */}
))} {!isPatient && oralDietNutrientFieldArray.fields.length > 0 && ( )} Texture {oralDietTextureFieldArray.fields.length === 0 && ( <> {!isPatient && ( )} No textures added yet. )} {oralDietTextureFieldArray.fields.map((field, index) => (

Texture {index + 1}

{!isPatient && ( )}
{/* oralDiet.texture.modifier */} {/* oralDiet.texture.foodType */}
))} {!isPatient && oralDietTextureFieldArray.fields.length > 0 && ( )} {/* oralDiet.fluidConsistencyType */} {/* oralDiet.instruction */} ( )}/> Schedule {oralDietScheduleFieldArray.fields.length === 0 && ( <> {!isPatient && ( )} No schedules added yet. )} {oralDietScheduleFieldArray.fields.map((field, index) => (

Schedule {index + 1}

{/* The WordPress label here read "Remove texture" — a copy-paste mislabel; this removes a SCHEDULE. Corrected during the conversion, because `label` becomes the aria-label and the wrong word would otherwise reach screen readers. */} {!isPatient && ( )}
{/* oralDiet.schedule */}
))} {!isPatient && oralDietScheduleFieldArray.fields.length > 0 && ( )}
); } // supplement if (tab.name === 'supplement') { return (
{supplementFieldArray.fields.length === 0 && ( <> {!isPatient && ( )} No supplements added yet. )} {supplementFieldArray.fields.map((field, index) => (

Supplement {index + 1}

{!isPatient && ( )}
{/* supplement.type */} {/* supplement.productName */} ( )}/> {/* supplement.quantity */} {/* supplement.instruction */} ( )}/> {/* supplement.schedule */} Schedule
))} {!isPatient && supplementFieldArray.fields.length > 0 && ( )}
); } // enteralFormula if (tab.name === 'enteralFormula') { return (
{/* enteralFormula.baseFormulaType */} {/* enteralFormula.baseFormulaProductName */} ( )}/> Additives {/* enteralFormula.additiveType */} {/* enteralFormula.additiveProductName */} ( )}/> {/* enteralFormula.caloricDensity */} Administration {/* enteralFormula.routeofAdministration */} {/* enteralFormula.maxVolumeToDeliver */} Administration Instructions {/* enteralFormula.administrationInstruction */} ( )}/> Administration Details {enteralFormulaAdministrationFieldArray.fields.length === 0 && ( <> {!isPatient && ( )} No administration details added yet. )} {enteralFormulaAdministrationFieldArray.fields.map((field, index) => (

Administration {index + 1}

{!isPatient && ( )}
{/* enteralFormula.administration.schedule */} {/* enteralFormula.administration.quantity */} {/* occurrence */} {watch(`enteralFormula.administration.${index}.rate`) === 'quantity' && ( <> {/* enteralFormula.administration.rateQuantity */} )} {watch(`enteralFormula.administration.${index}.rate`) === 'ratio' && ( <> {/* enteralFormula.administration.rateRatio */} )}
))} {!isPatient && enteralFormulaAdministrationFieldArray.fields.length > 0 && ( )}
); } // preferences if (tab.name === 'preferences') { return (
{/* foodPreferenceModifier */} {/* excludeFoodModifier */}
); } // notes if (tab.name === 'notes') { return (
{/* note */}
); } }}
); }; export default FhirNutritionOrder;