Skip to content

Commit

Permalink
OHRI-2315: To display HIV Status badge appear on the Infant banner (#…
Browse files Browse the repository at this point in the history
…1931)

* To display HIV Status badge appear on the Infant banner

* ensure only the required outcome status display

* fix failling test

* remove age restriction on displaying the MOther/infant name on the banner
  • Loading branch information
lucyjemutai authored Oct 23, 2024
1 parent ecc1a7f commit 527b2a9
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}));
Expand All @@ -27,6 +32,10 @@ describe('PatientStatusBannerTag', () => {
isError: false,
});

(usePatientOutcome as jest.Mock).mockReturnValue({
patientOutcome: null,
});

(usePatientFamilyNames as jest.Mock).mockReturnValue({
childrenNames: [],
motherName: null,
Expand All @@ -37,7 +46,6 @@ describe('PatientStatusBannerTag', () => {
});

const { container } = render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);

expect(container.firstChild).toBeNull();
});

Expand All @@ -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,
Expand All @@ -59,6 +71,7 @@ describe('PatientStatusBannerTag', () => {

render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
expect(screen.getByText('HIV Positive')).toBeInTheDocument();
expect(screen.getByText('Still in Care')).toBeInTheDocument();
});

it('should display the correct tag for HIV negative status', () => {
Expand All @@ -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,
Expand All @@ -79,6 +96,7 @@ describe('PatientStatusBannerTag', () => {

render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
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', () => {
Expand All @@ -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',
Expand All @@ -108,6 +130,10 @@ describe('PatientStatusBannerTag', () => {
isError: false,
});

(usePatientOutcome as jest.Mock).mockReturnValue({
patientOutcome: null,
});

(usePatientFamilyNames as jest.Mock).mockReturnValue({
childrenNames: [],
motherName: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -20,19 +34,16 @@ export function PatientStatusBannerTag({ patientUuid }) {

return (
<>
{/* HIV Status Display */}
{hivStatus === 'positive' && <Tag type="red">{t('hivPositive', 'HIV Positive')}</Tag>}
{hivStatus === 'negative' && <Tag type="green">{t('hivNegative', 'HIV Negative')}</Tag>}

{/* Mother Name Display (if patient is under 10) */}
{patientAge !== null && patientAge <= 14 && motherName && <Tag type="purple">Mother: {motherName}</Tag>}
{patientOutcome && outcomeTagColor && <Tag type={outcomeTagColor}>{patientOutcome}</Tag>}

{/* Children Names Display (if patient is female and over 10) */}
{patientAge !== null && patientAge > 14 && patientGender === 'F' && childrenNames.length > 0 && (
{motherName && <Tag type="purple">Mother: {motherName}</Tag>}

{patientGender === 'F' && childrenNames.length > 0 && (
<Tag type="purple">Children: {childrenNames.join(' || ')}</Tag>
)}
</>
);
}

export default PatientStatusBannerTag;
Original file line number Diff line number Diff line change
@@ -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<string | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isError, setIsError] = useState<boolean>(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 };
};
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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) {
Expand Down

0 comments on commit 527b2a9

Please sign in to comment.