@finspringinnovations/fixeddepositsdk 1.0.3 → 1.0.4

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 (43) hide show
  1. package/lib/api/customerApi.js +1 -0
  2. package/lib/api/fdApi.d.ts +401 -1
  3. package/lib/api/fdApi.js +24 -2
  4. package/lib/config/workflowConstants.d.ts +40 -30
  5. package/lib/config/workflowConstants.js +35 -24
  6. package/lib/navigation/RootNavigator.js +62 -81
  7. package/lib/navigation/types.d.ts +4 -1
  8. package/lib/navigation/workflowNavigator.d.ts +1 -1
  9. package/lib/navigation/workflowNavigator.js +107 -26
  10. package/lib/screens/AadhaarVerification.js +1 -11
  11. package/lib/screens/AddBankAccount.js +1 -11
  12. package/lib/screens/BankDetail.js +1 -11
  13. package/lib/screens/Employee.js +1 -11
  14. package/lib/screens/FDCalculator.js +1 -11
  15. package/lib/screens/FDList.js +529 -416
  16. package/lib/screens/FindIFSC.js +1 -11
  17. package/lib/screens/NomineeDetail.js +12 -22
  18. package/lib/screens/PayNow.js +1 -11
  19. package/lib/screens/Payment.js +2 -11
  20. package/lib/screens/PaymentStatus.js +11 -21
  21. package/lib/screens/ReviewKYC.js +1 -11
  22. package/lib/types/workflowTypes.d.ts +1 -1
  23. package/package.json +1 -1
  24. package/src/api/customerApi.ts +1 -0
  25. package/src/api/fdApi.ts +28 -1
  26. package/src/config/workflowConstants.ts +51 -39
  27. package/src/constants/strings/bank.ts +80 -80
  28. package/src/navigation/RootNavigator.tsx +646 -663
  29. package/src/navigation/types.ts +4 -1
  30. package/src/navigation/workflowNavigator.ts +170 -107
  31. package/src/screens/AadhaarVerification.tsx +1 -15
  32. package/src/screens/AddBankAccount.tsx +2 -16
  33. package/src/screens/BankDetail.tsx +1 -15
  34. package/src/screens/Employee.tsx +1 -15
  35. package/src/screens/FDCalculator.tsx +1 -15
  36. package/src/screens/FDList.tsx +2311 -2171
  37. package/src/screens/FindIFSC.tsx +2 -16
  38. package/src/screens/NomineeDetail.tsx +762 -775
  39. package/src/screens/PayNow.tsx +2 -16
  40. package/src/screens/Payment.tsx +190 -203
  41. package/src/screens/PaymentStatus.tsx +574 -588
  42. package/src/screens/ReviewKYC.tsx +1 -15
  43. package/src/types/workflowTypes.ts +1 -10
@@ -1,69 +1,69 @@
1
- import React, { useEffect } from 'react';
2
1
  import { createStackNavigator } from '@react-navigation/stack';
2
+ import React, { useEffect } from 'react';
3
+ import { Alert, BackHandler, Platform } from 'react-native';
3
4
  import type { RootStackParamList, SDKNavigationConfig } from './types';
4
- import { BackHandler, Platform, Alert } from 'react-native';
5
- import { navigationRef } from './helpers';
6
5
 
7
6
  // Import screens
8
- import FDListScreen from '../screens/FDList';
9
- import FDCalculatorScreen from '../screens/FDCalculator';
10
7
  import AadhaarVerificationScreen from '../screens/AadhaarVerification';
11
- import ReviewKYCScreen from '../screens/ReviewKYC';
12
- import EmployeeScreen from '../screens/Employee';
13
- import NomineeDetailScreen from '../screens/NomineeDetail';
14
- import BankDetailScreen from '../screens/BankDetail';
15
8
  import AddBankAccountScreen from '../screens/AddBankAccount';
9
+ import BankDetailScreen from '../screens/BankDetail';
10
+ import EmployeeScreen from '../screens/Employee';
11
+ import FDCalculatorScreen from '../screens/FDCalculator';
12
+ import FDListScreen from '../screens/FDList';
16
13
  import FindIFSCScreen from '../screens/FindIFSC';
14
+ import NomineeDetailScreen from '../screens/NomineeDetail';
17
15
  import PayNowScreen from '../screens/PayNow';
18
16
  import PaymentScreen from '../screens/Payment';
19
17
  import PaymentStatusScreen from '../screens/PaymentStatus';
18
+ import ReviewKYCScreen from '../screens/ReviewKYC';
20
19
 
21
20
  // Import full SDK navigators and initialization functions
22
21
  import {
23
- initializeSDK as initializeShriramSDK,
24
- initializeEnvironment as initializeShriramEnvironment,
25
- RootNavigator as ShriramRootNavigator,
26
- navigationRef as shriramNavigationRef,
27
- ThemeProvider as ShriramThemeProvider,
28
- ApiProvider as ShriramApiProvider,
29
- MasterDataProvider as ShriramMasterDataProvider,
30
- useMasterData as useShriramMasterData,
31
- useAppDispatch as useShriramAppDispatch,
32
- setFDListSelected as setShriramFDListSelected,
33
- setOnboardingIds as setShriramOnboardingIds,
34
- setGlobalData as setShriramGlobalData,
35
- type AppData as ShriramAppData,
36
- type EnvironmentData as ShriramEnvironmentData
37
- } from '@finspringinnovations/shriramfdsdk';
38
- import {
39
- initializeSDK as initializeMahindraSDK,
40
- initializeEnvironment as initializeMahindraEnvironment,
41
- RootNavigator as MahindraRootNavigator,
42
- navigationRef as mahindraNavigationRef,
43
- ThemeProvider as MahindraThemeProvider,
44
- ApiProvider as MahindraApiProvider,
45
- MasterDataProvider as MahindraMasterDataProvider,
46
- useMasterData as useMahindraMasterData,
47
- useAppDispatch as useMahindraAppDispatch,
48
- setFDListSelected as setMahindraFDListSelected,
49
- setOnboardingIds as setMahindraOnboardingIds,
50
- type AppData as MahindraAppData,
51
- type EnvironmentData as MahindraEnvironmentData
22
+ initializeEnvironment as initializeMahindraEnvironment,
23
+ initializeSDK as initializeMahindraSDK,
24
+ ApiProvider as MahindraApiProvider,
25
+ MasterDataProvider as MahindraMasterDataProvider,
26
+ navigationRef as mahindraNavigationRef,
27
+ RootNavigator as MahindraRootNavigator,
28
+ ThemeProvider as MahindraThemeProvider,
29
+ setFDListSelected as setMahindraFDListSelected,
30
+ setOnboardingIds as setMahindraOnboardingIds,
31
+ setPaymentSession as setMahindraPaymentSession,
32
+ useAppDispatch as useMahindraAppDispatch,
33
+ useMasterData as useMahindraMasterData,
34
+ type AppData as MahindraAppData,
35
+ type EnvironmentData as MahindraEnvironmentData
52
36
  } from '@finspringinnovations/mahindrafdsdk';
