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 { 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 { useFormContext, Controller, useFieldArray } from 'react-hook-form'; import { IValueSet, useAuthServiceContext, useValueSetServiceContext } from '../../services'; import { FhirAnnotation, FhirCode, FhirCodeableConcept, FhirPeriod, FhirQuantity, FhirRatio, FhirReference, FhirReferenceCollection, FhirValueSetSearch, TypeSelector } from '../../components'; import { useFhirConditions, useFhirDevices, useFhirEncounters, useFhirEpisodesOfCare, useFhirMedicationAdministrationBroadcast, useFhirMedicationAdministrations, useFhirMedicationRequests, useFhirObservations, useFhirPractitioners, useFhirProcedures, useFhirRelatedPersons } from '../../hooks'; import { FhirResource } from 'fhir/r4'; import { PlusCircle, Trash2 } from 'lucide-react'; interface FhirMedicationAdministrationProps { elevated?: boolean; disabled?: boolean; enableInlineActions?: boolean; } const PerformerActorReferences: React.FC<{ index: number; disabled: boolean; readonly: boolean; enableInlineActions: boolean; }> = ({ index, disabled, readonly = false, enableInlineActions = true }) => { const { control } = useFormContext(); const itemReferenceFieldArray = useFieldArray({ control, name: `performer.${index}.actor` }); const { practitionersList } = useFhirPractitioners(); const { devicesList } = useFhirDevices(); const { relatedPersonsList } = useFhirRelatedPersons(); return ( { switch (referenceType) { case 'Practitioner': return practitionersList.map(p => p.practitioner); case 'RelatedPerson': return relatedPersonsList; case 'Device': return devicesList; default: return []; } }} required={true} disabled={disabled} readonly={readonly} multiple={false} enableInlineActions={enableInlineActions}/> ); }; export const FhirMedicationAdministration: 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 [medicationAdminStatus, setMedicationAdminStatus] = useState([]); const [reasonMedicationNotGivenCodes, setReasonMedicationNotGivenCodes] = useState([]); const [medicationAdminCategory, setMedicationAdminCategory] = useState([]); const [medAdminPerformFunction, setMedAdminPerformFunction] = useState([]); const [reasonMedicationGivenCodes, setReasonMedicationGivenCodes] = useState([]); const [administrationMethodCodes, setAdministrationMethodCodes] = useState([]); const isPatient = [USER_ROLES.PATIENT, USER_ROLES.RELATED_PERSON].includes(userRole as string); const spacerMargin = '24px'; useFhirMedicationAdministrationBroadcast(); const { medicationAdministrationsList } = useFhirMedicationAdministrations(); const { encountersList } = useFhirEncounters(); const { episodesOfCareList } = useFhirEpisodesOfCare(); const { conditionsList } = useFhirConditions(); const { devicesList } = useFhirDevices(); const { proceduresList } = useFhirProcedures(); const { observationsList } = useFhirObservations(); const { medicationRequestsList } = useFhirMedicationRequests(); const medicationType = watch('medicationType'); const effectiveType = watch('effectiveType'); const rateType = watch('dosage.rateType'); const contextFieldArray = useFieldArray({ control, name: 'context' }); const reasonReferenceFieldArray = useFieldArray({ control, name: 'reasonReference' }); const performerFieldArray = useFieldArray({ control, name: 'performer' }); const partOfFieldArray = useFieldArray({ control, name: 'partOf' }); useEffect(() => { const loadValueSets = async () => { setLoading(true); try { const [ medicationAdminStatusValueSet, reasonMedicationNotGivenCodesValueSet, medicationAdminCategoryValueSet, medAdminPerformFunctionValueSet, reasonMedicationGivenCodesValueSet, administrationMethodCodesValueSet ] = await Promise.all([ fetchValueSet(valueSetUrls.medicationAdminStatus), fetchValueSet(valueSetUrls.reasonMedicationNotGivenCodes), fetchValueSet(valueSetUrls.medicationAdminCategory), fetchValueSet(valueSetUrls.medAdminPerformFunction), fetchValueSet(valueSetUrls.reasonMedicationGivenCodes), fetchValueSet(valueSetUrls.administrationMethodCodes) ]); setMedicationAdminStatus(medicationAdminStatusValueSet); setReasonMedicationNotGivenCodes(reasonMedicationNotGivenCodesValueSet); setMedicationAdminCategory(medicationAdminCategoryValueSet); setMedAdminPerformFunction(medAdminPerformFunctionValueSet); setReasonMedicationGivenCodes(reasonMedicationGivenCodesValueSet); setAdministrationMethodCodes(administrationMethodCodesValueSet); } catch (err) { console.error('Error loading value sets:', err); } finally { setLoading(false); } }; loadValueSets(); }, [fetchValueSet, valueSetUrls]); const addPerformer = () => { performerFieldArray.append({ function: null, actor: null }); }; const removePerformer = (index: number) => { performerFieldArray.remove(index); }; return ( {elevated && } Details {/* medicationCodeableConcept */} {medicationType === 'codeableConcept' && ( <> )} {medicationType === 'reference' && ( <> {/* medicationReference */} )} {/* status */} {/* statusReason */} {/* category */} {/* effectiveType */} {effectiveType === 'dateTime' && ( <> {/* effectiveDateTime */} ( <> {fieldState.error && ( Date is required )} )}/> )} {effectiveType === 'period' && ( <> {/* effectivePeriod */} )} {/* request */} {/* device */} {/* context */} { switch (referenceType) { case 'Encounter': return encountersList; case 'EpisodeOfCare': return episodesOfCareList; default: return []; } }} required={false} disabled={disabled} readonly={isPatient} multiple={false} enableInlineActions={enableInlineActions}/> {(tab) => { // dosage if (tab.name === 'dosage') { return (
{/* dosage.rateType */} {rateType === 'ratio' && ( <> {/* dosage.rateRatio */} )} {rateType === 'quantity' && ( <> {/* dosage.rateQuantity */} )} {/* dosage.text */} ( )}/> {/* dosage.site */} {/* dosage.route */} {/* dosage.method */} {/* dosage.dose */}
); } // reasons if (tab.name === 'reasons') { return (
{/* reasonMedicationGivenCodes */} {/* reasonReference */} { switch (referenceType) { case 'Condition': return conditionsList; case 'Observation': return observationsList; default: return []; } }} required={false} multiple={true} disabled={disabled} readonly={isPatient} enableInlineActions={enableInlineActions}/>
); } // performers if (tab.name === 'performers') { return (
{performerFieldArray.fields.length === 0 && ( <> {!isPatient && ( )} No performers added yet. )} {performerFieldArray.fields.map((field, index) => (

Performer {index + 1}

{!isPatient && ( )}
{/* performerType */} {/* performer */}
))} {!isPatient && performerFieldArray.fields.length > 0 && ( )}
); } // partOf if (tab.name === 'partOf') { return (
{/* partOf */} { switch (referenceType) { case 'MedicationAdministration': return medicationAdministrationsList; case 'Procedure': return proceduresList; default: return []; } }} required={false} disabled={disabled} readonly={isPatient} enableInlineActions={enableInlineActions}/>
); } // notes if (tab.name === 'notes') { return (
{/* note */}
); } }}
); }; export default FhirMedicationAdministration;