@eka-care/abha-stg 0.1.35 → 0.1.37

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 (115) hide show
  1. package/{index.html → dist/index.html} +2 -1
  2. package/dist/sdk/abha/css/abha.css +1 -0
  3. package/dist/sdk/abha/js/abha.js +63 -0
  4. package/package.json +1 -1
  5. package/package/styles/pds2/border.ts +0 -69
  6. package/package/styles/pds2/colors.ts +0 -70
  7. package/package/styles/pds2/spacing.ts +0 -1007
  8. package/package/tailwind/tailwind.config.ts +0 -124
  9. package/postcss.config.js +0 -6
  10. package/scripts/build-purged-css.cjs +0 -70
  11. package/src/App.css +0 -0
  12. package/src/App.tsx +0 -43
  13. package/src/api-queries/aorta-go/v3/get-profile-patient.ts +0 -32
  14. package/src/api-queries/aorta-go/v3/get-profiles-phr-user.ts +0 -26
  15. package/src/api-queries/aorta-go/v3/post-auth-init-v2.ts +0 -34
  16. package/src/api-queries/aorta-go/v3/post-auth-logout-v2.ts +0 -32
  17. package/src/api-queries/aorta-go/v3/post-auth-verify-v2.ts +0 -38
  18. package/src/api-queries/aorta-go/v3/post-profile-switch.ts +0 -39
  19. package/src/api-queries/ndhm/get-abdm-register-suggest.ts +0 -37
  20. package/src/api-queries/ndhm/get-pincode-details.ts +0 -28
  21. package/src/api-queries/ndhm/post-abdm-login-init.ts +0 -37
  22. package/src/api-queries/ndhm/post-abdm-login-phr.ts +0 -37
  23. package/src/api-queries/ndhm/post-abdm-login-verify.ts +0 -37
  24. package/src/api-queries/ndhm/post-abdm-profile-eka-link-phr.ts +0 -40
  25. package/src/api-queries/ndhm/post-abdm-profile-eka.ts +0 -66
  26. package/src/api-queries/ndhm/post-abdm-register-abha-number-create-phr.ts +0 -37
  27. package/src/api-queries/ndhm/post-abdm-register-mobile-create-phr.ts +0 -66
  28. package/src/api-queries/ndhm/post-abdm-register-mobile-resend-otp.ts +0 -32
  29. package/src/api-queries/ndhm/post-abdm-register-mobile-verify.ts +0 -38
  30. package/src/api-queries/ndhm/post-abdm-register-phr-check.ts +0 -34
  31. package/src/api-queries/ndhm/post-register-aadhaar-create-phr.ts +0 -37
  32. package/src/api-queries/ndhm/post-register-aadhaar-init.ts +0 -34
  33. package/src/api-queries/ndhm/post-register-aadhaar-mobile-resend-otp.ts +0 -34
  34. package/src/api-queries/ndhm/post-register-aadhaar-mobile-verify.ts +0 -37
  35. package/src/api-queries/ndhm/post-register-aadhaar-resend-otp.ts +0 -34
  36. package/src/api-queries/ndhm/post-register-aadhaar-verify.ts +0 -40
  37. package/src/api-queries/ndhm/post-register-mobile-init.ts +0 -34
  38. package/src/api-queries/use-get-profiles-patient.ts +0 -12
  39. package/src/api-queries/use-get-profiles-phr-user.ts +0 -28
  40. package/src/api-queries/use-post-abdm-login-verify-v1.ts +0 -26
  41. package/src/api-queries/use-post-auth-verify-v2.ts +0 -50
  42. package/src/api-queries/use-post-profile-switch.ts +0 -58
  43. package/src/api-queries/use-post-register-mobile-create-phr.ts +0 -39
  44. package/src/api-queries/user-post-abdm-profile-login-phr.ts +0 -26
  45. package/src/assets/Success.json +0 -1
  46. package/src/assets/react.svg +0 -1
  47. package/src/atoms/button/custom-button.tsx +0 -32
  48. package/src/atoms/button/index.tsx +0 -40
  49. package/src/atoms/button/types.d.ts +0 -31
  50. package/src/atoms/header.tsx +0 -25
  51. package/src/atoms/input-field/index.tsx +0 -63
  52. package/src/atoms/input-field/patient-input-field.tsx +0 -16
  53. package/src/atoms/input-field/types.ts +0 -24
  54. package/src/atoms/pds2-otp-input/index.tsx +0 -35
  55. package/src/atoms/pds2-otp-input/types.d.ts +0 -3
  56. package/src/atoms/single-input-chip/index.tsx +0 -32
  57. package/src/atoms/single-input-chip/types.ts +0 -6
  58. package/src/atoms/spinner.tsx +0 -33
  59. package/src/atoms/text-separator.tsx +0 -11
  60. package/src/atoms/ui/spinner.tsx +0 -75
  61. package/src/constants/constants.ts +0 -376
  62. package/src/fetch-client/index.ts +0 -164
  63. package/src/index.css +0 -152
  64. package/src/main.tsx +0 -374
  65. package/src/molecules/abha/bottom-sheet/bottom-sheet-wrapper.tsx +0 -40
  66. package/src/molecules/abha/bottom-sheet/index.tsx +0 -66
  67. package/src/molecules/abha/spaced-input-component.tsx +0 -168
  68. package/src/molecules/copyright-year.tsx +0 -16
  69. package/src/molecules/exit-popup/index.tsx +0 -101
  70. package/src/molecules/pds2-otp-component/index.tsx +0 -147
  71. package/src/organisms/abha/abha-header.tsx +0 -25
  72. package/src/organisms/abha/abha-stepper.tsx +0 -83
  73. package/src/organisms/abha/error-bottom-sheet.tsx +0 -27
  74. package/src/organisms/abha/otp-card.tsx +0 -99
  75. package/src/organisms/abha/verification-status.tsx +0 -30
  76. package/src/organisms/choose-language/choose-language.tsx +0 -53
  77. package/src/organisms/choose-language/types.ts +0 -10
  78. package/src/organisms/screen-switcher/screen-switcher.tsx +0 -80
  79. package/src/routes/abha-aadhaar-verification-status-screen.tsx +0 -246
  80. package/src/routes/abha-created-screen.tsx +0 -45
  81. package/src/routes/abha-login-otp-verify-screen.tsx +0 -519
  82. package/src/routes/abha-mobile-linking-status-screen.tsx +0 -267
  83. package/src/routes/abha-otp-and-mobile-screen.tsx +0 -435
  84. package/src/routes/abha-phone-number-verification-screen.tsx +0 -388
  85. package/src/routes/create-abha-address-screen.tsx +0 -928
  86. package/src/routes/create-abha-with-aadhaar-screen.tsx +0 -986
  87. package/src/routes/create-eka-profile-screen.tsx +0 -831
  88. package/src/routes/get-all-profiles-screen.tsx +0 -161
  89. package/src/routes/login-or-create-abha-address-screen.tsx +0 -1056
  90. package/src/routes/login-with-abha-screen.tsx +0 -454
  91. package/src/routes/select-abha-from-list-screen.tsx +0 -792
  92. package/src/routes/select-eka-profile-screen.tsx +0 -446
  93. package/src/routes/utils/trackAbhaEvent.ts +0 -41
  94. package/src/stores/auth-abha-store/index.ts +0 -152
  95. package/src/stores/auth-abha-store/types.ts +0 -217
  96. package/src/utils/mock-auth-response.ts +0 -29
  97. package/src/utils/send-event-utils.ts +0 -76
  98. package/src/utils/validations.ts +0 -89
  99. package/src/vite-env.d.ts +0 -1
  100. package/tailwind.config.ts +0 -9
  101. package/tsconfig.json +0 -25
  102. package/tsconfig.node.json +0 -10
  103. package/tsconfig.node.tsbuildinfo +0 -1
  104. package/tsconfig.tsbuildinfo +0 -1
  105. package/vite.config.d.ts +0 -2
  106. package/vite.config.js +0 -30
  107. package/vite.config.ts +0 -35
  108. /package/{public → dist}/images/adhaar.webp +0 -0
  109. /package/{public → dist}/images/at-the-rate.webp +0 -0
  110. /package/{public → dist}/images/avatar.webp +0 -0
  111. /package/{public → dist}/images/ayushman-bharat.webp +0 -0
  112. /package/{public → dist}/images/circle-checkmark.webp +0 -0
  113. /package/{public → dist}/images/link-abha.webp +0 -0
  114. /package/{public → dist}/images/national-authority.webp +0 -0
  115. /package/{public → dist}/images/three-dots.webp +0 -0
