@ampath/esm-reports-app 1.0.0-next.4 → 1.0.0-next.41
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/dist/110.js +1 -0
- package/dist/110.js.map +1 -0
- package/dist/{260.js → 205.js} +1 -1
- package/dist/{260.js.map → 205.js.map} +1 -1
- package/dist/812.js +1 -1
- package/dist/812.js.map +1 -1
- package/dist/822.js +2 -0
- package/dist/822.js.map +1 -0
- package/dist/ampath-esm-reports-app.js +1 -1
- package/dist/ampath-esm-reports-app.js.buildmanifest.json +95 -74
- package/dist/ampath-esm-reports-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/common/report-filters/report-filters.component.tsx +68 -7
- package/src/common/report-filters/report-filters.scss +42 -0
- package/src/dashboard/reports-dasboard.tsx +21 -0
- package/src/reports/datatable-wrapper/datatable-wrapper.component.tsx +54 -0
- package/src/reports/moh-240/moh-240-header.component.tsx +61 -0
- package/src/reports/moh-240/moh-240.component.tsx +93 -0
- package/src/reports/moh-240/moh-240.scss +11 -0
- package/src/reports/moh-240/sub-reports/moh-240-register.component.tsx +75 -0
- package/src/reports/moh-240/sub-reports/page-summary.component.tsx +98 -0
- package/src/reports/moh-505/moh-505-header.component.tsx +62 -0
- package/src/reports/moh-505/moh-505.component.tsx +440 -0
- package/src/reports/moh-505/moh-505.scss +3 -0
- package/src/reports/moh-705B/moh-204b-register.component.tsx +236 -0
- package/src/reports/moh-705B/moh-705b.component.tsx +524 -0
- package/src/reports/moh-705B/moh-705b.scss +44 -0
- package/src/reports/moh-705a/moh-705a.component.tsx +528 -0
- package/src/reports/moh-705a/moh-705a.scss +45 -0
- package/src/reports/moh-705a/registers/moh-204a-register.component.tsx +321 -0
- package/src/reports/moh-705a/type.ts +6 -0
- package/src/reports/moh-706/moh-706-header.component.tsx +61 -0
- package/src/reports/moh-706/moh-706.component.tsx +117 -0
- package/src/reports/moh-706/moh-706.scss +30 -0
- package/src/reports/moh-706/sub-reports/bacteriology/bacteriology.component.tsx +124 -0
- package/src/reports/moh-706/sub-reports/blood-chemistry/blood-chemistry.component.tsx +318 -0
- package/src/reports/moh-706/sub-reports/drug-susceptibility-testing/drug-susceptibility-testing.component.tsx +137 -0
- package/src/reports/moh-706/sub-reports/haematology/haematology.component.tsx +179 -0
- package/src/reports/moh-706/sub-reports/histology-and-cytology/histology-and-cytology.component.tsx +88 -0
- package/src/reports/moh-706/sub-reports/parasitology/parasitology.component.tsx +121 -0
- package/src/reports/moh-706/sub-reports/serology/serology.component.tsx +47 -0
- package/src/reports/moh-706/sub-reports/specimen-referral-to-higher-levels/specimen-referral-to-higher-levels.component.tsx +39 -0
- package/src/reports/moh-706/sub-reports/urine-analysis/urine-analysis.component.tsx +108 -0
- package/src/reports/moh-710/moh-710.component.tsx +211 -79
- package/src/reports/moh-710/moh-710.scss +5 -1
- package/src/reports/moh-710/registers/moh-511-710-register.component.tsx +263 -0
- package/src/reports/moh-710/registers/type.ts +31 -0
- package/src/reports/moh-711/moh-711.component.tsx +109 -1234
- package/src/reports/moh-711/moh711.scss +92 -8
- package/src/reports/moh-711/registers/moh-333-register.component.tsx +639 -0
- package/src/reports/moh-711/registers/moh-405-register.component.tsx +521 -0
- package/src/reports/moh-711/registers/moh-406-register.component.tsx +533 -0
- package/src/reports/moh-711/registers/moh-510-register.component.tsx +61 -0
- package/src/reports/moh-711/registers/moh-511-register.component.tsx +271 -0
- package/src/reports/moh-711/registers/type.ts +192 -0
- package/src/reports/moh-711/sections/anc.component.tsx +159 -0
- package/src/reports/moh-711/sections/cervical-cancer.component.tsx +148 -0
- package/src/reports/moh-711/sections/chanis.component.tsx +367 -0
- package/src/reports/moh-711/sections/family-planning.component.tsx +221 -0
- package/src/reports/moh-711/sections/gbv.component.tsx +115 -0
- package/src/reports/moh-711/sections/maternity.component.tsx +326 -0
- package/src/reports/moh-711/sections/medical-social-work.component.tsx +83 -0
- package/src/reports/moh-711/sections/other.component.tsx +47 -0
- package/src/reports/moh-711/sections/physiotherapy.component.tsx +61 -0
- package/src/reports/moh-711/sections/pnc.component.tsx +125 -0
- package/src/reports/moh-711/sections/post-abortion.component.tsx +42 -0
- package/src/reports/moh-711/sections/rehabilitation.component.tsx +57 -0
- package/src/reports/moh-711/sections/report-compiled-by.component.tsx +42 -0
- package/src/reports/moh-711/sections/tb-screening.component.tsx +57 -0
- package/src/reports/moh-717/moh-717.component.tsx +120 -946
- package/src/reports/moh-717/moh717.scss +138 -3
- package/src/reports/moh-717/registers/nutrition-register.component.tsx +48 -0
- package/src/reports/moh-717/sections/finance.component.tsx +42 -0
- package/src/reports/moh-717/sections/inpatient.component.tsx +374 -0
- package/src/reports/moh-717/sections/maternity.component.tsx +126 -0
- package/src/reports/moh-717/sections/medical-records.component.tsx +35 -0
- package/src/reports/moh-717/sections/mortuary.component.tsx +43 -0
- package/src/reports/moh-717/sections/operations.component.tsx +53 -0
- package/src/reports/moh-717/sections/orthopaedic-trauma.component.tsx +98 -0
- package/src/reports/moh-717/sections/outpatient.component.tsx +597 -0
- package/src/reports/moh-717/sections/pharmacy.component.tsx +43 -0
- package/src/reports/moh-717/sections/preparedby.component.tsx +47 -0
- package/src/reports/moh-717/sections/special-services.component.tsx +114 -0
- package/src/reports/moh-731/moh-731.component.tsx +181 -0
- package/src/reports/moh-731/moh-731.scss +118 -0
- package/src/reports/moh-731/registers/moh-366.component.tsx +478 -0
- package/src/reports/moh-731/registers/moh-366.scss +45 -0
- package/src/reports/moh-731/registers/prep-register.component.tsx +292 -0
- package/src/reports/moh-731/registers/prep-registers.scss +45 -0
- package/src/reports/moh-731/sections/hiv-and-tb-treatment.component.tsx +932 -0
- package/src/reports/moh-731/sections/hiv-testing-and-pre-exposure.component.tsx +569 -0
- package/src/reports/moh-731/sections/pmtct.component.tsx +451 -0
- package/src/reports/moh-740/moh-740.component.scss +120 -0
- package/src/reports/moh-740/moh-740.component.tsx +1271 -0
- package/src/reports/moh-740/moh-740.resource.ts +42 -0
- package/src/reports/moh-740/registers/moh-222-daily-register/moh-222-daily-register.scss +18 -0
- package/src/reports/moh-740/registers/moh-222-daily-register/moh-222-daily-register.tsx +104 -0
- package/src/reports/moh-740/registers/moh-270-permanent-register/moh-270-permanent-register.scss +18 -0
- package/src/reports/moh-740/registers/moh-270-permanent-register/moh-270-permanent-register.tsx +79 -0
- package/src/reports/moh-740/registers/moh-740-patient-list.scss +0 -0
- package/src/reports/moh-740/registers/moh-740-patient-list.tsx +66 -0
- package/src/reports/moh-740/shared/data-cell/data-cell.scss +6 -0
- package/src/reports/moh-740/shared/data-cell/data-cell.tsx +23 -0
- package/src/reports/moh-740/shared/utils/format-indicator.ts +22 -0
- package/src/reports/moh-740/shared/utils/indicator-register-map.ts +157 -0
- package/src/reports/moh-740/types/index.ts +216 -0
- package/src/reports/moh-745/moh-745.component.tsx +928 -0
- package/src/reports/moh-745/moh-745.scss +74 -0
- package/src/reports/moh-745/registers/moh-412-register.component.tsx +191 -0
- package/src/reports/moh-745/registers/type.ts +30 -0
- package/src/reports/table-wrapper/table-row-mapper.component.tsx +53 -0
- package/src/reports/table-wrapper/table-wrapper.component.tsx +21 -0
- package/src/reports/table-wrapper/table-wrapper.scss +31 -0
- package/src/resources/moh-505.resource.ts +86 -0
- package/src/resources/moh-705.resource.ts +117 -0
- package/src/resources/moh-706.resource.ts +86 -0
- package/src/resources/moh-710.resource.ts +28 -0
- package/src/resources/moh-711.resource.ts +146 -0
- package/src/resources/moh-717.resource.ts +27 -0
- package/src/resources/moh-731.resource.ts +96 -0
- package/src/resources/moh-745.resource.ts +64 -0
- package/src/root.component.tsx +39 -0
- package/src/routes.json +3 -1
- package/src/utils/utils.ts +36 -0
- package/dist/367.js +0 -2
- package/dist/367.js.map +0 -1
- package/dist/86.js +0 -1
- package/dist/86.js.map +0 -1
- /package/dist/{367.js.LICENSE.txt → 822.js.LICENSE.txt} +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ArrowLeft } from '@carbon/react/icons';
|
|
2
1
|
import { useNavigate } from 'react-router-dom';
|
|
3
2
|
import React from 'react';
|
|
4
3
|
import { Button } from '@carbon/react';
|
|
@@ -12,6 +11,7 @@ interface ReportFiltersComponentProps {
|
|
|
12
11
|
onGenerate?: (filters: { startDate?: string; endDate?: string; month?: string }) => void;
|
|
13
12
|
isLoding?: boolean;
|
|
14
13
|
}
|
|
14
|
+
|
|
15
15
|
const ReportFiltersComponent: React.FC<ReportFiltersComponentProps> = ({
|
|
16
16
|
reportName,
|
|
17
17
|
mode = 'daily',
|
|
@@ -35,28 +35,43 @@ const ReportFiltersComponent: React.FC<ReportFiltersComponentProps> = ({
|
|
|
35
35
|
return `${year}-${month}`;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
const [activeTab, setActiveTab] = React.useState<'monthly' | 'custom'>('monthly');
|
|
39
|
+
|
|
38
40
|
const [startDateString, setStartDateString] = React.useState<string>(getToday());
|
|
39
41
|
const [endDateString, setEndDateString] = React.useState<string>(getToday());
|
|
40
42
|
const [monthString, setMonthString] = React.useState<string>(getPreviousMonth());
|
|
43
|
+
|
|
41
44
|
const [selectedFacility, setSelectedFacility] = React.useState<string>('');
|
|
42
45
|
const [facility, setFacility] = React.useState<string>('Select Facility');
|
|
43
46
|
|
|
44
47
|
const generateReport = () => {
|
|
45
48
|
if (onGenerate) {
|
|
46
49
|
const filters: { startDate?: string; endDate?: string; month?: string } = {};
|
|
50
|
+
|
|
47
51
|
if (mode === 'daily') {
|
|
48
52
|
filters.startDate = startDateString;
|
|
49
53
|
filters.endDate = endDateString;
|
|
50
|
-
} else if (mode === 'monthly') {
|
|
51
|
-
filters.month = monthString;
|
|
52
54
|
}
|
|
55
|
+
|
|
56
|
+
if (mode === 'monthly') {
|
|
57
|
+
if (activeTab === 'monthly') {
|
|
58
|
+
filters.month = monthString;
|
|
59
|
+
} else {
|
|
60
|
+
filters.startDate = startDateString;
|
|
61
|
+
filters.endDate = endDateString;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
onGenerate(filters);
|
|
54
66
|
}
|
|
55
67
|
};
|
|
68
|
+
|
|
56
69
|
return (
|
|
57
70
|
<>
|
|
58
71
|
<div className={styles.titleContainer}>
|
|
59
|
-
<
|
|
72
|
+
<Button className={styles.backIcon} onClick={() => navigate('/')}>
|
|
73
|
+
Back
|
|
74
|
+
</Button>
|
|
60
75
|
<h2 className={styles.title}>{reportName}</h2>
|
|
61
76
|
</div>
|
|
62
77
|
<div className={styles.filtersContainer}>
|
|
@@ -82,11 +97,31 @@ const ReportFiltersComponent: React.FC<ReportFiltersComponentProps> = ({
|
|
|
82
97
|
/>
|
|
83
98
|
</div>
|
|
84
99
|
)}
|
|
100
|
+
|
|
85
101
|
{mode === 'monthly' && (
|
|
86
102
|
<div>
|
|
87
|
-
|
|
103
|
+
{/* Tabs */}
|
|
104
|
+
<div className={styles.tabsContainer}>
|
|
105
|
+
<Button
|
|
106
|
+
className={activeTab === 'monthly' ? styles.activeTab : styles.tab}
|
|
107
|
+
onClick={() => setActiveTab('monthly')}
|
|
108
|
+
>
|
|
109
|
+
Monthly
|
|
110
|
+
</Button>
|
|
111
|
+
|
|
112
|
+
<Button
|
|
113
|
+
className={activeTab === 'custom' ? styles.activeTab : styles.tab}
|
|
114
|
+
onClick={() => setActiveTab('custom')}
|
|
115
|
+
>
|
|
116
|
+
Custom
|
|
117
|
+
</Button>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
{/* Monthly tab */}
|
|
121
|
+
{activeTab === 'monthly' && (
|
|
88
122
|
<div>
|
|
89
123
|
<label htmlFor="month">Month:</label>
|
|
124
|
+
|
|
90
125
|
<input
|
|
91
126
|
id="month"
|
|
92
127
|
type="month"
|
|
@@ -95,13 +130,38 @@ const ReportFiltersComponent: React.FC<ReportFiltersComponentProps> = ({
|
|
|
95
130
|
onChange={(e) => setMonthString(e.target.value)}
|
|
96
131
|
/>
|
|
97
132
|
</div>
|
|
98
|
-
|
|
99
|
-
|
|
133
|
+
)}
|
|
134
|
+
|
|
135
|
+
{/* Custom tab */}
|
|
136
|
+
{activeTab === 'custom' && (
|
|
137
|
+
<div className={styles.dateContainer}>
|
|
138
|
+
<label htmlFor="customStartDate">Start Date:</label>
|
|
139
|
+
<label htmlFor="customEndDate">End Date:</label>
|
|
140
|
+
|
|
141
|
+
<input
|
|
142
|
+
id="customStartDate"
|
|
143
|
+
type="date"
|
|
144
|
+
className={styles.input}
|
|
145
|
+
value={startDateString}
|
|
146
|
+
onChange={(e) => setStartDateString(e.target.value)}
|
|
147
|
+
/>
|
|
148
|
+
|
|
149
|
+
<input
|
|
150
|
+
id="customEndDate"
|
|
151
|
+
type="date"
|
|
152
|
+
className={styles.input}
|
|
153
|
+
value={endDateString}
|
|
154
|
+
onChange={(e) => setEndDateString(e.target.value)}
|
|
155
|
+
/>
|
|
156
|
+
</div>
|
|
157
|
+
)}
|
|
100
158
|
</div>
|
|
101
159
|
)}
|
|
160
|
+
|
|
102
161
|
{isFacility === 'true' && (
|
|
103
162
|
<div>
|
|
104
163
|
<label>Facility</label>
|
|
164
|
+
|
|
105
165
|
<select
|
|
106
166
|
className={styles.input}
|
|
107
167
|
name="selectedFacility"
|
|
@@ -113,6 +173,7 @@ const ReportFiltersComponent: React.FC<ReportFiltersComponentProps> = ({
|
|
|
113
173
|
</div>
|
|
114
174
|
)}
|
|
115
175
|
</div>
|
|
176
|
+
|
|
116
177
|
{!isLoding && (
|
|
117
178
|
<div className={styles.buttonContainer}>
|
|
118
179
|
<Button onClick={generateReport}>Generate Report</Button>
|
|
@@ -46,4 +46,46 @@
|
|
|
46
46
|
justify-content: flex-end;
|
|
47
47
|
gap: 10px;
|
|
48
48
|
margin: 0 2rem;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.tabsContainer {
|
|
52
|
+
display: flex;
|
|
53
|
+
gap: 1rem;
|
|
54
|
+
margin-bottom: 1rem;
|
|
55
|
+
align-items: center;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.tab,
|
|
59
|
+
.activeTab {
|
|
60
|
+
display: flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
justify-content: center;
|
|
63
|
+
min-height: 2.5rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.tab {
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
justify-content: center;
|
|
70
|
+
|
|
71
|
+
min-height: 2.5rem;
|
|
72
|
+
|
|
73
|
+
background: transparent;
|
|
74
|
+
color: green;
|
|
75
|
+
|
|
76
|
+
border: 1px solid black;
|
|
77
|
+
cursor: pointer;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.activeTab {
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
justify-content: center;
|
|
84
|
+
|
|
85
|
+
min-height: 2.5rem;
|
|
86
|
+
|
|
87
|
+
background: green;
|
|
88
|
+
color: white;
|
|
89
|
+
|
|
90
|
+
border: 1px solid black;
|
|
49
91
|
}
|
|
@@ -18,6 +18,27 @@ const ReportsDashboard: React.FC<ReportsDashboardProps> = () => {
|
|
|
18
18
|
<ClickableTile onClick={() => navigate('/moh-717')} className={styles.tile}>
|
|
19
19
|
MOH-717 REPORT
|
|
20
20
|
</ClickableTile>
|
|
21
|
+
<ClickableTile onClick={() => navigate('/moh-706')} className={styles.tile}>
|
|
22
|
+
MOH-706 REPORT
|
|
23
|
+
</ClickableTile>
|
|
24
|
+
<ClickableTile onClick={() => navigate('/moh-505')} className={styles.tile}>
|
|
25
|
+
MOH-505 REPORT
|
|
26
|
+
</ClickableTile>
|
|
27
|
+
<ClickableTile onClick={() => navigate('/moh-705a')} className={styles.tile}>
|
|
28
|
+
MOH-705A REPORT
|
|
29
|
+
</ClickableTile>
|
|
30
|
+
<ClickableTile onClick={() => navigate('/moh-705b')} className={styles.tile}>
|
|
31
|
+
MOH-705B REPORT
|
|
32
|
+
</ClickableTile>
|
|
33
|
+
<ClickableTile onClick={() => navigate('/moh-745')} className={styles.tile}>
|
|
34
|
+
MOH-745 REPORT
|
|
35
|
+
</ClickableTile>
|
|
36
|
+
<ClickableTile onClick={() => navigate('/moh-740')} className={styles.tile}>
|
|
37
|
+
MOH-740 REPORT
|
|
38
|
+
</ClickableTile>
|
|
39
|
+
<ClickableTile onClick={() => navigate('/moh-731')} className={styles.tile}>
|
|
40
|
+
MOH-731 REPORT
|
|
41
|
+
</ClickableTile>
|
|
21
42
|
</div>
|
|
22
43
|
</>
|
|
23
44
|
);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { DataTable, type DataTableHeader, type DataTableRow, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@carbon/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
interface DatatableWrapperProps {
|
|
5
|
+
rows: Omit<DataTableRow<any[]>, "cells">[];
|
|
6
|
+
headers: DataTableHeader[];
|
|
7
|
+
subHeaders?: string[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const DatatableWrapper: React.FC<DatatableWrapperProps> = ({ rows, headers, subHeaders = [] }) => {
|
|
11
|
+
return <DataTable rows={rows} headers={headers}>
|
|
12
|
+
{({
|
|
13
|
+
rows,
|
|
14
|
+
headers,
|
|
15
|
+
getTableProps,
|
|
16
|
+
getHeaderProps,
|
|
17
|
+
getRowProps,
|
|
18
|
+
getCellProps,
|
|
19
|
+
}) => (
|
|
20
|
+
<Table {...getTableProps()}>
|
|
21
|
+
<TableHead>
|
|
22
|
+
<TableRow>
|
|
23
|
+
{headers.map((header) => (
|
|
24
|
+
<TableHeader {...getHeaderProps({ header })}>
|
|
25
|
+
{header.header}
|
|
26
|
+
</TableHeader>
|
|
27
|
+
))}
|
|
28
|
+
</TableRow>
|
|
29
|
+
{
|
|
30
|
+
(subHeaders && subHeaders.length) &&
|
|
31
|
+
<TableRow>
|
|
32
|
+
{subHeaders.map((head, i) => (
|
|
33
|
+
<TableHeader key={i}>
|
|
34
|
+
{head}
|
|
35
|
+
</TableHeader>
|
|
36
|
+
))}
|
|
37
|
+
</TableRow>
|
|
38
|
+
}
|
|
39
|
+
</TableHead>
|
|
40
|
+
<TableBody>
|
|
41
|
+
{rows.map((row) => (
|
|
42
|
+
<TableRow {...getRowProps({ row })}>
|
|
43
|
+
{row.cells.map((cell) => (
|
|
44
|
+
<TableCell {...getCellProps({ cell })}>{cell.value}</TableCell>
|
|
45
|
+
))}
|
|
46
|
+
</TableRow>
|
|
47
|
+
))}
|
|
48
|
+
</TableBody>
|
|
49
|
+
</Table>
|
|
50
|
+
)}
|
|
51
|
+
</DataTable>
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default DatatableWrapper;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import TableWrapper from "../table-wrapper/table-wrapper.component";
|
|
3
|
+
import TableRowMapper from "../table-wrapper/table-row-mapper.component";
|
|
4
|
+
import { getCell } from "../../utils/utils";
|
|
5
|
+
import styles from './moh-240.scss';
|
|
6
|
+
|
|
7
|
+
const MOH240Header: React.FC = () => {
|
|
8
|
+
const tableRows = useMemo(() => {
|
|
9
|
+
return [
|
|
10
|
+
{
|
|
11
|
+
tableCells: [
|
|
12
|
+
getCell("", "County:", 1, 1, true),
|
|
13
|
+
getCell("", "", 3),
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
tableCells: [
|
|
18
|
+
getCell("", "Sub-County:", 1, 1, true),
|
|
19
|
+
getCell("", "", 3),
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
tableCells: [
|
|
24
|
+
getCell("", "Health Facility:", 1, 1, true),
|
|
25
|
+
getCell("", "", 3),
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
tableCells: [
|
|
30
|
+
getCell("", "KMHFL Code:", 1, 1, true),
|
|
31
|
+
getCell("", "", 3),
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
tableCells: [
|
|
36
|
+
getCell("", "Type:", 1, 1, true),
|
|
37
|
+
getCell("", ""),
|
|
38
|
+
getCell("", "Man. Agency:", 1, 1, true),
|
|
39
|
+
getCell("", ""),
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
tableCells: [
|
|
44
|
+
getCell("", "Start date:", 1, 1, true),
|
|
45
|
+
getCell("", ""),
|
|
46
|
+
getCell("", "End date:", 1, 1, true),
|
|
47
|
+
getCell("", ""),
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
return <div className={styles.headerSection}>
|
|
54
|
+
<h3>Laboratory (LAB) Register MOH 240</h3>
|
|
55
|
+
<TableWrapper>
|
|
56
|
+
<TableRowMapper tableRows={tableRows} />
|
|
57
|
+
</TableWrapper>
|
|
58
|
+
</div>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default MOH240Header;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { useSearchParams } from "react-router-dom";
|
|
3
|
+
import { Button, Loading } from '@carbon/react';
|
|
4
|
+
import Moh240Register from "./sub-reports/moh-240-register.component";
|
|
5
|
+
import Moh240PageSummary from "./sub-reports/page-summary.component";
|
|
6
|
+
import { getMoh706PatientList } from "../../resources/moh-706.resource";
|
|
7
|
+
import { getMoh505PatientList } from "../../resources/moh-505.resource";
|
|
8
|
+
import MOH240Header from "./moh-240-header.component";
|
|
9
|
+
import styles from "./moh-240.scss";
|
|
10
|
+
import { navigate } from "@openmrs/esm-framework";
|
|
11
|
+
|
|
12
|
+
const Moh240Report: React.FC = () => {
|
|
13
|
+
const [searchParams] = useSearchParams();
|
|
14
|
+
const [patientList, setPatientList] = useState<any[]>([]);
|
|
15
|
+
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
16
|
+
const [errorMessage, setErrorMessage] = useState<string>('');
|
|
17
|
+
const [indicator, setIndicator] = useState<string>('');
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const locationUuids = searchParams.get('locationUuids');
|
|
21
|
+
const startDate = searchParams.get('startDate');
|
|
22
|
+
const endDate = searchParams.get('endDate');
|
|
23
|
+
const indicators = searchParams.get('indicators');
|
|
24
|
+
const report = searchParams.get('report');
|
|
25
|
+
|
|
26
|
+
if (locationUuids && startDate && endDate && indicators) {
|
|
27
|
+
setIndicator(indicators);
|
|
28
|
+
fetchPatientList({ locationUuids, startDate, endDate, indicators, report: report || 'moh-706' });
|
|
29
|
+
}
|
|
30
|
+
}, [searchParams]);
|
|
31
|
+
|
|
32
|
+
const fetchPatientList = async (params: { locationUuids: string; startDate: string; endDate: string; indicators: string; report: string }) => {
|
|
33
|
+
setIsLoading(true);
|
|
34
|
+
setErrorMessage('');
|
|
35
|
+
try {
|
|
36
|
+
let result;
|
|
37
|
+
if (params.report === 'moh-505') {
|
|
38
|
+
result = await getMoh505PatientList(params);
|
|
39
|
+
} else {
|
|
40
|
+
result = await getMoh706PatientList(params);
|
|
41
|
+
}
|
|
42
|
+
setPatientList(result);
|
|
43
|
+
} catch (error: any) {
|
|
44
|
+
setErrorMessage(error instanceof Error ? error.message : String(error));
|
|
45
|
+
} finally {
|
|
46
|
+
setIsLoading(false);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const navigateBack = () => {
|
|
51
|
+
const report = searchParams.get('report');
|
|
52
|
+
const locationUuids = searchParams.get('locationUuids');
|
|
53
|
+
const startDate = searchParams.get('startDate');
|
|
54
|
+
const endDate = searchParams.get('endDate');
|
|
55
|
+
|
|
56
|
+
const params = new URLSearchParams();
|
|
57
|
+
if (locationUuids) params.append('locationUuids', locationUuids);
|
|
58
|
+
if (startDate) params.append('startDate', startDate);
|
|
59
|
+
if (endDate) params.append('endDate', endDate);
|
|
60
|
+
navigate({ to: `home/reports/${report}?${params.toString()}` });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<>
|
|
65
|
+
<div className={styles.buttonContainer}>
|
|
66
|
+
<Button onClick={navigateBack}>Back</Button>
|
|
67
|
+
</div>
|
|
68
|
+
{isLoading && <Loading description="Fetching patient list...." />}
|
|
69
|
+
{!isLoading && errorMessage && (
|
|
70
|
+
<div>
|
|
71
|
+
<a href="#" className="close" data-dismiss="alert">
|
|
72
|
+
×
|
|
73
|
+
</a>
|
|
74
|
+
<h4>
|
|
75
|
+
<strong>
|
|
76
|
+
<span className="glyphicon glyphicon-warning-sign"></span>{' '}
|
|
77
|
+
</strong>{' '}
|
|
78
|
+
An error occurred while trying to load the patient list. Please try again.
|
|
79
|
+
</h4>
|
|
80
|
+
<p>
|
|
81
|
+
<small>{errorMessage}</small>
|
|
82
|
+
</p>
|
|
83
|
+
</div>
|
|
84
|
+
)}
|
|
85
|
+
|
|
86
|
+
<MOH240Header />
|
|
87
|
+
<Moh240Register patientList={patientList} indicator={indicator} />
|
|
88
|
+
<Moh240PageSummary />
|
|
89
|
+
</>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export default Moh240Report;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import DatatableWrapper from "../../datatable-wrapper/datatable-wrapper.component";
|
|
3
|
+
import styles from "../moh-240.scss";
|
|
4
|
+
interface Moh240RegisterProps {
|
|
5
|
+
patientList?: any[];
|
|
6
|
+
indicator?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const Moh240Register: React.FC<Moh240RegisterProps> = ({ patientList = [], indicator = '' }) => {
|
|
10
|
+
const headers = [
|
|
11
|
+
{ key: 'date', header: 'Date (DD/MM/YYYY)' },
|
|
12
|
+
{ key: 'opd_ip_ref_no', header: 'OPD / IPD Ref. No.' },
|
|
13
|
+
{ key: 'lab_no', header: 'Lab. No. (new client)' },
|
|
14
|
+
{ key: 'revisit_no', header: 'Revisit No.' },
|
|
15
|
+
{ key: 'full_name', header: 'Full Names (Three names)' },
|
|
16
|
+
{ key: 'age', header: 'Age' },
|
|
17
|
+
{ key: 'sex', header: 'Sex' },
|
|
18
|
+
{ key: 'county_sub_county', header: 'County / Sub County' },
|
|
19
|
+
{ key: 'village_estate_landmark', header: 'Village / Estate / Landmark' },
|
|
20
|
+
{ key: 'telephone_number', header: 'Telephone Number' },
|
|
21
|
+
{ key: 'clinical_diagnosis', header: 'Clinical Diagnosis' },
|
|
22
|
+
{ key: 'prior_treatment', header: 'Prior Treatment' },
|
|
23
|
+
{ key: 'type_of_specimen', header: 'Type of Specimen' },
|
|
24
|
+
{ key: 'condition_of_specimen', header: 'Condition of Specimen' },
|
|
25
|
+
{ key: 'investigation_required', header: 'Investigation Required' },
|
|
26
|
+
{ key: 'test_datetime', header: 'Date Sample Collected' },
|
|
27
|
+
{ key: 'date_sample_received', header: 'Date Sample Received' },
|
|
28
|
+
{ key: 'clinician_name', header: 'Clinician Name' },
|
|
29
|
+
{ key: 'date_sample_analysed', header: 'Date Sample Analysed' },
|
|
30
|
+
{ key: 'results', header: 'Results' },
|
|
31
|
+
{ key: 'date_results_dispatched', header: 'Date Results Dispatched' },
|
|
32
|
+
{ key: 'amount_charged', header: 'Amount Charged' },
|
|
33
|
+
{ key: 'receipt_number', header: 'Receipt Number' },
|
|
34
|
+
{ key: 'referrals', header: 'Referrals (From Other HF / To Other HF / 3rd Tier Reference Laboratories)' },
|
|
35
|
+
{ key: 'comments', header: 'Comments' },
|
|
36
|
+
{ key: 'testing_officer', header: 'Name of Analysing/Testing Officer' },
|
|
37
|
+
{ key: 'signature', header: 'Signature' }
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const getResultField = (ind: string) => {
|
|
41
|
+
if (ind.startsWith('min_') || ind.startsWith('max_')) {
|
|
42
|
+
return ind.substring(4);
|
|
43
|
+
}
|
|
44
|
+
if (ind.startsWith('total_')) {
|
|
45
|
+
return ind.substring(6);
|
|
46
|
+
}
|
|
47
|
+
if (ind.startsWith('positive_')) {
|
|
48
|
+
return ind.substring(9);
|
|
49
|
+
}
|
|
50
|
+
return ind;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const resultField = getResultField(indicator);
|
|
54
|
+
|
|
55
|
+
const subHeaders = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA'];
|
|
56
|
+
|
|
57
|
+
const rows = patientList.map((patient, index) => {
|
|
58
|
+
const row: any = {};
|
|
59
|
+
headers.forEach(header => {
|
|
60
|
+
if (header.key === 'results') {
|
|
61
|
+
row[header.key] = patient[resultField] || '';
|
|
62
|
+
} else {
|
|
63
|
+
row[header.key] = patient[header.key] || '';
|
|
64
|
+
}
|
|
65
|
+
row["id"] = header.key + index;
|
|
66
|
+
});
|
|
67
|
+
return row;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return <div className={styles.wrapper}>
|
|
71
|
+
<DatatableWrapper headers={headers} rows={rows} subHeaders={subHeaders} />
|
|
72
|
+
</div>
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default Moh240Register;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import TableWrapper from "../../table-wrapper/table-wrapper.component";
|
|
3
|
+
import TableRowMapper from "../../table-wrapper/table-row-mapper.component";
|
|
4
|
+
import { getCell } from "../../../utils/utils";
|
|
5
|
+
import styles from "../moh-240.scss";
|
|
6
|
+
|
|
7
|
+
const Moh240PageSummary: React.FC = () => {
|
|
8
|
+
const tableRows = useMemo(() => {
|
|
9
|
+
return [
|
|
10
|
+
{
|
|
11
|
+
tableCells: [
|
|
12
|
+
getCell("", "Page Summary", 8, 1, true),
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
tableCells: [
|
|
17
|
+
getCell("", "Malaria Testing", 3, 1, true),
|
|
18
|
+
getCell("", "Type of test", 2, 1, true),
|
|
19
|
+
getCell("", "Referrals", 3, 1, true),
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
tableCells: [
|
|
24
|
+
getCell("", "", 1, 2, true),
|
|
25
|
+
getCell("", "Number", 2, 1, true),
|
|
26
|
+
getCell("", "", 1, 2, true),
|
|
27
|
+
getCell("", "Number", 1, 2, true),
|
|
28
|
+
getCell("", "", 1, 1, true),
|
|
29
|
+
getCell("", "Number", 2, 1, true),
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
tableCells: [
|
|
34
|
+
,
|
|
35
|
+
getCell("", "OPD", 1, 1, true),
|
|
36
|
+
getCell("", "IP", 1, 1, true),
|
|
37
|
+
,
|
|
38
|
+
,
|
|
39
|
+
getCell(),
|
|
40
|
+
getCell("", "Routine", 1, 1, true),
|
|
41
|
+
getCell("", "Specialized", 1, 1, true),
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
tableCells: [
|
|
46
|
+
getCell("", "Malaria BS (Under five years)"),
|
|
47
|
+
getCell(),
|
|
48
|
+
getCell(),
|
|
49
|
+
getCell("", "No. of Routine tests", 1, 2),
|
|
50
|
+
getCell("", "", 1, 2),
|
|
51
|
+
getCell("", "From Other HF"),
|
|
52
|
+
getCell(),
|
|
53
|
+
getCell()
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
tableCells: [
|
|
58
|
+
getCell("", "Malaria BS (5 years and above)"),
|
|
59
|
+
getCell(),
|
|
60
|
+
getCell(),
|
|
61
|
+
,
|
|
62
|
+
,
|
|
63
|
+
getCell("", "To Other HF"),
|
|
64
|
+
getCell(),
|
|
65
|
+
getCell(),
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
tableCells: [
|
|
70
|
+
getCell("", "Malaria Rapid Diagnostic Tests (Under five years)"),
|
|
71
|
+
getCell(),
|
|
72
|
+
getCell(),
|
|
73
|
+
getCell("", "No. of Special tests", 1, 2),
|
|
74
|
+
getCell("", "", 1, 2),
|
|
75
|
+
getCell("", "To Reference Laboratories", 1, 2),
|
|
76
|
+
getCell("", "", 1, 2),
|
|
77
|
+
getCell("", "", 1, 2)
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
tableCells: [
|
|
82
|
+
getCell("", "Malaria Rapid Diagnostic Tests (5 years and above)"),
|
|
83
|
+
getCell(),
|
|
84
|
+
getCell()
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
]
|
|
88
|
+
}, []);
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
return <div className={styles.wrapper}>
|
|
92
|
+
<TableWrapper>
|
|
93
|
+
<TableRowMapper tableRows={tableRows} />
|
|
94
|
+
</TableWrapper>
|
|
95
|
+
</div>
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default Moh240PageSummary;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import TableWrapper from "../table-wrapper/table-wrapper.component";
|
|
3
|
+
import TableRowMapper from "../table-wrapper/table-row-mapper.component";
|
|
4
|
+
import { getCell } from "../../utils/utils";
|
|
5
|
+
import styles from './moh-505.scss';
|
|
6
|
+
|
|
7
|
+
const MOH505Header: React.FC = () => {
|
|
8
|
+
const tableRows = useMemo(() => {
|
|
9
|
+
return [
|
|
10
|
+
{
|
|
11
|
+
tableCells: [
|
|
12
|
+
getCell("", "County:", 1, 1, true),
|
|
13
|
+
getCell("", "", 3),
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
tableCells: [
|
|
18
|
+
getCell("", "Sub-County:", 1, 1, true),
|
|
19
|
+
getCell("", "", 3),
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
tableCells: [
|
|
24
|
+
getCell("", "Health Facility:", 1, 1, true),
|
|
25
|
+
getCell("", "", 3),
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
tableCells: [
|
|
30
|
+
getCell("", "KMHFL code:", 1, 1, true),
|
|
31
|
+
getCell("", "", 3),
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
tableCells: [
|
|
36
|
+
getCell("", "Facility Type:", 1, 1, true),
|
|
37
|
+
getCell("", ""),
|
|
38
|
+
getCell("", "Man. Agency:", 1, 1, true),
|
|
39
|
+
getCell("", ""),
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
tableCells: [
|
|
44
|
+
getCell("", "Start date:", 1, 1, true),
|
|
45
|
+
getCell("", ""),
|
|
46
|
+
getCell("", "End date:", 1, 1, true),
|
|
47
|
+
getCell("", ""),
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
return <div className={styles.headerSection}>
|
|
54
|
+
<h3>MOH 505 IDSR</h3>
|
|
55
|
+
<h3>Weekly Epidemic Monitoring Form</h3>
|
|
56
|
+
<TableWrapper>
|
|
57
|
+
<TableRowMapper tableRows={tableRows} />
|
|
58
|
+
</TableWrapper>
|
|
59
|
+
</div>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default MOH505Header;
|