@finspringinnovations/fdsdk 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/baseApi.js +17 -6
- package/lib/api/masterDataApi.js +21 -1
- package/lib/api/workflowApi.js +46 -1
- package/lib/assets/images/images.d.ts +1 -0
- package/lib/assets/images/images.js +1 -0
- package/lib/components/FDCard.js +9 -0
- package/lib/hooks/usePaymentSSE.d.ts +7 -1
- package/lib/hooks/usePaymentSSE.js +101 -12
- package/lib/navigation/RootNavigator.d.ts +1 -0
- package/lib/navigation/RootNavigator.js +12 -4
- package/lib/navigation/index.d.ts +1 -0
- package/lib/navigation/index.js +2 -2
- package/lib/screens/AadhaarVerification.js +2 -2
- package/lib/screens/FDCalculator.d.ts +1 -0
- package/lib/screens/FDCalculator.js +11 -4
- package/lib/screens/FDList.js +37 -64
- package/lib/screens/Payment.js +42 -28
- package/lib/screens/PaymentStatus.js +24 -26
- package/lib/screens/ReviewKYC.js +45 -97
- package/package.json +1 -1
- package/src/api/baseApi.ts +19 -6
- package/src/api/masterDataApi.ts +21 -3
- package/src/api/workflowApi.ts +50 -1
- package/src/assets/images/images.js +1 -0
- package/src/assets/images/shriram.png +0 -0
- package/src/components/FDCard.tsx +15 -0
- package/src/hooks/usePaymentSSE.ts +109 -15
- package/src/navigation/RootNavigator.tsx +12 -3
- package/src/navigation/index.tsx +3 -1
- package/src/screens/AadhaarVerification.tsx +2 -2
- package/src/screens/FDCalculator.tsx +12 -4
- package/src/screens/FDList.tsx +37 -76
- package/src/screens/Payment.tsx +45 -35
- package/src/screens/PaymentStatus.tsx +25 -40
- package/src/screens/ReviewKYC.tsx +94 -170
package/src/screens/Payment.tsx
CHANGED
|
@@ -5,9 +5,8 @@ import SafeAreaWrapper from '../components/SafeAreaWrapper';
|
|
|
5
5
|
import { useColors } from '../theme/ThemeContext';
|
|
6
6
|
import { decryptResponse } from '../utils/encryption';
|
|
7
7
|
import { getEncryptionConfig } from '../config/encryptionConfig';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { usePaymentStatusTimer, PaymentStatus } from '../hooks/usePaymentStatusTimer';
|
|
8
|
+
import { useAppSelector } from '../store';
|
|
9
|
+
import { usePaymentSSE } from '../hooks/usePaymentSSE';
|
|
11
10
|
|
|
12
11
|
export interface PaymentProps {
|
|
13
12
|
onGoBack?: () => void;
|
|
@@ -32,33 +31,16 @@ const Payment: React.FC<PaymentProps> = ({
|
|
|
32
31
|
const styles = createStyles(colors);
|
|
33
32
|
const webViewRef = useRef<WebView>(null);
|
|
34
33
|
const [loading, setLoading] = useState(true);
|
|
35
|
-
const currentStatusRef = useRef<PaymentStatus>('pending');
|
|
36
|
-
const { transactionId } = getPaymentSession();
|
|
37
34
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
onPaymentFailure?.(response);
|
|
48
|
-
}
|
|
49
|
-
else if (status === 'pending') {
|
|
50
|
-
onPaymentPending?.(response);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
useFocusEffect(
|
|
57
|
-
React.useCallback(() => {
|
|
58
|
-
startTimer();
|
|
59
|
-
|
|
60
|
-
}, [startTimer, stopTimer])
|
|
61
|
-
);
|
|
35
|
+
const applicationId = useAppSelector((state: any) => state?.onboarding?.applicationId);
|
|
36
|
+
const workflowInstanceId = useAppSelector((state: any) => state?.onboarding?.workflowInstanceId);
|
|
37
|
+
const entityId = useAppSelector((state: any) => state?.onboarding?.entityid);
|
|
38
|
+
const providerId = useAppSelector((state: any) => state?.onboarding?.providerId);
|
|
39
|
+
const { start: startPaymentSSE, stop: stopPaymentSSE } = usePaymentSSE();
|
|
40
|
+
const onSuccessRef = useRef(onPaymentSuccess);
|
|
41
|
+
const onFailureRef = useRef(onPaymentFailure);
|
|
42
|
+
onSuccessRef.current = onPaymentSuccess;
|
|
43
|
+
onFailureRef.current = onPaymentFailure;
|
|
62
44
|
|
|
63
45
|
|
|
64
46
|
|
|
@@ -89,6 +71,40 @@ const Payment: React.FC<PaymentProps> = ({
|
|
|
89
71
|
setLoading(false);
|
|
90
72
|
};
|
|
91
73
|
|
|
74
|
+
// SSE: listen for payment status while user is on Payment WebView (same as web integration)
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (!applicationId || !paymentUrl?.trim()) return;
|
|
77
|
+
|
|
78
|
+
startPaymentSSE(
|
|
79
|
+
applicationId,
|
|
80
|
+
{
|
|
81
|
+
onPaymentStatus: (status, payload) => {
|
|
82
|
+
const normalized = String(status || '').toUpperCase();
|
|
83
|
+
if (normalized === 'SUCCESS') {
|
|
84
|
+
stopPaymentSSE();
|
|
85
|
+
onSuccessRef.current?.(payload);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (normalized === 'FAILED') {
|
|
89
|
+
stopPaymentSSE();
|
|
90
|
+
onFailureRef.current?.(payload);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
onError: () => {
|
|
94
|
+
if (__DEV__) console.warn('[Payment] SSE connection error');
|
|
95
|
+
},
|
|
96
|
+
onConnected: () => {
|
|
97
|
+
if (__DEV__) console.log('[Payment] SSE connected for payment status');
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{ workflowInstanceId, applicationId, entityid: entityId, providerId }
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return () => {
|
|
104
|
+
stopPaymentSSE();
|
|
105
|
+
};
|
|
106
|
+
}, [applicationId, paymentUrl, workflowInstanceId, entityId, providerId, startPaymentSSE, stopPaymentSSE]);
|
|
107
|
+
|
|
92
108
|
const handleMessage = async (event: any) => {
|
|
93
109
|
try {
|
|
94
110
|
const dataString = event.nativeEvent.data;
|
|
@@ -133,18 +149,13 @@ const Payment: React.FC<PaymentProps> = ({
|
|
|
133
149
|
const paymentStatus = response.data?.paymentStatus?.toLowerCase();
|
|
134
150
|
|
|
135
151
|
if (paymentStatus === 'success') {
|
|
136
|
-
currentStatusRef.current = "success";
|
|
137
|
-
stopTimer();
|
|
138
152
|
onPaymentSuccess?.(response);
|
|
139
153
|
} else if (paymentStatus === 'failed') {
|
|
140
|
-
currentStatusRef.current = "failed";
|
|
141
|
-
stopTimer();
|
|
142
154
|
onPaymentFailure?.(response);
|
|
143
155
|
} else {
|
|
144
156
|
onPaymentPending?.(response);
|
|
145
157
|
}
|
|
146
158
|
} else {
|
|
147
|
-
currentStatusRef.current = "pending";
|
|
148
159
|
onPaymentPending?.(response);
|
|
149
160
|
}
|
|
150
161
|
|
|
@@ -252,4 +263,3 @@ const createStyles = (colors: any) => StyleSheet.create({
|
|
|
252
263
|
});
|
|
253
264
|
|
|
254
265
|
export default Payment;
|
|
255
|
-
|
|
@@ -15,8 +15,7 @@ import { setPaymentSession, getPaymentSession } from '../state/paymentSession';
|
|
|
15
15
|
import { useRoute } from '@react-navigation/native';
|
|
16
16
|
import { BANK_STRINGS } from '../constants/strings/bank';
|
|
17
17
|
import { COMMON_STRINGS } from '../constants/strings/common';
|
|
18
|
-
import {
|
|
19
|
-
import { usePaymentStatusTimer } from '../hooks/usePaymentStatusTimer';
|
|
18
|
+
import { usePaymentSSE } from '../hooks/usePaymentSSE';
|
|
20
19
|
|
|
21
20
|
export interface PaymentStatusProps {
|
|
22
21
|
onRetry?: () => void;
|
|
@@ -64,23 +63,7 @@ const PaymentStatus: React.FC<PaymentStatusProps> = ({
|
|
|
64
63
|
const entityId = useAppSelector((state: any) => state?.onboarding?.entityid);
|
|
65
64
|
const providerId = useAppSelector((state: any) => state?.onboarding?.providerId);
|
|
66
65
|
|
|
67
|
-
const {
|
|
68
|
-
startTimer,
|
|
69
|
-
stopTimer,
|
|
70
|
-
triggerStatusCheck,
|
|
71
|
-
isCheckingStatus,
|
|
72
|
-
} = usePaymentStatusTimer({
|
|
73
|
-
transactionId: finalTransactionId,
|
|
74
|
-
overrides: {
|
|
75
|
-
providerId,
|
|
76
|
-
workflowInstanceId,
|
|
77
|
-
applicationid: applicationId,
|
|
78
|
-
entityid: entityId,
|
|
79
|
-
},
|
|
80
|
-
onStatusUpdate: (nextStatus) => {
|
|
81
|
-
setCurrentStatus(nextStatus);
|
|
82
|
-
},
|
|
83
|
-
});
|
|
66
|
+
const { start: startPaymentSSE, stop: stopPaymentSSE } = usePaymentSSE();
|
|
84
67
|
|
|
85
68
|
// Payment Retry API
|
|
86
69
|
const [paymentRetry, {
|
|
@@ -118,20 +101,33 @@ const PaymentStatus: React.FC<PaymentStatusProps> = ({
|
|
|
118
101
|
};
|
|
119
102
|
|
|
120
103
|
useEffect(() => {
|
|
121
|
-
if (currentStatus
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
stopTimer();
|
|
104
|
+
if (currentStatus !== 'pending' || !applicationId) {
|
|
105
|
+
stopPaymentSSE();
|
|
106
|
+
return;
|
|
125
107
|
}
|
|
126
108
|
|
|
109
|
+
startPaymentSSE(applicationId, {
|
|
110
|
+
onPaymentStatus: (status) => {
|
|
111
|
+
const normalized = String(status || '').toUpperCase();
|
|
112
|
+
if (normalized === 'SUCCESS') {
|
|
113
|
+
setCurrentStatus('success');
|
|
114
|
+
stopPaymentSSE();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (normalized === 'FAILED') {
|
|
118
|
+
setCurrentStatus('failed');
|
|
119
|
+
stopPaymentSSE();
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
onError: () => {
|
|
123
|
+
// keep pending state; stream can be restarted on re-render
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
127
|
return () => {
|
|
128
|
-
|
|
128
|
+
stopPaymentSSE();
|
|
129
129
|
};
|
|
130
|
-
}, [currentStatus,
|
|
131
|
-
|
|
132
|
-
const handlePaymentReverseFeed = async () => {
|
|
133
|
-
await triggerStatusCheck();
|
|
134
|
-
};
|
|
130
|
+
}, [applicationId, currentStatus, startPaymentSSE, stopPaymentSSE]);
|
|
135
131
|
|
|
136
132
|
// Handle payment retry when status is failed
|
|
137
133
|
const handlePaymentRetry = async () => {
|
|
@@ -181,9 +177,6 @@ const PaymentStatus: React.FC<PaymentStatusProps> = ({
|
|
|
181
177
|
// Get user info from app data
|
|
182
178
|
const userInfo = getUserInfoForAPI();
|
|
183
179
|
|
|
184
|
-
// Get API configuration
|
|
185
|
-
const apiConfig = getApiConfig();
|
|
186
|
-
|
|
187
180
|
// Prepare request payload
|
|
188
181
|
const requestPayload = {
|
|
189
182
|
userReferenceId: userInfo.id
|
|
@@ -412,13 +405,6 @@ const PaymentStatus: React.FC<PaymentStatusProps> = ({
|
|
|
412
405
|
disabled={isLoadingPaymentRetry}
|
|
413
406
|
/>
|
|
414
407
|
)}
|
|
415
|
-
{/* {currentStatus === 'pending' && (
|
|
416
|
-
<ActionButton
|
|
417
|
-
title={isCheckingStatus ? COMMON_STRINGS.CHECKING : BANK_STRINGS.REFRESH_STATUS_BUTTON}
|
|
418
|
-
onPress={handlePaymentReverseFeed}
|
|
419
|
-
disabled={isCheckingStatus}
|
|
420
|
-
/>
|
|
421
|
-
)} */}
|
|
422
408
|
</View>
|
|
423
409
|
</View>
|
|
424
410
|
</SafeAreaWrapper>
|
|
@@ -545,4 +531,3 @@ const createStyles = (colors: any, typography: any, status: 'success' | 'failed'
|
|
|
545
531
|
};
|
|
546
532
|
|
|
547
533
|
export default PaymentStatus;
|
|
548
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef } from 'react';
|
|
2
2
|
import { useRoute } from '@react-navigation/native';
|
|
3
|
-
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Alert, Image, TouchableWithoutFeedback, Keyboard, TextInput
|
|
3
|
+
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Alert, Image, TouchableWithoutFeedback, Keyboard, TextInput } from 'react-native';
|
|
4
4
|
import Icon from 'react-native-vector-icons/Ionicons';
|
|
5
5
|
import SafeAreaWrapper from '../components/SafeAreaWrapper';
|
|
6
6
|
import { Header, DropdownSelector } from '../components';
|
|
@@ -209,7 +209,6 @@ const ReviewKYC: React.FC<ReviewKYCProps> = ({
|
|
|
209
209
|
|
|
210
210
|
// State to track marital status dropdown visibility
|
|
211
211
|
const [showMaritalStatusMenu, setShowMaritalStatusMenu] = useState(false);
|
|
212
|
-
const [isGoingBack, setIsGoingBack] = useState(false);
|
|
213
212
|
|
|
214
213
|
// Ref to track currently focused text input
|
|
215
214
|
const focusedTextInputRef = useRef<TextInput | null>(null);
|
|
@@ -287,10 +286,6 @@ const ReviewKYC: React.FC<ReviewKYCProps> = ({
|
|
|
287
286
|
// Validate individual field and set error
|
|
288
287
|
const validateField = (field: keyof KYCData, value: string): string => {
|
|
289
288
|
if (!value || value.trim().length === 0) {
|
|
290
|
-
// Use "District" for area field
|
|
291
|
-
if (field === 'area') {
|
|
292
|
-
return 'District is required';
|
|
293
|
-
}
|
|
294
289
|
return `${field.charAt(0).toUpperCase() + field.slice(1)} is required`;
|
|
295
290
|
}
|
|
296
291
|
|
|
@@ -298,12 +293,6 @@ const ReviewKYC: React.FC<ReviewKYCProps> = ({
|
|
|
298
293
|
const textFields = ['area', 'city', 'addressLine1', 'addressLine2', 'state', 'country'];
|
|
299
294
|
if (textFields.includes(field)) {
|
|
300
295
|
if (value.trim().length < 2) {
|
|
301
|
-
// Use "Address" for addressLine1 and addressLine2
|
|
302
|
-
if (field === 'addressLine1' || field === 'addressLine2') {
|
|
303
|
-
return 'Address must be at least 2 characters';
|
|
304
|
-
} else if (field === 'area') {
|
|
305
|
-
return 'District must be at least 2 characters';
|
|
306
|
-
}
|
|
307
296
|
return `${field.charAt(0).toUpperCase() + field.slice(1)} must be at least 2 characters`;
|
|
308
297
|
}
|
|
309
298
|
}
|
|
@@ -334,9 +323,7 @@ const ReviewKYC: React.FC<ReviewKYCProps> = ({
|
|
|
334
323
|
|
|
335
324
|
return (
|
|
336
325
|
<View style={styles.errorContainer}>
|
|
337
|
-
{
|
|
338
|
-
<Icon name="warning" size={16} color={colors.error || '#FF0000'} style={styles.errorIcon} />
|
|
339
|
-
)}
|
|
326
|
+
<Icon name="warning" size={16} color={colors.error || '#FF0000'} style={styles.errorIcon} />
|
|
340
327
|
<Text style={styles.errorText}>{error}</Text>
|
|
341
328
|
</View>
|
|
342
329
|
);
|
|
@@ -550,6 +537,8 @@ const ReviewKYC: React.FC<ReviewKYCProps> = ({
|
|
|
550
537
|
return;
|
|
551
538
|
}
|
|
552
539
|
const data = getGlobalData();
|
|
540
|
+
|
|
541
|
+
console.log('panRapidNumber global data check', data, panRapidNumber);
|
|
553
542
|
// Decide next screen based on panrapidnumber existence
|
|
554
543
|
if (panRapidNumber && data.completeFDData) {
|
|
555
544
|
navigate('PayNow', { fdData: fdDataFromRoute });
|
|
@@ -597,13 +586,6 @@ const ReviewKYC: React.FC<ReviewKYCProps> = ({
|
|
|
597
586
|
autoCapitalize={variant === 'email' ? 'none' : 'words'}
|
|
598
587
|
onFocus={() => textInputRef && handleFieldFocus(textInputRef)}
|
|
599
588
|
textInputRef={textInputRef}
|
|
600
|
-
returnKeyType="done"
|
|
601
|
-
onSubmitEditing={() => {
|
|
602
|
-
if (textInputRef?.current) {
|
|
603
|
-
textInputRef.current.blur();
|
|
604
|
-
}
|
|
605
|
-
Keyboard.dismiss();
|
|
606
|
-
}}
|
|
607
589
|
/>
|
|
608
590
|
{renderFieldError(field)}
|
|
609
591
|
</View>
|
|
@@ -674,163 +656,119 @@ const ReviewKYC: React.FC<ReviewKYCProps> = ({
|
|
|
674
656
|
onDatePress={() => {
|
|
675
657
|
// TODO: Implement date picker if needed
|
|
676
658
|
}}
|
|
677
|
-
returnKeyType="done"
|
|
678
|
-
onSubmitEditing={() => {
|
|
679
|
-
if (textInputRef?.current) {
|
|
680
|
-
textInputRef.current.blur();
|
|
681
|
-
}
|
|
682
|
-
Keyboard.dismiss();
|
|
683
|
-
}}
|
|
684
659
|
/>
|
|
685
660
|
{renderFieldError(field)}
|
|
686
661
|
</View>
|
|
687
662
|
);
|
|
688
663
|
|
|
689
|
-
// Handler for back button (used by both header and hardware back button)
|
|
690
|
-
const handleBackPress = async () => {
|
|
691
|
-
setIsGoingBack(true);
|
|
692
|
-
try {
|
|
693
|
-
const userInfo = getUserInfoForAPI();
|
|
694
|
-
await previousState({
|
|
695
|
-
providerId: defaultProviderId,
|
|
696
|
-
workflowInstanceId,
|
|
697
|
-
userreferenceid: userInfo.userReferenceId,
|
|
698
|
-
applicationid: applicationId,
|
|
699
|
-
entityid: entityId,
|
|
700
|
-
});
|
|
701
|
-
} catch (e) {
|
|
702
|
-
// Handle error silently
|
|
703
|
-
} finally {
|
|
704
|
-
setIsGoingBack(false);
|
|
705
|
-
//onGoBack?.();
|
|
706
|
-
navigate('FDCalculator');
|
|
707
|
-
}
|
|
708
|
-
};
|
|
709
|
-
|
|
710
|
-
// Handle Android hardware back button
|
|
711
|
-
useEffect(() => {
|
|
712
|
-
if (Platform.OS !== 'android') return;
|
|
713
|
-
|
|
714
|
-
const onHardwareBackPress = () => {
|
|
715
|
-
handleBackPress();
|
|
716
|
-
return true; // Prevent default behavior
|
|
717
|
-
};
|
|
718
|
-
|
|
719
|
-
const backHandler = BackHandler.addEventListener(
|
|
720
|
-
'hardwareBackPress',
|
|
721
|
-
onHardwareBackPress
|
|
722
|
-
);
|
|
723
|
-
|
|
724
|
-
return () => backHandler.remove();
|
|
725
|
-
}, [defaultProviderId, workflowInstanceId, applicationId, entityId]);
|
|
726
|
-
|
|
727
664
|
return (
|
|
728
665
|
<SafeAreaWrapper
|
|
729
666
|
includeTop={false}
|
|
730
667
|
bottomPadding={25}
|
|
731
|
-
statusBarColor="#
|
|
732
|
-
statusBarStyle="
|
|
668
|
+
statusBarColor="#f8f9fa"
|
|
669
|
+
statusBarStyle="dark-content"
|
|
733
670
|
>
|
|
734
671
|
<Header
|
|
735
672
|
title="Review KYC"
|
|
736
|
-
onBackPress={
|
|
673
|
+
onBackPress={async () => {
|
|
674
|
+
try {
|
|
675
|
+
const userInfo = getUserInfoForAPI();
|
|
676
|
+
await previousState({
|
|
677
|
+
providerId: defaultProviderId,
|
|
678
|
+
workflowInstanceId,
|
|
679
|
+
userreferenceid: userInfo.userReferenceId,
|
|
680
|
+
applicationid: applicationId,
|
|
681
|
+
entityid: entityId,
|
|
682
|
+
});
|
|
683
|
+
} catch (e) {
|
|
684
|
+
// Handle error silently
|
|
685
|
+
} finally {
|
|
686
|
+
//onGoBack?.();
|
|
687
|
+
navigate('FDCalculator');
|
|
688
|
+
}
|
|
689
|
+
}}
|
|
737
690
|
backgroundColor={colors.primary}
|
|
738
691
|
/>
|
|
739
692
|
|
|
740
|
-
<
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
693
|
+
<ScrollView
|
|
694
|
+
style={styles.container}
|
|
695
|
+
showsVerticalScrollIndicator={false}
|
|
696
|
+
scrollEnabled={!isLoadingPanRapid}
|
|
744
697
|
>
|
|
745
|
-
<
|
|
746
|
-
|
|
747
|
-
showsVerticalScrollIndicator={false}
|
|
748
|
-
scrollEnabled={!isLoadingPanRapid}
|
|
749
|
-
keyboardShouldPersistTaps="handled"
|
|
750
|
-
contentContainerStyle={styles.scrollContent}
|
|
751
|
-
>
|
|
752
|
-
<TouchableWithoutFeedback onPress={isLoadingPanRapid ? undefined : closeDropdown}>
|
|
698
|
+
<TouchableWithoutFeedback onPress={isLoadingPanRapid ? undefined : closeDropdown}>
|
|
699
|
+
<View>
|
|
753
700
|
<View>
|
|
754
|
-
<
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
701
|
+
<TextFieldWithLabel
|
|
702
|
+
label="Pan Card"
|
|
703
|
+
value={kycData.panCard}
|
|
704
|
+
onChangeText={(text) => updateField('panCard', text)}
|
|
705
|
+
placeholder="Enter PAN Card"
|
|
706
|
+
editable={false}
|
|
707
|
+
variant="text"
|
|
708
|
+
maxLength={10}
|
|
709
|
+
keyboardType="default"
|
|
710
|
+
autoCapitalize="characters"
|
|
711
|
+
onFocus={() => handleFieldFocus(panCardRef)}
|
|
712
|
+
textInputRef={panCardRef}
|
|
713
|
+
/>
|
|
714
|
+
{renderFieldError('panCard')}
|
|
715
|
+
</View>
|
|
716
|
+
|
|
717
|
+
{renderDateField('Date of Birth', kycData.dateOfBirth, 'dateOfBirth', false, dateOfBirthRef)}
|
|
718
|
+
|
|
719
|
+
{renderMaritalStatusDropdown()}
|
|
720
|
+
|
|
721
|
+
{renderInputField('Area', kycData.area, 'area', 'Enter Area', true, 'text', 50, areaRef)}
|
|
722
|
+
|
|
723
|
+
{renderInputField('City', kycData.city, 'city', 'Enter City', true, 'text', 30, cityRef)}
|
|
724
|
+
|
|
725
|
+
{renderInputField('Address line 1', kycData.addressLine1, 'addressLine1', 'Enter Address Line 1', true, 'text', 100, addressLine1Ref)}
|
|
726
|
+
|
|
727
|
+
{renderInputField('Address line 2', kycData.addressLine2, 'addressLine2', 'Enter Address Line 2', true, 'text', 100, addressLine2Ref)}
|
|
728
|
+
|
|
729
|
+
{renderInputField('Pincode', kycData.pincode, 'pincode', 'Enter Pincode', true, 'numeric', 6, pincodeRef)}
|
|
730
|
+
|
|
731
|
+
{renderInputField('State', kycData.state, 'state', 'Enter State', true, 'text', undefined, stateRef)}
|
|
732
|
+
|
|
733
|
+
{renderInputField('Country', kycData.country, 'country', 'Enter Country', true, 'text', undefined, countryRef)}
|
|
734
|
+
|
|
735
|
+
<View style={styles.checkboxContainer}>
|
|
736
|
+
<TouchableOpacity
|
|
737
|
+
style={styles.checkbox}
|
|
738
|
+
onPress={() => updateField('useExistingAddress', !kycData.useExistingAddress)}
|
|
739
|
+
>
|
|
740
|
+
<View style={[
|
|
741
|
+
styles.checkboxBox,
|
|
742
|
+
kycData.useExistingAddress && styles.checkboxChecked
|
|
743
|
+
]}>
|
|
744
|
+
{kycData.useExistingAddress ? (
|
|
745
|
+
<Image
|
|
746
|
+
source={{ uri: (themeName === 'dark') ? base64Images.checkBoxDark : base64Images.filledCheckBox }}
|
|
747
|
+
resizeMode="cover"
|
|
748
|
+
width={20}
|
|
749
|
+
height={20}
|
|
750
|
+
/>
|
|
751
|
+
) : (
|
|
752
|
+
(themeName === 'dark') ? (
|
|
806
753
|
<Image
|
|
807
|
-
source={{ uri:
|
|
754
|
+
source={{ uri: base64Images.unCheckBoxDark }}
|
|
808
755
|
resizeMode="cover"
|
|
809
756
|
width={20}
|
|
810
757
|
height={20}
|
|
811
758
|
/>
|
|
812
|
-
) :
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
) : null
|
|
821
|
-
)}
|
|
822
|
-
</View>
|
|
823
|
-
</TouchableOpacity>
|
|
824
|
-
<Text style={styles.checkboxText}>
|
|
825
|
-
For existing customers, we'll use the address from our records. For new customers, the address from your Aadhar card will be used. To update, please raise a service request with valid address proof.
|
|
826
|
-
</Text>
|
|
827
|
-
</View>
|
|
759
|
+
) : null
|
|
760
|
+
)}
|
|
761
|
+
</View>
|
|
762
|
+
</TouchableOpacity>
|
|
763
|
+
<Text style={styles.checkboxText}>
|
|
764
|
+
For existing customers, we'll use the address from our records. For new customers, the address from your Aadhar card will be used. To update, please raise a service request with valid address proof.
|
|
765
|
+
</Text>
|
|
766
|
+
</View>
|
|
828
767
|
|
|
829
768
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
</KeyboardAvoidingView>
|
|
769
|
+
</View>
|
|
770
|
+
</TouchableWithoutFeedback>
|
|
771
|
+
</ScrollView>
|
|
834
772
|
<ActionButton
|
|
835
773
|
title="Continue"
|
|
836
774
|
onPress={handleContinue}
|
|
@@ -842,28 +780,16 @@ const ReviewKYC: React.FC<ReviewKYCProps> = ({
|
|
|
842
780
|
<View style={styles.loadingOverlay} pointerEvents="auto">
|
|
843
781
|
</View>
|
|
844
782
|
)}
|
|
845
|
-
{/* Loading overlay for back navigation */}
|
|
846
|
-
{isGoingBack && (
|
|
847
|
-
<View style={styles.loadingOverlay} pointerEvents="auto">
|
|
848
|
-
<ActivityIndicator size="large" color={colors.primary} />
|
|
849
|
-
</View>
|
|
850
|
-
)}
|
|
851
783
|
</SafeAreaWrapper>
|
|
852
784
|
);
|
|
853
785
|
};
|
|
854
786
|
|
|
855
787
|
const createStyles = (colors: any, typography: any, themeName?: string) => StyleSheet.create({
|
|
856
|
-
keyboardAvoidingView: {
|
|
857
|
-
flex: 1,
|
|
858
|
-
},
|
|
859
788
|
container: {
|
|
860
789
|
flex: 1,
|
|
861
790
|
paddingHorizontal: 16,
|
|
862
791
|
paddingTop: 20,
|
|
863
792
|
},
|
|
864
|
-
scrollContent: {
|
|
865
|
-
flexGrow: 1,
|
|
866
|
-
},
|
|
867
793
|
checkboxContainer: {
|
|
868
794
|
flexDirection: 'row',
|
|
869
795
|
alignItems: 'flex-start',
|
|
@@ -947,10 +873,8 @@ const createStyles = (colors: any, typography: any, themeName?: string) => Style
|
|
|
947
873
|
right: 0,
|
|
948
874
|
bottom: 0,
|
|
949
875
|
backgroundColor: 'rgba(0, 0, 0, 0.3)',
|
|
950
|
-
justifyContent: 'center',
|
|
951
|
-
alignItems: 'center',
|
|
952
876
|
zIndex: 1000,
|
|
953
877
|
},
|
|
954
878
|
});
|
|
955
879
|
|
|
956
|
-
export default ReviewKYC;
|
|
880
|
+
export default ReviewKYC;
|