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..ed87b20c7 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: '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('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..b47f84d2f 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,13 +2,27 @@ 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 { childrenNames, motherName, patientAge, patientGender, isLoading, isError } =
- usePatientFamilyNames(patientUuid);
+
+ const { patientOutcome } = usePatientOutcome(patientUuid);
+
+ const greenOutcomes = ['Still in Care', 'HIV negative infant discharged from PMTCT'];
+ 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, patientGender, isLoading, isError } = usePatientFamilyNames(patientUuid);
if (isLoading) {
return null;
@@ -20,19 +34,16 @@ export function PatientStatusBannerTag({ patientUuid }) {
return (
<>
- {/* HIV Status Display */}
{hivStatus === 'positive' && {t('hivPositive', 'HIV Positive')}}
{hivStatus === 'negative' && {t('hivNegative', 'HIV Negative')}}
- {/* Mother Name Display (if patient is under 10) */}
- {patientAge !== null && patientAge <= 14 && motherName && Mother: {motherName}}
+ {patientOutcome && outcomeTagColor && {patientOutcome}}
- {/* Children Names Display (if patient is female and over 10) */}
- {patientAge !== null && patientAge > 14 && patientGender === 'F' && childrenNames.length > 0 && (
+ {motherName && Mother: {motherName}}
+
+ {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 };
+};
diff --git a/packages/esm-commons-lib/src/components/banner-tags/usePatientFamilyNames.ts b/packages/esm-commons-lib/src/components/banner-tags/usePatientFamilyNames.ts
index dcd04e330..2a1e79835 100644
--- a/packages/esm-commons-lib/src/components/banner-tags/usePatientFamilyNames.ts
+++ b/packages/esm-commons-lib/src/components/banner-tags/usePatientFamilyNames.ts
@@ -11,7 +11,6 @@ export const usePatientFamilyNames = (patientUuid: string) => {
const fetchFamilyData = useCallback(async () => {
try {
- // Fetch patient demographics (age and gender)
const response = await fetch(`/openmrs/ws/rest/v1/patient/${patientUuid}?v=full`);
const patient = await response.json();
setPatientAge(patient.person.age);
@@ -36,11 +35,12 @@ export const usePatientFamilyNames = (patientUuid: string) => {
const motherRelationship = relationships.find(
(relationship) =>
- relationship.relationshipType?.displayAIsToB === 'Mother' ||
- relationship.relationshipType?.displayBIsToA === 'Child',
+ (relationship.relationshipType?.displayAIsToB === 'Mother' ||
+ relationship.relationshipType?.displayBIsToA === 'Child') &&
+ relationship.personA?.uuid !== patientUuid,
);
- setMotherName(motherRelationship?.personA?.display || 'Mother not found');
+ setMotherName(motherRelationship?.personA?.display || null);
setIsLoading(false);
} catch (error) {