@@ -1,831 +0,0 @@
1
- import { ArrowLeftRegularIcon } from '@eka-care/icons';
2
- import { ABHA_AUTH_FLOW_METHOD, ABHA_V3_SKIP_STATES, GET_EXTRA_HEADERS, LOADING_STATE } from '../constants/constants';
3
- import { useEffect, useMemo, useState } from 'react';
4
- import Pds2Button from '../atoms/button';
5
- import Pds2Header from '../atoms/header';
6
- import Pds2InputField from '../atoms/input-field';
7
- import Pds2SingleInputChip from '../atoms/single-input-chip';
8
- import useAuthAbhaStore from '../stores/auth-abha-store';
9
- import { SCREEN_NAMES } from '../stores/auth-abha-store/types';
10
- import { TVerifyToken } from '../api-queries/use-post-auth-verify-v2';
11
- import AbhaErrorBottomSheet from '../organisms/abha/error-bottom-sheet';
12
- import { TCachedQueryPhrResponse } from '../api-queries/use-post-register-mobile-create-phr';
13
- import { queryClient } from '../App';
14
- import usePostProfileSwitch from '../api-queries/use-post-profile-switch';
15
- import ExitPopup from '../molecules/exit-popup';
16
-
17
- import AbhaStepper from '../organisms/abha/abha-stepper';
18
- import handleSendEvent from '../utils/send-event-utils';
19
- import getPincodeDetails from '../api-queries/ndhm/get-pincode-details';
20
- import postAbdmProfileEka from '../api-queries/ndhm/post-abdm-profile-eka';
21
-
22
- const CreateEkaProfileScreen = () => {
23
- const screen = useAuthAbhaStore((state) => state.screen);
24
- const selectedAbhaAddress = useAuthAbhaStore((state) => state.selectedAbhaAddress);
25
- const setBottomsheetErrorInfo = useAuthAbhaStore((state) => state.setBottomsheetErrorInfo);
26
- const clearAbhaAuthStore = useAuthAbhaStore((state) => state.clearAbhaAuthStore);
27
- const goBackLoginScreen = useAuthAbhaStore((state) => state.goBackLoginScreen);
28
- const [isLoading, setIsLoading] = useState<LOADING_STATE>(LOADING_STATE.IDLE);
29
- const [profileData, setProfileData] = useState<TProfileData>({
30
- firstname: '',
31
- lastname: '',
32
- date_of_birth: '',
33
- pincode: '',
34
- gender: '',
35
- });
36
- const [error, setError] = useState<TProfileDataError>({
37
- firstname: '',
38
- lastname: '',
39
- date_of_birth: '',
40
- pincode: '',
41
- gender: '',
42
- });
43
- const [createProfileError, setCreateProfileError] = useState<string | null>(null);
44
- const { mutateAsync: postProfileSwitchMutate } = usePostProfileSwitch();
45
- const [isExitPopupOpen, setIsExitPopupOpen] = useState<boolean>(false);
46
- const ekaProfileInfo = useAuthAbhaStore((state) => state.ekaProfileInfo);
47
- const setEkaProfileInfo = useAuthAbhaStore((state) => state.setEkaProfileInfo);
48
- const setScreen = useAuthAbhaStore((state) => state.setScreen);
49
- const topScreen = screen[screen.length - 1];
50
- const aadhaarVerificationSkipStateStatus = useAuthAbhaStore(
51
- (state) => state.aadhaarVerificationSkipStateStatus
52
- );
53
-
54
- // const authVerifyV2Response = queryClient.getQueryData<TVerifyToken>(['authVerifyV2Response']);
55
- const cachedProfilePhrResponse = queryClient.getQueryData<TCachedQueryPhrResponse>([
56
- 'abdmProfilePhrResponse',
57
- ]);
58
-
59
- const selectedFlowMethod = useAuthAbhaStore((state) => state.abhaAuthFlowMethod);
60
- const [profilePatient, setprofilePatient] = useState<TProfileData>({
61
- firstname: '',
62
- lastname: '',
63
- date_of_birth: '',
64
- pincode: '',
65
- gender: '',
66
- });
67
-
68
- const isDocAppRequest = useAuthAbhaStore((state) => state.isDocAppRequest);
69
- const clientId = useAuthAbhaStore((state) => state.clientId);
70
- const isEkaAppLogin = useAuthAbhaStore((state) => state.isEkaAppLogin);
71
- const isNewLoginOrCreateFlow = useAuthAbhaStore((state) => state.isNewLoginOrCreateFlow);
72
- const txnId = useAuthAbhaStore((state) => state.txnId);
73
- const extra_headers = GET_EXTRA_HEADERS();
74
- const [pincodeApiError, setPincodeApiError] = useState<string | null>(null);
75
- const selectedMethod = useAuthAbhaStore((state) => state.abhaAuthFlowMethod);
76
-
77
- const trackAbhaEvent = ({ name, data = {} }: { name: string; data?: Record<string, any> }) => {
78
- const baseProps = {
79
- login_platform: clientId,
80
- is_eka_app_login: isEkaAppLogin ? 'true' : 'false',
81
- is_new_login_or_create_flow: isNewLoginOrCreateFlow ? 'true' : 'false',
82
- txn_id: txnId || 'missing txnId',
83
- oid: extra_headers?.['X-User-ID'] ? 'true' : 'false',
84
- access_token: extra_headers?.['auth'] ? 'true' : 'false',
85
- flow: selectedMethod ?? ""
86
- };
87
-
88
- const eventData = {
89
- ...baseProps,
90
- ...data,
91
- };
92
-
93
- handleSendEvent({
94
- eventName: name,
95
- eventData,
96
- });
97
-
98
- window.curio?.pushToMixpanel?.(name, eventData);
99
- };
100
-
101
- // Run on component mount or when clientId changes
102
- useEffect(() => {
103
- // Track "create profile screen" page view
104
- trackAbhaEvent({
105
- name: 'page_view',
106
- data: {
107
- page_view: 'create_profile_screen',
108
- },
109
- });
110
- }, [clientId]);
111
-
112
- // Run on component mount to set status bar color
113
- useEffect(() => {
114
- // Change status bar to light gray
115
- if (window.EkaAbha?.changeStatusBarColor) {
116
- window.EkaAbha.changeStatusBarColor('#F2F4F7');
117
- return () => {
118
- // Cleanup: reset color to white on unmount
119
- if (window.EkaAbha?.changeStatusBarColor) window?.EkaAbha?.changeStatusBarColor('#FFFFFF');
120
- };
121
- }
122
- }, []); // Run only once on mount
123
-
124
- useEffect(() => {
125
- // If PHR data is available, use it to prefill form
126
- if (cachedProfilePhrResponse) {
127
- const {
128
- first_name,
129
- last_name,
130
- gender,
131
- pincode,
132
- day_of_birth,
133
- month_of_birth,
134
- year_of_birth,
135
- } = cachedProfilePhrResponse;
136
-
137
- const correctedDay = day_of_birth === 0 ? 1 : day_of_birth;
138
- const correctedMonth = month_of_birth === 0 ? 1 : month_of_birth;
139
-
140
- const dateOfBirth = `${year_of_birth}-${String(correctedMonth).padStart(2, '0')}-${String(correctedDay).padStart(2, '0')}`;
141
-
142
- trackAbhaEvent({
143
- name: 'profile_data_set_from_phr_cache',
144
- data: {
145
- source: 'phr_cache',
146
- date_of_birth: dateOfBirth,
147
- firstname: first_name ?? 'missing',
148
- lastname: last_name ?? 'missing',
149
- gender: gender ?? 'missing',
150
- pincode: pincode ?? 'missing',
151
- dob_day: day_of_birth ?? 'missing',
152
- dob_month: month_of_birth ?? 'missing',
153
- dob_year: year_of_birth ?? 'missing',
154
- flow: selectedMethod ?? ""
155
- },
156
- });
157
-
158
- // Set profile data with properly formatted date
159
- setProfileData({
160
- firstname: first_name,
161
- lastname: last_name,
162
- gender: gender,
163
- pincode: pincode,
164
- date_of_birth: dateOfBirth,
165
- });
166
- return;
167
- }
168
-
169
- // Fallback: use Eka profile info if available
170
- if (ekaProfileInfo) {
171
-
172
- let year = '1983';
173
- let month = '01';
174
- let day = '01';
175
-
176
- if (ekaProfileInfo.date_of_birth) {
177
- const parts = ekaProfileInfo.date_of_birth.split('-');
178
- year = parts[0];
179
- month = parts[1] === '00' || !parts[1] ? '01' : parts[1];
180
- day = parts[2] === '00' || !parts[2] ? '01' : parts[2];
181
- }
182
-
183
- const normalizedDate = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
184
-
185
- setProfileData({
186
- firstname: ekaProfileInfo.firstname,
187
- lastname: ekaProfileInfo.lastname,
188
- gender: ekaProfileInfo.gender,
189
- pincode: ekaProfileInfo.pincode,
190
- date_of_birth: normalizedDate,
191
- oid: ekaProfileInfo.oid,
192
- });
193
-
194
- trackAbhaEvent({
195
- name: 'profile_data_set_from_eka_profile',
196
- data: {
197
- source: 'eka_profile',
198
- date_of_birth: ekaProfileInfo?.date_of_birth ?? 'missing',
199
- firstname: ekaProfileInfo?.firstname ?? 'missing',
200
- lastname: ekaProfileInfo?.lastname ?? 'missing',
201
- gender: ekaProfileInfo?.gender ?? 'missing',
202
- pincode: ekaProfileInfo?.pincode ?? 'missing',
203
- oid: ekaProfileInfo?.oid ?? 'missing',
204
- },
205
- });
206
- }
207
- }, [cachedProfilePhrResponse, ekaProfileInfo]);
208
-
209
- // Determine if "Create Profile" button should be enabled
210
- const buttonState = useMemo(() => {
211
- if (
212
- profileData.firstname &&
213
- !error.firstname &&
214
- profileData.date_of_birth &&
215
- !error.date_of_birth &&
216
- profileData.pincode &&
217
- !error.pincode &&
218
- profileData.gender &&
219
- !error.gender
220
- )
221
- return true;
222
- else return false;
223
- }, [profileData, error]);
224
-
225
- // Handle click on "Create Profile" button
226
- const handleCreateProfileClick = async () => {
227
-
228
- const newError: TProfileDataError = {
229
- firstname: '',
230
- lastname: '',
231
- date_of_birth: '',
232
- pincode: '',
233
- gender: '',
234
- };
235
-
236
- setError(newError);
237
-
238
- if (!profileData.firstname.trim()) newError.firstname = 'Enter Name';
239
- if (!profileData.lastname.trim()) newError.lastname = 'This field is required';
240
- if (!profileData.date_of_birth) newError.date_of_birth = 'Enter DOB';
241
- if (!profileData.gender) newError.gender = 'Select Gender';
242
- if (!profileData.pincode) newError.pincode = 'Enter Valid Pincode';
243
-
244
-
245
- if (!buttonState) {
246
- // (optionally you could scroll to the first invalid field here)
247
- return;
248
- }
249
-
250
- // Track button click
251
- trackAbhaEvent({
252
- name: 'create_profile_screen_clicks',
253
- data: {
254
- type: 'create_profile',
255
- },
256
- });
257
-
258
- // Set loading state before navigation or API call
259
- setIsLoading(LOADING_STATE.LOADING);
260
-
261
- // Flow 1: Only creating Eka profile
262
- if (topScreen === SCREEN_NAMES.CREATE_EKA_PROFILE) {
263
- // If creating Eka profile, move to next screen to create ABHA address
264
- trackAbhaEvent({
265
- name: 'navigate_to_create_abha_address_screen',
266
- data: {
267
- type: 'next',
268
- pincode_entered: profileData?.pincode ?? 'unknown',
269
- eka_profile_info_pincode: ekaProfileInfo?.pincode ?? 'unknown',
270
- flow_type: selectedFlowMethod || 'unknown_method',
271
- },
272
- });
273
-
274
- if (selectedFlowMethod === ABHA_AUTH_FLOW_METHOD.MOBILE) {
275
- const data = await getPincodeDetails({
276
- pincode: Number(profileData.pincode),
277
- });
278
-
279
- if (data?.error) {
280
- // Display error to user
281
- setPincodeApiError(data?.error ? 'Invalid Pincode' : null);
282
- setIsLoading(LOADING_STATE.REJECTED);
283
- trackAbhaEvent({
284
- name: 'pincode_api_failed',
285
- data: {
286
- type: 'error',
287
- error: data?.error,
288
- },
289
- });
290
- return;
291
- }
292
-
293
- trackAbhaEvent({
294
- name: 'pincode_api_success',
295
- data: {
296
- type: 'verify',
297
- pincode_received: !!data.pincode,
298
- txn_id: txnId,
299
- },
300
- });
301
-
302
- if (data?.pincode) {
303
- setCreateProfileError(null);
304
- setEkaProfileInfo(profileData);
305
- trackAbhaEvent({
306
- name: 'eka_profile_info_set',
307
- data: {
308
- firstname: profileData?.firstname,
309
- lastname: profileData?.lastname,
310
- gender: profileData?.gender,
311
- pincode: profileData?.pincode,
312
- date_of_birth: profileData?.date_of_birth,
313
- },
314
- });
315
- setScreen(SCREEN_NAMES.CREATE_ABHA_ADDRESS);
316
- return;
317
- }
318
-
319
- trackAbhaEvent({
320
- name: 'no_action_on_pincode',
321
- data: {
322
- type: 'verify',
323
- pincode_entered: !!data.pincode,
324
- txn_id: txnId,
325
- },
326
- });
327
-
328
- return;
329
- } else if (selectedFlowMethod === ABHA_AUTH_FLOW_METHOD.AADHAR_NUMBER) {
330
- setEkaProfileInfo(profileData);
331
- trackAbhaEvent({
332
- name: 'eka_profile_info_set',
333
- data: {
334
- firstname: profileData?.firstname,
335
- lastname: profileData?.lastname,
336
- gender: profileData?.gender,
337
- pincode: profileData?.pincode,
338
- date_of_birth: profileData?.date_of_birth,
339
- },
340
- });
341
- setScreen(SCREEN_NAMES.CREATE_ABHA_ADDRESS);
342
- return;
343
- }
344
- }
345
-
346
- // Flow 2: Creating both PHR and Eka profile
347
- if (topScreen === SCREEN_NAMES.CREATE_PHR_EKA_PROFILE) {
348
- // Abort if ABHA address is missing
349
- if (!selectedAbhaAddress) {
350
- trackAbhaEvent({
351
- name: 'abha_create_eka_profile_abha_address_missing',
352
- data: {
353
- platform: clientId,
354
- },
355
- });
356
- return;
357
- }
358
- // Split date of birth string into day, month, year
359
- const [year, month, day] = profileData.date_of_birth
360
- ? profileData?.date_of_birth?.split('-')
361
- : ['', '', ''];
362
-
363
- // Construct profile data payload for ABDM API
364
- const profileEkaData = {
365
- abha_address: selectedAbhaAddress,
366
- day_of_birth: parseInt(day),
367
- first_name: profileData.firstname,
368
- gender: profileData.gender,
369
- last_name: profileData.lastname || '',
370
- month_of_birth: parseInt(month),
371
- pincode: profileData.pincode,
372
- year_of_birth: parseInt(year),
373
- };
374
-
375
- trackAbhaEvent({
376
- name: 'profile_eka_process_started',
377
- data: {
378
- platform: clientId,
379
- date_of_birth: profileData?.date_of_birth || null,
380
- dob_day: day || null,
381
- dob_month: month || null,
382
- dob_year: year || null,
383
- },
384
- });
385
-
386
- // Call API to create Eka profile with PHR
387
- const {
388
- error: phrError,
389
- eka,
390
- action: errorAction,
391
- } = await postAbdmProfileEka({ ...profileEkaData });
392
-
393
- // If an actionable error is returned (e.g. show bottom sheet)
394
- if (errorAction) {
395
- trackAbhaEvent({
396
- name: 'profile_eka_process_failed',
397
- data: {
398
- platform: clientId,
399
- error_message: errorAction?.cta?.title || 'unknown_error',
400
- error_message_exists: !!errorAction?.cta?.title,
401
- },
402
- });
403
- setBottomsheetErrorInfo(errorAction);
404
- return;
405
- }
406
-
407
- // If API fails or returns invalid Eka profile
408
- if (phrError || !eka || !eka.oid) {
409
- trackAbhaEvent({
410
- name: 'profile_process_failed',
411
- data: {
412
- platform: clientId,
413
- error_message: phrError || 'Unknown error',
414
- eka_oid: eka?.oid || 'missing',
415
- eka_exists: !!eka,
416
- date_of_birth: profileData?.date_of_birth || 'missing',
417
- dob_day: day || 'missing',
418
- dob_month: month || 'missing',
419
- dob_year: year || 'missing',
420
- parsed_date_valid: Boolean(parseInt(day) && parseInt(month) && parseInt(year)),
421
- firstname: profileData?.firstname || 'missing',
422
- gender: profileData?.gender || 'missing',
423
- pincode: profileData?.pincode || 'missing',
424
- },
425
- });
426
- setIsLoading(LOADING_STATE.REJECTED);
427
- setCreateProfileError(phrError || 'Something went wrong. Please try again.');
428
- return;
429
- }
430
-
431
- trackAbhaEvent({
432
- name: 'profile_eka_process_success',
433
- data: {
434
- platform: clientId,
435
- eka: eka,
436
- },
437
- });
438
-
439
- trackAbhaEvent({
440
- name: 'profile_switch_process_started',
441
- data: {
442
- platform: clientId,
443
- error_message: phrError,
444
- eka: eka,
445
- },
446
- });
447
-
448
- // Switch to newly created Eka profile
449
- const profileSwitchResponse = await postProfileSwitchMutate({
450
- oid: eka.oid,
451
- });
452
-
453
- // If profile switch fails
454
- if (profileSwitchResponse.error) {
455
- trackAbhaEvent({
456
- name: 'profile_switch_process_failed',
457
- data: {
458
- platform: clientId,
459
- error_message: profileSwitchResponse.error || 'Something went wrong, please try again',
460
- error_message_exists: !!profileSwitchResponse.error,
461
- },
462
- });
463
- setIsLoading(LOADING_STATE.REJECTED);
464
- setCreateProfileError(
465
- profileSwitchResponse.error?.message || 'Something went wrong, please try again'
466
- );
467
- return;
468
- }
469
-
470
- trackAbhaEvent({
471
- name: 'profile_switch_process_success',
472
- data: {
473
- platform: clientId,
474
- eka: eka,
475
- },
476
- });
477
-
478
- // Profile switch success
479
- setIsLoading(LOADING_STATE.RESOLVED);
480
- return;
481
- }
482
- };
483
-
484
- const handleErrorBottomsheetButtonClick = () => {
485
- goBackLoginScreen();
486
- const isAppLogin = useAuthAbhaStore.getState().isEkaAppLogin;
487
- clearAbhaAuthStore();
488
- useAuthAbhaStore.setState({ isEkaAppLogin: isAppLogin });
489
- };
490
-
491
- return (
492
- <div className="pds2-w-full pds2-flex pds2-flex-col pds2-bg-bg-01 pds2-h-full">
493
- <Pds2Header
494
- title="Create ABHA Address"
495
- prefixIcon={
496
- <button
497
- className="pds2-w-24 pds2-h-24 pds2-rounded-full pds2-flex pds2-items-center pds2-justify-center ripple"
498
- onClick={() => setIsExitPopupOpen(true)}
499
- >
500
- <ArrowLeftRegularIcon className="" />
501
- </button>
502
- }
503
- className="pds2-bg-bg-white"
504
- />
505
- <AbhaStepper/>
506
- <div className="pds2-flex pds2-flex-col pds2-flex-1 pds2-p-8 pds2-overflow-y-auto">
507
- <div className="pds2-flex pds2-items-center pds2-justify-between">
508
- {/* <div className="pds2-space-y-2 pds2-text-text-01">
509
- {isDocAppRequest ? (
510
- <div className="Heading4Semibold">Create ABHA Profile</div>
511
- ) : (
512
- <>
513
- <div className="Heading4Semibold">Create your</div>
514
- <div className="Heading2Semibold">Eka Profile</div>
515
- </>
516
- )}
517
- </div> */}
518
- {/* <div className="pds2-relative">
519
- <img src="/images/avatar.webp" alt="avatar" className="pds2-w-96 pds2-h-96" />
520
- <button className="pds2-flex pds2-items-center pds2-space-x-4 pds2-text-text-brand pds2-px-8 pds2-py-4 pds2-border-1 pds2-border-border-brand-01 pds2-rounded-8 pds2-bg-bg-white pds2-absolute -pds2-bottom-12 pds2-right-6">
521
- <CameraSolidIcon className="pds2-w-14 pds2-h-14" />
522
- <div className="Label1Semibold pds2-min-w-max">Add photo</div>
523
- </button>
524
- </div> */}
525
- </div>
526
- <UserDetailsForm
527
- profileData={profileData}
528
- setProfileData={setProfileData}
529
- error={error}
530
- setError={setError}
531
- pincodeApiError={pincodeApiError}
532
- />
533
- </div>
534
- {createProfileError && (
535
- <div className="pds2-p-16 pds2-text-text-error pds2-text-center">{createProfileError}</div>
536
- )}
537
- <div className="pds2-sticky pds2-bottom-0 pds2-bg-bg-white pds2-w-full">
538
- {selectedAbhaAddress &&
539
- aadhaarVerificationSkipStateStatus === ABHA_V3_SKIP_STATES.ABHA_END ? (
540
- <div className="pds2-flex pds2-items-center pds2-justify-between pds2-w-full pds2-px-16 pds2-py-6 pds2-bg-border-brand-02">
541
- <div className="">
542
- <span className="pds2-text-text-03 Body2Regular">Creating for: </span>
543
- <span className="pds2-text-text-01 Body2Semibold">{selectedAbhaAddress}</span>
544
- </div>
545
- <button
546
- onClick={goBackLoginScreen}
547
- className="Body2Semibold pds2-text-text-brand pds2-rounded-full ripple pds2-px-8 pds2-py-2"
548
- >
549
- Change
550
- </button>
551
- </div>
552
- ) : null}
553
- <div className="pds2-p-16 pds2-w-full">
554
- <Pds2Button
555
- className="pds2-w-full"
556
- title="Create Profile"
557
- state={isLoading === LOADING_STATE.LOADING ? 'disabled' : 'enabled'}
558
- onClick={handleCreateProfileClick}
559
- isLoading={isLoading === LOADING_STATE.LOADING}
560
- />
561
- </div>
562
- </div>
563
- <AbhaErrorBottomSheet onSubmitClick={handleErrorBottomsheetButtonClick} />
564
- <ExitPopup open={isExitPopupOpen} setOpen={setIsExitPopupOpen} />
565
- </div>
566
- );
567
- };
568
- export default CreateEkaProfileScreen;
569
-
570
- const genders = [
571
- { id: 'M', name: 'Male' },
572
- { id: 'F', name: 'Female' },
573
- { id: 'O', name: 'Other' },
574
- ];
575
-
576
- type TProfileData = {
577
- firstname: string;
578
- lastname: string;
579
- date_of_birth: string;
580
- pincode: string;
581
- gender: string;
582
- oid?: string;
583
- };
584
-
585
- interface TProfileDataError extends TProfileData {}
586
-
587
- const UserDetailsForm = ({
588
- profileData,
589
- setProfileData,
590
- error,
591
- setError,
592
- pincodeApiError,
593
- }: {
594
- profileData: TProfileData;
595
- setProfileData: (val: TProfileData) => void;
596
- error: TProfileDataError;
597
- setError: (val: TProfileDataError) => void;
598
- pincodeApiError?: string | null;
599
- }) => {
600
- const handleInputChange = ({
601
- event,
602
- name,
603
- }: {
604
- event: React.ChangeEvent<HTMLInputElement>;
605
- name: string;
606
- }) => {
607
- const value = event.target.value;
608
- let errorMsg = '';
609
- switch (name) {
610
- case 'firstname':
611
- if (!value.trim()) errorMsg = 'This field is required';
612
- else errorMsg = '';
613
- break;
614
- case 'lastname':
615
- if (!value || value.length < 0) errorMsg = 'This field is required';
616
- else errorMsg = '';
617
- break;
618
- case 'pincode':
619
- if (!value || isNaN(Number(value)) || value.length != 6)
620
- errorMsg = 'Pincode must consist of exactly 6 digits';
621
- else errorMsg = '';
622
- break;
623
- case 'date_of_birth':
624
- if (!value || value > new Date().toISOString().split('T')[0])
625
- errorMsg = 'Date of Birth is invalid';
626
- else errorMsg = '';
627
- break;
628
- default:
629
- break;
630
- }
631
-
632
- setError({
633
- ...error,
634
- [name]: errorMsg,
635
- });
636
-
637
- setProfileData({
638
- ...profileData,
639
- [name]: value,
640
- });
641
- };
642
-
643
- const handleGenderChange = (value: string) => {
644
- setProfileData({
645
- ...profileData,
646
- gender: value,
647
- });
648
- setError({
649
- ...error,
650
- gender: '',
651
- });
652
- };
653
-
654
- const isPincodeFieldErrorToBeShown = (profileData: any, ekaProfileInfo: any): boolean => {
655
- // if ekaProfileInfo already has a pincode, skip the validation
656
- if (ekaProfileInfo?.pincode) {
657
- return false;
658
- }
659
-
660
- // Validate if firstName, gender, and date_of_birth are filled in profileData
661
- const isProfileDataComplete =
662
- (profileData.firstname ?? '').trim() !== '' &&
663
- (profileData.gender ?? '').trim() !== '' &&
664
- (profileData.date_of_birth ?? '').trim() !== '';
665
-
666
- // If profileData is incomplete, skip pincode error check
667
- if (!isProfileDataComplete) {
668
- return false;
669
- }
670
-
671
- // Check if pincode is empty or invalid (check length and numeric)
672
- if (!profileData.pincode || (profileData.pincode + '').length !== 6) {
673
- return true; // Show error if pincode is missing or invalid
674
- }
675
-
676
- return false;
677
- };
678
-
679
- const ekaProfileInfo = useAuthAbhaStore((state) => state.ekaProfileInfo);
680
- const selectedFlowMethod = useAuthAbhaStore((state) => state.abhaAuthFlowMethod);
681
-
682
- return (
683
- <form className="pds2-flex pds2-flex-col pds2-space-y-32 pds2-pt-16 pds2-px-16">
684
- <label className="pds2-space-y-8">
685
- <div className="Body3Medium pds2-text-text-04">
686
- Your name
687
- <span className="pds2-text-text-error Body3Semibold">*</span>
688
- </div>
689
- <div className="pds2-flex pds2-gap-8">
690
- <div className="pds2-flex pds2-flex-col">
691
- <Pds2InputField
692
- isMandatory={true}
693
- textColor="pds2-text-text-01"
694
- padding="pds2-px-16 pds2-py-12"
695
- borderRadius="pds2-rounded-12"
696
- borderStyle="focus-within:pds2-ring-2 focus-within:pds2-ring-border-brand-01 focus-within:pds2-ring-offset-2"
697
- placeholder="Firstname"
698
- value={profileData.firstname}
699
- onChange={e => handleInputChange({ event: e, name: 'firstname' })}
700
- autoCapitalize="on"
701
- disabled={
702
- !!ekaProfileInfo?.firstname &&
703
- selectedFlowMethod === ABHA_AUTH_FLOW_METHOD.AADHAR_NUMBER
704
- }
705
- error={error.firstname}
706
- />
707
- {error.firstname && (
708
- <div className="Body3Medium pds2-text-text-error pds2-mt-4">
709
- {error.firstname}
710
- </div>
711
- )}
712
- </div>
713
-
714
- <div>
715
- <Pds2InputField
716
- textColor="pds2-text-text-01"
717
- padding="pds2-px-16 pds2-py-12"
718
- borderRadius="pds2-rounded-12"
719
- borderStyle="focus-within:pds2-ring-2 focus-within:pds2-ring-border-brand-01 focus-within:pds2-ring-offset-2"
720
- placeholder="Lastname"
721
- value={profileData.lastname}
722
- onChange={e => handleInputChange({ event: e, name: 'lastname' })}
723
- autoCapitalize="on"
724
- disabled={
725
- !!ekaProfileInfo?.lastname &&
726
- selectedFlowMethod === ABHA_AUTH_FLOW_METHOD.AADHAR_NUMBER
727
- }
728
- />
729
- </div>
730
- </div>
731
- </label>
732
-
733
- <div className="pds2-space-y-8">
734
- <div className="pds2-space-y-4">
735
- <div className="Body3Medium pds2-text-text-04">
736
- Gender
737
- <span className="pds2-text-text-error Body3Semibold">*</span>
738
- </div>
739
- <div className="pds2-flex pds2-gap-16">
740
- {genders.map((item, idx) => (
741
- <div
742
- key={idx}
743
- className={`${
744
- error.gender
745
- ? 'pds2-border-2 pds2-rounded-12 pds2-border-text-error placeholder:pds2-text-text-error'
746
- : 'focus-within:pds2-ring-2 focus-within:pds2-ring-border-brand-01 focus-within:pds2-ring-offset-2 placeholder:pds2-text-text-04'
747
- }`}
748
- >
749
- <Pds2SingleInputChip
750
- isSelected={item.id === profileData.gender}
751
- title={item.name}
752
- onSelect={() => handleGenderChange(item.id)}
753
- />
754
- </div>
755
- ))}
756
- </div>
757
- {error.gender && (
758
- <div className="Body3Medium pds2-text-text-error pds2-mt-2">
759
- {error.gender}
760
- </div>
761
- )}
762
- </div>
763
-
764
-
765
- <div className="pds2-flex pds2-flex-col">
766
- <Pds2InputField
767
- label="Date of Birth"
768
- isMandatory={true}
769
- textColor="pds2-text-text-01"
770
- padding="pds2-px-16 pds2-py-12"
771
- borderRadius="pds2-rounded-12"
772
- borderStyle="focus-within:pds2-ring-2 focus-within:pds2-ring-border-brand-01 focus-within:pds2-ring-offset-2"
773
- value={profileData.date_of_birth}
774
- disabled={
775
- !!ekaProfileInfo?.date_of_birth &&
776
- selectedFlowMethod === ABHA_AUTH_FLOW_METHOD.AADHAR_NUMBER
777
- }
778
- onChange={(e) =>
779
- handleInputChange({ event: e, name: 'date_of_birth' })
780
- }
781
- type="date"
782
- maxDate={new Date().toISOString().split('T')[0]}
783
- error={error.date_of_birth}
784
- />
785
- {error.date_of_birth && (
786
- <div className="Body3Medium pds2-text-text-error pds2-mt-2">
787
- {error.date_of_birth}
788
- </div>
789
- )}
790
- </div>
791
- </div>
792
-
793
-
794
- <div className="pds2-flex pds2-flex-col pds2-space-y-4">
795
- <Pds2InputField
796
- label="Pincode"
797
- isMandatory={true}
798
- textColor="pds2-text-text-01"
799
- padding="pds2-px-16 pds2-py-12"
800
- borderRadius="pds2-rounded-12"
801
- borderStyle={
802
- isPincodeFieldErrorToBeShown(profileData, ekaProfileInfo) || pincodeApiError
803
- ? 'pds2-border-1 pds2-border-text-error'
804
- : ''
805
- }
806
- value={profileData.pincode}
807
- placeholder="Enter Pincode"
808
- disabled={
809
- !!ekaProfileInfo?.pincode && selectedFlowMethod === ABHA_AUTH_FLOW_METHOD.AADHAR_NUMBER
810
- }
811
- onChange={(e) => {
812
- if (e.target.value.length > 6) return;
813
- handleInputChange({ event: e, name: 'pincode' });
814
- }}
815
- type="number"
816
- error={
817
- isPincodeFieldErrorToBeShown(profileData, ekaProfileInfo) ? error.pincode : ''
818
- }
819
- textStyle={
820
- isPincodeFieldErrorToBeShown(profileData, ekaProfileInfo) || pincodeApiError
821
- ? 'placeholder:pds2-text-text-error'
822
- : 'placeholder:pds2-text-text-04'
823
- }
824
- />
825
- {pincodeApiError || error.pincode && (
826
- <div className="Body3Medium pds2-text-text-error pds2-mt-4">{error.pincode}</div>
827
- )}
828
- </div>
829
- </form>
830
- );
831
- };