@kenyaemr/esm-care-panel-app 4.1.1-pre.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +42 -0
- package/LICENSE.md +401 -0
- package/README.md +5 -0
- package/dist/150.js +1 -0
- package/dist/150.js.map +1 -0
- package/dist/24.js +2 -0
- package/dist/24.js.LICENSE.txt +19 -0
- package/dist/24.js.map +1 -0
- package/dist/561.js +1 -0
- package/dist/561.js.map +1 -0
- package/dist/574.js +1 -0
- package/dist/690.js +1 -0
- package/dist/690.js.map +1 -0
- package/dist/709.js +1 -0
- package/dist/709.js.map +1 -0
- package/dist/784.js +2 -0
- package/dist/784.js.LICENSE.txt +9 -0
- package/dist/784.js.map +1 -0
- package/dist/832.js +1 -0
- package/dist/832.js.map +1 -0
- package/dist/858.js +2 -0
- package/dist/858.js.LICENSE.txt +3 -0
- package/dist/858.js.map +1 -0
- package/dist/958.js +2 -0
- package/dist/958.js.LICENSE.txt +15 -0
- package/dist/958.js.map +1 -0
- package/dist/kenyaemr-esm-care-panel-app.js +1 -0
- package/dist/kenyaemr-esm-care-panel-app.js.buildmanifest.json +354 -0
- package/dist/kenyaemr-esm-care-panel-app.js.map +1 -0
- package/dist/kenyaemr-esm-care-panel-app.old +1 -0
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -0
- package/package.json +50 -0
- package/src/care-panel/care-panel.component.tsx +67 -0
- package/src/care-panel/care-panel.scss +50 -0
- package/src/config-schema.ts +1 -0
- package/src/declarations.d.tsx +2 -0
- package/src/hooks/useEnrollmentHistory.ts +34 -0
- package/src/hooks/usePatientSummary.ts +14 -0
- package/src/hooks/useProgramSummary.ts +14 -0
- package/src/index.ts +43 -0
- package/src/patient-summary/patient-summary.component.tsx +575 -0
- package/src/patient-summary/patient-summary.scss +83 -0
- package/src/print-layout/print.component.tsx +16 -0
- package/src/print-layout/print.scss +10 -0
- package/src/program-enrollment/program-enrollment.component.tsx +243 -0
- package/src/program-enrollment/program-enrollment.scss +75 -0
- package/src/program-summary/program-summary.component.tsx +233 -0
- package/src/program-summary/program-summary.scss +70 -0
- package/src/types/index.ts +156 -0
- package/translations/en.json +1 -0
- package/tsconfig.json +5 -0
- package/webpack.config.js +1 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
@use '@carbon/styles/scss/type';
|
|
2
|
+
@use '@carbon/styles/scss/spacing';
|
|
3
|
+
@use '@carbon/colors';
|
|
4
|
+
@import '~@openmrs/esm-styleguide/src/vars';
|
|
5
|
+
|
|
6
|
+
.bodyContainer {
|
|
7
|
+
margin: spacing.$spacing-03;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.desktopHeading {
|
|
11
|
+
h4 {
|
|
12
|
+
@include type.type-style('heading-compact-02');
|
|
13
|
+
color: $text-02;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.tabletHeading {
|
|
18
|
+
h4 {
|
|
19
|
+
@include type.type-style('heading-03');
|
|
20
|
+
color: $text-02;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.desktopHeading,
|
|
25
|
+
.tabletHeading {
|
|
26
|
+
display: flex;
|
|
27
|
+
justify-content: space-between;
|
|
28
|
+
text-transform: capitalize;
|
|
29
|
+
margin-bottom: spacing.$spacing-02;
|
|
30
|
+
margin-top: spacing.$spacing-02;
|
|
31
|
+
|
|
32
|
+
h4:after {
|
|
33
|
+
content: '';
|
|
34
|
+
display: block;
|
|
35
|
+
width: 2rem;
|
|
36
|
+
padding-top: 0.188rem;
|
|
37
|
+
border-bottom: 0.375rem solid var(--brand-03);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.heading:after {
|
|
42
|
+
content: '';
|
|
43
|
+
display: block;
|
|
44
|
+
width: 2rem;
|
|
45
|
+
padding-top: 0.188rem;
|
|
46
|
+
border-bottom: 0.375rem solid var(--brand-03);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.card {
|
|
50
|
+
background-color: $ui-02;
|
|
51
|
+
padding: spacing.$spacing-04;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.value {
|
|
55
|
+
@include type.type-style('productive-heading-03');
|
|
56
|
+
color: colors.$gray-100;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.label {
|
|
60
|
+
@include type.type-style('label-01');
|
|
61
|
+
color: $text-02;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.container {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-direction: row;
|
|
67
|
+
padding-left: 1rem;
|
|
68
|
+
flex-wrap: wrap;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.content {
|
|
72
|
+
margin-top: spacing.$spacing-05;
|
|
73
|
+
width: 30%;
|
|
74
|
+
margin-left: spacing.$spacing-03;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.btnHidden {
|
|
78
|
+
visibility: hidden;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.btnShow {
|
|
82
|
+
visibility: visible;
|
|
83
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
|
+
import styles from './print.scss';
|
|
3
|
+
import { useConfig } from '@openmrs/esm-framework';
|
|
4
|
+
|
|
5
|
+
export function PrintComponent() {
|
|
6
|
+
const componentRef = useRef(null);
|
|
7
|
+
const { logo } = useConfig();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<div className={styles.printPage}>
|
|
11
|
+
<div ref={componentRef}>{logo?.src ? <img src={logo.src} alt={logo?.alt} width={110} height={40} /> : null}</div>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default PrintComponent;
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { Tile, Button } from '@carbon/react';
|
|
4
|
+
import styles from './program-enrollment.scss';
|
|
5
|
+
import { Edit } from '@carbon/react/icons';
|
|
6
|
+
import { useLayoutType, useVisit } from '@openmrs/esm-framework';
|
|
7
|
+
import isNull from 'lodash-es/isNull';
|
|
8
|
+
import { ProgramType } from '../types';
|
|
9
|
+
|
|
10
|
+
interface ProgramEnrollmentProps {
|
|
11
|
+
patientUuid: string;
|
|
12
|
+
programName: string;
|
|
13
|
+
data: Array<any>;
|
|
14
|
+
formEntrySub: any;
|
|
15
|
+
launchPatientWorkspace: Function;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const ProgramEnrollment: React.FC<ProgramEnrollmentProps> = ({
|
|
19
|
+
patientUuid,
|
|
20
|
+
programName,
|
|
21
|
+
data,
|
|
22
|
+
formEntrySub,
|
|
23
|
+
launchPatientWorkspace,
|
|
24
|
+
}) => {
|
|
25
|
+
const { t } = useTranslation();
|
|
26
|
+
const isTablet = useLayoutType() == 'tablet';
|
|
27
|
+
const { currentVisit } = useVisit(patientUuid);
|
|
28
|
+
const handleOpenWorkspace = (formUuid, formName, encounterUuid) => {
|
|
29
|
+
const mutateForm = () => {};
|
|
30
|
+
formEntrySub.next({ formUuid, encounterUuid });
|
|
31
|
+
launchPatientWorkspace('patient-form-entry-workspace', {
|
|
32
|
+
workspaceTitle: formName,
|
|
33
|
+
mutateForm,
|
|
34
|
+
formUuid,
|
|
35
|
+
encounterUuid,
|
|
36
|
+
visit: currentVisit,
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (isNull(data)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div>
|
|
46
|
+
<section>
|
|
47
|
+
{data.map((enrollment) =>
|
|
48
|
+
enrollment.status === 'Active' && programName === enrollment.programName ? (
|
|
49
|
+
<>
|
|
50
|
+
{enrollment.programName && (
|
|
51
|
+
<div className={isTablet ? styles.tabletHeading : styles.desktopHeading}>
|
|
52
|
+
<h4 className={styles.title}>{t('currentEnrollmentDetails', 'Current enrollment details')}</h4>
|
|
53
|
+
</div>
|
|
54
|
+
)}
|
|
55
|
+
{enrollment.data.map((program) => (
|
|
56
|
+
<Tile className={styles.card}>
|
|
57
|
+
<div className={styles.btnDiscontinue}>
|
|
58
|
+
<Button
|
|
59
|
+
size="sm"
|
|
60
|
+
iconDescription={t('edit', 'Edit')}
|
|
61
|
+
onClick={() =>
|
|
62
|
+
handleOpenWorkspace(
|
|
63
|
+
program.enrollmentFormUuid,
|
|
64
|
+
program.enrollmentFormName,
|
|
65
|
+
program.enrollmentEncounterUuid,
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
kind="tertiary"
|
|
69
|
+
renderIcon={(props) => <Edit size={16} {...props} />}>
|
|
70
|
+
{t('edit', 'Edit')}{' '}
|
|
71
|
+
</Button>
|
|
72
|
+
<Button
|
|
73
|
+
size="sm"
|
|
74
|
+
kind="danger--ghost"
|
|
75
|
+
onClick={() =>
|
|
76
|
+
handleOpenWorkspace(program.discontinuationFormUuid, program.discontinuationFormName, '')
|
|
77
|
+
}>
|
|
78
|
+
{t('discontinue', 'Discontinue')}
|
|
79
|
+
</Button>
|
|
80
|
+
</div>
|
|
81
|
+
<div className={styles.labelContainer}>
|
|
82
|
+
<div className={styles.content}>
|
|
83
|
+
<p>{t('enrolled', 'Enrolled')}</p>
|
|
84
|
+
<span className={styles.value}>{program?.dateEnrolled}</span>
|
|
85
|
+
</div>
|
|
86
|
+
{program.programName === ProgramType.HIV ? (
|
|
87
|
+
<>
|
|
88
|
+
<div className={styles.content}>
|
|
89
|
+
<p>{t('whoStage', 'WHO Stage')}</p>
|
|
90
|
+
<p>
|
|
91
|
+
<span className={styles.value}>{program?.whoStage}</span>
|
|
92
|
+
</p>
|
|
93
|
+
</div>
|
|
94
|
+
<div className={styles.content}>
|
|
95
|
+
<p>{t('entryPoint', 'Entry point')}</p>
|
|
96
|
+
<p>
|
|
97
|
+
<span className={styles.value}>{program?.entryPoint}</span>
|
|
98
|
+
</p>
|
|
99
|
+
</div>
|
|
100
|
+
</>
|
|
101
|
+
) : null}
|
|
102
|
+
{program.programName === ProgramType.MCH_MOTHER ? (
|
|
103
|
+
<>
|
|
104
|
+
<div className={styles.content}>
|
|
105
|
+
<p>{t('lmp', 'LMP')} </p>
|
|
106
|
+
<span className={styles.value}>{program?.lmp ? program?.lmp : '--'}</span>
|
|
107
|
+
</div>
|
|
108
|
+
<div className={styles.content}>
|
|
109
|
+
<p>{t('edd', 'EDD')} </p>
|
|
110
|
+
<span className={styles.value}>{program?.eddLmp ? program?.eddLmp : '--'}</span>
|
|
111
|
+
</div>
|
|
112
|
+
<div className={styles.content}>
|
|
113
|
+
<p>{t('gravida', 'Gravida')} </p>
|
|
114
|
+
<span className={styles.value}>{program?.gravida ? program?.gravida : '--'}</span>
|
|
115
|
+
</div>
|
|
116
|
+
<div className={styles.content}>
|
|
117
|
+
<p>{t('parity', 'Parity')} </p>
|
|
118
|
+
<span className={styles.value}>{program?.parity ? program?.parity : '--'}</span>
|
|
119
|
+
</div>
|
|
120
|
+
<div className={styles.content}>
|
|
121
|
+
<p>{t('gestationInWeeks', 'Gestation in weeks')} </p>
|
|
122
|
+
<span className={styles.value}>
|
|
123
|
+
{program?.gestationInWeeks ? program?.gestationInWeeks : '--'}
|
|
124
|
+
</span>
|
|
125
|
+
</div>
|
|
126
|
+
</>
|
|
127
|
+
) : null}
|
|
128
|
+
{program.programName === ProgramType.MCH_CHILD ? (
|
|
129
|
+
<div className={styles.content}>
|
|
130
|
+
<p>{t('entryPoint', 'Entry point')}</p>
|
|
131
|
+
<span className={styles.value}>{program?.entryPoint ? program?.entryPoint : '--'}</span>
|
|
132
|
+
</div>
|
|
133
|
+
) : null}
|
|
134
|
+
{program.programName === ProgramType.TPT ? (
|
|
135
|
+
<div className={styles.content}>
|
|
136
|
+
<p>{t('indicationForTpt', 'Indication for TPT')} </p>
|
|
137
|
+
<span className={styles.value}>
|
|
138
|
+
{program?.tptIndication ? program?.tptIndication : '--'}
|
|
139
|
+
</span>{' '}
|
|
140
|
+
</div>
|
|
141
|
+
) : null}
|
|
142
|
+
</div>
|
|
143
|
+
</Tile>
|
|
144
|
+
))}
|
|
145
|
+
</>
|
|
146
|
+
) : enrollment.status === 'Inactive' && programName === enrollment.programName ? (
|
|
147
|
+
<>
|
|
148
|
+
{enrollment.programName && (
|
|
149
|
+
<div className={isTablet ? styles.tabletHeading : styles.desktopHeading}>
|
|
150
|
+
<h4 className={styles.title}>{t('historicEnrollment', 'Historic enrollment')}</h4>
|
|
151
|
+
</div>
|
|
152
|
+
)}
|
|
153
|
+
{enrollment.data.map((program) => (
|
|
154
|
+
<Tile className={styles.card}>
|
|
155
|
+
<div className={styles.btnDiscontinue}>
|
|
156
|
+
<Button
|
|
157
|
+
size="sm"
|
|
158
|
+
iconDescription={t('edit', 'Edit')}
|
|
159
|
+
onClick={() =>
|
|
160
|
+
handleOpenWorkspace(
|
|
161
|
+
program.discontinuationFormUuid,
|
|
162
|
+
program.discontinuationFormName,
|
|
163
|
+
program.discontinuationEncounterUuid,
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
kind="tertiary"
|
|
167
|
+
renderIcon={(props) => <Edit size={16} {...props} />}>
|
|
168
|
+
{t('edit', 'Edit')}{' '}
|
|
169
|
+
</Button>
|
|
170
|
+
<Button
|
|
171
|
+
size="sm"
|
|
172
|
+
kind="ghost"
|
|
173
|
+
onClick={() => handleOpenWorkspace(program.enrollmentFormUuid, program.enrollmentFormName, '')}>
|
|
174
|
+
{t('enroll', 'Enroll')}
|
|
175
|
+
</Button>
|
|
176
|
+
</div>
|
|
177
|
+
<div className={styles.labelContainer}>
|
|
178
|
+
<div className={styles.content}>
|
|
179
|
+
<p className={styles.label}>{t('completed', 'Completed')}</p>
|
|
180
|
+
<span className={styles.value}>{program?.dateCompleted}</span>
|
|
181
|
+
</div>
|
|
182
|
+
{program.programName === ProgramType.HIV ? (
|
|
183
|
+
<>
|
|
184
|
+
<div className={styles.content}>
|
|
185
|
+
<p>{t('whoStage', 'WHO Stage')} </p>
|
|
186
|
+
<span className={styles.value}>{program?.whoStage ? program?.whoStage : '--'} </span>
|
|
187
|
+
</div>
|
|
188
|
+
<div className={styles.content}>
|
|
189
|
+
<p>{t('entryPoint', 'Entry point')} </p>
|
|
190
|
+
<span className={styles.value}>{program?.entryPoint ? program?.entryPoint : '--'} </span>
|
|
191
|
+
</div>
|
|
192
|
+
</>
|
|
193
|
+
) : null}
|
|
194
|
+
{program.programName === ProgramType.MCH_MOTHER ? (
|
|
195
|
+
<>
|
|
196
|
+
<div className={styles.content}>
|
|
197
|
+
<p>{t('gestationInWeeks', 'Gestation in weeks')} </p>
|
|
198
|
+
<span className={styles.content}>
|
|
199
|
+
{program?.gestationInWeeks ? program?.gestationInWeeks : '--'}
|
|
200
|
+
</span>
|
|
201
|
+
</div>
|
|
202
|
+
<div className={styles.content}>
|
|
203
|
+
<p>{t('lmp', 'LMP')} </p>
|
|
204
|
+
<span className={styles.value}>{program?.lmp ? program?.lmp : '--'} </span>
|
|
205
|
+
</div>
|
|
206
|
+
<div className={styles.content}>
|
|
207
|
+
<p>{t('edd', 'EDD')} </p>
|
|
208
|
+
<span className={styles.value}>{program?.eddLmp ? program?.eddLmp : '--'} </span>
|
|
209
|
+
</div>
|
|
210
|
+
<div className={styles.content}>
|
|
211
|
+
<p>{t('gravida', 'Gravida')} </p>
|
|
212
|
+
<span className={styles.value}>{program?.gravida ? program?.gravida : '--'} </span>
|
|
213
|
+
</div>
|
|
214
|
+
<div className={styles.content}>
|
|
215
|
+
<p>{t('parity', 'Parity')} </p>
|
|
216
|
+
<span className={styles.value}>{program?.parity ? program?.parity : '--'} </span>
|
|
217
|
+
</div>
|
|
218
|
+
</>
|
|
219
|
+
) : null}
|
|
220
|
+
{program.programName === ProgramType.MCH_CHILD ? (
|
|
221
|
+
<div className={styles.content}>
|
|
222
|
+
<p>{t('entryPoint', 'Entry point')} </p>
|
|
223
|
+
<span className={styles.value}>{program?.entryPoint ? program?.entryPoint : '--'} </span>
|
|
224
|
+
</div>
|
|
225
|
+
) : null}
|
|
226
|
+
{program.programName === ProgramType.TPT ? (
|
|
227
|
+
<div className={styles.content}>
|
|
228
|
+
<p>{t('indicationForTpt', 'Indication for TPT')} </p>
|
|
229
|
+
<span className={styles.value}>{program?.tptIndication ? program?.tptIndication : '--'} </span>
|
|
230
|
+
</div>
|
|
231
|
+
) : null}
|
|
232
|
+
</div>
|
|
233
|
+
</Tile>
|
|
234
|
+
))}
|
|
235
|
+
</>
|
|
236
|
+
) : null,
|
|
237
|
+
)}
|
|
238
|
+
</section>
|
|
239
|
+
</div>
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
export default ProgramEnrollment;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
@use '@carbon/styles/scss/type';
|
|
2
|
+
@use '@carbon/styles/scss/spacing';
|
|
3
|
+
@use '@carbon/colors';
|
|
4
|
+
@import '~@openmrs/esm-styleguide/src/vars';
|
|
5
|
+
|
|
6
|
+
.desktopHeading {
|
|
7
|
+
h4 {
|
|
8
|
+
@include type.type-style('heading-compact-02');
|
|
9
|
+
color: $text-02;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.tabletHeading {
|
|
14
|
+
h4 {
|
|
15
|
+
@include type.type-style('heading-03');
|
|
16
|
+
color: $text-02;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.desktopHeading,
|
|
21
|
+
.tabletHeading {
|
|
22
|
+
text-align: left;
|
|
23
|
+
text-transform: capitalize;
|
|
24
|
+
margin-bottom: spacing.$spacing-02;
|
|
25
|
+
margin-top: spacing.$spacing-02;
|
|
26
|
+
|
|
27
|
+
h4:after {
|
|
28
|
+
content: '';
|
|
29
|
+
display: block;
|
|
30
|
+
width: 2rem;
|
|
31
|
+
padding-top: 0.188rem;
|
|
32
|
+
border-bottom: 0.375rem solid var(--brand-03);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.heading:after {
|
|
37
|
+
content: '';
|
|
38
|
+
display: block;
|
|
39
|
+
width: 2rem;
|
|
40
|
+
padding-top: 0.188rem;
|
|
41
|
+
border-bottom: 0.375rem solid var(--brand-03);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.card {
|
|
45
|
+
background-color: $ui-02;
|
|
46
|
+
margin-top: spacing.$spacing-03;
|
|
47
|
+
background-color: #f4f4f4;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.btnEdit {
|
|
51
|
+
margin-left: auto;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.btnDiscontinue {
|
|
55
|
+
display: flex;
|
|
56
|
+
justify-content: flex-end;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.labelContainer {
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: row;
|
|
62
|
+
padding-left: 1rem;
|
|
63
|
+
flex-wrap: wrap;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.value {
|
|
67
|
+
@include type.type-style('productive-heading-03');
|
|
68
|
+
color: colors.$gray-100;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.content {
|
|
72
|
+
margin-top: spacing.$spacing-05;
|
|
73
|
+
width: 30%;
|
|
74
|
+
margin-left: spacing.$spacing-03;
|
|
75
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styles from './program-summary.scss';
|
|
3
|
+
import { useProgramSummary } from '../hooks/useProgramSummary';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { useLayoutType } from '@openmrs/esm-framework';
|
|
6
|
+
import { StructuredListSkeleton } from '@carbon/react';
|
|
7
|
+
import { ProgramType } from '../types';
|
|
8
|
+
|
|
9
|
+
interface ProgramSummaryProps {
|
|
10
|
+
patientUuid: string;
|
|
11
|
+
programName: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ProgramSummary: React.FC<ProgramSummaryProps> = ({ patientUuid, programName }) => {
|
|
15
|
+
const { data, isError, isLoading } = useProgramSummary(patientUuid);
|
|
16
|
+
const { t } = useTranslation();
|
|
17
|
+
const isTablet = useLayoutType() == 'tablet';
|
|
18
|
+
|
|
19
|
+
if (isLoading) {
|
|
20
|
+
return <StructuredListSkeleton role="progressbar" />;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (isError) {
|
|
24
|
+
return <span>{t('errorProgramSummary', 'Error loading HIV summary')}</span>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (Object.keys(data)?.length === 0) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (Object.keys(data).length > 0) {
|
|
32
|
+
return (
|
|
33
|
+
<>
|
|
34
|
+
{Object.entries(data).map(([key, val]) =>
|
|
35
|
+
key == ProgramType.HIV && programName == ProgramType.HIV ? (
|
|
36
|
+
<div className={styles.card}>
|
|
37
|
+
<div className={isTablet ? styles.tabletHeading : styles.desktopHeading}>
|
|
38
|
+
<h4 className={styles.title}> {t('currentStatus', 'Current status')}</h4>
|
|
39
|
+
</div>
|
|
40
|
+
<div className={styles.container}>
|
|
41
|
+
<div className={styles.content}>
|
|
42
|
+
<p>{t('lastViralLoad', 'Last viral load')}</p>
|
|
43
|
+
<p>
|
|
44
|
+
{' '}
|
|
45
|
+
<span className={styles.value}>{data?.HIV?.ldlValue}</span>
|
|
46
|
+
{data?.HIV?.ldlDate ? <span>({data?.HIV?.ldlDate})</span> : ''}{' '}
|
|
47
|
+
</p>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div className={styles.content}>
|
|
51
|
+
<p>{t('lastCd4Count', 'Last CD4 count')}</p>
|
|
52
|
+
<p>
|
|
53
|
+
{' '}
|
|
54
|
+
<span className={styles.value}>{data?.HIV?.cd4}</span>{' '}
|
|
55
|
+
{data?.HIV?.cd4Date ? <span> ({data?.HIV?.cd4Date}) </span> : ''}
|
|
56
|
+
</p>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div className={styles.content}>
|
|
60
|
+
<p>{t('CD4Percentage', 'CD4 percentage')}</p>
|
|
61
|
+
<p>
|
|
62
|
+
{' '}
|
|
63
|
+
<span className={styles.value}>{data?.HIV?.cd4Percent}</span>{' '}
|
|
64
|
+
{data?.HIV?.cd4PercentDate ? <span>({data?.HIV?.cd4PercentDate}) </span> : ''}
|
|
65
|
+
</p>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div className={styles.content}>
|
|
69
|
+
<p>{t('lastWhoStage', 'Last WHO stage')}</p>
|
|
70
|
+
<p>
|
|
71
|
+
{' '}
|
|
72
|
+
<span className={styles.value}>
|
|
73
|
+
{' '}
|
|
74
|
+
{t('whoStage', 'WHO STAGE')} {data?.HIV?.whoStage}
|
|
75
|
+
</span>{' '}
|
|
76
|
+
{data?.HIV?.whoStageDate ? <span> ({data?.HIV?.whoStageDate}) </span> : ''}
|
|
77
|
+
</p>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<div className={styles.content}>
|
|
81
|
+
<p>{t('regimen', 'Regimen')}</p>
|
|
82
|
+
<p className={styles.value}>{data?.HIV?.lastEncDetails?.regimenShortDisplay} </p>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<div className={styles.content}>
|
|
86
|
+
<p>{t('regimenStartDate', ' Date started regimen')}</p>
|
|
87
|
+
<p className={styles.value}>{data?.HIV?.lastEncDetails?.startDate}</p>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
) : key == ProgramType.TB && programName == ProgramType.TB ? (
|
|
92
|
+
<div className={styles.card}>
|
|
93
|
+
<div className={isTablet ? styles.tabletHeading : styles.desktopHeading}>
|
|
94
|
+
<h4 className={styles.title}> {t('currentStatus', 'Current status')}</h4>
|
|
95
|
+
</div>
|
|
96
|
+
<div className={styles.container}>
|
|
97
|
+
<div className={styles.content}>
|
|
98
|
+
<p>{t('treatmentNumber:', 'Treatment number')}</p>
|
|
99
|
+
<p>
|
|
100
|
+
{' '}
|
|
101
|
+
<span className={styles.value}>{data?.TB?.tbTreatmentNumber}</span>{' '}
|
|
102
|
+
</p>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div className={styles.content}>
|
|
106
|
+
<p>{t('diseaseClassification', 'Disease classification')}</p>
|
|
107
|
+
<p>
|
|
108
|
+
{' '}
|
|
109
|
+
<span className={styles.value}>{data?.TB?.tbDiseaseClassification}</span>{' '}
|
|
110
|
+
{data?.TB?.tbDiseaseClassificationDate ? (
|
|
111
|
+
<span> ({data?.TB?.tbDiseaseClassificationDate}) </span>
|
|
112
|
+
) : (
|
|
113
|
+
''
|
|
114
|
+
)}
|
|
115
|
+
</p>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div className={styles.content}>
|
|
119
|
+
<p>{t('patientClassification', 'Patient classification')}</p>
|
|
120
|
+
<p>
|
|
121
|
+
{' '}
|
|
122
|
+
<span className={styles.value}>{data?.TB?.tbPatientClassification}</span>
|
|
123
|
+
</p>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<div className={styles.content}>
|
|
127
|
+
<p>{t('regimen', 'Regimen')}</p>
|
|
128
|
+
<p className={styles.value}>
|
|
129
|
+
{' '}
|
|
130
|
+
{data?.TB?.lastTbEncounter
|
|
131
|
+
? data?.TB?.lastTbEncounter?.regimenShortDisplay
|
|
132
|
+
: t('neverOnTbRegimen', 'Never on TB regimen')}{' '}
|
|
133
|
+
</p>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
) : key == ProgramType.MCHMOTHER && programName == ProgramType.MCHMOTHER ? (
|
|
138
|
+
<div className={styles.card}>
|
|
139
|
+
<div className={isTablet ? styles.tabletHeading : styles.desktopHeading}>
|
|
140
|
+
<h4 className={styles.title}> {t('currentStatus', 'Current status')}</h4>
|
|
141
|
+
</div>
|
|
142
|
+
<div className={styles.container}>
|
|
143
|
+
<div className={styles.content}>
|
|
144
|
+
<p>{t('hivStatus:', 'HIV status')}</p>
|
|
145
|
+
<p>
|
|
146
|
+
{' '}
|
|
147
|
+
<span className={styles.value}>{data?.mchMother?.hivStatus}</span>{' '}
|
|
148
|
+
{data?.mchMother?.hivStatusDate ? <span>({data?.mchMother?.hivStatusDate})</span> : ''}{' '}
|
|
149
|
+
</p>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<div className={styles.content}>
|
|
153
|
+
<p>{t('onART', 'On ART')}</p>
|
|
154
|
+
<p>
|
|
155
|
+
{' '}
|
|
156
|
+
<span className={styles.value}>{data?.mchMother?.onHaart}</span>{' '}
|
|
157
|
+
{data?.mchMother?.onHaartDate ? <span> ({data?.mchMother?.onHaartDate}) </span> : ''}
|
|
158
|
+
</p>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
) : key == ProgramType.MCHCHILD && programName == ProgramType.MCHCHILD ? (
|
|
163
|
+
<div className={styles.card}>
|
|
164
|
+
<div className={isTablet ? styles.tabletHeading : styles.desktopHeading}>
|
|
165
|
+
<h4 className={styles.title}> {t('currentStatus', 'Current status')}</h4>
|
|
166
|
+
</div>
|
|
167
|
+
<div className={styles.container}>
|
|
168
|
+
<div className={styles.content}>
|
|
169
|
+
<p>{t('currentProphylaxisUsed:', 'Current prophylaxis used')}</p>
|
|
170
|
+
<p>
|
|
171
|
+
{' '}
|
|
172
|
+
<span className={styles.value}>{data?.mchChild?.currentProphylaxisUsed}</span>{' '}
|
|
173
|
+
{data?.mchChild?.currentProphylaxisUsedDate ? (
|
|
174
|
+
<span>({data?.mchChild?.currentProphylaxisUsedDate})</span>
|
|
175
|
+
) : (
|
|
176
|
+
''
|
|
177
|
+
)}{' '}
|
|
178
|
+
</p>
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
<div className={styles.content}>
|
|
182
|
+
<p>{t('currentFeedingOption', 'Current feeding option')}</p>
|
|
183
|
+
<p>
|
|
184
|
+
{' '}
|
|
185
|
+
<span className={styles.value}>{data?.mchChild?.currentFeedingOption}</span>{' '}
|
|
186
|
+
{data?.mchChild?.currentFeedingOptionDate ? (
|
|
187
|
+
<span> ({data?.mchChild?.currentFeedingOptionDate}) </span>
|
|
188
|
+
) : (
|
|
189
|
+
''
|
|
190
|
+
)}
|
|
191
|
+
</p>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div className={styles.content}>
|
|
195
|
+
<p>{t('milestonesAttained', 'Milestones Attained')}</p>
|
|
196
|
+
<p>
|
|
197
|
+
{' '}
|
|
198
|
+
<span className={styles.value}>{data?.mchChild?.milestonesAttained}</span>{' '}
|
|
199
|
+
{data?.mchChild?.milestonesAttainedDate ? (
|
|
200
|
+
<span> ({data?.mchChild?.milestonesAttainedDate}) </span>
|
|
201
|
+
) : (
|
|
202
|
+
''
|
|
203
|
+
)}
|
|
204
|
+
</p>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<div className={styles.content}>
|
|
208
|
+
<p>{t('heiOutcome', 'HEI Outcome')}</p>
|
|
209
|
+
<p>
|
|
210
|
+
{' '}
|
|
211
|
+
<span className={styles.value}>{data?.mchChild?.heiOutcome}</span>{' '}
|
|
212
|
+
{data?.mchChild?.heiOutcomeDate ? <span> ({data?.mchChild?.heiOutcomeDate}) </span> : ''}
|
|
213
|
+
</p>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<div className={styles.content}>
|
|
217
|
+
<p>{t('hivStatus', 'HIV Status')}</p>
|
|
218
|
+
<p>
|
|
219
|
+
{' '}
|
|
220
|
+
<span className={styles.value}>{data?.mchChild?.hivStatus}</span>{' '}
|
|
221
|
+
{data?.mchChild?.hivStatusDate ? <span> ({data?.mchChild?.hivStatusDate}) </span> : ''}
|
|
222
|
+
</p>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
) : null,
|
|
227
|
+
)}
|
|
228
|
+
</>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export default ProgramSummary;
|