37
+ import {
38
+ initializeEnvironment as initializeShriramEnvironment,
39
+ initializeSDK as initializeShriramSDK,
40
+ setFDListSelected as setShriramFDListSelected,
41
+ setGlobalData as setShriramGlobalData,
42
+ setOnboardingIds as setShriramOnboardingIds,
43
+ ApiProvider as ShriramApiProvider,
44
+ MasterDataProvider as ShriramMasterDataProvider,
45
+ navigationRef as shriramNavigationRef,
46
+ RootNavigator as ShriramRootNavigator,
47
+ ThemeProvider as ShriramThemeProvider,
48
+ useAppDispatch as useShriramAppDispatch,
49
+ useMasterData as useShriramMasterData,
50
+ type AppData as ShriramAppData,
51
+ type EnvironmentData as ShriramEnvironmentData
52
+ } from '@finspringinnovations/shriramfdsdk';
53
53
 
54
54
  // Import NavigationContainer and tree wrappers
55
55
  import { NavigationContainer, NavigationIndependentTree } from '@react-navigation/native';
56
56
 
57
57
  // Import navigation helpers
58
- import { goBack, navigate, replace, pop } from './helpers';
59
58
  import { getPaymentSession } from '../state/paymentSession';
59
+ import { goBack, navigate, pop } from './helpers';
60
60
 
61
61
  // Import data getters from fdsdk
62
62
  import { getAppData, getEnvironmentData } from '../config/appDataConfig';
63
63
  import { useMasterData } from '../providers/MasterDataProvider';
64
64
  import { useTheme } from '../theme/ThemeContext';
65
65
 
66
- const Stack = createStackNavigator<RootStackParamList>();
66
+ const Stack = createStackNavigator < RootStackParamList > ();
67
67
  const MahindraRootNavigatorAny = MahindraRootNavigator as React.ComponentType<any>;
68
68
 
69
69
  // ─── Module-level SDK content components ───────────────────────────────────
@@ -73,648 +73,631 @@ const MahindraRootNavigatorAny = MahindraRootNavigator as React.ComponentType<an
73
73
  // entire SDK NavigationContainer (and all child screens) on every render.
74
74
 
75
75
  interface ShriramSDKContentProps {
76
- masterData: any;
77
- routeParams: any;
78
- onSDKExit: (fdDetails?: any) => void;
79
- onSDKPanRequired: () => void;
76
+ masterData: any;
77
+ routeParams: any;
78
+ onSDKExit: (fdDetails?: any) => void;
79
+ onSDKPanRequired: () => void;
80
80
  }
81
81
 
82
82
  const ShriramSDKContent: React.FC<ShriramSDKContentProps> = ({
83
- masterData,
84
- routeParams,
85
- onSDKExit,
86
- onSDKPanRequired,
83
+ masterData,
84
+ routeParams,
85
+ onSDKExit,
86
+ onSDKPanRequired,
87
87
  }) => {
88
- const { setMasterData } = useShriramMasterData();
89
- const shriramDispatch = useShriramAppDispatch();
90
-
91
- React.useEffect(() => {
92
- if (masterData) {
93
- const dataToSet = masterData.data || masterData;
94
- setMasterData(dataToSet);
95
- }
96
- }, [masterData, setMasterData]);
97
-
98
- React.useEffect(() => {
99
- if (routeParams.fdListSelectedData) {
100
- try {
101
- shriramDispatch(setShriramFDListSelected(routeParams.fdListSelectedData));
102
- } catch (e) {
103
- console.log('[RootNavigator] Error setting Shriram FDListSelected:', e);
104
- }
105
- }
106
- }, [routeParams.fdListSelectedData, shriramDispatch]);
107
-
108
- React.useEffect(() => {
109
- if (routeParams.onboardingIds) {
110
- try {
111
- shriramDispatch(setShriramOnboardingIds({
112
- ...routeParams.onboardingIds,
113
- providerId: routeParams.providerId || routeParams.onboardingIds?.providerId,
114
- }));
115
- } catch (e) {
116
- console.log('[RootNavigator] Error setting Shriram OnboardingIds:', e);
117
- }
118
- }
119
- }, [routeParams.onboardingIds, shriramDispatch]);
120
-
121
- React.useEffect(() => {
122
- if (routeParams.shriramSDKGlobalData) {
123
- try {
124
- const completeFDData = !!routeParams.shriramSDKGlobalData;
125
- setShriramGlobalData({ completeFDData });
126
- } catch (e) {
127
- console.log('[RootNavigator] Error setting Shriram GlobalData:', e);
128
- }
129
- }
130
- }, [routeParams.shriramSDKGlobalData]);
131
-
132
- return (
133
- <ShriramRootNavigator
134
- config={{
135
- initialRouteName: routeParams.initialRouteName || 'FDCalculator',
136
- initialPaymentStatusParams: routeParams.initialPaymentStatusParams,
137
- initialFDContext: {
138
- providerId: routeParams.providerId,
139
- fdListSelectedData: routeParams.fdListSelectedData,
140
- completeFDData: routeParams.completeFDData,
141
- },
142
- } as any}
143
- onExit={onSDKExit}
144
- onPanRequired={onSDKPanRequired}
145
- />
146
- );
88
+ const { setMasterData } = useShriramMasterData();
89
+ const shriramDispatch = useShriramAppDispatch();
90
+
91
+ const [initialized, setInitialized] = React.useState(false);
92
+
93
+ React.useEffect(() => {
94
+ // Perform all dispatches sequentially to ensure state is ready
95
+ if (masterData) {
96
+ const dataToSet = masterData.data || masterData;
97
+ setMasterData(dataToSet);
98
+ }
99
+
100
+ if (routeParams.fdListSelectedData) {
101
+ try {
102
+ shriramDispatch(setShriramFDListSelected(routeParams.fdListSelectedData));
103
+ } catch (e) {
104
+ console.log('[RootNavigator] Error setting Shriram FDListSelected:', e);
105
+ }
106
+ }
107
+
108
+ if (routeParams.onboardingIds) {
109
+ try {
110
+ shriramDispatch(setShriramOnboardingIds({
111
+ ...routeParams.onboardingIds,
112
+ providerId: routeParams.providerId || routeParams.onboardingIds?.providerId,
113
+ }));
114
+ } catch (e) {
115
+ console.log('[RootNavigator] Error setting Shriram OnboardingIds:', e);
116
+ }
117
+ }
118
+
119
+ if (routeParams.shriramSDKGlobalData) {
120
+ try {
121
+ const completeFDData = !!routeParams.shriramSDKGlobalData;
122
+ setShriramGlobalData({ completeFDData });
123
+ } catch (e) {
124
+ console.log('[RootNavigator] Error setting Shriram GlobalData:', e);
125
+ }
126
+ }
127
+
128
+ setInitialized(true);
129
+ }, [masterData, routeParams, shriramDispatch, setMasterData]);
130
+
131
+ if (!initialized) {
132
+ return null; // Or a loading spinner if preferred
133
+ }
134
+
135
+
136
+ return (
137
+ <ShriramRootNavigator
138
+ config={{
139
+ initialRouteName: routeParams.initialRouteName || 'FDCalculator',
140
+ initialPaymentStatusParams: routeParams.initialPaymentStatusParams,
141
+ initialFDContext: {
142
+ providerId: routeParams.providerId,
143
+ fdListSelectedData: routeParams.fdListSelectedData,
144
+ completeFDData: routeParams.completeFDData,
145
+ },
146
+ } as any}
147
+ onExit={onSDKExit}
148
+ onPanRequired={onSDKPanRequired}
149
+ />
150
+ );
147
151
  };
