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 { useFormContext, Controller, useFieldArray } from 'react-hook-form'; import { IValueSet, useAuthServiceContext, useValueSetServiceContext } from '../../services'; import { FhirAnnotation, FhirCode, FhirCodeableConcept, FhirPeriod, FhirQuantity, FhirReference, FhirReferenceCollection, FhirTiming, FhirValueSetSearch, TypeSelector } from '../../components'; import { useFhirAppointments, useFhirCarePlanBroadcast, useFhirCarePlans, useFhirCareTeams, useFhirConditions, useFhirDeviceRequests, useFhirDevices, useFhirEncounters, useFhirGoals, useFhirHealthcareServices, useFhirLocations, useFhirMedicationRequests, useFhirNutritionOrders, useFhirObservations, useFhirPractitioners, useFhirRelatedPersons, useFhirVisionPrescriptions } from '../../hooks'; import { FhirResource } from 'fhir/r4'; import { PlusCircle, Trash2 } from 'lucide-react'; // - WordPress's ToggleControl, swapped for the ui/* adapter. Same props, same JSX; // only `__nextHasNoMarginBottom` is dropped, which means nothing outside WordPress. import { ToggleControl } from '../ui/toggle-control'; interface FhirCarePlanProps { elevated?: boolean; disabled?: boolean; enableInlineActions?: boolean; } const ActivityReference: React.FC<{ index: number; disabled: boolean; readonly: boolean; enableInlineActions: boolean; }> = ({ index, disabled, readonly = false, enableInlineActions = true }) => { const { control } = useFormContext(); const itemReferenceFieldArray = useFieldArray({ control, name: `activity.${index}.reference` }); const { appointmentsList } = useFhirAppointments(); const { deviceRequestsList } = useFhirDeviceRequests(); const { medicationRequestsList } = useFhirMedicationRequests(); const { nutritionOrdersList } = useFhirNutritionOrders(); const { visionPrescriptionsList } = useFhirVisionPrescriptions(); return ( { switch (referenceType) { case 'Appointment': return appointmentsList; case 'DeviceRequest': return deviceRequestsList; case 'MedicationRequest': return medicationRequestsList; case 'NutritionOrder': return nutritionOrdersList; case 'VisionPrescription': return visionPrescriptionsList; default: return []; } }} required={true} disabled={disabled} readonly={readonly} multiple={false} enableInlineActions={enableInlineActions}/> ); }; const ActivityDetailReasonReferences: React.FC<{ index: number; disabled: boolean; readonly: boolean; enableInlineActions: boolean; }> = ({ index, disabled, readonly = false, enableInlineActions = true }) => { const { control } = useFormContext(); const itemReferenceFieldArray = useFieldArray({ control, name: `activity.${index}.detail.reasonReference` }); const { conditionsList } = useFhirConditions(); const { observationsList } = useFhirObservations(); return ( { switch (referenceType) { case 'Condition': return conditionsList; case 'Observation': return observationsList; default: return []; } }} required={false} disabled={disabled} readonly={readonly} enableInlineActions={enableInlineActions}/> ); }; const ActivityDetailPerformers: React.FC<{ index: number; disabled: boolean; readonly: boolean; enableInlineActions: boolean; }> = ({ index, disabled, readonly = false, enableInlineActions = true }) => { const { control } = useFormContext(); const itemReferenceFieldArray = useFieldArray({ control, name: `activity.${index}.detail.performer` }); const { practitionersList } = useFhirPractitioners(); const { relatedPersonsList } = useFhirRelatedPersons(); const { careTeamsList } = useFhirCareTeams(); const { healthcareServicesList } = useFhirHealthcareServices(); const { devicesList } = useFhirDevices(); return ( { switch (referenceType) { case 'Practitioner': return practitionersList.map(p => p.practitioner); case 'RelatedPerson': return relatedPersonsList; case 'CareTeam': return careTeamsList; case 'HealthcareService': return healthcareServicesList; case 'Device': return devicesList; default: return []; } }} required={false} disabled={disabled} readonly={readonly} enableInlineActions={enableInlineActions}/> ); }; export const FhirCarePlan: 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 [carePlanIntent, setCarePlanIntent] = useState([]); const [carePlanCategory, setCarePlanCategory] = useState([]); const [carePlanActivityOutcome, setCarePlanActivityOutcome] = useState([]); const [carePlanActivityKind, setCarePlanActivityKind] = useState([]); const [carePlanActivityStatus, setCarePlanActivityStatus] = useState([]); const isPatient = [USER_ROLES.PATIENT, USER_ROLES.RELATED_PERSON].includes(userRole as string); const spacerMargin = '24px'; useFhirCarePlanBroadcast(); const { carePlansList} = useFhirCarePlans(); const { locationsList } = useFhirLocations(); const { encountersList } = useFhirEncounters(); const { conditionsList } = useFhirConditions(); const { goalsList } = useFhirGoals(); const activityFieldArray = useFieldArray({ control, name: 'activity' }); useEffect(() => { const loadValueSets = async () => { setLoading(true); try { const [ requestStatusValueSet, carePlanIntentValueSet, carePlanCategoryValueSet, carePlanActivityOutcomeValueSet, carePlanActivityKindValueSet, carePlanActivityStatusValueSet, ] = await Promise.all([ fetchValueSet(valueSetUrls.requestStatus), fetchValueSet(valueSetUrls.carePlanIntent), fetchValueSet(valueSetUrls.carePlanCategory), fetchValueSet(valueSetUrls.carePlanActivityOutcome), fetchValueSet(valueSetUrls.carePlanActivityKind), fetchValueSet(valueSetUrls.carePlanActivityStatus), ]); setRequestStatus(requestStatusValueSet); setCarePlanIntent(carePlanIntentValueSet); setCarePlanCategory(carePlanCategoryValueSet); setCarePlanActivityOutcome(carePlanActivityOutcomeValueSet); setCarePlanActivityKind(carePlanActivityKindValueSet); setCarePlanActivityStatus(carePlanActivityStatusValueSet); } catch (err) { console.error('Error loading value sets:', err); } finally { setLoading(false); } }; loadValueSets(); }, [fetchValueSet, valueSetUrls]); const addActivity = () => { activityFieldArray.append({ outcomeCodeableConcept: [], outcomeReference: [], progress: [], reference: null, detail: { status: '', kind: '', code: null, reasonCode: [], reasonReference: [], goal: [], statusReason: null, doNotPerform: false, scheduledString: '', scheduledTiming: {}, location: null, performer: [], productCodeableConcept: null, productReference: null, dailyAmount: null, quantity: null, description: '' } }); }; const removeActivity = (index: number) => { activityFieldArray.remove(index); }; return ( {elevated && } Details {/* title */} ( )}/> {/* basedOn */} {/* replaces */} {/* partOf */} {/* status */} {/* intent */} {/* description */} ( )}/> {/* category */} {/* created */} ( )}/> {/* period */} {/* addresses */} {/* goal */} {/* encounter */} {(tab) => { // activities if (tab.name === 'activities') { return (
{activityFieldArray.fields.length === 0 && ( <> Activities {!isPatient && ( )} No activities added yet. )} {activityFieldArray.fields.map((field, index) => (

Activity {index + 1}

{!isPatient && ( )}
{/* activity.outcomeCodeableConcept */} {/* activity.reference */} {/**/} {/**/} {/* activity.progress */} Activity Detail {/* detail.kind */} {/* detail.status */} {/* detail.statusReason */} {/**/} {/**/} {/* detail.code */} {/* detail.doNotPerform */} ( )}/> {/* detail.productCodeableConcept */} {/* detail.reasonCode */} {/* reasonReference */} {/* detail.dailyAmount */} {/* detail.quantity */} {/* detail.description */} ( )}/> {/* detail.scheduled */} {watch(`activity.${index}.detail.scheduled`) === 'timing' && ( <> {/* detail.scheduledTiming */} )} {watch(`activity.${index}.detail.scheduled`) === 'period' && ( <> {/* detail.scheduledPeriod */} )} {/* detail.goal */} {/* detail.location */}
))} {!isPatient && activityFieldArray.fields.length > 0 && ( )}
); } // notes if (tab.name === 'notes') { return (
{/* note */}
); } }}
); }; export default FhirCarePlan;