react-native-timacare 3.1.3-beta → 3.1.5-beta
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/commonjs/assets/svgs/index.js +1 -1
- package/lib/commonjs/assets/svgs/index.js.flow +2 -0
- package/lib/commonjs/assets/svgs/index.js.map +1 -1
- package/lib/commonjs/assets/svgs/notify.svg +18 -0
- package/lib/commonjs/assets/tts/Banner.png +0 -0
- package/lib/commonjs/assets/tts/otp.png +0 -0
- package/lib/commonjs/navigation/primary-navigator.js +1 -1
- package/lib/commonjs/navigation/primary-navigator.js.flow +13 -1
- package/lib/commonjs/navigation/primary-navigator.js.map +1 -1
- package/lib/commonjs/screens/home/index.js +1 -1
- package/lib/commonjs/screens/home/index.js.flow +146 -7
- package/lib/commonjs/screens/home/index.js.map +1 -1
- package/lib/commonjs/screens/liveness/LivenessStore.js +1 -1
- package/lib/commonjs/screens/liveness/LivenessStore.js.flow +87 -0
- package/lib/commonjs/screens/liveness/LivenessStore.js.map +1 -1
- package/lib/commonjs/screens/liveness-v2/index.js +1 -1
- package/lib/commonjs/screens/liveness-v2/index.js.flow +36 -16
- package/lib/commonjs/screens/liveness-v2/index.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/LoanInterestRate.js +2 -0
- package/lib/commonjs/screens/toan-trinh-so/LoanInterestRate.js.flow +373 -0
- package/lib/commonjs/screens/toan-trinh-so/LoanInterestRate.js.map +1 -0
- package/lib/commonjs/screens/toan-trinh-so/ReviewInformation.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/ReviewInformation.js.flow +1 -1
- package/lib/commonjs/screens/toan-trinh-so/ReviewInformation.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/ReviewInformationOther.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/ReviewInformationOther.js.flow +1 -0
- package/lib/commonjs/screens/toan-trinh-so/ReviewInformationOther.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/ReviewLoan.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/ReviewLoan.js.flow +100 -1
- package/lib/commonjs/screens/toan-trinh-so/ReviewLoan.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/TTSOTP.js +2 -0
- package/lib/commonjs/screens/toan-trinh-so/TTSOTP.js.flow +356 -0
- package/lib/commonjs/screens/toan-trinh-so/TTSOTP.js.map +1 -0
- package/lib/commonjs/screens/toan-trinh-so/TTSSignLoan.js +2 -0
- package/lib/commonjs/screens/toan-trinh-so/TTSSignLoan.js.flow +143 -0
- package/lib/commonjs/screens/toan-trinh-so/TTSSignLoan.js.map +1 -0
- package/lib/commonjs/services/api/api.js +1 -1
- package/lib/commonjs/services/api/api.js.flow +17 -0
- package/lib/commonjs/services/api/api.js.map +1 -1
- package/lib/commonjs/utils/index.js +1 -1
- package/lib/commonjs/utils/index.js.flow +67 -45
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/module/assets/svgs/index.js +1 -1
- package/lib/module/assets/svgs/index.js.map +1 -1
- package/lib/module/assets/svgs/notify.svg +18 -0
- package/lib/module/assets/tts/Banner.png +0 -0
- package/lib/module/assets/tts/otp.png +0 -0
- package/lib/module/navigation/primary-navigator.js +1 -1
- package/lib/module/navigation/primary-navigator.js.map +1 -1
- package/lib/module/screens/home/index.js +1 -1
- package/lib/module/screens/home/index.js.map +1 -1
- package/lib/module/screens/liveness/LivenessStore.js +1 -1
- package/lib/module/screens/liveness/LivenessStore.js.map +1 -1
- package/lib/module/screens/liveness-v2/index.js +1 -1
- package/lib/module/screens/liveness-v2/index.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/LoanInterestRate.js +2 -0
- package/lib/module/screens/toan-trinh-so/LoanInterestRate.js.map +1 -0
- package/lib/module/screens/toan-trinh-so/ReviewInformation.js +1 -1
- package/lib/module/screens/toan-trinh-so/ReviewInformation.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/ReviewInformationOther.js +1 -1
- package/lib/module/screens/toan-trinh-so/ReviewInformationOther.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/ReviewLoan.js +1 -1
- package/lib/module/screens/toan-trinh-so/ReviewLoan.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/TTSOTP.js +2 -0
- package/lib/module/screens/toan-trinh-so/TTSOTP.js.map +1 -0
- package/lib/module/screens/toan-trinh-so/TTSSignLoan.js +2 -0
- package/lib/module/screens/toan-trinh-so/TTSSignLoan.js.map +1 -0
- package/lib/module/services/api/api.js +1 -1
- package/lib/module/services/api/api.js.map +1 -1
- package/lib/module/utils/index.js +1 -1
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/assets/svgs/index.d.ts +2 -1
- package/lib/typescript/assets/svgs/index.d.ts.map +1 -1
- package/lib/typescript/navigation/primary-navigator.d.ts +3 -0
- package/lib/typescript/navigation/primary-navigator.d.ts.map +1 -1
- package/lib/typescript/screens/home/index.d.ts.map +1 -1
- package/lib/typescript/screens/liveness/LivenessStore.d.ts +1 -0
- package/lib/typescript/screens/liveness/LivenessStore.d.ts.map +1 -1
- package/lib/typescript/screens/liveness-v2/index.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/LoanInterestRate.d.ts +2 -0
- package/lib/typescript/screens/toan-trinh-so/LoanInterestRate.d.ts.map +1 -0
- package/lib/typescript/screens/toan-trinh-so/ReviewInformationOther.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/ReviewLoan.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/TTSOTP.d.ts +2 -0
- package/lib/typescript/screens/toan-trinh-so/TTSOTP.d.ts.map +1 -0
- package/lib/typescript/screens/toan-trinh-so/TTSSignLoan.d.ts +2 -0
- package/lib/typescript/screens/toan-trinh-so/TTSSignLoan.d.ts.map +1 -0
- package/lib/typescript/services/api/api.d.ts +16 -0
- package/lib/typescript/services/api/api.d.ts.map +1 -1
- package/lib/typescript/utils/index.d.ts +8 -0
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/assets/svgs/index.tsx +2 -0
- package/src/assets/svgs/notify.svg +18 -0
- package/src/assets/tts/Banner.png +0 -0
- package/src/assets/tts/otp.png +0 -0
- package/src/navigation/primary-navigator.tsx +13 -1
- package/src/screens/home/index.tsx +146 -7
- package/src/screens/liveness/LivenessStore.tsx +87 -0
- package/src/screens/liveness-v2/index.tsx +36 -16
- package/src/screens/toan-trinh-so/LoanInterestRate.tsx +373 -0
- package/src/screens/toan-trinh-so/ReviewInformation.tsx +1 -1
- package/src/screens/toan-trinh-so/ReviewInformationOther.tsx +1 -0
- package/src/screens/toan-trinh-so/ReviewLoan.tsx +100 -1
- package/src/screens/toan-trinh-so/TTSOTP.tsx +356 -0
- package/src/screens/toan-trinh-so/TTSSignLoan.tsx +143 -0
- package/src/services/api/api.ts +17 -0
- package/src/utils/index.tsx +67 -45
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
//@ts-nocheck
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
Alert,
|
|
5
|
+
Image,
|
|
6
|
+
ImageStyle,
|
|
7
|
+
SafeAreaView,
|
|
8
|
+
ScrollView,
|
|
9
|
+
StyleSheet,
|
|
10
|
+
TouchableOpacity,
|
|
11
|
+
View,
|
|
12
|
+
} from 'react-native';
|
|
13
|
+
import { commonStyles } from '../CommonStyles';
|
|
14
|
+
import { IconBackWhite } from '../../assets/icons';
|
|
15
|
+
import { MText } from '../../components/MText';
|
|
16
|
+
import {
|
|
17
|
+
CodeField,
|
|
18
|
+
Cursor,
|
|
19
|
+
useBlurOnFulfill,
|
|
20
|
+
useClearByFocusCell,
|
|
21
|
+
} from 'react-native-confirmation-code-field';
|
|
22
|
+
import { Api } from '../../services/api';
|
|
23
|
+
import Loading from '../../components/Loading';
|
|
24
|
+
import { ScreenNames } from '../../navigation';
|
|
25
|
+
|
|
26
|
+
const logoView: ImageStyle = {
|
|
27
|
+
position: 'absolute',
|
|
28
|
+
width: '100%',
|
|
29
|
+
height: '100%',
|
|
30
|
+
resizeMode: 'cover',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default function TTSOTP({ navigation, route }: any) {
|
|
34
|
+
const loan = route?.params?.loan;
|
|
35
|
+
const [description, setDescription] = useState(
|
|
36
|
+
'Vui lòng click “Gửi mã OTP” để nhận mã xác thực được gửi vào số điện thoại của bạn'
|
|
37
|
+
);
|
|
38
|
+
const [timeLeft, setTimeLeft] = useState(300);
|
|
39
|
+
const [isResendEnabled, setIsResendEnabled] = useState(false);
|
|
40
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
41
|
+
const [isCounting, setIsCounting] = useState(false);
|
|
42
|
+
const CELL_COUNT = 6;
|
|
43
|
+
const [value, setValue] = useState('');
|
|
44
|
+
const ref = useBlurOnFulfill({ value, cellCount: CELL_COUNT });
|
|
45
|
+
|
|
46
|
+
const [props, getCellOnLayoutHandler] = useClearByFocusCell({
|
|
47
|
+
value,
|
|
48
|
+
setValue,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
let interval: NodeJS.Timeout;
|
|
53
|
+
if (isCounting && timeLeft > 0) {
|
|
54
|
+
interval = setInterval(() => {
|
|
55
|
+
setTimeLeft((prev) => prev - 1);
|
|
56
|
+
}, 1000);
|
|
57
|
+
} else if (timeLeft === 0) {
|
|
58
|
+
setIsCounting(false);
|
|
59
|
+
setIsResendEnabled(true);
|
|
60
|
+
}
|
|
61
|
+
return () => clearInterval(interval);
|
|
62
|
+
}, [isCounting, timeLeft]);
|
|
63
|
+
|
|
64
|
+
const sendOtp = async () => {
|
|
65
|
+
setIsLoading(true);
|
|
66
|
+
const response = await Api.getInstance().signContractForBorrower({
|
|
67
|
+
loanBriefId: loan.id,
|
|
68
|
+
});
|
|
69
|
+
setIsLoading(false);
|
|
70
|
+
if (response.kind === 'ok' && response.data.meta.errorCode === 200) {
|
|
71
|
+
setTimeLeft(300);
|
|
72
|
+
setDescription(
|
|
73
|
+
'Mã xác thực OTP của bạn sẽ được gửi vào số điện thoại của bạn, vui lòng nhập mã để hoàn thành ký hợp đồng.'
|
|
74
|
+
);
|
|
75
|
+
setIsCounting(true);
|
|
76
|
+
} else {
|
|
77
|
+
Alert.alert('Thông báo', response.data.meta.errorMessage, [
|
|
78
|
+
{ text: 'Đồng ý' },
|
|
79
|
+
]);
|
|
80
|
+
setValue('');
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const resendOtp = async () => {
|
|
85
|
+
setIsLoading(true);
|
|
86
|
+
const response = await Api.getInstance().eSignSendOTP({
|
|
87
|
+
customerId: loan?.id,
|
|
88
|
+
});
|
|
89
|
+
setIsLoading(false);
|
|
90
|
+
if (response.kind === 'ok' && response.data.meta.errorCode === 200) {
|
|
91
|
+
setDescription(
|
|
92
|
+
'Mã xác thực OTP đã được gửi lại vào số điện thoại của bạn, vui lòng nhập mã để hoàn thành ký hợp đồng.'
|
|
93
|
+
);
|
|
94
|
+
setTimeLeft(300);
|
|
95
|
+
setIsCounting(true);
|
|
96
|
+
setIsResendEnabled(false);
|
|
97
|
+
setValue('');
|
|
98
|
+
} else {
|
|
99
|
+
Alert.alert('Thông báo', response.data.meta.errorMessage, [
|
|
100
|
+
{ text: 'Đồng ý' },
|
|
101
|
+
]);
|
|
102
|
+
setValue('');
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const onSubmit = async () => {
|
|
107
|
+
if (value.length === CELL_COUNT) {
|
|
108
|
+
setIsLoading(true);
|
|
109
|
+
const response = await Api.getInstance().confirmSignContractForBorrower({
|
|
110
|
+
loanBriefId: loan.id,
|
|
111
|
+
otp: value,
|
|
112
|
+
});
|
|
113
|
+
setIsLoading(false);
|
|
114
|
+
if (response.kind === 'ok' && response.data.meta.errorCode === 200) {
|
|
115
|
+
Alert.alert('Thông báo', 'Ký hợp đồng thành công', [
|
|
116
|
+
{
|
|
117
|
+
text: 'Đồng ý',
|
|
118
|
+
onPress: () => {
|
|
119
|
+
navigation.dispatch(
|
|
120
|
+
CommonActions.reset({
|
|
121
|
+
index: 1,
|
|
122
|
+
routes: [
|
|
123
|
+
{
|
|
124
|
+
name: ScreenNames.Main,
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
})
|
|
128
|
+
);
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
]);
|
|
132
|
+
} else {
|
|
133
|
+
Alert.alert('Thông báo', response.data.meta.errorMessage, [
|
|
134
|
+
{ text: 'Đồng ý' },
|
|
135
|
+
]);
|
|
136
|
+
setValue('');
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
Alert.alert('Thông báo', 'Vui lòng nhập đầy đủ mã OTP gồm 6 chữ số.', [
|
|
140
|
+
{ text: 'Đồng ý' },
|
|
141
|
+
]);
|
|
142
|
+
setValue('');
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const formatTime = (seconds: number) => {
|
|
147
|
+
const m = Math.floor(seconds / 60)
|
|
148
|
+
.toString()
|
|
149
|
+
.padStart(2, '0');
|
|
150
|
+
const s = (seconds % 60).toString().padStart(2, '0');
|
|
151
|
+
return `${m}:${s}`;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<View style={commonStyles.fill}>
|
|
156
|
+
<Image source={require('../../assets/tts/otp.png')} style={logoView} />
|
|
157
|
+
<SafeAreaView style={commonStyles.fill}>
|
|
158
|
+
<View
|
|
159
|
+
style={{
|
|
160
|
+
paddingVertical: 16,
|
|
161
|
+
}}
|
|
162
|
+
>
|
|
163
|
+
<TouchableOpacity
|
|
164
|
+
onPress={() => {
|
|
165
|
+
navigation.goBack();
|
|
166
|
+
}}
|
|
167
|
+
style={{
|
|
168
|
+
position: 'absolute',
|
|
169
|
+
left: 10,
|
|
170
|
+
top: 16,
|
|
171
|
+
width: 25,
|
|
172
|
+
height: 25,
|
|
173
|
+
zIndex: 1000,
|
|
174
|
+
alignItems: 'center',
|
|
175
|
+
}}
|
|
176
|
+
>
|
|
177
|
+
<IconBackWhite />
|
|
178
|
+
</TouchableOpacity>
|
|
179
|
+
<MText
|
|
180
|
+
style={{
|
|
181
|
+
fontSize: 16,
|
|
182
|
+
color: '#FDFDFD',
|
|
183
|
+
fontWeight: 'bold',
|
|
184
|
+
textAlign: 'center',
|
|
185
|
+
}}
|
|
186
|
+
>
|
|
187
|
+
Xác thực OTP
|
|
188
|
+
</MText>
|
|
189
|
+
</View>
|
|
190
|
+
<ScrollView>
|
|
191
|
+
<MText
|
|
192
|
+
style={{
|
|
193
|
+
color: '#FFFFFF',
|
|
194
|
+
textAlign: 'center',
|
|
195
|
+
marginTop: 16,
|
|
196
|
+
paddingHorizontal: 24,
|
|
197
|
+
}}
|
|
198
|
+
>
|
|
199
|
+
{description}
|
|
200
|
+
</MText>
|
|
201
|
+
<CodeField
|
|
202
|
+
ref={ref}
|
|
203
|
+
{...props}
|
|
204
|
+
value={value}
|
|
205
|
+
onChangeText={setValue}
|
|
206
|
+
cellCount={CELL_COUNT}
|
|
207
|
+
rootStyle={styles.codeFieldRoot}
|
|
208
|
+
keyboardType="number-pad"
|
|
209
|
+
textContentType="oneTimeCode"
|
|
210
|
+
renderCell={({ index, symbol, isFocused }) => (
|
|
211
|
+
<View
|
|
212
|
+
key={index}
|
|
213
|
+
style={[styles.cell, isFocused && styles.focusCell]}
|
|
214
|
+
onLayout={getCellOnLayoutHandler(index)}
|
|
215
|
+
>
|
|
216
|
+
<MText style={styles.cellText}>
|
|
217
|
+
{symbol || (isFocused ? <Cursor /> : null)}
|
|
218
|
+
</MText>
|
|
219
|
+
</View>
|
|
220
|
+
)}
|
|
221
|
+
/>
|
|
222
|
+
<View
|
|
223
|
+
style={{
|
|
224
|
+
flexDirection: 'row',
|
|
225
|
+
alignItems: 'center',
|
|
226
|
+
justifyContent: 'center',
|
|
227
|
+
marginTop: 40,
|
|
228
|
+
}}
|
|
229
|
+
>
|
|
230
|
+
{isCounting ? (
|
|
231
|
+
<TouchableOpacity
|
|
232
|
+
onPress={() => {
|
|
233
|
+
onSubmit();
|
|
234
|
+
}}
|
|
235
|
+
style={{
|
|
236
|
+
backgroundColor: 'white',
|
|
237
|
+
borderRadius: 4,
|
|
238
|
+
height: 40,
|
|
239
|
+
alignItems: 'center',
|
|
240
|
+
paddingHorizontal: 20,
|
|
241
|
+
justifyContent: 'center',
|
|
242
|
+
}}
|
|
243
|
+
>
|
|
244
|
+
<MText
|
|
245
|
+
style={{
|
|
246
|
+
color: 'rgba(239, 89, 46, 1)',
|
|
247
|
+
fontSize: 16,
|
|
248
|
+
}}
|
|
249
|
+
>
|
|
250
|
+
Xác nhận
|
|
251
|
+
</MText>
|
|
252
|
+
</TouchableOpacity>
|
|
253
|
+
) : isResendEnabled ? (
|
|
254
|
+
<TouchableOpacity
|
|
255
|
+
onPress={() => {
|
|
256
|
+
resendOtp();
|
|
257
|
+
}}
|
|
258
|
+
style={{
|
|
259
|
+
backgroundColor: 'white',
|
|
260
|
+
borderRadius: 4,
|
|
261
|
+
height: 40,
|
|
262
|
+
alignItems: 'center',
|
|
263
|
+
paddingHorizontal: 20,
|
|
264
|
+
justifyContent: 'center',
|
|
265
|
+
}}
|
|
266
|
+
>
|
|
267
|
+
<MText
|
|
268
|
+
style={{
|
|
269
|
+
color: 'rgba(239, 89, 46, 1)',
|
|
270
|
+
fontSize: 16,
|
|
271
|
+
}}
|
|
272
|
+
>
|
|
273
|
+
Gửi lại mã OTP
|
|
274
|
+
</MText>
|
|
275
|
+
</TouchableOpacity>
|
|
276
|
+
) : (
|
|
277
|
+
<TouchableOpacity
|
|
278
|
+
onPress={() => {
|
|
279
|
+
sendOtp();
|
|
280
|
+
}}
|
|
281
|
+
style={{
|
|
282
|
+
backgroundColor: 'white',
|
|
283
|
+
borderRadius: 4,
|
|
284
|
+
height: 40,
|
|
285
|
+
alignItems: 'center',
|
|
286
|
+
paddingHorizontal: 20,
|
|
287
|
+
justifyContent: 'center',
|
|
288
|
+
}}
|
|
289
|
+
>
|
|
290
|
+
<MText
|
|
291
|
+
style={{
|
|
292
|
+
color: 'rgba(239, 89, 46, 1)',
|
|
293
|
+
fontSize: 16,
|
|
294
|
+
}}
|
|
295
|
+
>
|
|
296
|
+
Gửi mã OTP
|
|
297
|
+
</MText>
|
|
298
|
+
</TouchableOpacity>
|
|
299
|
+
)}
|
|
300
|
+
</View>
|
|
301
|
+
{isCounting && (
|
|
302
|
+
<MText
|
|
303
|
+
style={{
|
|
304
|
+
textAlign: 'center',
|
|
305
|
+
marginTop: 16,
|
|
306
|
+
color: '#FFFFFF',
|
|
307
|
+
fontSize: 14,
|
|
308
|
+
}}
|
|
309
|
+
>
|
|
310
|
+
Gửi lại mã OTP sau{' '}
|
|
311
|
+
<MText
|
|
312
|
+
style={{
|
|
313
|
+
color: '#FFFFFF',
|
|
314
|
+
fontWeight: 'bold',
|
|
315
|
+
}}
|
|
316
|
+
>
|
|
317
|
+
({formatTime(timeLeft)})
|
|
318
|
+
</MText>
|
|
319
|
+
</MText>
|
|
320
|
+
)}
|
|
321
|
+
</ScrollView>
|
|
322
|
+
</SafeAreaView>
|
|
323
|
+
<Loading isLoading={isLoading} />
|
|
324
|
+
</View>
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const styles = StyleSheet.create({
|
|
329
|
+
codeFieldRoot: {
|
|
330
|
+
width: '85%',
|
|
331
|
+
alignSelf: 'center',
|
|
332
|
+
marginTop: 24,
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
cell: {
|
|
336
|
+
width: 50,
|
|
337
|
+
height: 50,
|
|
338
|
+
borderRadius: 8,
|
|
339
|
+
justifyContent: 'center',
|
|
340
|
+
alignItems: 'center',
|
|
341
|
+
backgroundColor: 'rgba(253, 253, 253, 0.3)',
|
|
342
|
+
},
|
|
343
|
+
focusCell: {
|
|
344
|
+
// backgroundColor: '#FFFFFF',
|
|
345
|
+
// borderRadius: 8,
|
|
346
|
+
// borderWidth: 1,
|
|
347
|
+
// borderColor: '#EF592E',
|
|
348
|
+
},
|
|
349
|
+
|
|
350
|
+
cellText: {
|
|
351
|
+
fontSize: 24,
|
|
352
|
+
textAlign: 'center',
|
|
353
|
+
color: '#FFFFFF',
|
|
354
|
+
fontWeight: 'bold',
|
|
355
|
+
},
|
|
356
|
+
});
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
//@ts-nocheck
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { SafeAreaView, ScrollView, TouchableOpacity, View } from 'react-native';
|
|
4
|
+
import { MText } from '../../components/MText';
|
|
5
|
+
import { CheckBoxActive, IconBack } from '../../assets/icons';
|
|
6
|
+
import LinearGradient from 'react-native-linear-gradient';
|
|
7
|
+
import { CommonActions, useNavigation } from '@react-navigation/native';
|
|
8
|
+
import { ScreenNames } from '../../navigation';
|
|
9
|
+
import Pdf from 'react-native-pdf';
|
|
10
|
+
|
|
11
|
+
export default function TTSSignLoan(props) {
|
|
12
|
+
const loan = props?.route?.params?.loan;
|
|
13
|
+
const navigation = useNavigation();
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<View
|
|
17
|
+
style={{
|
|
18
|
+
backgroundColor: '#ffffff',
|
|
19
|
+
flex: 1,
|
|
20
|
+
}}
|
|
21
|
+
>
|
|
22
|
+
<SafeAreaView
|
|
23
|
+
style={{
|
|
24
|
+
backgroundColor: '#ffffff',
|
|
25
|
+
flex: 1,
|
|
26
|
+
}}
|
|
27
|
+
>
|
|
28
|
+
<View
|
|
29
|
+
style={{
|
|
30
|
+
paddingVertical: 16,
|
|
31
|
+
borderBottomWidth: 1,
|
|
32
|
+
borderBottomColor: '#F2F2F2',
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
<TouchableOpacity
|
|
36
|
+
onPress={() => {
|
|
37
|
+
navigation.goBack();
|
|
38
|
+
}}
|
|
39
|
+
style={{
|
|
40
|
+
position: 'absolute',
|
|
41
|
+
left: 10,
|
|
42
|
+
top: 16,
|
|
43
|
+
width: 25,
|
|
44
|
+
height: 25,
|
|
45
|
+
zIndex: 1000,
|
|
46
|
+
alignItems: 'center',
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
<IconBack />
|
|
50
|
+
</TouchableOpacity>
|
|
51
|
+
<MText
|
|
52
|
+
style={{
|
|
53
|
+
fontSize: 16,
|
|
54
|
+
color: '#333333',
|
|
55
|
+
fontWeight: 'bold',
|
|
56
|
+
textAlign: 'center',
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
Đề nghị giao kết thoả thuận cho vay
|
|
60
|
+
</MText>
|
|
61
|
+
</View>
|
|
62
|
+
|
|
63
|
+
<View style={{ flex: 1 }}>
|
|
64
|
+
<Pdf
|
|
65
|
+
source={{
|
|
66
|
+
uri: 'https://file.tima.vn/uploads/ESignContract/9506778/HD-9506778_borrower_d0a70791-e213-4a83-b760-089df216afa4.pdf',
|
|
67
|
+
}}
|
|
68
|
+
onLoadComplete={(numberOfPages, filePath) => {
|
|
69
|
+
console.log(`Number of pages: ${numberOfPages}`);
|
|
70
|
+
}}
|
|
71
|
+
onPageChanged={(page, numberOfPages) => {
|
|
72
|
+
console.log(`Current page: ${page}`);
|
|
73
|
+
}}
|
|
74
|
+
onError={(error) => {
|
|
75
|
+
console.log(error);
|
|
76
|
+
}}
|
|
77
|
+
onPressLink={(uri) => {
|
|
78
|
+
console.log(`Link pressed: ${uri}`);
|
|
79
|
+
}}
|
|
80
|
+
style={{
|
|
81
|
+
flex: 1,
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
</View>
|
|
85
|
+
|
|
86
|
+
<View
|
|
87
|
+
style={{
|
|
88
|
+
borderTopWidth: 1,
|
|
89
|
+
borderTopColor: '#F2F2F2',
|
|
90
|
+
paddingVertical: 16,
|
|
91
|
+
}}
|
|
92
|
+
>
|
|
93
|
+
<View
|
|
94
|
+
style={{
|
|
95
|
+
flexDirection: 'row',
|
|
96
|
+
gap: 10,
|
|
97
|
+
paddingHorizontal: 16,
|
|
98
|
+
}}
|
|
99
|
+
>
|
|
100
|
+
<CheckBoxActive />
|
|
101
|
+
<MText
|
|
102
|
+
style={{
|
|
103
|
+
color: '#333333',
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
Tôi đồng ý với tất cả những điều kiện trong hợp đồng.
|
|
107
|
+
</MText>
|
|
108
|
+
</View>
|
|
109
|
+
<TouchableOpacity
|
|
110
|
+
onPress={() => {
|
|
111
|
+
navigation.push(ScreenNames.TTSOTP, { loan });
|
|
112
|
+
}}
|
|
113
|
+
style={{
|
|
114
|
+
marginTop: 24,
|
|
115
|
+
marginHorizontal: 16,
|
|
116
|
+
}}
|
|
117
|
+
>
|
|
118
|
+
<LinearGradient
|
|
119
|
+
start={{ x: 1, y: 0 }}
|
|
120
|
+
end={{ x: 0, y: 1 }}
|
|
121
|
+
style={{
|
|
122
|
+
height: 40,
|
|
123
|
+
borderRadius: 6,
|
|
124
|
+
alignItems: 'center',
|
|
125
|
+
justifyContent: 'center',
|
|
126
|
+
}}
|
|
127
|
+
colors={['#FF7A00', '#EF4123']}
|
|
128
|
+
>
|
|
129
|
+
<MText
|
|
130
|
+
style={{
|
|
131
|
+
color: 'white',
|
|
132
|
+
fontSize: 16,
|
|
133
|
+
}}
|
|
134
|
+
>
|
|
135
|
+
Xác nhận ký
|
|
136
|
+
</MText>
|
|
137
|
+
</LinearGradient>
|
|
138
|
+
</TouchableOpacity>
|
|
139
|
+
</View>
|
|
140
|
+
</SafeAreaView>
|
|
141
|
+
</View>
|
|
142
|
+
);
|
|
143
|
+
}
|
package/src/services/api/api.ts
CHANGED
|
@@ -2392,6 +2392,23 @@ export class Api {
|
|
|
2392
2392
|
}
|
|
2393
2393
|
}
|
|
2394
2394
|
|
|
2395
|
+
async verifyLiveness2(body: any) {
|
|
2396
|
+
// make the api call
|
|
2397
|
+
const response: ApiResponse<any> = await this.apisauce.post(`api/v2.0/autode/liveness`, body)
|
|
2398
|
+
myLog(response)
|
|
2399
|
+
// the typical ways to die when calling an api
|
|
2400
|
+
if (!response.ok) {
|
|
2401
|
+
const problem = getGeneralApiProblem(response)
|
|
2402
|
+
if (problem) return problem
|
|
2403
|
+
}
|
|
2404
|
+
// transform the data into the format we are expecting
|
|
2405
|
+
try {
|
|
2406
|
+
return { kind: "ok", data: response.data }
|
|
2407
|
+
} catch {
|
|
2408
|
+
return { kind: "bad-data" }
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2395
2412
|
async saveImages(body: any) {
|
|
2396
2413
|
// make the api call
|
|
2397
2414
|
const response: ApiResponse<any> = await this.apisauce.post(`api/v1.0/timacare/save_image_liveness`, body)
|
package/src/utils/index.tsx
CHANGED
|
@@ -1,97 +1,119 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
|
-
import moment from
|
|
2
|
+
import moment from 'moment';
|
|
3
3
|
|
|
4
4
|
export const formatMoney = (x) => {
|
|
5
5
|
try {
|
|
6
6
|
// if (x) {
|
|
7
7
|
x = x
|
|
8
8
|
.toString()
|
|
9
|
-
.replace(/,/g,
|
|
9
|
+
.replace(/,/g, '')
|
|
10
10
|
.match(/^[-+]?[0-9]*?[0-9]+$/g)
|
|
11
|
-
.join(
|
|
11
|
+
.join('');
|
|
12
12
|
// x = Number(x);
|
|
13
13
|
// x = Number.isNaN(x) ? 0 : x;
|
|
14
|
-
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g,
|
|
14
|
+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
15
15
|
// } else {
|
|
16
16
|
// return '0';
|
|
17
17
|
// }
|
|
18
18
|
} catch (e) {
|
|
19
|
-
return
|
|
19
|
+
return '';
|
|
20
20
|
}
|
|
21
|
-
}
|
|
21
|
+
};
|
|
22
22
|
|
|
23
23
|
export const getMoney = (x) => {
|
|
24
24
|
try {
|
|
25
|
-
x = x.toString().replace(/,|\./g,
|
|
26
|
-
return Number(x)
|
|
25
|
+
x = x.toString().replace(/,|\./g, '');
|
|
26
|
+
return Number(x);
|
|
27
27
|
} catch (e) {
|
|
28
|
-
return 0
|
|
28
|
+
return 0;
|
|
29
29
|
}
|
|
30
|
-
}
|
|
30
|
+
};
|
|
31
31
|
|
|
32
32
|
export const removeAccent = (str) => {
|
|
33
|
-
str = str?.toLowerCase()
|
|
34
|
-
str = str.replace(/A|Á|À|Ã|Ạ|Â|Ấ|Ầ|Ẫ|Ậ|Ă|Ắ|Ằ|Ẵ|Ặ/g,
|
|
35
|
-
str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g,
|
|
36
|
-
str = str.replace(/E|É|È|Ẽ|Ẹ|Ê|Ế|Ề|Ễ|Ệ/,
|
|
37
|
-
str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g,
|
|
38
|
-
str = str.replace(/I|Í|Ì|Ĩ|Ị/g,
|
|
39
|
-
str = str.replace(/ì|í|ị|ỉ|ĩ/g,
|
|
40
|
-
str = str.replace(/O|Ó|Ò|Õ|Ọ|Ô|Ố|Ồ|Ỗ|Ộ|Ơ|Ớ|Ờ|Ỡ|Ợ/g,
|
|
41
|
-
str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g,
|
|
42
|
-
str = str.replace(/U|Ú|Ù|Ũ|Ụ|Ư|Ứ|Ừ|Ữ|Ự/g,
|
|
43
|
-
str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g,
|
|
44
|
-
str = str.replace(/Y|Ý|Ỳ|Ỹ|Ỵ/g,
|
|
45
|
-
str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g,
|
|
46
|
-
str = str.replace(/Đ/g,
|
|
47
|
-
str = str.replace(/đ/g,
|
|
33
|
+
str = str?.toLowerCase();
|
|
34
|
+
str = str.replace(/A|Á|À|Ã|Ạ|Â|Ấ|Ầ|Ẫ|Ậ|Ă|Ắ|Ằ|Ẵ|Ặ/g, 'A');
|
|
35
|
+
str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a');
|
|
36
|
+
str = str.replace(/E|É|È|Ẽ|Ẹ|Ê|Ế|Ề|Ễ|Ệ/, 'E');
|
|
37
|
+
str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, 'e');
|
|
38
|
+
str = str.replace(/I|Í|Ì|Ĩ|Ị/g, 'I');
|
|
39
|
+
str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i');
|
|
40
|
+
str = str.replace(/O|Ó|Ò|Õ|Ọ|Ô|Ố|Ồ|Ỗ|Ộ|Ơ|Ớ|Ờ|Ỡ|Ợ/g, 'O');
|
|
41
|
+
str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o');
|
|
42
|
+
str = str.replace(/U|Ú|Ù|Ũ|Ụ|Ư|Ứ|Ừ|Ữ|Ự/g, 'U');
|
|
43
|
+
str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u');
|
|
44
|
+
str = str.replace(/Y|Ý|Ỳ|Ỹ|Ỵ/g, 'Y');
|
|
45
|
+
str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y');
|
|
46
|
+
str = str.replace(/Đ/g, 'D');
|
|
47
|
+
str = str.replace(/đ/g, 'd');
|
|
48
48
|
// Some system encode vietnamese combining accent as individual utf-8 characters
|
|
49
|
-
str = str.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g,
|
|
50
|
-
str = str.replace(/\u02C6|\u0306|\u031B/g,
|
|
51
|
-
return str
|
|
52
|
-
}
|
|
49
|
+
str = str.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, ''); // Huyền sắc hỏi ngã nặng
|
|
50
|
+
str = str.replace(/\u02C6|\u0306|\u031B/g, ''); // Â, Ê, Ă, Ơ, Ư
|
|
51
|
+
return str;
|
|
52
|
+
};
|
|
53
53
|
|
|
54
54
|
export const formatDDMMYYY = (date) => {
|
|
55
55
|
if (date) {
|
|
56
|
-
return moment(date).format(
|
|
56
|
+
return moment(date).format('DD/MM/YYYY');
|
|
57
57
|
}
|
|
58
|
-
return null
|
|
59
|
-
}
|
|
58
|
+
return null;
|
|
59
|
+
};
|
|
60
60
|
|
|
61
61
|
export const EnumGender = [
|
|
62
62
|
{
|
|
63
63
|
id: 0,
|
|
64
|
-
name:
|
|
64
|
+
name: 'Nam',
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
id: 1,
|
|
68
|
-
name:
|
|
68
|
+
name: 'Nữ',
|
|
69
69
|
},
|
|
70
|
-
]
|
|
70
|
+
];
|
|
71
71
|
|
|
72
72
|
export const EnumMaritalStatus = [
|
|
73
73
|
{
|
|
74
74
|
id: 0,
|
|
75
|
-
name:
|
|
75
|
+
name: 'Chưa kết hôn',
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
id: 1,
|
|
79
|
-
name:
|
|
79
|
+
name: 'Đã kết hôn',
|
|
80
80
|
},
|
|
81
|
-
]
|
|
81
|
+
];
|
|
82
82
|
|
|
83
83
|
export const EnumPurpose = [
|
|
84
84
|
{
|
|
85
85
|
id: 3008,
|
|
86
|
-
name:
|
|
86
|
+
name: 'Mua sắm trang thiết bị, vật dụng gia đình',
|
|
87
87
|
},
|
|
88
|
-
]
|
|
88
|
+
];
|
|
89
89
|
|
|
90
90
|
export const diffDays = (fromDate, toDate) => {
|
|
91
|
-
const oneDay = 24 * 60 * 60 * 1000 // hours*minutes*seconds*milliseconds
|
|
92
|
-
const firstDate = new Date(fromDate)
|
|
93
|
-
const secondDate = new Date(toDate)
|
|
91
|
+
const oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds
|
|
92
|
+
const firstDate = new Date(fromDate);
|
|
93
|
+
const secondDate = new Date(toDate);
|
|
94
94
|
|
|
95
95
|
//@ts-ignore
|
|
96
|
-
return Math.round(Math.abs((firstDate - secondDate) / oneDay))
|
|
97
|
-
}
|
|
96
|
+
return Math.round(Math.abs((firstDate - secondDate) / oneDay));
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const EnumTypeCar = [
|
|
100
|
+
{
|
|
101
|
+
id: 1,
|
|
102
|
+
name: 'Xe con/xe bán tải',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 2,
|
|
106
|
+
name: 'Xe tải/ xe khách',
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
export const EnumTypeAsset = [
|
|
111
|
+
{
|
|
112
|
+
id: 1,
|
|
113
|
+
name: 'Cá nhân',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: 2,
|
|
117
|
+
name: 'Doanh nghiệp',
|
|
118
|
+
},
|
|
119
|
+
];
|