148
152
 
149
153
  interface MahindraSDKContentProps {
150
- masterData: any;
151
- routeParams: any;
152
- onSDKExit: (fdDetails?: any) => void;
153
- onSDKPanRequired: () => void;
154
+ masterData: any;
155
+ routeParams: any;
156
+ onSDKExit: (fdDetails?: any) => void;
157
+ onSDKPanRequired: () => void;
154
158
  }
155
159
 
156
160
  const MahindraSDKContent: React.FC<MahindraSDKContentProps> = ({
157
- masterData,
158
- routeParams,
159
- onSDKExit,
160
- onSDKPanRequired,
161
+ masterData,
162
+ routeParams,
163
+ onSDKExit,
164
+ onSDKPanRequired,
161
165
  }) => {
162
- const { setMasterData } = useMahindraMasterData();
163
- const mahindraDispatch = useMahindraAppDispatch();
164
-
165
- React.useEffect(() => {
166
- if (masterData) {
167
- const dataToSet = masterData.data || masterData;
168
- setMasterData(dataToSet);
169
- }
170
- }, [masterData, setMasterData]);
171
-
172
- React.useEffect(() => {
173
- if (routeParams.fdListSelectedData) {
174
- try {
175
- mahindraDispatch(setMahindraFDListSelected(routeParams.fdListSelectedData));
176
- } catch (e) {
177
- console.log('[RootNavigator] Error setting Mahindra FDListSelected:', e);
178
- }
179
- }
180
- }, [routeParams.fdListSelectedData, mahindraDispatch]);
181
-
182
- React.useEffect(() => {
183
- if (routeParams.onboardingIds) {
184
- try {
185
- mahindraDispatch(setMahindraOnboardingIds({
186
- ...routeParams.onboardingIds,
187
- providerId: routeParams.providerId || routeParams.onboardingIds?.providerId,
188
- }));
189
- } catch (e) {
190
- console.log('[RootNavigator] Error setting Mahindra OnboardingIds:', e);
191
- }
192
- }
193
- }, [routeParams.onboardingIds, mahindraDispatch]);
194
-
195
- return (
196
- <MahindraRootNavigatorAny
197
- config={{
198
- initialRouteName: routeParams.initialRouteName || 'FDCalculator',
199
- forceFetchCustomerDetails: !!routeParams.forceFetchCustomerDetails,
200
- initialFDContext: {
201
- providerId: routeParams.providerId,
202
- fdListSelectedData: routeParams.fdListSelectedData,
203
- completeFDData: routeParams.completeFDData,
204
- },
205
- }}
206
- onExit={onSDKExit}
207
- onPanRequired={onSDKPanRequired}
208
- />
209
- );
166
+ const { setMasterData } = useMahindraMasterData();
167
+ const mahindraDispatch = useMahindraAppDispatch();
168
+
169
+ const [initialized, setInitialized] = React.useState(false);
170
+
171
+ React.useEffect(() => {
172
+ // Perform all dispatches sequentially to ensure state is ready
173
+ if (masterData) {
174
+ const dataToSet = masterData.data || masterData;
175
+ setMasterData(dataToSet);
176
+ }
177
+
178
+ if (routeParams.fdListSelectedData) {
179
+ try {
180
+ mahindraDispatch(setMahindraFDListSelected(routeParams.fdListSelectedData));
181
+ } catch (e) {
182
+ console.log('[RootNavigator] Error setting Mahindra FDListSelected:', e);
183
+ }
184
+ }
185
+
186
+ if (routeParams.onboardingIds) {
187
+ try {
188
+ mahindraDispatch(setMahindraOnboardingIds({
189
+ ...routeParams.onboardingIds,
190
+ providerId: routeParams.providerId || routeParams.onboardingIds?.providerId,
191
+ }));
192
+ } catch (e) {
193
+ console.log('[RootNavigator] Error setting Mahindra OnboardingIds:', e);
194
+ }
195
+ }
196
+
197
+ if (routeParams.initialPaymentUrl) {
198
+ setMahindraPaymentSession({
199
+ paymentUrl: routeParams.initialPaymentUrl,
200
+ transactionId: routeParams.initialPaymentTransactionId,
201
+ });
202
+ }
203
+
204
+ setInitialized(true);
205
+ }, [masterData, routeParams, mahindraDispatch, setMasterData]);
206
+
207
+ if (!initialized) {
208
+ return null;
209
+ }
210
+
211
+
212
+ return (
213
+ <MahindraRootNavigatorAny
214
+ config={{
215
+ initialRouteName: routeParams.initialRouteName || 'FDCalculator',
216
+ forceFetchCustomerDetails: !!routeParams.forceFetchCustomerDetails,
217
+ initialPaymentStatusParams: routeParams.initialPaymentStatusParams,
218
+ initialFDContext: {
219
+ providerId: routeParams.providerId,
220
+ fdListSelectedData: routeParams.fdListSelectedData,
221
+ completeFDData: routeParams.completeFDData,
222
+ },
223
+ }}
224
+ onExit={onSDKExit}
225
+ onPanRequired={onSDKPanRequired}
226
+ />
227
+ );
210
228
  };
211
229
  // ───────────────────────────────────────────────────────────────────────────
212
230
 
213
231
  interface RootNavigatorProps {
214
- config?: SDKNavigationConfig;
215
- onExit?: (fdDetails?: any) => void;
216
- onPanRequired?: () => void;
232
+ config?: SDKNavigationConfig;
233
+ onExit?: (fdDetails?: any) => void;
234
+ onPanRequired?: () => void;
217
235
  }
218
236
 
