@ampath/esm-patient-registration-app 9.2.0-next.16 → 9.2.0-next.18

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.
Files changed (40) hide show
  1. package/dist/2498.js +2 -0
  2. package/dist/2498.js.map +1 -0
  3. package/dist/4395.js +1 -1
  4. package/dist/4395.js.map +1 -1
  5. package/dist/5239.js +1 -1
  6. package/dist/5239.js.map +1 -1
  7. package/dist/6276.js +1 -1
  8. package/dist/6276.js.map +1 -1
  9. package/dist/6741.js +1 -0
  10. package/dist/6741.js.map +1 -0
  11. package/dist/7821.js +1 -1
  12. package/dist/7821.js.map +1 -1
  13. package/dist/8414.js +1 -1
  14. package/dist/8414.js.map +1 -1
  15. package/dist/8434.js +1 -1
  16. package/dist/8434.js.map +1 -1
  17. package/dist/8882.js +1 -1
  18. package/dist/8882.js.map +1 -1
  19. package/dist/main.js +1 -1
  20. package/dist/main.js.map +1 -1
  21. package/dist/openmrs-esm-patient-registration-app.js +1 -1
  22. package/dist/openmrs-esm-patient-registration-app.js.buildmanifest.json +56 -56
  23. package/dist/routes.json +1 -1
  24. package/package.json +1 -1
  25. package/src/patient-registration/client-registry/client-dependants/list/client-depandants.component.tsx +55 -0
  26. package/src/patient-registration/client-registry/client-details/client-details.tsx +42 -0
  27. package/src/patient-registration/client-registry/client-registry-search.component.tsx +156 -69
  28. package/src/patient-registration/client-registry/client-registry-search.scss +26 -0
  29. package/src/patient-registration/client-registry/client-registry.resource.ts +1 -1
  30. package/src/patient-registration/client-registry/hie-client-adapter.ts +56 -0
  31. package/src/patient-registration/client-registry/types/index.ts +200 -0
  32. package/src/patient-registration/client-registry-search/client-registry.resource.ts +1 -1
  33. package/src/patient-registration/custom-patient-registration.scss +6 -0
  34. package/src/patient-registration/patient-registration.component.tsx +23 -12
  35. package/src/patient-registration/patient-registration.resource.ts +4 -5
  36. package/dist/6996.js +0 -1
  37. package/dist/6996.js.map +0 -1
  38. package/dist/9933.js +0 -2
  39. package/dist/9933.js.map +0 -1
  40. /package/dist/{9933.js.LICENSE.txt → 2498.js.LICENSE.txt} +0 -0
@@ -1,13 +1,31 @@
1
1
  import React, { useState } from 'react';
2
- import { Button, TextInput, InlineLoading, InlineNotification, Dropdown } from '@carbon/react';
2
+ import {
3
+ Button,
4
+ TextInput,
5
+ InlineLoading,
6
+ InlineNotification,
7
+ Dropdown,
8
+ Modal,
9
+ ModalBody,
10
+ Tabs,
11
+ TabList,
12
+ Tab,
13
+ TabPanels,
14
+ TabPanel,
15
+ } from '@carbon/react';
3
16
  import { showSnackbar, useSession } from '@openmrs/esm-framework';
4
17
  import { useFormikContext } from 'formik';
5
- import styles from '../patient-registration.scss';
18
+ import styles from './client-registry-search.scss';
6
19
  import { requestCustomOtp, validateCustomOtp, fetchClientRegistryData } from './client-registry.resource';
7
20
  import { applyClientRegistryMapping } from './map-client-registry-to-form-utils';
21
+ import ClientDetails from './client-details/client-details';
22
+ import { type HieClient } from './types';
23
+ import ClientDependantList from './client-dependants/list/client-depandants.component';
8
24
 
9
25
  export interface ClientRegistryLookupSectionProps {
10
26
  onClientVerified?: () => void;
27
+ onModalClose: () => void;
28
+ open: boolean;
11
29
  }
12
30
 
