@kenyaemr/esm-patient-registration-app 4.4.1 → 4.4.2
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/144.js +2 -0
- package/dist/144.js.map +1 -0
- package/dist/207.js +1 -1
- package/dist/330.js +1 -0
- package/dist/330.js.map +1 -0
- package/dist/574.js +1 -1
- package/dist/59.js +1 -0
- package/dist/59.js.map +1 -0
- package/dist/68.js +1 -1
- package/dist/68.js.map +1 -1
- package/dist/735.js +1 -1
- package/dist/{909.js → 821.js} +1 -1
- package/dist/{909.js.map → 821.js.map} +1 -1
- package/dist/{698.js → 822.js} +1 -1
- package/dist/822.js.map +1 -0
- package/dist/887.js +1 -1
- package/dist/kenyaemr-esm-patient-registration-app.js +1 -1
- package/dist/kenyaemr-esm-patient-registration-app.js.buildmanifest.json +122 -74
- package/dist/kenyaemr-esm-patient-registration-app.old +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/index.ts +18 -0
- package/src/offline.resources.ts +1 -8
- package/src/patient-registration/field/address/address-field.component.tsx +1 -0
- package/src/patient-registration/patient-registration-hooks.ts +77 -6
- package/src/patient-registration/patient-registration-types.tsx +7 -1
- package/src/patient-registration/patient-registration.component.tsx +26 -3
- package/src/patient-verification/assets/counties.json +236 -0
- package/src/patient-verification/assets/verification-assets.ts +11 -0
- package/src/patient-verification/patient-verification-hook.tsx +156 -0
- package/src/patient-verification/patient-verification-utils.ts +173 -0
- package/src/patient-verification/patient-verification.component.tsx +110 -0
- package/src/patient-verification/patient-verification.scss +30 -0
- package/src/patient-verification/verification-modal/confirm-prompt.component.tsx +69 -0
- package/src/patient-verification/verification-modal/empty-prompt.component.tsx +35 -0
- package/src/patient-verification/verification-types.ts +50 -0
- package/translations/en.json +17 -1
- package/dist/417.js +0 -2
- package/dist/417.js.map +0 -1
- package/dist/698.js.map +0 -1
- /package/dist/{417.js.LICENSE.txt → 144.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { showModal } from '@openmrs/esm-framework';
|
|
2
|
+
import { FormikProps } from 'formik';
|
|
3
|
+
import { FormValues } from '../patient-registration/patient-registration-types';
|
|
4
|
+
import { ClientRegistryPatient, RegistryPatient } from './verification-types';
|
|
5
|
+
import counties from './assets/counties.json';
|
|
6
|
+
|
|
7
|
+
export function handleClientRegistryResponse(
|
|
8
|
+
clientResponse: ClientRegistryPatient,
|
|
9
|
+
props: FormikProps<FormValues>,
|
|
10
|
+
searchTerm: string,
|
|
11
|
+
) {
|
|
12
|
+
if (clientResponse?.clientExists === false) {
|
|
13
|
+
const nupiIdentifiers = {
|
|
14
|
+
['nationalId']: {
|
|
15
|
+
initialValue: searchTerm,
|
|
16
|
+
identifierUuid: undefined,
|
|
17
|
+
selectedSource: { uuid: '', name: '' },
|
|
18
|
+
preferred: false,
|
|
19
|
+
required: false,
|
|
20
|
+
identifierTypeUuid: '49af6cdc-7968-4abb-bf46-de10d7f4859f',
|
|
21
|
+
identifierName: 'National ID',
|
|
22
|
+
identifierValue: searchTerm,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
const dispose = showModal('empty-client-registry-modal', {
|
|
26
|
+
onConfirm: () => {
|
|
27
|
+
props.setValues({ ...props.values, identifiers: { ...props.values.identifiers, ...nupiIdentifiers } });
|
|
28
|
+
dispose();
|
|
29
|
+
},
|
|
30
|
+
close: () => dispose(),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (clientResponse?.clientExists) {
|
|
35
|
+
const {
|
|
36
|
+
client: {
|
|
37
|
+
middleName,
|
|
38
|
+
lastName,
|
|
39
|
+
firstName,
|
|
40
|
+
contact,
|
|
41
|
+
country,
|
|
42
|
+
countyOfBirth,
|
|
43
|
+
residence,
|
|
44
|
+
identifications,
|
|
45
|
+
gender,
|
|
46
|
+
dateOfBirth,
|
|
47
|
+
isAlive,
|
|
48
|
+
clientNumber,
|
|
49
|
+
educationLevel,
|
|
50
|
+
occupation,
|
|
51
|
+
maritalStatus,
|
|
52
|
+
},
|
|
53
|
+
} = clientResponse;
|
|
54
|
+
|
|
55
|
+
const nupiIdentifiers = {
|
|
56
|
+
['nationalId']: {
|
|
57
|
+
initialValue: identifications !== undefined && identifications[0]?.identificationNumber,
|
|
58
|
+
identifierUuid: undefined,
|
|
59
|
+
selectedSource: { uuid: '', name: '' },
|
|
60
|
+
preferred: false,
|
|
61
|
+
required: false,
|
|
62
|
+
identifierTypeUuid: '49af6cdc-7968-4abb-bf46-de10d7f4859f',
|
|
63
|
+
identifierName: 'National ID',
|
|
64
|
+
identifierValue: identifications !== undefined && identifications[0]?.identificationNumber,
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
['nationalUniquePatientIdentifier']: {
|
|
68
|
+
identifierTypeUuid: 'f85081e2-b4be-4e48-b3a4-7994b69bb101',
|
|
69
|
+
identifierName: 'National Unique patient identifier',
|
|
70
|
+
identifierValue: clientNumber,
|
|
71
|
+
initialValue: clientNumber,
|
|
72
|
+
identifierUuid: undefined,
|
|
73
|
+
selectedSource: { uuid: '', name: '' },
|
|
74
|
+
preferred: false,
|
|
75
|
+
required: false,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const dispose = showModal('confirm-client-registry-modal', {
|
|
80
|
+
onConfirm: () => {
|
|
81
|
+
props.setValues({
|
|
82
|
+
...props.values,
|
|
83
|
+
familyName: lastName,
|
|
84
|
+
middleName: middleName,
|
|
85
|
+
givenName: firstName,
|
|
86
|
+
gender: gender === 'male' ? 'Male' : 'Female',
|
|
87
|
+
birthdate: new Date(dateOfBirth),
|
|
88
|
+
isDead: !isAlive,
|
|
89
|
+
attributes: {
|
|
90
|
+
'b2c38640-2603-4629-aebd-3b54f33f1e3a': contact?.primaryPhone,
|
|
91
|
+
'94614350-84c8-41e0-ac29-86bc107069be': contact?.secondaryPhone,
|
|
92
|
+
'b8d0b331-1d2d-4a9a-b741-1816f498bdb6': contact?.emailAddress ?? '',
|
|
93
|
+
},
|
|
94
|
+
address: {
|
|
95
|
+
address1: residence?.address,
|
|
96
|
+
address2: '',
|
|
97
|
+
address4: residence?.ward,
|
|
98
|
+
cityVillage: residence?.village,
|
|
99
|
+
stateProvince: residence?.subCounty,
|
|
100
|
+
countyDistrict: counties.find((county) => county.code === parseInt(residence?.county))?.name,
|
|
101
|
+
country: 'Kenya',
|
|
102
|
+
postalCode: residence?.address,
|
|
103
|
+
},
|
|
104
|
+
identifiers: { ...props.values.identifiers, ...nupiIdentifiers },
|
|
105
|
+
obs: {
|
|
106
|
+
'1054AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA':
|
|
107
|
+
props.values.concepts.find((concept) => concept.display?.toLowerCase() === maritalStatus?.toLowerCase())
|
|
108
|
+
?.uuid ?? '',
|
|
109
|
+
'1712AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA':
|
|
110
|
+
props.values.concepts.find((concept) => concept.display?.toLowerCase() === educationLevel?.toLowerCase())
|
|
111
|
+
?.uuid ?? '',
|
|
112
|
+
'1542AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA':
|
|
113
|
+
props.values.concepts.find((concept) => concept.display?.toLowerCase() === occupation?.toLowerCase())
|
|
114
|
+
?.uuid ?? '',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
dispose();
|
|
118
|
+
},
|
|
119
|
+
close: () => dispose(),
|
|
120
|
+
patient: clientResponse.client,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function generateNUPIPayload(formValues: FormValues): RegistryPatient {
|
|
126
|
+
const educationLevel = formValues.concepts.find(
|
|
127
|
+
(concept) => concept.uuid === formValues.obs['1712AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'],
|
|
128
|
+
);
|
|
129
|
+
const occupation = formValues.concepts.find(
|
|
130
|
+
(concept) => concept.uuid === formValues.obs['1542AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'],
|
|
131
|
+
);
|
|
132
|
+
const maritalStatus = formValues.concepts.find(
|
|
133
|
+
(concept) => concept.uuid === formValues.obs['1054AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'],
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
let createRegistryPatient: RegistryPatient = {
|
|
137
|
+
firstName: formValues?.givenName,
|
|
138
|
+
middleName: formValues?.middleName,
|
|
139
|
+
lastName: formValues?.familyName,
|
|
140
|
+
gender: formValues?.gender === 'Male' ? 'male' : 'female',
|
|
141
|
+
dateOfBirth: new Date(formValues.birthdate).toISOString(),
|
|
142
|
+
isAlive: !formValues.isDead,
|
|
143
|
+
residence: {
|
|
144
|
+
county: `0${counties.find((county) => county.name.includes(formValues.address['countyDistrict']))?.code}`,
|
|
145
|
+
subCounty: formValues.address['stateProvince']?.toLocaleLowerCase(),
|
|
146
|
+
ward: formValues.address['address4']?.toLocaleLowerCase(),
|
|
147
|
+
village: formValues.address['cityVillage'],
|
|
148
|
+
landmark: formValues.address['address2'],
|
|
149
|
+
address: formValues.address['postalCode'],
|
|
150
|
+
},
|
|
151
|
+
nextOfKins: [],
|
|
152
|
+
contact: {
|
|
153
|
+
primaryPhone: formValues.attributes['b2c38640-2603-4629-aebd-3b54f33f1e3a'],
|
|
154
|
+
secondaryPhone: formValues.attributes['94614350-84c8-41e0-ac29-86bc107069be'],
|
|
155
|
+
emailAddress: formValues.attributes['b8d0b331-1d2d-4a9a-b741-1816f498bdb6'],
|
|
156
|
+
},
|
|
157
|
+
country: 'KE',
|
|
158
|
+
countyOfBirth: `0${counties.find((county) => county.name.includes(formValues.address['countyDistrict']))?.code}`,
|
|
159
|
+
educationLevel: educationLevel?.display?.toLowerCase() ?? '',
|
|
160
|
+
religion: '',
|
|
161
|
+
occupation: occupation?.display?.toLowerCase() ?? '',
|
|
162
|
+
maritalStatus: maritalStatus?.display?.toLowerCase() ?? '',
|
|
163
|
+
originFacilityKmflCode: '',
|
|
164
|
+
nascopCCCNumber: '',
|
|
165
|
+
identifications: [
|
|
166
|
+
{
|
|
167
|
+
identificationType: 'national-id',
|
|
168
|
+
identificationNumber: formValues.identifiers['nationalId']?.identifierValue,
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
};
|
|
172
|
+
return createRegistryPatient;
|
|
173
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { Tile, ComboBox, Layer, Button, Search, InlineLoading } from '@carbon/react';
|
|
4
|
+
import styles from './patient-verification.scss';
|
|
5
|
+
import { countries, verificationIdentifierTypes } from './assets/verification-assets';
|
|
6
|
+
import { searchClientRegistry, useGlobalProperties } from './patient-verification-hook';
|
|
7
|
+
import { showToast } from '@openmrs/esm-framework';
|
|
8
|
+
import { handleClientRegistryResponse } from './patient-verification-utils';
|
|
9
|
+
import { FormValues } from '../patient-registration/patient-registration-types';
|
|
10
|
+
import { FormikProps } from 'formik';
|
|
11
|
+
|
|
12
|
+
interface PatientVerificationProps {
|
|
13
|
+
props: FormikProps<FormValues>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const PatientVerification: React.FC<PatientVerificationProps> = ({ props }) => {
|
|
17
|
+
const { t } = useTranslation();
|
|
18
|
+
const { data, isLoading, error } = useGlobalProperties();
|
|
19
|
+
const [verificationCriteria, setVerificationCriteria] = useState({
|
|
20
|
+
searchTerm: '',
|
|
21
|
+
identifierType: '',
|
|
22
|
+
});
|
|
23
|
+
const [isLoadingSearch, setIsLoadingSearch] = useState(false);
|
|
24
|
+
|
|
25
|
+
const handleSearch = async () => {
|
|
26
|
+
setIsLoadingSearch(true);
|
|
27
|
+
try {
|
|
28
|
+
const clientRegistryResponse = await searchClientRegistry(
|
|
29
|
+
verificationCriteria.identifierType,
|
|
30
|
+
verificationCriteria.searchTerm,
|
|
31
|
+
props.values.token,
|
|
32
|
+
);
|
|
33
|
+
setIsLoadingSearch(false);
|
|
34
|
+
handleClientRegistryResponse(clientRegistryResponse, props, verificationCriteria.searchTerm);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
showToast({
|
|
37
|
+
title: 'Client registry error',
|
|
38
|
+
description: `Please reload the registration page and re-try again, if the issue persist contact system administrator`,
|
|
39
|
+
millis: 10000,
|
|
40
|
+
kind: 'error',
|
|
41
|
+
critical: true,
|
|
42
|
+
});
|
|
43
|
+
setIsLoadingSearch(false);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (error) {
|
|
48
|
+
return (
|
|
49
|
+
<Tile className={styles.errorWrapper}>
|
|
50
|
+
<p>Error occurred while reaching the client registry, please proceed with registration and try again later</p>
|
|
51
|
+
</Tile>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
return (
|
|
55
|
+
<div id={'patientVerification'}>
|
|
56
|
+
<h3 className={styles.productiveHeading02} style={{ color: '#161616' }}>
|
|
57
|
+
{t('clientVerificationWithClientRegistry', 'Client verification with client registry')}
|
|
58
|
+
</h3>
|
|
59
|
+
<div style={{ margin: '1rem 0 1rem' }}>
|
|
60
|
+
<Layer>
|
|
61
|
+
{isLoading && <InlineLoading status="active" iconDescription="Loading" description="Loading data..." />}
|
|
62
|
+
</Layer>
|
|
63
|
+
<Tile className={styles.verificationWrapper}>
|
|
64
|
+
<Layer>
|
|
65
|
+
<ComboBox
|
|
66
|
+
ariaLabel={t('selectCountry', 'Select country')}
|
|
67
|
+
id="selectCountry"
|
|
68
|
+
items={countries}
|
|
69
|
+
itemToString={(item) => item?.name ?? ''}
|
|
70
|
+
label="Combo box menu options"
|
|
71
|
+
titleText={t('selectCountry', 'Select country')}
|
|
72
|
+
initialSelectedItem={countries[0]}
|
|
73
|
+
/>
|
|
74
|
+
</Layer>
|
|
75
|
+
<Layer>
|
|
76
|
+
<ComboBox
|
|
77
|
+
ariaLabel={t('selectIdentifierType', 'Select identifier type')}
|
|
78
|
+
id="selectIdentifierType"
|
|
79
|
+
items={verificationIdentifierTypes}
|
|
80
|
+
itemToString={(item) => item?.name ?? ''}
|
|
81
|
+
label="Combo box menu options"
|
|
82
|
+
titleText={t('selectIdentifierType', 'Select identifier type')}
|
|
83
|
+
onChange={({ selectedItem }) =>
|
|
84
|
+
setVerificationCriteria({ ...verificationCriteria, identifierType: selectedItem.value })
|
|
85
|
+
}
|
|
86
|
+
/>
|
|
87
|
+
</Layer>
|
|
88
|
+
<Layer>
|
|
89
|
+
<Search
|
|
90
|
+
id="search-1"
|
|
91
|
+
autoFocus
|
|
92
|
+
placeHolderText="Search"
|
|
93
|
+
disabled={!verificationCriteria.identifierType}
|
|
94
|
+
onChange={(event) => setVerificationCriteria({ ...verificationCriteria, searchTerm: event.target.value })}
|
|
95
|
+
/>
|
|
96
|
+
</Layer>
|
|
97
|
+
{!isLoadingSearch ? (
|
|
98
|
+
<Button disabled={!verificationCriteria.identifierType && !isLoading} size="md" onClick={handleSearch}>
|
|
99
|
+
{t('validate', 'Validate')}
|
|
100
|
+
</Button>
|
|
101
|
+
) : (
|
|
102
|
+
<InlineLoading status="active" iconDescription="Loading" description="Searching client registry" />
|
|
103
|
+
)}
|
|
104
|
+
</Tile>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export default PatientVerification;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
@use '@carbon/colors';
|
|
2
|
+
@import '../patient-registration/patient-registration.scss';
|
|
3
|
+
|
|
4
|
+
/* Desktop */
|
|
5
|
+
:global(.omrs-breakpoint-gt-tablet) {
|
|
6
|
+
.verificationWrapper {
|
|
7
|
+
display: grid;
|
|
8
|
+
grid-template-columns: 1fr 1fr 1fr 1fr;
|
|
9
|
+
column-gap: 0.325rem;
|
|
10
|
+
align-items: flex-end;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Tablet */
|
|
15
|
+
:global(.omrs-breakpoint-lt-desktop) {
|
|
16
|
+
.verificationWrapper {
|
|
17
|
+
row-gap: 0.5rem;
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.errorWrapper {
|
|
25
|
+
color: colors.$red-50;
|
|
26
|
+
margin: 0 0 1rem 0;
|
|
27
|
+
display: flex;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
align-items: center;
|
|
30
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { Button } from '@carbon/react';
|
|
4
|
+
import { age, ExtensionSlot, formatDate } from '@openmrs/esm-framework';
|
|
5
|
+
import capitalize from 'lodash-es/capitalize';
|
|
6
|
+
|
|
7
|
+
const PatientInfo: React.FC<{ label: string; value: string }> = ({ label, value }) => {
|
|
8
|
+
return (
|
|
9
|
+
<div style={{ display: 'grid', gridTemplateColumns: '0.25fr 0.75fr', margin: '0.25rem' }}>
|
|
10
|
+
<span style={{ minWidth: '5rem', fontWeight: 'bold' }}>{label}</span>
|
|
11
|
+
<span>{value}</span>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
interface ConfirmPromptProps {
|
|
17
|
+
onConfirm: void;
|
|
18
|
+
close: void;
|
|
19
|
+
patient: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const ConfirmPrompt: React.FC<ConfirmPromptProps> = ({ close, onConfirm, patient }) => {
|
|
23
|
+
const { t } = useTranslation();
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<div className="cds--modal-header">
|
|
27
|
+
<h3 className="cds--modal-header__heading">
|
|
28
|
+
{t('clientRegistryEmpty', `Patient ${patient?.firstName} ${patient?.lastName} found`)}
|
|
29
|
+
</h3>
|
|
30
|
+
</div>
|
|
31
|
+
<div className="cds--modal-content">
|
|
32
|
+
<p>
|
|
33
|
+
{t(
|
|
34
|
+
'patientDetailsFound',
|
|
35
|
+
'Patient information found in the registry, do you want to use the information to continue with registration?',
|
|
36
|
+
)}
|
|
37
|
+
</p>
|
|
38
|
+
<div style={{ display: 'flex', margin: '1rem' }}>
|
|
39
|
+
<ExtensionSlot
|
|
40
|
+
style={{ display: 'flex', alignItems: 'center' }}
|
|
41
|
+
extensionSlotName="patient-photo-slot"
|
|
42
|
+
state={{ patientName: `${patient?.firstName} ${patient?.lastName}` }}
|
|
43
|
+
/>
|
|
44
|
+
<div style={{ width: '100%', marginLeft: '0.625rem' }}>
|
|
45
|
+
<PatientInfo
|
|
46
|
+
label={t('patientName', 'Patient name')}
|
|
47
|
+
value={`${patient?.firstName} ${patient?.lastName}`}
|
|
48
|
+
/>
|
|
49
|
+
<PatientInfo
|
|
50
|
+
label={t('nationalId', 'National ID')}
|
|
51
|
+
value={patient?.identifications[0]?.identificationNumber}
|
|
52
|
+
/>
|
|
53
|
+
<PatientInfo label={t('age', 'Age')} value={age(patient?.dateOfBirth)} />
|
|
54
|
+
<PatientInfo label={t('dateOfBirth', 'Date of birth')} value={formatDate(new Date(patient?.dateOfBirth))} />
|
|
55
|
+
<PatientInfo label={t('gender', 'Gender')} value={capitalize(patient?.gender)} />
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
<div className="cds--modal-footer">
|
|
60
|
+
<Button kind="secondary" onClick={close}>
|
|
61
|
+
{t('cancel', 'Cancel')}
|
|
62
|
+
</Button>
|
|
63
|
+
<Button onClick={onConfirm}>{t('useValues', 'Use values')}</Button>
|
|
64
|
+
</div>
|
|
65
|
+
</>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default ConfirmPrompt;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { Button } from '@carbon/react';
|
|
4
|
+
|
|
5
|
+
interface EmptyPromptProps {
|
|
6
|
+
onConfirm: void;
|
|
7
|
+
close: void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const EmptyPrompt: React.FC<EmptyPromptProps> = ({ close, onConfirm }) => {
|
|
11
|
+
const { t } = useTranslation();
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
<div className="cds--modal-header">
|
|
15
|
+
<h3 className="cds--modal-header__heading">{t('clientRegistryEmpty', 'Create & Post Patient')}</h3>
|
|
16
|
+
</div>
|
|
17
|
+
<div className="cds--modal-content">
|
|
18
|
+
<p>
|
|
19
|
+
{t(
|
|
20
|
+
'patientNotFound',
|
|
21
|
+
'The patient records could not be found in Client registry, do you want to continue to create and post patient to registry',
|
|
22
|
+
)}
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
<div className="cds--modal-footer">
|
|
26
|
+
<Button kind="secondary" onClick={close}>
|
|
27
|
+
{t('cancel', 'Cancel')}
|
|
28
|
+
</Button>
|
|
29
|
+
<Button onClick={onConfirm}>{t('continue', 'Continue to registration')}</Button>
|
|
30
|
+
</div>
|
|
31
|
+
</>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default EmptyPrompt;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface ClientIdentification {
|
|
2
|
+
identificationType: string;
|
|
3
|
+
identificationNumber: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface ClientContact {
|
|
7
|
+
primaryPhone: string;
|
|
8
|
+
secondaryPhone?: string;
|
|
9
|
+
emailAddress?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ClientRegistryPatient {
|
|
13
|
+
clientExists: boolean;
|
|
14
|
+
client?: RegistryPatient;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface RegistryPatient {
|
|
18
|
+
clientNumber?: string;
|
|
19
|
+
firstName: string;
|
|
20
|
+
middleName: string;
|
|
21
|
+
lastName: string;
|
|
22
|
+
dateOfBirth: string;
|
|
23
|
+
maritalStatus?: string;
|
|
24
|
+
gender: string;
|
|
25
|
+
occupation?: string;
|
|
26
|
+
religion?: string;
|
|
27
|
+
educationLevel?: string;
|
|
28
|
+
country: string;
|
|
29
|
+
countyOfBirth?: string;
|
|
30
|
+
isAlive: boolean;
|
|
31
|
+
originFacilityKmflCode?: string;
|
|
32
|
+
isOnART?: string;
|
|
33
|
+
nascopCCCNumber?: string;
|
|
34
|
+
residence: {
|
|
35
|
+
county: string;
|
|
36
|
+
subCounty: string;
|
|
37
|
+
ward: string;
|
|
38
|
+
village: string;
|
|
39
|
+
landmark: string;
|
|
40
|
+
address: string;
|
|
41
|
+
};
|
|
42
|
+
identifications: Array<ClientIdentification>;
|
|
43
|
+
contact: ClientContact;
|
|
44
|
+
nextOfKins: Array<{
|
|
45
|
+
name: string;
|
|
46
|
+
relationship: string;
|
|
47
|
+
residence: string;
|
|
48
|
+
contact: ClientContact;
|
|
49
|
+
}>;
|
|
50
|
+
}
|
package/translations/en.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"address1": "Address line 1",
|
|
4
4
|
"address2": "Address line 2",
|
|
5
5
|
"addressHeader": "Address",
|
|
6
|
+
"age": "Age",
|
|
6
7
|
"allFieldsRequiredText": "All fields are required unless marked optional",
|
|
7
8
|
"autoGeneratedPlaceholderText": "Auto-generated",
|
|
8
9
|
"birthdayNotInTheFuture": "Birthday cannot be in the future",
|
|
@@ -11,11 +12,15 @@
|
|
|
11
12
|
"cancel": "Cancel",
|
|
12
13
|
"causeOfDeathInputLabel": "Cause of Death",
|
|
13
14
|
"cityVillage": "City",
|
|
15
|
+
"clientRegistryEmpty": "Create & Post Patient",
|
|
16
|
+
"clientVerificationWithClientRegistry": "Client verification with client registry",
|
|
14
17
|
"configure": "Configure",
|
|
15
18
|
"contactSection": "Contact Details",
|
|
19
|
+
"continue": "Continue",
|
|
16
20
|
"country": "Country",
|
|
17
21
|
"countyDistrict": "District",
|
|
18
22
|
"createNew": "Create New",
|
|
23
|
+
"dateOfBirth": "Date of birth",
|
|
19
24
|
"dateOfBirthLabelText": "Date of Birth",
|
|
20
25
|
"deathDateInputLabel": "Date of Death",
|
|
21
26
|
"deathdayNotInTheFuture": "Death day cannot be in the future",
|
|
@@ -38,6 +43,7 @@
|
|
|
38
43
|
"female": "Female",
|
|
39
44
|
"fieldErrorTitleMessage": "The following fields have errors:",
|
|
40
45
|
"fullNameLabelText": "Full Name",
|
|
46
|
+
"gender": "Gender",
|
|
41
47
|
"genderLabelText": "Sex",
|
|
42
48
|
"genderRequired": "Gender is required",
|
|
43
49
|
"genderUnspecified": "Gender is not specified",
|
|
@@ -54,6 +60,7 @@
|
|
|
54
60
|
"male": "Male",
|
|
55
61
|
"middleNameLabelText": "Middle Name",
|
|
56
62
|
"months": "Months",
|
|
63
|
+
"nationalId": "National ID",
|
|
57
64
|
"negativeMonths": "Negative months",
|
|
58
65
|
"negativeYears": "Negative years",
|
|
59
66
|
"no": "No",
|
|
@@ -62,8 +69,14 @@
|
|
|
62
69
|
"optional": "optional",
|
|
63
70
|
"other": "Other",
|
|
64
71
|
"patient": "Patient",
|
|
72
|
+
"patientDetailsFound": "Patient information found in the registry, do you want to use the information to continue with registration?",
|
|
73
|
+
"patientName": "Patient name",
|
|
65
74
|
"patientNameKnown": "Patient's Name is Known?",
|
|
75
|
+
"patientNotFound": "The patient records could not be found in Client registry, do you want to continue to create and post patient to registry",
|
|
76
|
+
"phoneEmailLabelText": "Phone, Email, etc.",
|
|
77
|
+
"phoneNumberInputLabelText": "Phone number",
|
|
66
78
|
"postalCode": "Postcode",
|
|
79
|
+
"postToRegistry": "Post to registry",
|
|
67
80
|
"registerPatient": "Register Patient",
|
|
68
81
|
"registrationSuccessToastDescription": "The patient can now be found by searching for them using their name or ID number",
|
|
69
82
|
"registrationSuccessToastTitle": "New Patient Created",
|
|
@@ -77,7 +90,8 @@
|
|
|
77
90
|
"resetIdentifierTooltip": "Reset",
|
|
78
91
|
"restoreRelationshipActionButton": "Undo",
|
|
79
92
|
"searchAddress": "Search address",
|
|
80
|
-
"
|
|
93
|
+
"selectCountry": "Select country",
|
|
94
|
+
"selectIdentifierType": "Select identifier type",
|
|
81
95
|
"sexFieldLabelText": "Sex",
|
|
82
96
|
"stateProvince": "State",
|
|
83
97
|
"stroke": "Stroke",
|
|
@@ -87,6 +101,8 @@
|
|
|
87
101
|
"updatePatient": "Update Patient",
|
|
88
102
|
"updationSuccessToastDescription": "The patient's information has been successfully updated",
|
|
89
103
|
"updationSuccessToastTitle": "Patient Details Updated",
|
|
104
|
+
"useValues": "Use values",
|
|
105
|
+
"validate": "Validate",
|
|
90
106
|
"years": "Years",
|
|
91
107
|
"yearsEstimateRequired": "Years estimate required",
|
|
92
108
|
"yes": "Yes"
|