219
237
  const RootNavigator: React.FC<RootNavigatorProps> = ({
220
- config = {},
221
- onExit,
222
- onPanRequired,
238
+ config = {},
239
+ onExit,
240
+ onPanRequired,
223
241
  }) => {
224
- // State to track external SDK navigation
225
- const [externalSDK, setExternalSDK] = React.useState<'shriram' | 'mahindra' | null>(null);
226
- const [externalSDKFDData, setExternalSDKFDData] = React.useState<any>(null);
227
-
228
- // Stable exit callbacks — defined here so they're memoized across renders
229
- // and can be passed as stable props to the module-level SDK content components.
230
- const handleShriramExit = React.useCallback((fdDetails?: any) => {
231
- setExternalSDK(null);
232
- setExternalSDKFDData(null);
233
- navigate('FDList');
234
- if (fdDetails) onExit?.(fdDetails);
235
- }, [onExit]);
236
-
237
- const handleShriramPanRequired = React.useCallback(() => {
238
- setExternalSDK(null);
239
- setExternalSDKFDData(null);
240
- onPanRequired?.();
241
- onExit?.();
242
- }, [onExit, onPanRequired]);
243
-
244
- const handleMahindraExit = React.useCallback((fdDetails?: any) => {
245
- setExternalSDK(null);
246
- setExternalSDKFDData(null);
247
- navigate('FDList');
248
- if (fdDetails) onExit?.(fdDetails);
249
- }, [onExit]);
250
-
251
- const handleMahindraPanRequired = React.useCallback(() => {
252
- setExternalSDK(null);
253
- setExternalSDKFDData(null);
254
- onPanRequired?.();
255
- onExit?.();
256
- }, [onExit, onPanRequired]);
257
-
258
- // Get master data and theme from fdsdk – same theme (and themeName for dark/primary) is passed to Shriram and Mahindra
259
- const { masterData } = useMasterData();
260
- const { theme: fdsdkTheme, themeName: fdsdkThemeName } = useTheme();
261
-
262
- // Handle Android hardware back button
263
- useEffect(() => {
264
- if (Platform.OS !== 'android') return;
265
-
266
- let lastBackPressTime = 0;
267
-
268
- const onBackPress = () => {
269
- // Check if navigation is ready
270
- if (!navigationRef.current?.isReady()) {
271
- return false;
272
- }
273
-
274
- const now = Date.now();
275
-
276
- // Ignore synthetic back events triggered during forward navigation (debounce)
277
- if (now - lastBackPressTime < 300) {
278
- return false;
279
- }
280
-
281
- lastBackPressTime = now;
282
-
283
- const currentRoute = navigationRef.current?.getCurrentRoute()?.name;
284
-
285
- // Block back on Payment and PaymentStatus screens
286
- if (currentRoute === "Payment" || currentRoute === "PaymentStatus") {
287
- return true; // block hardware back
288
- }
289
-
290
- // FD Calculator should always redirect to FD List
291
- if (currentRoute === "FDCalculator") {
292
- navigationRef.current.navigate('FDList');
293
- return true;
294
- }
295
-
296
- // Skip FDList - let screen-specific handler handle it
297
- if (currentRoute === "FDList") {
298
- return false; // Let screen-specific handler handle it
299
- }
300
-
301
- // Enable back navigation everywhere else - use the same goBack() helper that header back buttons use
302
- goBack(); // This calls the same function as the header back button
303
- return true;
304
- };
305
-
306
- const subscription = BackHandler.addEventListener("hardwareBackPress", onBackPress);
307
-
308
- return () => {
309
- subscription.remove();
310
- };
311
- }, []);
312
-
313
- const {
314
- initialRouteName = 'FDList',
315
- customScreenOptions = {},
316
- } = config;
317
-
318
- const ensureExternalSdkInitialized = React.useCallback((sdkType: 'shriram' | 'mahindra') => {
319
- const appData = getAppData();
320
- const storedEnv = getEnvironmentData();
321
- const envData = storedEnv as ShriramEnvironmentData & MahindraEnvironmentData | null;
322
-
323
- if (!appData) {
324
- Alert.alert('Error', 'FDSDK app data is missing. Please restart the flow.');
325
- return false;
326
- }
327
- if (!envData) {
328
- Alert.alert('Error', 'FDSDK environment data is missing. Please initialize environment from host app.');
329
- return false;
330
- }
331
-
332
- try {
333
- if (sdkType === 'shriram') {
334
- initializeShriramEnvironment(envData as ShriramEnvironmentData);
335
- initializeShriramSDK(appData as ShriramAppData);
336
- } else {
337
- initializeMahindraEnvironment(envData as MahindraEnvironmentData);
338
- initializeMahindraSDK(appData as MahindraAppData);
339
- }
340
- return true;
341
- } catch (error: any) {
342
- Alert.alert(
343
- 'Error',
344
- `Failed to initialize ${sdkType === 'shriram' ? 'Shriram' : 'Mahindra'} SDK: ${error?.message || 'Unknown error'}`
345
- );
346
- return false;
347
- }
348
- }, []);
349
-
350
- // Default screen options
351
- const defaultScreenOptions = {
352
- headerShown: false,
353
- cardStyle: { backgroundColor: '#f8f9fa' },
354
- animationEnabled: true,
355
- gestureEnabled: true,
356
- ...customScreenOptions,
357
- };
358
-
359
- return (
360
- <Stack.Navigator
361
- initialRouteName={initialRouteName}
362
- screenOptions={defaultScreenOptions}
363
- >
364
- <Stack.Screen
365
- name="FDList"
366
- options={{ title: 'Fixed Deposits' }}
367
- >
368
- {(props) => (
369
- <FDListScreen
370
- onGoBack={() => {
371
- onExit?.();
372
- }}
373
- onSelectFD={(fdId) => {
374
- // FD selected
375
- }}
376
- onNavigateToFDCalculator={(fdData) => {
377
- navigate('FDCalculator', { fdData });
378
- }}
379
- onNavigateToExternalSDK={(sdkType, fdData, context) => {
380
- try {
381
- // Get app data and environment data from fdsdk
382
- const appData = getAppData();
383
- const envData = getEnvironmentData();
384
-
385
- // Validate that we have the required data
386
- if (!appData) {
387
- console.error('Cannot navigate to external SDK: App data not initialized');
388
- Alert.alert('Error', 'App data not available. Please initialize the SDK first.');
389
- return;
390
- }
391
-
392
- if (!envData) {
393
- console.error('Cannot navigate to external SDK: Environment data not initialized');
394
- Alert.alert('Error', 'Environment data not available. Please initialize the SDK first.');
395
- return;
396
- }
397
-
398
- // Initialize the target SDK with all data
399
- if (sdkType === 'shriram') {
400
- try {
401
- // Initialize Shriram SDK
402
- initializeShriramEnvironment(envData as ShriramEnvironmentData);
403
- initializeShriramSDK(appData as ShriramAppData);
404
-
405
- // Navigate to external SDK
406
- setExternalSDK('shriram');
407
- setExternalSDKFDData(fdData);
408
- navigate('ExternalSDK', {
409
- sdkType: 'shriram',
410
- fdData,
411
- providerId: context?.providerId,
412
- fdListSelectedData: context?.fdListSelectedData,
413
- completeFDData: context?.completeFDData,
414
- onboardingIds: context?.onboardingIds,
415
- });
416
- } catch (error: any) {
417
- console.error('Failed to initialize Shriram SDK:', error);
418
- Alert.alert('Error', `Failed to initialize Shriram SDK: ${error?.message || 'Unknown error'}`);
419
- }
420
- } else if (sdkType === 'mahindra') {
421
- try {
422
- // Initialize Mahindra SDK
423
- initializeMahindraEnvironment(envData as MahindraEnvironmentData);
424
- initializeMahindraSDK(appData as MahindraAppData);
425
-
426
- // Navigate to external SDK
427
- setExternalSDK('mahindra');
428
- setExternalSDKFDData(fdData);
429
- navigate('ExternalSDK', {
430
- sdkType: 'mahindra',
431
- fdData,
432
- providerId: context?.providerId,
433
- fdListSelectedData: context?.fdListSelectedData,
434
- completeFDData: context?.completeFDData,
435
- onboardingIds: context?.onboardingIds,
436
- });
437
- } catch (error: any) {
438
- console.error('Failed to initialize Mahindra SDK:', error);
439
- Alert.alert('Error', `Failed to initialize Mahindra SDK: ${error?.message || 'Unknown error'}`);
440
- }
441
- } else {
442
- console.warn('Unknown SDK type:', sdkType);
443
- }
444
- } catch (error: any) {
445
- console.error('Error in onNavigateToExternalSDK:', error);
446
- Alert.alert('Error', `Navigation error: ${error?.message || 'Unknown error'}`);
447
- }
448
- }}
449
- {...props}
450
- />
451
- )}
452
- </Stack.Screen>
453
-
454
- <Stack.Screen
455
- name="FDCalculator"
456
- options={{ title: 'FD Calculator' }}
457
- >
458
- {(props) => (
459
- <FDCalculatorScreen
460
- onGoBack={() => goBack()}
461
- onNavigateToReviewKYC={() => navigate('ReviewKYC', { fdData: props.route.params?.fdData })}
462
- fdData={(props.route.params as any)?.fdData}
463
- {...props}
464
- />
465
- )}
466
- </Stack.Screen>
467
-
468
- <Stack.Screen
469
- name="ExternalSDK"
470
- options={{ title: 'External SDK', gestureEnabled: false }}
471
- >
472
- {(props) => {
473
- const { sdkType } = (props.route.params as any) || {};
474
- const routeParams = (props.route.params as any) || {};
475
- const externalMasterData = routeParams.masterData;
476
- // #region agent log
477
- fetch('http://127.0.0.1:7653/ingest/94b18a39-caf3-48fd-98f5-bf1838d9491a',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'04da7c'},body:JSON.stringify({sessionId:'04da7c',runId:'pending-masterdata-trace',hypothesisId:'H3',location:'fdsdk/navigation/RootNavigator.tsx:295',message:'ExternalSDK route handoff',data:{sdkType:sdkType||null,providerId:routeParams?.providerId||null,onboardingProviderId:routeParams?.onboardingIds?.providerId||null,fdListSelectedProviderId:routeParams?.fdListSelectedData?.providerId||null,hasMasterData:!!externalMasterData,masterDataHasDataKey:!!externalMasterData?.data},timestamp:Date.now()})}).catch(()=>{});
478
- // #endregion agent log
479
- console.log('[RootNavigator][DEBUG][ExternalSDK] ENTRY', {
480
- sdkType,
481
- providerId: routeParams.providerId,
482
- onboardingProviderId: routeParams.onboardingIds?.providerId,
483
- fdListSelectedProviderId: routeParams.fdListSelectedData?.providerId,
484
- hasMasterData: !!externalMasterData,
485
- masterDataTopKeys: externalMasterData ? Object.keys(externalMasterData).slice(0, 20) : [],
486
- nestedDataTopKeys: externalMasterData?.data ? Object.keys(externalMasterData.data).slice(0, 20) : [],
487
- });
488
- if (sdkType === 'shriram' || sdkType === 'mahindra') {
489
- const ok = ensureExternalSdkInitialized(sdkType);
490
- if (!ok) return null;
491
- }
492
-
493
- if (sdkType === 'shriram') {
494
- return (
495
- <ShriramApiProvider>
496
- <ShriramMasterDataProvider>
497
- <ShriramThemeProvider theme={fdsdkTheme as any} initialTheme={fdsdkThemeName as any}>
498
- <NavigationIndependentTree>
499
- <NavigationContainer ref={shriramNavigationRef}>
500
- <ShriramSDKContent
501
- masterData={externalMasterData}
502
- routeParams={routeParams}
503
- onSDKExit={handleShriramExit}
504
- onSDKPanRequired={handleShriramPanRequired}
505
- />
506
- </NavigationContainer>
507
- </NavigationIndependentTree>
508
- </ShriramThemeProvider>
509
- </ShriramMasterDataProvider>
510
- </ShriramApiProvider>
511
- );
512
- }
513
-
514
- if (sdkType === 'mahindra') {
515
- return (
516
- <MahindraApiProvider>
517
- <MahindraMasterDataProvider>
518
- <MahindraThemeProvider theme={fdsdkTheme as any} initialTheme={fdsdkThemeName as any}>
519
- <NavigationIndependentTree>
520
- <NavigationContainer ref={mahindraNavigationRef}>
521
- <MahindraSDKContent
522
- masterData={externalMasterData}
523
- routeParams={routeParams}
524
- onSDKExit={handleMahindraExit}
525
- onSDKPanRequired={handleMahindraPanRequired}
526
- />
527
- </NavigationContainer>
528
- </NavigationIndependentTree>
529
- </MahindraThemeProvider>
530
- </MahindraMasterDataProvider>
531
- </MahindraApiProvider>
532
- );
533
- }
534
-
535
- return null;
536
- }}
537
- </Stack.Screen>
538
-
539
- <Stack.Screen
540
- name="AadhaarVerification"
541
- options={{ title: 'Aadhaar Verification' }}
542
- >
543
- {(props) => (
544
- <AadhaarVerificationScreen
545
- onGoBack={() => goBack()}
546
- onVerificationComplete={() => {
547
- navigate('Employee');
548
- }}
549
- {...props}
550
- />
551
- )}
552
- </Stack.Screen>
553
-
554
- <Stack.Screen
555
- name="ReviewKYC"
556
- options={{ title: 'Review KYC' }}
557
- >
558
- {(props) => (
559
- <ReviewKYCScreen
560
- onGoBack={() => goBack()}
561
- onContinue={() => {
562
- navigate('Employee');
563
- }}
564
- {...props}
565
- />
566
- )}
567
- </Stack.Screen>
568
-
569
- <Stack.Screen
570
- name="Employee"
571
- options={{ title: 'Occupation' }}
572
- >
573
- {(props) => (
574
- <EmployeeScreen
575
- onGoBack={() => goBack()}
576
- onContinue={() => {
577
- navigate('NomineeDetail');
578
- }}
579
- {...props}
580
- />
581
- )}
582
- </Stack.Screen>
583
-
584
- <Stack.Screen
585
- name="NomineeDetail"
586
- options={{ title: 'Nominee Details' }}
587
- >
588
- {(props) => (
589
- <NomineeDetailScreen
590
- onGoBack={() => goBack()}
591
- onSave={() => {
592
- navigate('BankDetail');
593
- }}
594
- {...props}
595
- />
596
- )}
597
- </Stack.Screen>
598
-
599
- <Stack.Screen
600
- name="BankDetail"
601
- options={{ title: 'Bank Details' }}
602
- >
603
- {(props) => (
604
- <BankDetailScreen
605
- onGoBack={() => goBack()}
606
- onContinue={() => {
607
- navigate('PayNow');
608
- }}
609
- onAddAccount={() => {
610
- navigate('AddBankAccount');
611
- }}
612
- {...props}
613
- />
614
- )}
615
- </Stack.Screen>
616
-
617
- <Stack.Screen
618
- name="AddBankAccount"
619
- options={{ title: 'Add Bank Account' }}
620
- >
621
- {(props) => (
622
- <AddBankAccountScreen
623
- onGoBack={() => goBack()}
624
- onContinue={() => {
625
- goBack();
626
- }}
627
- onFindIFSC={() => {
628
- navigate('FindIFSC');
629
- }}
630
- selectedIFSC={(() => {
631
- const params = (props.route.params as any);
632
- return params?.selectedIFSC;
633
- })()}
634
- {...props}
635
- />
636
- )}
637
- </Stack.Screen>
638
-
639
- <Stack.Screen
640
- name="FindIFSC"
641
- options={{ title: 'Find IFSC' }}
642
- >
643
- {(props) => (
644
- <FindIFSCScreen
645
- onGoBack={() => goBack()}
646
- onSelect={(ifscData) => {
647
- pop(1);
648
- navigate('AddBankAccount', { selectedIFSC: ifscData });
649
- }}
650
- initialSearchTerm={(props.route.params as any)?.initialSearchTerm}
651
- {...props}
652
- />
653
- )}
654
- </Stack.Screen>
655
-
656
- <Stack.Screen
657
- name="PayNow"
658
- options={{ title: 'Pay Now' }}
659
- >
660
- {(props) => (
661
- <PayNowScreen
662
- onGoBack={() => goBack()}
663
- onConfirm={() => {
664
- // onConfirm is handled inside PayNow after createFD; keep fallback
665
- }}
666
- fdData={(props.route.params as any)?.fdData}
667
- {...props}
668
- />
669
- )}
670
- </Stack.Screen>
671
-
672
- <Stack.Screen
673
- name="Payment"
674
- options={{ title: 'Payment' }}
675
- >
676
- {(props) => (
677
- <PaymentScreen
678
- onGoBack={() => goBack()}
679
- paymentUrl={(props.route.params as any)?.paymentUrl ?? getPaymentSession().paymentUrl ?? ''}
680
- onPaymentSuccess={(data) => {
681
- navigate('PaymentStatus', {
682
- status: 'success',
683
- paymentData: data
684
- } as any);
685
- }}
686
- onPaymentFailure={(error) => {
687
- navigate('PaymentStatus', {
688
- status: 'failed',
689
- paymentData: error
690
- } as any);
691
- }}
692
- {...props}
693
- />
694
- )}
695
- </Stack.Screen>
696
-
697
- <Stack.Screen
698
- name="PaymentStatus"
699
- options={{ title: 'Payment Status' }}
700
- >
701
- {(props) => (
702
- <PaymentStatusScreen
703
- status={(props.route.params as any)?.status || 'pending'}
704
- transactionId={(props.route.params as any)?.transactionId}
705
- fdData={(props.route.params as any)?.fdData}
706
- onRetry={() => {
707
- navigate('Payment');
708
- }}
709
- onContinue={(fdDetails) => {
710
- onExit?.(fdDetails);
711
- }}
712
- {...props}
713
- />
714
- )}
715
- </Stack.Screen>
716
- </Stack.Navigator>
717
- );
242
+ // State to track external SDK navigation
243
+ const [externalSDK, setExternalSDK] = React.useState < 'shriram' | 'mahindra' | null > (null);
244
+ const [externalSDKFDData, setExternalSDKFDData] = React.useState < any > (null);
245
+
246
+ // Stable exit callbacks — defined here so they're memoized across renders
247
+ // and can be passed as stable props to the module-level SDK content components.
248
+ const handleShriramExit = React.useCallback((fdDetails?: any) => {
249
+ setExternalSDK(null);
250
+ setExternalSDKFDData(null);
251
+ navigate('FDList');
252
+ if (fdDetails) onExit?.(fdDetails);
253
+ }, [onExit]);
254
+
255
+ const handleShriramPanRequired = React.useCallback(() => {
256
+ setExternalSDK(null);
257
+ setExternalSDKFDData(null);
258
+ onPanRequired?.();
259
+ onExit?.();
260
+ }, [onExit, onPanRequired]);
261
+
262
+ const handleMahindraExit = React.useCallback((fdDetails?: any) => {
263
+ setExternalSDK(null);
264
+ setExternalSDKFDData(null);
265
+ navigate('FDList');
266
+ if (fdDetails) onExit?.(fdDetails);
267
+ }, [onExit]);
268
+
269
+ const handleMahindraPanRequired = React.useCallback(() => {
270
+ setExternalSDK(null);
271
+ setExternalSDKFDData(null);
272
+ onPanRequired?.();
273
+ onExit?.();
274
+ }, [onExit, onPanRequired]);
275
+
276
+ // Get master data and theme from fdsdk – same theme (and themeName for dark/primary) is passed to Shriram and Mahindra
277
+ const { masterData } = useMasterData();
278
+ const { theme: fdsdkTheme, themeName: fdsdkThemeName } = useTheme();
279
+
280
+ // Handle Android hardware back button
281
+ useEffect(() => {
282
+ if (Platform.OS !== 'android') return;
283
+
284
+ const onBackPress = () => {
285
+ // Return true to consume the event and do nothing (stop back navigation)
286
+ return true;
287
+ };
288
+
289
+ const subscription = BackHandler.addEventListener("hardwareBackPress", onBackPress);
290
+
291
+ return () => {
292
+ subscription.remove();
293
+ };
294
+ }, []);
295
+
296
+ const {
297
+ initialRouteName = 'FDList',
298
+ customScreenOptions = {},
299
+ } = config;
300
+
301
+ const ensureExternalSdkInitialized = React.useCallback((sdkType: 'shriram' | 'mahindra') => {
302
+ const appData = getAppData();
303
+ const storedEnv = getEnvironmentData();
304
+ const envData = storedEnv as ShriramEnvironmentData & MahindraEnvironmentData | null;
305
+
306
+ if (!appData) {
307
+ Alert.alert('Error', 'FDSDK app data is missing. Please restart the flow.');
308
+ return false;
309
+ }
310
+ if (!envData) {
311
+ Alert.alert('Error', 'FDSDK environment data is missing. Please initialize environment from host app.');
312
+ return false;
313
+ }
314
+
315
+ try {
316
+ if (sdkType === 'shriram') {
317
+ initializeShriramEnvironment(envData as ShriramEnvironmentData);
318
+ initializeShriramSDK(appData as ShriramAppData);
319
+ } else {
320
+ initializeMahindraEnvironment(envData as MahindraEnvironmentData);
321
+ initializeMahindraSDK(appData as MahindraAppData);
322
+ }
323
+ return true;
324
+ } catch (error: any) {
325
+ Alert.alert(
326
+ 'Error',
327
+ `Failed to initialize ${sdkType === 'shriram' ? 'Shriram' : 'Mahindra'} SDK: ${error?.message || 'Unknown error'}`
328
+ );
329
+ return false;
330
+ }
331
+ }, []);
332
+
333
+ // Default screen options
334
+ const defaultScreenOptions = {
335
+ headerShown: false,
336
+ cardStyle: { backgroundColor: '#f8f9fa' },
337
+ animationEnabled: true,
338
+ gestureEnabled: false,
339
+ ...customScreenOptions,
340
+ };
341
+
342
+ return (
343
+ <Stack.Navigator
344
+ initialRouteName={initialRouteName}
345
+ screenOptions={defaultScreenOptions}
346
+ >
347
+ <Stack.Screen
348
+ name="FDList"
349
+ options={{ title: 'Fixed Deposits' }}
350
+ >
351
+ {(props) => (
352
+ <FDListScreen
353
+ onGoBack={() => {
354
+ onExit?.();
355
+ }}
356
+ onSelectFD={(fdId) => {
357
+ // FD selected
358
+ }}
359
+ onNavigateToFDCalculator={(fdData) => {
360
+ navigate('FDCalculator', { fdData });
361
+ }}
362
+ onNavigateToExternalSDK={(sdkType, fdData, context) => {
363
+ try {
364
+ // Get app data and environment data from fdsdk
365
+ const appData = getAppData();
366
+ const envData = getEnvironmentData();
367
+
368
+ // Validate that we have the required data
369
+ if (!appData) {
370
+ console.error('Cannot navigate to external SDK: App data not initialized');
371
+ Alert.alert('Error', 'App data not available. Please initialize the SDK first.');
372
+ return;
373
+ }
374
+
375
+ if (!envData) {
376
+ console.error('Cannot navigate to external SDK: Environment data not initialized');
377
+ Alert.alert('Error', 'Environment data not available. Please initialize the SDK first.');
378
+ return;
379
+ }
380
+
381
+ // Initialize the target SDK with all data
382
+ if (sdkType === 'shriram') {
383
+ try {
384
+ // Initialize Shriram SDK
385
+ initializeShriramEnvironment(envData as ShriramEnvironmentData);
386
+ initializeShriramSDK(appData as ShriramAppData);
387
+
388
+ // Navigate to external SDK
389
+ setExternalSDK('shriram');
390
+ setExternalSDKFDData(fdData);
391
+ navigate('ExternalSDK', {
392
+ sdkType: 'shriram',
393
+ fdData,
394
+ providerId: context?.providerId,
395
+ fdListSelectedData: context?.fdListSelectedData,
396
+ completeFDData: context?.completeFDData,
397
+ onboardingIds: context?.onboardingIds,
398
+ });
399
+ } catch (error: any) {
400
+ console.error('Failed to initialize Shriram SDK:', error);
401
+ Alert.alert('Error', `Failed to initialize Shriram SDK: ${error?.message || 'Unknown error'}`);
402
+ }
403
+ } else if (sdkType === 'mahindra') {
404
+ try {
405
+ // Initialize Mahindra SDK
406
+ initializeMahindraEnvironment(envData as MahindraEnvironmentData);
407
+ initializeMahindraSDK(appData as MahindraAppData);
408
+
409
+ // Navigate to external SDK
410
+ setExternalSDK('mahindra');
411
+ setExternalSDKFDData(fdData);
412
+ navigate('ExternalSDK', {
413
+ sdkType: 'mahindra',
414
+ fdData,
415
+ providerId: context?.providerId,
416
+ fdListSelectedData: context?.fdListSelectedData,
417
+ completeFDData: context?.completeFDData,
418
+ onboardingIds: context?.onboardingIds,
419
+ });
420
+ } catch (error: any) {
421
+ console.error('Failed to initialize Mahindra SDK:', error);
422
+ Alert.alert('Error', `Failed to initialize Mahindra SDK: ${error?.message || 'Unknown error'}`);
423
+ }
424
+ } else {
425
+ console.warn('Unknown SDK type:', sdkType);
426
+ }
427
+ } catch (error: any) {
428
+ console.error('Error in onNavigateToExternalSDK:', error);
429
+ Alert.alert('Error', `Navigation error: ${error?.message || 'Unknown error'}`);
430
+ }
431
+ }}
432
+ {...props}
433
+ />
434
+ )}
435
+ </Stack.Screen>
436
+
437
+ <Stack.Screen
438
+ name="FDCalculator"
439
+ options={{ title: 'FD Calculator' }}
440
+ >
441
+ {(props) => (
442
+ <FDCalculatorScreen
443
+ onGoBack={() => goBack()}
444
+ onNavigateToReviewKYC={() => navigate('ReviewKYC', { fdData: props.route.params?.fdData })}
445
+ fdData={(props.route.params as any)?.fdData}
446
+ {...props}
447
+ />
448
+ )}
449
+ </Stack.Screen>
450
+
451
+ <Stack.Screen
452
+ name="ExternalSDK"
453
+ options={{ title: 'External SDK', gestureEnabled: false }}
454
+ >
455
+ {(props) => {
456
+ const { sdkType } = (props.route.params as any) || {};
457
+ const routeParams = (props.route.params as any) || {};
458
+ const externalMasterData = routeParams.masterData;
459
+ // #region agent log
460
+ fetch('http://127.0.0.1:7653/ingest/94b18a39-caf3-48fd-98f5-bf1838d9491a', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '04da7c' }, body: JSON.stringify({ sessionId: '04da7c', runId: 'pending-masterdata-trace', hypothesisId: 'H3', location: 'fdsdk/navigation/RootNavigator.tsx:295', message: 'ExternalSDK route handoff', data: { sdkType: sdkType || null, providerId: routeParams?.providerId || null, onboardingProviderId: routeParams?.onboardingIds?.providerId || null, fdListSelectedProviderId: routeParams?.fdListSelectedData?.providerId || null, hasMasterData: !!externalMasterData, masterDataHasDataKey: !!externalMasterData?.data }, timestamp: Date.now() }) }).catch(() => { });
461
+ // #endregion agent log
462
+ console.log('[RootNavigator][DEBUG][ExternalSDK] ENTRY', {
463
+ sdkType,
464
+ providerId: routeParams.providerId,
465
+ onboardingProviderId: routeParams.onboardingIds?.providerId,
466
+ fdListSelectedProviderId: routeParams.fdListSelectedData?.providerId,
467
+ hasMasterData: !!externalMasterData,
468
+ masterDataTopKeys: externalMasterData ? Object.keys(externalMasterData).slice(0, 20) : [],
469
+ nestedDataTopKeys: externalMasterData?.data ? Object.keys(externalMasterData.data).slice(0, 20) : [],
470
+ });
471
+ if (sdkType === 'shriram' || sdkType === 'mahindra') {
472
+ const ok = ensureExternalSdkInitialized(sdkType);
473
+ if (!ok) return null;
474
+ }
475
+
476
+ if (sdkType === 'shriram') {
477
+ return (
478
+ <ShriramApiProvider>
479
+ <ShriramMasterDataProvider>
480
+ <ShriramThemeProvider theme={fdsdkTheme as any} initialTheme={fdsdkThemeName as any}>
481
+ <NavigationIndependentTree>
482
+ <NavigationContainer ref={shriramNavigationRef}>
483
+ <ShriramSDKContent
484
+ masterData={externalMasterData}
485
+ routeParams={routeParams}
486
+ onSDKExit={handleShriramExit}
487
+ onSDKPanRequired={handleShriramPanRequired}
488
+ />
489
+ </NavigationContainer>
490
+ </NavigationIndependentTree>
491
+ </ShriramThemeProvider>
492
+ </ShriramMasterDataProvider>
493
+ </ShriramApiProvider>
494
+ );
495
+ }
496
+
497
+ if (sdkType === 'mahindra') {
498
+ return (
499
+ <MahindraApiProvider>
500
+ <MahindraMasterDataProvider>
501
+ <MahindraThemeProvider theme={fdsdkTheme as any} initialTheme={fdsdkThemeName as any}>
502
+ <NavigationIndependentTree>
503
+ <NavigationContainer ref={mahindraNavigationRef}>
504
+ <MahindraSDKContent
505
+ masterData={externalMasterData}
506
+ routeParams={routeParams}
507
+ onSDKExit={handleMahindraExit}
508
+ onSDKPanRequired={handleMahindraPanRequired}
509
+ />
510
+ </NavigationContainer>
511
+ </NavigationIndependentTree>
512
+ </MahindraThemeProvider>
513
+ </MahindraMasterDataProvider>
514
+ </MahindraApiProvider>
515
+ );
516
+ }
517
+
518
+ return null;
519
+ }}
520
+ </Stack.Screen>
521
+
522
+ <Stack.Screen
523
+ name="AadhaarVerification"
524
+ options={{ title: 'Aadhaar Verification' }}
525
+ >
526
+ {(props) => (
527
+ <AadhaarVerificationScreen
528
+ onGoBack={() => goBack()}
529
+ onVerificationComplete={() => {
530
+ navigate('Employee');
531
+ }}
532
+ {...props}
533
+ />
534
+ )}
535
+ </Stack.Screen>
536
+
537
+ <Stack.Screen
538
+ name="ReviewKYC"
539
+ options={{ title: 'Review KYC' }}
540
+ >
541
+ {(props) => (
542
+ <ReviewKYCScreen
543
+ onGoBack={() => goBack()}
544
+ onContinue={() => {
545
+ navigate('Employee');
546
+ }}
547
+ {...props}
548
+ />
549
+ )}
550
+ </Stack.Screen>
551
+
552
+ <Stack.Screen
553
+ name="Employee"
554
+ options={{ title: 'Occupation' }}
555
+ >
556
+ {(props) => (
557
+ <EmployeeScreen
558
+ onGoBack={() => goBack()}
559
+ onContinue={() => {
560
+ navigate('NomineeDetail');
561
+ }}
562
+ {...props}
563
+ />
564
+ )}
565
+ </Stack.Screen>
566
+
567
+ <Stack.Screen
568
+ name="NomineeDetail"
569
+ options={{ title: 'Nominee Details' }}
570
+ >
571
+ {(props) => (
572
+ <NomineeDetailScreen
573
+ onGoBack={() => goBack()}
574
+ onSave={() => {
575
+ navigate('BankDetail');
576
+ }}
577
+ {...props}
578
+ />
579
+ )}
580
+ </Stack.Screen>
581
+
582
+ <Stack.Screen
583
+ name="BankDetail"
584
+ options={{ title: 'Bank Details' }}
585
+ >
586
+ {(props) => (
587
+ <BankDetailScreen
588
+ onGoBack={() => goBack()}
589
+ onContinue={() => {
590
+ navigate('PayNow');
591
+ }}
592
+ onAddAccount={() => {
593
+ navigate('AddBankAccount');
594
+ }}
595
+ {...props}
596
+ />
597
+ )}
598
+ </Stack.Screen>
599
+
600
+ <Stack.Screen
601
+ name="AddBankAccount"
602
+ options={{ title: 'Add Bank Account' }}
603
+ >
604
+ {(props) => (
605
+ <AddBankAccountScreen
606
+ onGoBack={() => goBack()}
607
+ onContinue={() => {
608
+ goBack();
609
+ }}
610
+ onFindIFSC={() => {
611
+ navigate('FindIFSC');
612
+ }}
613
+ selectedIFSC={(() => {
614
+ const params = (props.route.params as any);
615
+ return params?.selectedIFSC;
616
+ })()}
617
+ {...props}
618
+ />
619
+ )}
620
+ </Stack.Screen>
621
+
622
+ <Stack.Screen
623
+ name="FindIFSC"
624
+ options={{ title: 'Find IFSC' }}
625
+ >
626
+ {(props) => (
627
+ <FindIFSCScreen
628
+ onGoBack={() => goBack()}
629
+ onSelect={(ifscData) => {
630
+ pop(1);
631
+ navigate('AddBankAccount', { selectedIFSC: ifscData });
632
+ }}
633
+ initialSearchTerm={(props.route.params as any)?.initialSearchTerm}
634
+ {...props}
635
+ />
636
+ )}
637
+ </Stack.Screen>
638
+
639
+ <Stack.Screen
640
+ name="PayNow"
641
+ options={{ title: 'Pay Now' }}
642
+ >
643
+ {(props) => (
644
+ <PayNowScreen
645
+ onGoBack={() => goBack()}
646
+ onConfirm={() => {
647
+ // onConfirm is handled inside PayNow after createFD; keep fallback
648
+ }}
649
+ fdData={(props.route.params as any)?.fdData}
650
+ {...props}
651
+ />
652
+ )}
653
+ </Stack.Screen>
654
+
655
+ <Stack.Screen
656
+ name="Payment"
657
+ options={{ title: 'Payment' }}
658
+ >
659
+ {(props) => (
660
+ <PaymentScreen
661
+ onGoBack={() => goBack()}
662
+ paymentUrl={(props.route.params as any)?.paymentUrl ?? getPaymentSession().paymentUrl ?? ''}
663
+ onPaymentSuccess={(data) => {
664
+ navigate('PaymentStatus', {
665
+ status: 'success',
666
+ paymentData: data
667
+ } as any);
668
+ }}
669
+ onPaymentFailure={(error) => {
670
+ navigate('PaymentStatus', {
671
+ status: 'failed',
672
+ paymentData: error
673
+ } as any);
674
+ }}
675
+ {...props}
676
+ />
677
+ )}
678
+ </Stack.Screen>
679
+
680
+ <Stack.Screen
681
+ name="PaymentStatus"
682
+ options={{ title: 'Payment Status' }}
683
+ >
684
+ {(props) => (
685
+ <PaymentStatusScreen
686
+ status={(props.route.params as any)?.status || 'pending'}
687
+ transactionId={(props.route.params as any)?.transactionId}
688
+ fdData={(props.route.params as any)?.fdData}
689
+ onRetry={() => {
690
+ navigate('Payment');
691
+ }}
692
+ onContinue={(fdDetails) => {
693
+ onExit?.(fdDetails);
694
+ }}
695
+ {...props}
696
+ />
697
+ )}
698
+ </Stack.Screen>
699
+ </Stack.Navigator>
700
+ );
718
701
  };
719
702
 
720
703
  export default RootNavigator;