13
31
  export type IdentifierType = 'National ID' | 'Alien ID' | 'Passport' | 'Mandate Number' | 'Refugee ID';
@@ -20,7 +38,11 @@ export const IDENTIFIER_TYPES: IdentifierType[] = [
20
38
  'Refugee ID',
21
39
  ];
22
40
 
23
- const ClientRegistryLookupSection: React.FC<ClientRegistryLookupSectionProps> = ({ onClientVerified }) => {
41
+ const ClientRegistryLookupSection: React.FC<ClientRegistryLookupSectionProps> = ({
42
+ onClientVerified,
43
+ open,
44
+ onModalClose,
45
+ }) => {
24
46
  const { setFieldValue } = useFormikContext<any>();
25
47
  const [identifierType, setIdentifierType] = useState<IdentifierType>('National ID');
26
48
  const [identifierValue, setIdentifierValue] = useState('');
@@ -31,6 +53,7 @@ const ClientRegistryLookupSection: React.FC<ClientRegistryLookupSectionProps> =
31
53
  const [sessionId, setSessionId] = useState('');
32
54
  const [error, setError] = useState<string>('');
33
55
  const { sessionLocation } = useSession();
56
+ const [client, setClient] = useState<HieClient>();
34
57
  const locationUuid = sessionLocation?.uuid;
35
58
 
36
59
  async function withTimeout<T>(promise: Promise<T>, ms = 10000): Promise<T> {
@@ -64,8 +87,7 @@ const ClientRegistryLookupSection: React.FC<ClientRegistryLookupSectionProps> =
64
87
  if (patients.length === 0) throw new Error('No matching patient found in Client Registry.');
65
88
 
66
89
  const patient = patients[0];
67
- applyClientRegistryMapping(patient, setFieldValue);
68
-
90
+ setClient(patient);
69
91
  showSnackbar({
70
92
  kind: 'success',
71
93
  title: 'Client Data Loaded',
@@ -156,77 +178,142 @@ const ClientRegistryLookupSection: React.FC<ClientRegistryLookupSectionProps> =
156
178
  }
157
179
  };
158
180
 
181
+ const useHieData = () => {
182
+ applyClientRegistryMapping(client, setFieldValue);
183
+ onModalClose();
184
+ };
185
+ const registerOnAfyaYangu = () => {
186
+ window.open('https://afyayangu.go.ke/', '_blank');
187
+ };
188
+
159
189
  return (
160
- <div className={styles.section}>
161
- <h4 className={styles.sectionTitle}>Client Registry Verification</h4>
190
+ <Modal
191
+ open={open}
192
+ size="lg"
193
+ onSecondarySubmit={onModalClose}
194
+ onRequestClose={onModalClose}
195
+ onRequestSubmit={registerOnAfyaYangu}
196
+ primaryButtonText="Register on Afya Yangu"
197
+ secondaryButtonText="Cancel">
198
+ <ModalBody>
199
+ <div className={styles.modalVerificationLayout}>
200
+ <h4 className={styles.sectionTitle}>Client Registry Verification</h4>
162
201
 
163
- {error && (
164
- <div className={styles.notificationSpacing}>
165
- <InlineNotification title="Error" subtitle={error} kind="error" lowContrast />
166
- </div>
167
- )}
168
-
169
- <div className={styles.fieldGroup}>
170
- <Dropdown
171
- id="identifier-type-dropdown"
172
- label="Identifier Type"
173
- titleText="Select Identifier Type"
174
- items={IDENTIFIER_TYPES}
175
- selectedItem={identifierType}
176
- onChange={({ selectedItem }) => setIdentifierType(selectedItem as IdentifierType)}
177
- disabled={otpSent}
178
- />
179
- </div>
180
-
181
- <div className={styles.fieldGroup}>
182
- <TextInput
183
- id="identifier-value"
184
- labelText={`${identifierType} Value`}
185
- value={identifierValue}
186
- onChange={(e) => setIdentifierValue(e.target.value)}
187
- disabled={otpSent}
188
- placeholder={`Enter ${identifierType.toLowerCase()} value`}
189
- />
190
- </div>
191
-
192
- <div style={{ marginTop: '0.75rem' }}>
193
- {!otpSent ? (
194
- <Button kind="secondary" onClick={handleSendOtp} disabled={loading}>
195
- {loading ? <InlineLoading description="Sending..." /> : 'Send OTP'}
196
- </Button>
197
- ) : (
198
- <>
199
- <div style={{ marginTop: '0.75rem' }}>
200
- <TextInput
201
- id="otp-input"
202
- labelText="Enter OTP"
203
- value={otp}
204
- onChange={(e) => setOtp(e.target.value)}
205
- disabled={otpVerified}
206
- placeholder="Enter the code sent to your phone"
207
- />
202
+ {error && (
203
+ <div className={styles.notificationSpacing}>
204
+ <InlineNotification title="Error" subtitle={error} kind="error" lowContrast />
208
205
  </div>
206
+ )}
207
+ {!client ? (
208
+ <div className={styles.formSection}>
209
+ {!otpSent ? (
210
+ <>
211
+ <div className={styles.formRow}>
212
+ <div className={styles.formControl}>
213
+ <Dropdown
214
+ id="identifier-type-dropdown"
215
+ label="Identifier Type"
216
+ titleText="Select Identifier Type"
217
+ items={IDENTIFIER_TYPES}
218
+ selectedItem={identifierType}
219
+ onChange={({ selectedItem }) => setIdentifierType(selectedItem as IdentifierType)}
220
+ disabled={otpSent}
221
+ />
222
+ </div>
209
223
 
210
- <div style={{ marginTop: '0.5rem', display: 'flex', gap: '0.5rem' }}>
211
- {!otpVerified ? (
212
- <Button size="sm" kind="secondary" onClick={handleVerifyOtp} disabled={loading}>
213
- {loading ? <InlineLoading description="Verifying..." /> : 'Verify OTP'}
214
- </Button>
224
+ <div className={styles.formControl}>
225
+ <TextInput
226
+ id="identifier-value"
227
+ labelText={`${identifierType} Value`}
228
+ value={identifierValue}
229
+ onChange={(e) => setIdentifierValue(e.target.value)}
230
+ disabled={otpSent}
231
+ placeholder={`Enter ${identifierType.toLowerCase()} value`}
232
+ />
233
+ </div>
234
+ </div>
235
+ <div className={styles.formRow}>
236
+ <div className={styles.formControl}>
237
+ <Button kind="primary" onClick={handleSendOtp} disabled={loading}>
238
+ {loading ? <InlineLoading description="Sending..." /> : 'Send OTP'}
239
+ </Button>
240
+ </div>
241
+ </div>
242
+ </>
215
243
  ) : (
216
- <Button kind="primary" onClick={handleFetchCR} disabled={loading}>
217
- {loading ? <InlineLoading description="Fetching..." /> : 'Fetch Client Registry Data'}
218
- </Button>
219
- )}
220
- {!otpVerified && (
221
- <Button size="sm" kind="tertiary" onClick={() => setOtpSent(false)}>
222
- Change ID
223
- </Button>
244
+ <>
245
+ {!otpVerified ? (
246
+ <>
247
+ <div className={styles.formRow}>
248
+ <div className={styles.formControl}>
249
+ <TextInput
250
+ id="otp-input"
251
+ labelText="Enter OTP"
252
+ value={otp}
253
+ onChange={(e) => setOtp(e.target.value)}
254
+ disabled={otpVerified}
255
+ placeholder="Enter the code sent to your phone"
256
+ />
257
+ </div>
258
+ </div>
259
+ <div className={styles.formRow}>
260
+ <div className={styles.actionBtn}>
261
+ <Button kind="primary" onClick={handleVerifyOtp} disabled={loading}>
262
+ {loading ? <InlineLoading description="Verifying..." /> : 'Verify OTP'}
263
+ </Button>
264
+ </div>
265
+ <div className={styles.actionBtn}>
266
+ <Button kind="secondary" onClick={handleSendOtp} disabled={loading}>
267
+ {loading ? <InlineLoading description="Resending OTP..." /> : 'Resend OTP'}
268
+ </Button>
269
+ </div>
270
+ <div className={styles.actionBtn}>
271
+ <Button kind="tertiary" onClick={() => setOtpSent(false)}>
272
+ Back
273
+ </Button>
274
+ </div>
275
+ </div>
276
+ </>
277
+ ) : (
278
+ <>
279
+ <div className={styles.formRow}>
280
+ <div className={styles.formControl}>
281
+ <Button kind="primary" onClick={handleFetchCR} disabled={loading}>
282
+ {loading ? <InlineLoading description="Fetching..." /> : 'Fetch Client Registry Data'}
283
+ </Button>
284
+ </div>
285
+ </div>
286
+ </>
287
+ )}
288
+ </>
224
289
  )}
225
290
  </div>
226
- </>
227
- )}
228
- </div>
229
- </div>
291
+ ) : (
292
+ <></>
293
+ )}
294
+
295
+ {otpVerified && client ? (
296
+ <div className="clientDataSection">
297
+ <Tabs>
298
+ <TabList contained>
299
+ <Tab>Patient</Tab>
300
+ <Tab>Dependants</Tab>
301
+ </TabList>
302
+ <TabPanels>
303
+ <TabPanel>{client ? <ClientDetails client={client} /> : <></>}</TabPanel>
304
+ <TabPanel>
305
+ {client.dependants ? <ClientDependantList hieDependants={client.dependants} /> : <></>}
306
+ </TabPanel>
307
+ </TabPanels>
308
+ </Tabs>
309
+ <Button onClick={useHieData}>Use Data</Button>
310
+ </div>
311
+ ) : (
312
+ <></>
313
+ )}
314
+ </div>
315
+ </ModalBody>
316
+ </Modal>
230
317
  );
231
318
  };
232
319
 
@@ -0,0 +1,26 @@
1
+ .modalVerificationLayout {
2
+ display: flex;
3
+ flex-direction: column;
4
+ row-gap: 10px;
5
+ width: 100%;
6
+ }
7
+ .formSection {
8
+ display: flex;
9
+ flex-direction: column;
10
+ width: 100%;
11
+ }
12
+ .formControl {
13
+ width: 45%;
14
+ }
15
+ .formRow {
16
+ display: flex;
17
+ flex-direction: row;
18
+ width: 100%;
19
+ column-gap: 10px;
20
+ padding-top: 5px;
21
+ padding-bottom: 5px;
22
+ }
23
+ .actionBtn {
24
+ display: flex;
25
+ flex-direction: column;
26
+ }
@@ -1,4 +1,4 @@
1
- const HIE_BASE_URL = 'https://ngx.ampath.or.ke/hie';
1
+ const HIE_BASE_URL = 'https://staging.ampath.or.ke/hie';
2
2
 
3
3
  export type RequestCustomOtpDto = {
4
4
  identificationNumber: string | number;
@@ -0,0 +1,56 @@
1
+ import { type HieIdentifications, type HieClient } from './types';
2
+
3
+ const clientDatailsFields = [
4
+ 'id',
5
+ 'other_identifications',
6
+ 'first_name',
7
+ 'middle_name',
8
+ 'last_name',
9
+ 'gender',
10
+ 'date_of_birth',
11
+ 'is_alive',
12
+ 'deceased_datetime',
13
+ 'phone',
14
+ 'email',
15
+ 'civil_status',
16
+ 'place_of_birth',
17
+ 'citizenship',
18
+ 'country',
19
+ 'county',
20
+ 'sub_county',
21
+ 'ward',
22
+ 'village_estate',
23
+ 'longitude',
24
+ 'latitude',
25
+ 'identification_type',
26
+ ];
27
+
28
+ export function generateHieClientDetails(hieClient: HieClient) {
29
+ let data = {};
30
+ Object.keys(hieClient)
31
+ .filter((key) => {
32
+ return clientDatailsFields.includes(key);
33
+ })
34
+ .forEach((key) => {
35
+ if (key === 'other_identifications') {
36
+ const otherIds = generateOtherIdentifications(hieClient[key]);
37
+ data = {
38
+ ...data,
39
+ ...otherIds,
40
+ };
41
+ } else if (key === 'identification_type') {
42
+ data[hieClient['identification_type']] = hieClient.identification_number;
43
+ } else {
44
+ const value = hieClient[key];
45
+ data[key] = value;
46
+ }
47
+ });
48
+ return data;
49
+ }
50
+ function generateOtherIdentifications(hieIdentifications: HieIdentifications[]) {
51
+ const other = {};
52
+ hieIdentifications.forEach((id) => {
53
+ other[id.identification_type] = id.identification_number;
54
+ });
55
+ return other;
56
+ }
@@ -0,0 +1,200 @@
1
+ export enum HieIdentificationType {
2
+ NationalID = 'National ID',
3
+ SHANumber = 'SHA Number',
4
+ HouseholdNumber = 'Household Number',
5
+ RefugeeID = 'Refugee ID',
6
+ AlienID = 'Alien ID',
7
+ MandateNumber = 'Mandate Number',
8
+ Cr = 'id',
9
+ TemporaryDependantID = 'Temporary Dependant ID',
10
+ }
11
+
12
+ export interface HieIdentifications {
13
+ identification_number: string;
14
+ identification_type: HieIdentificationType;
15
+ }
16
+
17
+ export interface HieDependant {
18
+ date_added: string;
19
+ relationship: string;
20
+ total: number;
21
+ result: HieClient[];
22
+ }
23
+
24
+ export interface AlternateContact {
25
+ contact_type: string;
26
+ contact_id: string;
27
+ contact_name: string;
28
+ relationship: string;
29
+ remarks: string;
30
+ }
31
+
32
+ export interface HieClient {
33
+ resourceType: string;
34
+ id: string;
35
+ meta: {
36
+ versionId: string;
37
+ creationTime: string;
38
+ lastUpdated: string;
39
+ source: string;
40
+ };
41
+ originSystem: {
42
+ system: string;
43
+ record_id: string;
44
+ };
45
+ title: string;
46
+ first_name: string;
47
+ middle_name: string;
48
+ last_name: string;
49
+ gender: string;
50
+ date_of_birth: string;
51
+ place_of_birth: string;
52
+ person_with_disability: number;
53
+ citizenship: string;
54
+ kra_pin: string;
55
+ preferred_primary_care_network: string;
56
+ employment_type: string;
57
+ domestic_worker_type: string;
58
+ civil_status: string;
59
+ identification_type: HieIdentificationType;
60
+ identification_number: string;
61
+ other_identifications: HieIdentifications[];
62
+ dependants: HieDependant[];
63
+ is_alive: number;
64
+ deceased_datetime: string;
65
+ phone: string;
66
+ biometrics_verified: number;
67
+ biometrics_score: number;
68
+ email: string;
69
+ country: string;
70
+ county: string;
71
+ sub_county: string;
72
+ ward: string;
73
+ village_estate: string;
74
+ building_house_no: string;
75
+ latitude: string;
76
+ longitude: string;
77
+ province_state_country: string;
78
+ zip_code: string;
79
+ identification_residence: string;
80
+ employer_name: string;
81
+ employer_pin: string;
82
+ disability_category: string;
83
+ disability_subcategory: string;
84
+ disability_cause: string;
85
+ in_lawful_custody: string;
86
+ admission_remand_number: string;
87
+ document_uploads: any[];
88
+ alternative_contacts: AlternateContact[];
89
+ gross_income: number;
90
+ gross_income_currency: string;
91
+ postal_address: string;
92
+ estimated_contribution: number;
93
+ estimated_annual_contribution: number;
94
+ city: string;
95
+ id_serial: string;
96
+ learning_institution_code: string;
97
+ learning_institution_name: string;
98
+ grade_level: string;
99
+ admission_number: string;
100
+ expected_year_of_graduation: string;
101
+ unconfirmed_dependants: HieDependant[];
102
+ is_agent: number;
103
+ agent_id: string;
104
+ }
105
+
106
+ export interface HieClientSearchDto {
107
+ identificationNumber: number | string;
108
+ identificationType: HieIdentificationType;
109
+ locationUuid: string;
110
+ }
111
+
112
+ export interface HieAmrsObj {
113
+ key: string;
114
+ title: string;
115
+ hieValue: string | number | boolean;
116
+ amrsValue: string | number | boolean;
117
+ }
118
+
119
+ export interface ValidateHieCustomOtpDto {
120
+ sessionId: string;
121
+ otp: number | string;
122
+ locationUuid: string;
123
+ }
124
+
125
+ export type HieOtpValidationStatus = 'valid' | 'invalid';
126
+
127
+ export interface ValidateHieCustomOtpResponse {
128
+ data: {
129
+ identification_type: string;
130
+ identification_number: string;
131
+ status: HieOtpValidationStatus;
132
+ };
133
+ source?: string;
134
+ }
135
+
136
+ export interface ValidateHieCustomOtpErrorResponse {
137
+ error: string;
138
+ details: string;
139
+ }
140
+
141
+ export interface RequestCustomOtpDto {
142
+ identificationNumber: string | number;
143
+ identificationType: string;
144
+ locationUuid: string;
145
+ }
146
+
147
+ export interface RequestCustomOtpResponse {
148
+ message: string;
149
+ sessionId: string;
150
+ maskedPhone: string;
151
+ }
152
+ export interface RequestCustomOtpErrorResponse {
153
+ error: string;
154
+ details: string;
155
+ }
156
+
157
+ export interface HieClientDependant extends HieClient {
158
+ date_added: string;
159
+ relationship: string;
160
+ }
161
+
162
+ export interface HieFacility {
163
+ id: string;
164
+ facility_name: string;
165
+ registration_number: string;
166
+ facility_code: string;
167
+ regulator: string;
168
+ facility_level: string;
169
+ facility_category: string;
170
+ facility_owner: string;
171
+ facility_type: string;
172
+ county: string;
173
+ sub_county: string;
174
+ ward: string;
175
+ found: number;
176
+ approved: number;
177
+ operational_status: string;
178
+ current_license_expiry_date: string;
179
+ }
180
+
181
+ export interface HieFacilitySearchResponse {
182
+ message: HieFacility;
183
+ }
184
+
185
+ export interface FacilitySearchFilter {
186
+ filterType: string;
187
+ filterValue: string;
188
+ locationUuid: string;
189
+ }
190
+
191
+ export enum FacilitySearchFilterType {
192
+ location = 'location',
193
+ facilityCode = 'facilityCode',
194
+ registrationNumber = 'registrationNumber',
195
+ }
196
+
197
+ export interface PatientShrSummaryFilter {
198
+ cr_id: string;
199
+ locationUuid: string;
200
+ }
@@ -10,7 +10,7 @@ import {
10
10
  } from './client-registry.types';
11
11
  import { mapAmrsPatientRelationship } from './map-client-registry-to-form-utils';
12
12
 
13
- const HIE_BASE_URL = 'https://ngx.ampath.or.ke/hie';
13
+ const HIE_BASE_URL = 'https://staging.ampath.or.ke/hie';
14
14
 
15
15
  async function postJson<T>(url: string, payload: unknown): Promise<T> {
16
16
  const response = await fetch(url, {
@@ -0,0 +1,6 @@
1
+ .patientVerification {
2
+ display: flex;
3
+ flex-direction: column;
4
+ row-gap: 10px;
5
+ padding-bottom: 10px;
6
+ }
@@ -25,6 +25,7 @@ import { type SavePatientForm, SavePatientTransactionManager } from './form-mana
25
25
  import { useInitialAddressFieldValues, useInitialFormValues, usePatientUuidMap } from './patient-registration-hooks';
26
26
  import BeforeSavePrompt from './before-save-prompt';
27
27
  import styles from './patient-registration.scss';
28
+ import customStyles from './custom-patient-registration.scss';
28
29
  import ClientRegistryLookupSection from './client-registry/client-registry-search.component';
29
30
 
30
31
  let exportedInitialFormValuesForTesting = {} as FormValues;
@@ -65,6 +66,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
65
66
  const { data: photo } = usePatientPhoto(patientToEdit?.id);
66
67
  const savePatientTransactionManager = useRef(new SavePatientTransactionManager());
67
68
  const validationSchema = getValidationSchema(config, t);
69
+ const [showVerifyModal, setShowVerifyModal] = useState<boolean>(false);
68
70
 
69
71
  useEffect(() => {
70
72
  exportedInitialFormValuesForTesting = initialFormValues;
@@ -166,6 +168,13 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
166
168
  }
167
169
  };
168
170
 
171
+ const openVerifyModal = () => {
172
+ setShowVerifyModal(true);
173
+ };
174
+ const closeVerifyModal = () => {
175
+ setShowVerifyModal(false);
176
+ };
177
+
169
178
  const createContextValue = useCallback(
170
179
  (formikProps) => ({
171
180
  identifierTypes,
@@ -244,20 +253,22 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
244
253
  </div>
245
254
  <div className={styles.infoGrid}>
246
255
  <PatientRegistrationContextProvider value={createContextValue(props)}>
247
- <div>
248
- {!isClientVerified && !inEditMode && (
249
- <div className={styles.notificationSpacing} style={{ marginTop: '1rem' }}>
250
- <InlineNotification
251
- title="Verification required"
252
- subtitle="Please complete Client Registry OTP verification before proceeding with registration."
253
- kind="info"
254
- lowContrast
256
+ <div className={customStyles.patientVerification}>
257
+ <h4>Patient Verification</h4>
258
+ <Button onClick={openVerifyModal}>Verify CR</Button>
259
+ {showVerifyModal ? (
260
+ <>
261
+ <ClientRegistryLookupSection
262
+ onClientVerified={() => setIsClientVerified(true)}
263
+ onModalClose={closeVerifyModal}
264
+ open={showVerifyModal}
255
265
  />
256
- </div>
266
+ </>
267
+ ) : (
268
+ <></>
257
269
  )}
258
-
259
- <ClientRegistryLookupSection onClientVerified={() => setIsClientVerified(true)} />
260
-
270
+ </div>
271
+ <div>
261
272
  {sections.map((section, index) => (
262
273
  <SectionWrapper
263
274
  key={`registration-section-${section.id}`}
@@ -47,21 +47,20 @@ export function saveEncounter(encounter: Encounter) {
47
47
 
48
48
  export function generateIdentifier(source: string) {
49
49
  const abortController = new AbortController();
50
- return openmrsFetch(`https://ngx.ampath.or.ke/amrs-id-generator/generateidentifier`, {
50
+
51
+ return openmrsFetch(`${restBaseUrl}/idgen/identifiersource/${source}/identifier`, {
51
52
  headers: {
52
53
  'Content-Type': 'application/json',
53
54
  },
54
55
  method: 'POST',
55
- body: {
56
- user: 1,
57
- },
56
+ body: {},
58
57
  signal: abortController.signal,
59
58
  });
60
59
  }
61
60
 
62
61
  export async function generateAmrsUniversalIdentifier() {
63
62
  const abortController = new AbortController();
64
- const resp = await openmrsFetch(`https://ngx.ampath.or.ke/amrs-id-generator/generateidentifier`, {
63
+ const resp = await openmrsFetch(`https://staging.ampath.or.ke/amrs-id-generator/generateidentifier`, {
65
64
  headers: {
66
65
  'Content-Type': 'application/json',
67
66
  },