diff --git a/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx b/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx index af6c214ad..996faf7fc 100644 --- a/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx +++ b/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx @@ -3,12 +3,17 @@ import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; import { PatientStatusBannerTag } from './patient-status-tag.component'; import { usePatientHivStatus } from './patientHivStatus'; +import { usePatientOutcome } from './useInfantFinalOutcome'; import { usePatientFamilyNames } from './usePatientFamilyNames'; jest.mock('./patientHivStatus', () => ({ usePatientHivStatus: jest.fn(), })); +jest.mock('./useInfantFinalOutcome', () => ({ + usePatientOutcome: jest.fn(), +})); + jest.mock('./usePatientFamilyNames', () => ({ usePatientFamilyNames: jest.fn(), })); @@ -27,6 +32,10 @@ describe('PatientStatusBannerTag', () => { isError: false, }); + (usePatientOutcome as jest.Mock).mockReturnValue({ + patientOutcome: null, + }); + (usePatientFamilyNames as jest.Mock).mockReturnValue({ childrenNames: [], motherName: null, @@ -37,7 +46,6 @@ describe('PatientStatusBannerTag', () => { }); const { container } = render(); - expect(container.firstChild).toBeNull(); }); @@ -48,6 +56,10 @@ describe('PatientStatusBannerTag', () => { isError: false, }); + (usePatientOutcome as jest.Mock).mockReturnValue({ + patientOutcome: 'Still in Care', + }); + (usePatientFamilyNames as jest.Mock).mockReturnValue({ childrenNames: [], motherName: null, @@ -59,6 +71,7 @@ describe('PatientStatusBannerTag', () => { render(); expect(screen.getByText('HIV Positive')).toBeInTheDocument(); + expect(screen.getByText('Still in Care')).toBeInTheDocument(); }); it('should display the correct tag for HIV negative status', () => { @@ -68,6 +81,10 @@ describe('PatientStatusBannerTag', () => { isError: false, }); + (usePatientOutcome as jest.Mock).mockReturnValue({ + patientOutcome: 'Confirmed HIV negative infant (discharged from PMTCT)', + }); + (usePatientFamilyNames as jest.Mock).mockReturnValue({ childrenNames: [], motherName: null, @@ -79,6 +96,7 @@ describe('PatientStatusBannerTag', () => { render(); expect(screen.getByText('HIV Negative')).toBeInTheDocument(); + expect(screen.getByText('Confirmed HIV negative infant (discharged from PMTCT)')).toBeInTheDocument(); }); it('should display mother’s name on the Infant banner', () => { @@ -88,6 +106,10 @@ describe('PatientStatusBannerTag', () => { isError: false, }); + (usePatientOutcome as jest.Mock).mockReturnValue({ + patientOutcome: 'Still in Care', + }); + (usePatientFamilyNames as jest.Mock).mockReturnValue({ childrenNames: [], motherName: 'Jane Doe', @@ -108,6 +130,10 @@ describe('PatientStatusBannerTag', () => { isError: false, }); + (usePatientOutcome as jest.Mock).mockReturnValue({ + patientOutcome: null, + }); + (usePatientFamilyNames as jest.Mock).mockReturnValue({ childrenNames: [], motherName: null, diff --git a/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx b/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx index 049c04451..dc81fc95a 100644 --- a/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx +++ b/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx @@ -2,11 +2,26 @@ import React from 'react'; import { Tag } from '@carbon/react'; import { useTranslation } from 'react-i18next'; import { usePatientHivStatus } from './patientHivStatus'; +import { usePatientOutcome } from './useInfantFinalOutcome'; import { usePatientFamilyNames } from './usePatientFamilyNames'; export function PatientStatusBannerTag({ patientUuid }) { const { t } = useTranslation(); + const { hivStatus } = usePatientHivStatus(patientUuid); + + const { patientOutcome } = usePatientOutcome(patientUuid); + + const greenOutcomes = ['Still in Care', 'Confirmed HIV negative infant (discharged from PMTCT)', 'Missing']; + const redOutcomes = ['Confirmed HIV Positive', 'Lost to Follow Up', 'Dead', 'Transferred Out']; + + let outcomeTagColor = ''; + if (greenOutcomes.includes(patientOutcome)) { + outcomeTagColor = 'green'; + } else if (redOutcomes.includes(patientOutcome)) { + outcomeTagColor = 'red'; + } + const { childrenNames, motherName, patientAge, patientGender, isLoading, isError } = usePatientFamilyNames(patientUuid); @@ -17,22 +32,18 @@ export function PatientStatusBannerTag({ patientUuid }) { if (isError) { return
Error fetching family information
; } - return ( <> - {/* HIV Status Display */} {hivStatus === 'positive' && {t('hivPositive', 'HIV Positive')}} {hivStatus === 'negative' && {t('hivNegative', 'HIV Negative')}} - {/* Mother Name Display (if patient is under 10) */} + {patientOutcome && outcomeTagColor && {patientOutcome}} + {patientAge !== null && patientAge <= 14 && motherName && Mother: {motherName}} - {/* Children Names Display (if patient is female and over 10) */} {patientAge !== null && patientAge > 14 && patientGender === 'F' && childrenNames.length > 0 && ( Children: {childrenNames.join(' || ')} )} ); } - -export default PatientStatusBannerTag; diff --git a/packages/esm-commons-lib/src/components/banner-tags/useInfantFinalOutcome.ts b/packages/esm-commons-lib/src/components/banner-tags/useInfantFinalOutcome.ts new file mode 100644 index 000000000..f459572d2 --- /dev/null +++ b/packages/esm-commons-lib/src/components/banner-tags/useInfantFinalOutcome.ts @@ -0,0 +1,36 @@ +import { useState, useEffect } from 'react'; +import { openmrsFetch, useConfig } from '@openmrs/esm-framework'; + +export const usePatientOutcome = (patientUuid: string) => { + const [patientOutcome, setPatientOutcome] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const [isError, setIsError] = useState(false); + const config = useConfig(); + + useEffect(() => { + const fetchPatientOutcome = async () => { + try { + const response = await fetch( + `/openmrs/ws/rest/v1/obs?patient=${patientUuid}&concept=${config.obsConcepts.outcomeStatus}&v=full`, + ); + const data = await response.json(); + + if (data.results.length > 0) { + const outcome = data.results[0].value; + setPatientOutcome(outcome.display ?? null); + } else { + setPatientOutcome(null); + } + } catch (error) { + console.error('Failed to fetch patient outcome:', error); + setIsError(true); + } finally { + setIsLoading(false); + } + }; + + fetchPatientOutcome(); + }, [patientUuid, config.obsConcepts.outcomeStatus]); + + return { patientOutcome, isLoading, isError }; +};