react-native-timacare 3.3.56-alert → 3.3.57-cccd
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/icons/index.js +1 -1
- package/lib/commonjs/assets/icons/index.js.flow +2 -0
- package/lib/commonjs/assets/icons/index.js.map +1 -1
- package/lib/commonjs/assets/icons/modal_confirm.svg +5 -5
- package/lib/commonjs/assets/icons/modal_notice.svg +32 -32
- package/lib/commonjs/assets/icons/modal_success.svg +26 -26
- package/lib/commonjs/assets/icons/modal_warning.svg +21 -21
- package/lib/commonjs/assets/icons/user_security.svg +10 -0
- package/lib/commonjs/assets/tts/Frame1000011947.png +0 -0
- package/lib/commonjs/navigation/primary-navigator.js +1 -1
- package/lib/commonjs/navigation/primary-navigator.js.flow +7 -0
- package/lib/commonjs/navigation/primary-navigator.js.map +1 -1
- package/lib/commonjs/screens/NFC/OcrStart.js +2 -0
- package/lib/commonjs/screens/NFC/OcrStart.js.flow +171 -0
- package/lib/commonjs/screens/NFC/OcrStart.js.map +1 -0
- package/lib/commonjs/screens/NFC/ScanMRZ.js +2 -0
- package/lib/commonjs/screens/NFC/ScanMRZ.js.flow +563 -0
- package/lib/commonjs/screens/NFC/ScanMRZ.js.map +1 -0
- package/lib/commonjs/screens/camera/CCCDCameraScreen.js +1 -1
- package/lib/commonjs/screens/camera/CCCDCameraScreen.js.flow +203 -133
- package/lib/commonjs/screens/camera/CCCDCameraScreen.js.map +1 -1
- package/lib/commonjs/screens/home/index.js +1 -1
- package/lib/commonjs/screens/home/index.js.flow +7 -112
- package/lib/commonjs/screens/home/index.js.map +1 -1
- package/lib/commonjs/screens/nationalID/index.js +1 -1
- package/lib/commonjs/screens/nationalID/index.js.flow +123 -218
- package/lib/commonjs/screens/nationalID/index.js.map +1 -1
- package/lib/commonjs/screens/nationalIDBack/index.js +1 -1
- package/lib/commonjs/screens/nationalIDBack/index.js.flow +129 -209
- package/lib/commonjs/screens/nationalIDBack/index.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/OCR.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/OCR.js.flow +269 -555
- package/lib/commonjs/screens/toan-trinh-so/OCR.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js.flow +225 -287
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js.map +1 -1
- package/lib/commonjs/utils/cameraCrop.js +2 -0
- package/lib/commonjs/utils/cameraCrop.js.flow +96 -0
- package/lib/commonjs/utils/cameraCrop.js.map +1 -0
- package/lib/module/assets/icons/index.js +1 -1
- package/lib/module/assets/icons/index.js.map +1 -1
- package/lib/module/assets/icons/modal_confirm.svg +5 -5
- package/lib/module/assets/icons/modal_notice.svg +32 -32
- package/lib/module/assets/icons/modal_success.svg +26 -26
- package/lib/module/assets/icons/modal_warning.svg +21 -21
- package/lib/module/assets/icons/user_security.svg +10 -0
- package/lib/module/assets/tts/Frame1000011947.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/NFC/OcrStart.js +2 -0
- package/lib/module/screens/NFC/OcrStart.js.map +1 -0
- package/lib/module/screens/NFC/ScanMRZ.js +2 -0
- package/lib/module/screens/NFC/ScanMRZ.js.map +1 -0
- package/lib/module/screens/camera/CCCDCameraScreen.js +1 -1
- package/lib/module/screens/camera/CCCDCameraScreen.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/nationalID/index.js +1 -1
- package/lib/module/screens/nationalID/index.js.map +1 -1
- package/lib/module/screens/nationalIDBack/index.js +1 -1
- package/lib/module/screens/nationalIDBack/index.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/OCR.js +1 -1
- package/lib/module/screens/toan-trinh-so/OCR.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/VehicleCamera.js +1 -1
- package/lib/module/screens/toan-trinh-so/VehicleCamera.js.map +1 -1
- package/lib/module/utils/cameraCrop.js +2 -0
- package/lib/module/utils/cameraCrop.js.map +1 -0
- package/lib/typescript/assets/icons/index.d.ts +2 -1
- package/lib/typescript/assets/icons/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/NFC/OcrStart.d.ts +2 -0
- package/lib/typescript/screens/NFC/OcrStart.d.ts.map +1 -0
- package/lib/typescript/screens/NFC/ScanMRZ.d.ts +15 -0
- package/lib/typescript/screens/NFC/ScanMRZ.d.ts.map +1 -0
- package/lib/typescript/screens/camera/CCCDCameraScreen.d.ts.map +1 -1
- package/lib/typescript/screens/home/index.d.ts.map +1 -1
- package/lib/typescript/screens/nationalID/index.d.ts.map +1 -1
- package/lib/typescript/screens/nationalIDBack/index.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/OCR.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/VehicleCamera.d.ts.map +1 -1
- package/lib/typescript/utils/cameraCrop.d.ts +43 -0
- package/lib/typescript/utils/cameraCrop.d.ts.map +1 -0
- package/package.json +2 -1
- package/src/assets/icons/index.tsx +2 -0
- package/src/assets/icons/modal_confirm.svg +5 -5
- package/src/assets/icons/modal_notice.svg +32 -32
- package/src/assets/icons/modal_success.svg +26 -26
- package/src/assets/icons/modal_warning.svg +21 -21
- package/src/assets/icons/user_security.svg +10 -0
- package/src/assets/tts/Frame1000011947.png +0 -0
- package/src/navigation/primary-navigator.tsx +7 -0
- package/src/screens/NFC/OcrStart.tsx +171 -0
- package/src/screens/NFC/ScanMRZ.tsx +563 -0
- package/src/screens/camera/CCCDCameraScreen.tsx +203 -133
- package/src/screens/home/index.tsx +7 -112
- package/src/screens/nationalID/index.tsx +123 -218
- package/src/screens/nationalIDBack/index.tsx +129 -209
- package/src/screens/toan-trinh-so/OCR.tsx +269 -555
- package/src/screens/toan-trinh-so/VehicleCamera.tsx +225 -287
- package/src/utils/cameraCrop.ts +96 -0
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
-
import React, {
|
|
2
|
+
import React, {
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useMemo,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
3
9
|
import {
|
|
4
10
|
ActivityIndicator,
|
|
5
|
-
Dimensions,
|
|
6
11
|
Platform,
|
|
7
12
|
StyleSheet,
|
|
8
13
|
TouchableOpacity,
|
|
@@ -10,10 +15,9 @@ import {
|
|
|
10
15
|
} from 'react-native';
|
|
11
16
|
import {
|
|
12
17
|
Camera as VisionCamera,
|
|
13
|
-
|
|
14
|
-
useCameraFormat,
|
|
18
|
+
useCameraDevices,
|
|
15
19
|
} from 'react-native-vision-camera';
|
|
16
|
-
import {
|
|
20
|
+
import { IconBack, TakePhotoSvg } from '../../assets/icons';
|
|
17
21
|
import { MText } from '../../components/MText';
|
|
18
22
|
import { AlertGlobal } from '../../components/ModalNotification/AlertGlobal';
|
|
19
23
|
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
|
@@ -25,31 +29,77 @@ import {
|
|
|
25
29
|
RESULTS,
|
|
26
30
|
openSettings,
|
|
27
31
|
} from 'react-native-permissions';
|
|
32
|
+
import {
|
|
33
|
+
cropPhotoToAspect,
|
|
34
|
+
pickClosestFocusDevice,
|
|
35
|
+
} from '../../utils/cameraCrop';
|
|
36
|
+
|
|
37
|
+
const ORANGE = '#F05123';
|
|
38
|
+
// Thẻ CMND/CCCD theo chuẩn ID-1: 85.6mm x 54mm
|
|
39
|
+
const CARD_ASPECT_RATIO = 85.6 / 54;
|
|
40
|
+
// Cắt ảnh vừa đúng khung (khung dùng aspectRatio = CARD_ASPECT_RATIO)
|
|
41
|
+
const FRAME_ASPECT = CARD_ASPECT_RATIO;
|
|
28
42
|
|
|
29
43
|
export default function CCCDCameraScreen(props) {
|
|
30
44
|
const insets = useSafeAreaInsets();
|
|
31
45
|
const navigation = useNavigation();
|
|
32
46
|
const isFocused = useIsFocused();
|
|
33
47
|
const myCamera = useRef(null);
|
|
48
|
+
const frameSize = useRef({ width: 0, height: 0 });
|
|
49
|
+
const focusTimer = useRef(null);
|
|
50
|
+
const takingRef = useRef(false);
|
|
34
51
|
const [passPermission, setPassPermission] = useState(false);
|
|
35
52
|
const [shouldRenderCamera, setShouldRenderCamera] = useState(false);
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
53
|
+
const [focusPoint, setFocusPoint] = useState(null);
|
|
54
|
+
|
|
55
|
+
// Chọn ống kính sau lấy nét gần nhất (macro) để chụp cận thẻ mà không mờ
|
|
56
|
+
const devices = useCameraDevices();
|
|
57
|
+
const device = useMemo(() => pickClosestFocusDevice(devices, 'back'), [
|
|
58
|
+
devices,
|
|
39
59
|
]);
|
|
40
60
|
|
|
61
|
+
// Lấy nét vào một điểm (toạ độ theo hệ của khung preview = camera view).
|
|
62
|
+
// Dùng cho chạm-để-lấy-nét và lấy nét giữa khung trước khi chụp -> tránh mờ
|
|
63
|
+
// khi đưa giấy tờ lại gần (camera không tự bám nét kịp).
|
|
64
|
+
const focusAt = useCallback(
|
|
65
|
+
async (x, y) => {
|
|
66
|
+
const cam = myCamera.current;
|
|
67
|
+
if (cam == null || !device?.supportsFocus) return;
|
|
68
|
+
setFocusPoint({ x, y });
|
|
69
|
+
if (focusTimer.current) clearTimeout(focusTimer.current);
|
|
70
|
+
focusTimer.current = setTimeout(() => setFocusPoint(null), 800);
|
|
71
|
+
try {
|
|
72
|
+
await cam.focus({ x, y });
|
|
73
|
+
} catch (e) {
|
|
74
|
+
// focus có thể lỗi nếu đang lấy nét dở hoặc điểm ngoài vùng -> bỏ qua
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
[device]
|
|
78
|
+
);
|
|
79
|
+
|
|
41
80
|
const takePicture = async () => {
|
|
42
|
-
if (myCamera.current == null) return;
|
|
81
|
+
if (myCamera.current == null || takingRef.current) return;
|
|
82
|
+
takingRef.current = true;
|
|
43
83
|
try {
|
|
84
|
+
// Lấy nét giữa khung trước khi chụp để tài liệu ở gần vẫn nét
|
|
85
|
+
const { width: fw, height: fh } = frameSize.current;
|
|
86
|
+
if (device?.supportsFocus && fw && fh) {
|
|
87
|
+
try {
|
|
88
|
+
await myCamera.current.focus({ x: fw / 2, y: fh / 2 });
|
|
89
|
+
} catch (e) {}
|
|
90
|
+
}
|
|
44
91
|
const data = await myCamera.current.takePhoto({
|
|
45
92
|
qualityPrioritization: 'quality',
|
|
46
93
|
});
|
|
94
|
+
// Cắt ảnh vừa đúng khung preview (giữ nguyên logic điều hướng bên dưới)
|
|
95
|
+
const uri = await cropPhotoToAspect(data, FRAME_ASPECT);
|
|
47
96
|
navigation.goBack();
|
|
48
97
|
if (props.route?.params?.callback) {
|
|
49
|
-
props.route.params.callback(
|
|
98
|
+
props.route.params.callback(uri);
|
|
50
99
|
}
|
|
51
100
|
} catch (err) {
|
|
52
101
|
console.error(err);
|
|
102
|
+
takingRef.current = false;
|
|
53
103
|
}
|
|
54
104
|
};
|
|
55
105
|
|
|
@@ -135,6 +185,9 @@ export default function CCCDCameraScreen(props) {
|
|
|
135
185
|
|
|
136
186
|
useEffect(() => {
|
|
137
187
|
requestPermissions();
|
|
188
|
+
return () => {
|
|
189
|
+
if (focusTimer.current) clearTimeout(focusTimer.current);
|
|
190
|
+
};
|
|
138
191
|
}, []);
|
|
139
192
|
|
|
140
193
|
useEffect(() => {
|
|
@@ -160,138 +213,155 @@ export default function CCCDCameraScreen(props) {
|
|
|
160
213
|
}
|
|
161
214
|
|
|
162
215
|
return (
|
|
163
|
-
<View
|
|
164
|
-
style={{
|
|
165
|
-
pointerEvents={'box-none'}
|
|
166
|
-
>
|
|
167
|
-
<View
|
|
168
|
-
style={[
|
|
169
|
-
commonStyles.alignCenter,
|
|
170
|
-
commonStyles.fill,
|
|
171
|
-
commonStyles.justifyCenter,
|
|
172
|
-
{
|
|
173
|
-
position: 'absolute',
|
|
174
|
-
width: Dimensions.get('window').width,
|
|
175
|
-
height: Dimensions.get('window').height,
|
|
176
|
-
},
|
|
177
|
-
]}
|
|
178
|
-
>
|
|
179
|
-
{device ? (
|
|
180
|
-
<View style={$cameraFrame}>
|
|
181
|
-
<VisionCamera
|
|
182
|
-
ref={myCamera}
|
|
183
|
-
style={StyleSheet.absoluteFill}
|
|
184
|
-
device={device}
|
|
185
|
-
isActive={true}
|
|
186
|
-
photo={true}
|
|
187
|
-
format={format}
|
|
188
|
-
/>
|
|
189
|
-
</View>
|
|
190
|
-
) : (
|
|
191
|
-
<ActivityIndicator />
|
|
192
|
-
)}
|
|
193
|
-
</View>
|
|
194
|
-
|
|
195
|
-
<View style={[$back, { top: insets.top + 16 }]}>
|
|
216
|
+
<View style={styles.container}>
|
|
217
|
+
<View style={[styles.header, { paddingTop: insets.top + 16 }]}>
|
|
196
218
|
<TouchableOpacity
|
|
197
|
-
onPress={() =>
|
|
198
|
-
|
|
199
|
-
}}
|
|
200
|
-
style={{
|
|
201
|
-
position: 'absolute',
|
|
202
|
-
left: 0,
|
|
203
|
-
width: 48,
|
|
204
|
-
height: 48,
|
|
205
|
-
zIndex: 1000,
|
|
206
|
-
alignItems: 'center',
|
|
207
|
-
}}
|
|
219
|
+
onPress={() => navigation.goBack()}
|
|
220
|
+
hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}
|
|
208
221
|
>
|
|
209
|
-
<
|
|
222
|
+
<IconBack />
|
|
210
223
|
</TouchableOpacity>
|
|
211
|
-
<
|
|
212
|
-
style={
|
|
213
|
-
|
|
214
|
-
zIndex: 10,
|
|
215
|
-
color: '#FFFFFF',
|
|
216
|
-
fontSize: 16,
|
|
217
|
-
}}
|
|
218
|
-
>
|
|
219
|
-
{props?.route?.params?.front
|
|
220
|
-
? 'Chụp CMND/ CCCD mặt trước'
|
|
221
|
-
: 'Chụp CMND/ CCCD mặt sau'}
|
|
222
|
-
</MText>
|
|
224
|
+
<View style={styles.titleWrap}>
|
|
225
|
+
<MText style={styles.headerTitle}>CMND / CCCD</MText>
|
|
226
|
+
</View>
|
|
223
227
|
</View>
|
|
228
|
+
|
|
229
|
+
<MText style={styles.instruction}>
|
|
230
|
+
{props?.route?.params?.front
|
|
231
|
+
? 'Chụp CMND/ CCCD mặt trước'
|
|
232
|
+
: 'Chụp CMND/ CCCD mặt sau'}
|
|
233
|
+
</MText>
|
|
234
|
+
|
|
235
|
+
{/* Khung tỉ lệ thẻ: vùng nhìn thấy của preview = vùng sẽ crop.
|
|
236
|
+
Chạm vào khung để lấy nét thủ công. */}
|
|
224
237
|
<View
|
|
225
|
-
style={
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
alignSelf: 'center',
|
|
229
|
-
flexDirection: 'column',
|
|
230
|
-
alignItems: 'center',
|
|
238
|
+
style={styles.photoFrame}
|
|
239
|
+
onLayout={(e) => {
|
|
240
|
+
frameSize.current = e.nativeEvent.layout;
|
|
231
241
|
}}
|
|
242
|
+
onStartShouldSetResponder={() => true}
|
|
243
|
+
onResponderRelease={(e) =>
|
|
244
|
+
focusAt(e.nativeEvent.locationX, e.nativeEvent.locationY)
|
|
245
|
+
}
|
|
232
246
|
>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
<
|
|
245
|
-
|
|
246
|
-
|
|
247
|
+
{device ? (
|
|
248
|
+
<VisionCamera
|
|
249
|
+
ref={myCamera}
|
|
250
|
+
style={StyleSheet.absoluteFill}
|
|
251
|
+
device={device}
|
|
252
|
+
isActive={isFocused}
|
|
253
|
+
photo={true}
|
|
254
|
+
/>
|
|
255
|
+
) : null}
|
|
256
|
+
<View style={[styles.corner, styles.cornerTL]} />
|
|
257
|
+
<View style={[styles.corner, styles.cornerTR]} />
|
|
258
|
+
<View style={[styles.corner, styles.cornerBL]} />
|
|
259
|
+
<View style={[styles.corner, styles.cornerBR]} />
|
|
260
|
+
{focusPoint && (
|
|
261
|
+
<View
|
|
262
|
+
pointerEvents="none"
|
|
263
|
+
style={[
|
|
264
|
+
styles.focusRing,
|
|
265
|
+
{ left: focusPoint.x - 32, top: focusPoint.y - 32 },
|
|
266
|
+
]}
|
|
267
|
+
/>
|
|
268
|
+
)}
|
|
247
269
|
</View>
|
|
270
|
+
|
|
271
|
+
<View style={styles.spacer} />
|
|
272
|
+
<MText style={[styles.hint, { marginTop: 0, marginBottom: 20 }]}>
|
|
273
|
+
Đưa giấy tờ lại gần cho vừa khung, chạm vào màn hình{'\n'}để lấy nét nếu
|
|
274
|
+
ảnh bị mờ.
|
|
275
|
+
</MText>
|
|
276
|
+
<TouchableOpacity
|
|
277
|
+
style={[styles.captureButton, { marginBottom: insets.bottom + 24 }]}
|
|
278
|
+
onPress={takePicture}
|
|
279
|
+
>
|
|
280
|
+
<TakePhotoSvg />
|
|
281
|
+
</TouchableOpacity>
|
|
248
282
|
</View>
|
|
249
283
|
);
|
|
250
284
|
}
|
|
251
285
|
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
286
|
+
const styles = StyleSheet.create({
|
|
287
|
+
container: { flex: 1, backgroundColor: '#FFFFFF' },
|
|
288
|
+
header: {
|
|
289
|
+
flexDirection: 'row',
|
|
290
|
+
alignItems: 'center',
|
|
291
|
+
paddingHorizontal: 16,
|
|
292
|
+
paddingTop: 8,
|
|
293
|
+
},
|
|
294
|
+
titleWrap: {
|
|
295
|
+
flex: 1,
|
|
296
|
+
alignItems: 'center',
|
|
297
|
+
justifyContent: 'center',
|
|
298
|
+
marginRight: 24,
|
|
299
|
+
},
|
|
300
|
+
headerTitle: { color: '#333333', fontSize: 16, fontWeight: '600' },
|
|
301
|
+
instruction: {
|
|
302
|
+
textAlign: 'center',
|
|
303
|
+
color: '#333333',
|
|
304
|
+
fontSize: 14,
|
|
305
|
+
lineHeight: 20,
|
|
306
|
+
marginTop: 20,
|
|
307
|
+
marginBottom: 28,
|
|
308
|
+
},
|
|
309
|
+
photoFrame: {
|
|
310
|
+
marginHorizontal: 24,
|
|
311
|
+
aspectRatio: CARD_ASPECT_RATIO,
|
|
312
|
+
borderRadius: 8,
|
|
313
|
+
overflow: 'hidden',
|
|
314
|
+
backgroundColor: '#000000',
|
|
315
|
+
},
|
|
316
|
+
corner: {
|
|
317
|
+
position: 'absolute',
|
|
318
|
+
width: 26,
|
|
319
|
+
height: 26,
|
|
320
|
+
borderColor: ORANGE,
|
|
321
|
+
},
|
|
322
|
+
focusRing: {
|
|
323
|
+
position: 'absolute',
|
|
324
|
+
width: 64,
|
|
325
|
+
height: 64,
|
|
326
|
+
borderRadius: 8,
|
|
327
|
+
borderWidth: 1.5,
|
|
328
|
+
borderColor: '#FFD54A',
|
|
329
|
+
},
|
|
330
|
+
cornerTL: {
|
|
331
|
+
top: 0,
|
|
332
|
+
left: 0,
|
|
333
|
+
borderTopWidth: 4,
|
|
334
|
+
borderLeftWidth: 4,
|
|
335
|
+
borderTopLeftRadius: 8,
|
|
336
|
+
},
|
|
337
|
+
cornerTR: {
|
|
338
|
+
top: 0,
|
|
339
|
+
right: 0,
|
|
340
|
+
borderTopWidth: 4,
|
|
341
|
+
borderRightWidth: 4,
|
|
342
|
+
borderTopRightRadius: 8,
|
|
343
|
+
},
|
|
344
|
+
cornerBL: {
|
|
345
|
+
bottom: 0,
|
|
346
|
+
left: 0,
|
|
347
|
+
borderBottomWidth: 4,
|
|
348
|
+
borderLeftWidth: 4,
|
|
349
|
+
borderBottomLeftRadius: 8,
|
|
350
|
+
},
|
|
351
|
+
cornerBR: {
|
|
352
|
+
bottom: 0,
|
|
353
|
+
right: 0,
|
|
354
|
+
borderBottomWidth: 4,
|
|
355
|
+
borderRightWidth: 4,
|
|
356
|
+
borderBottomRightRadius: 8,
|
|
357
|
+
},
|
|
358
|
+
hint: {
|
|
359
|
+
textAlign: 'center',
|
|
360
|
+
color: '#555555',
|
|
361
|
+
fontSize: 13,
|
|
362
|
+
lineHeight: 19,
|
|
363
|
+
marginTop: 48,
|
|
364
|
+
},
|
|
365
|
+
spacer: { flex: 1 },
|
|
366
|
+
captureButton: { alignSelf: 'center' },
|
|
367
|
+
});
|
|
@@ -11,22 +11,16 @@ import {
|
|
|
11
11
|
RefreshControl,
|
|
12
12
|
SafeAreaView,
|
|
13
13
|
ScrollView,
|
|
14
|
-
StatusBar,
|
|
15
14
|
StyleSheet,
|
|
16
15
|
TouchableOpacity,
|
|
17
16
|
View,
|
|
18
|
-
ViewStyle,
|
|
19
17
|
} from 'react-native';
|
|
20
|
-
import {
|
|
21
|
-
useNavigation,
|
|
22
|
-
StackActions,
|
|
23
|
-
CommonActions,
|
|
24
|
-
} from '@react-navigation/native';
|
|
18
|
+
import { useNavigation, StackActions } from '@react-navigation/native';
|
|
25
19
|
import { observer, Observer } from 'mobx-react-lite';
|
|
26
20
|
import { commonStyles } from '../CommonStyles';
|
|
27
21
|
import { MText } from '../../components/MText';
|
|
28
22
|
import { color } from '../../theme';
|
|
29
|
-
import {
|
|
23
|
+
import { formatDDMMYYY, formatMoney } from '../../utils';
|
|
30
24
|
import homeStore from './Store';
|
|
31
25
|
import { ScreenNames } from '../../navigation';
|
|
32
26
|
import {
|
|
@@ -37,40 +31,25 @@ import {
|
|
|
37
31
|
CheckBoxActive,
|
|
38
32
|
CIMBSmall,
|
|
39
33
|
Close2Icon,
|
|
40
|
-
CloseIcon,
|
|
41
34
|
Contract,
|
|
42
35
|
ContractActive,
|
|
43
36
|
ContractTimeIcon,
|
|
44
|
-
IconBackWhite,
|
|
45
37
|
IconEviden,
|
|
46
|
-
IconNavClose,
|
|
47
|
-
IconNotify,
|
|
48
38
|
IconSchedule,
|
|
49
|
-
IconSign,
|
|
50
39
|
IconSign2,
|
|
51
40
|
IconVideo,
|
|
52
41
|
Info,
|
|
53
42
|
LogoSmall,
|
|
54
43
|
NotFoundSvg,
|
|
55
|
-
OcrSvg,
|
|
56
|
-
SignDisable,
|
|
57
|
-
TimaNormal,
|
|
58
|
-
TopupSuccessSvg,
|
|
59
44
|
TopupSvg,
|
|
60
45
|
UpdateIcon,
|
|
61
46
|
} from '../../assets/icons';
|
|
62
47
|
import Geolocation from 'react-native-geolocation-service';
|
|
63
|
-
|
|
64
|
-
import {
|
|
65
|
-
getUniqueId,
|
|
66
|
-
getManufacturer,
|
|
67
|
-
getDeviceId,
|
|
68
|
-
} from 'react-native-device-info';
|
|
48
|
+
|
|
69
49
|
import FullSubmitStore from '../full-submit/store';
|
|
70
50
|
import QuickSubmitStore from '../quick-submit/store';
|
|
71
51
|
import LinearGradient from 'react-native-linear-gradient';
|
|
72
|
-
|
|
73
|
-
import notificationStore from '../notification/store';
|
|
52
|
+
|
|
74
53
|
import {
|
|
75
54
|
openSettings,
|
|
76
55
|
PERMISSIONS,
|
|
@@ -87,24 +66,7 @@ import SkeletonLoanList, {
|
|
|
87
66
|
} from '../../components/SkeletonLoanCard';
|
|
88
67
|
import MButton from '../../components/MButton';
|
|
89
68
|
import ttsStore from '../toan-trinh-so/store';
|
|
90
|
-
import {
|
|
91
|
-
IconOCRSuccess,
|
|
92
|
-
IconEdit,
|
|
93
|
-
IconEditSuccess,
|
|
94
|
-
IconEkyc,
|
|
95
|
-
IconEkycSuccess,
|
|
96
|
-
IconEkycDisable,
|
|
97
|
-
IconSignDisable,
|
|
98
|
-
IconTima16,
|
|
99
|
-
IconExpand,
|
|
100
|
-
IconExpandUp,
|
|
101
|
-
IconSignSuccess,
|
|
102
|
-
IconMoney2,
|
|
103
|
-
IconEditDisable,
|
|
104
|
-
IconTick,
|
|
105
|
-
IconOcr,
|
|
106
|
-
} from '../../assets/svgs';
|
|
107
|
-
import { o } from 'ramda';
|
|
69
|
+
import { IconMoney2 } from '../../assets/svgs';
|
|
108
70
|
import ItemTimaOne from '../../components/ItemTimaOne';
|
|
109
71
|
import ModalOptionLoan from '../../components/ModalOptionLoan';
|
|
110
72
|
import AlertLoan from '../../components/AlertLoan';
|
|
@@ -114,21 +76,11 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
114
76
|
import ItemMotoBikeLoan from './ItemMotoBikeLoan';
|
|
115
77
|
import BoxGuidline from './BoxGuidline';
|
|
116
78
|
import { AlertGlobal } from '../../components/ModalNotification/AlertGlobal';
|
|
117
|
-
|
|
118
|
-
const listBanners = [
|
|
119
|
-
require('../../assets/img/banner1.png'),
|
|
120
|
-
require('../../assets/img/banner2.png'),
|
|
121
|
-
];
|
|
122
|
-
|
|
123
|
-
const $action: ViewStyle = {
|
|
124
|
-
flexDirection: 'column',
|
|
125
|
-
alignItems: 'center',
|
|
126
|
-
};
|
|
79
|
+
import MHeader from '../../components/MHeader';
|
|
127
80
|
|
|
128
81
|
// Gradient cam thương hiệu, dùng lặp lại ở nhiều nút trong màn hình
|
|
129
82
|
const GRADIENT_ORANGE = ['#FF8E4F', '#EF592E'];
|
|
130
83
|
|
|
131
|
-
let _unsubscribe;
|
|
132
84
|
// Dữ liệu tham chiếu tĩnh (ngân hàng, nghề nghiệp, tỉnh...) chỉ cần prefetch 1 lần/phiên
|
|
133
85
|
let _didPrefetchRefData = false;
|
|
134
86
|
|
|
@@ -161,7 +113,6 @@ export const Home = observer(function Home() {
|
|
|
161
113
|
// Hành động điều hướng chờ chạy SAU khi modal đóng hẳn (onModalHide)
|
|
162
114
|
const pendingNavRef = React.useRef<(() => void) | null>(null);
|
|
163
115
|
const [listLoan, setListLoan] = useState<any[]>([]);
|
|
164
|
-
const [checkEKYC, setCheckEKYC] = useState<any>({});
|
|
165
116
|
const [isLoading, setIsLoading] = useState(false);
|
|
166
117
|
const [loanCimb, setLoanCimb] = useState(null);
|
|
167
118
|
const [loan, setLoan] = useState(null);
|
|
@@ -594,63 +545,7 @@ export const Home = observer(function Home() {
|
|
|
594
545
|
<View
|
|
595
546
|
style={[commonStyles.fill, { zIndex: 1, backgroundColor: '#FFFFFF' }]}
|
|
596
547
|
>
|
|
597
|
-
<
|
|
598
|
-
<View style={{ marginTop: insets.top + 16 }}>
|
|
599
|
-
<View
|
|
600
|
-
style={{
|
|
601
|
-
flexDirection: 'row',
|
|
602
|
-
paddingHorizontal: 16,
|
|
603
|
-
alignItems: 'center',
|
|
604
|
-
justifyContent: 'space-between',
|
|
605
|
-
paddingBottom: 8,
|
|
606
|
-
}}
|
|
607
|
-
>
|
|
608
|
-
<MText
|
|
609
|
-
style={{
|
|
610
|
-
fontWeight: 'bold',
|
|
611
|
-
color: 'white',
|
|
612
|
-
fontSize: 14,
|
|
613
|
-
}}
|
|
614
|
-
>
|
|
615
|
-
Vay Online 24/7
|
|
616
|
-
</MText>
|
|
617
|
-
<View
|
|
618
|
-
style={{
|
|
619
|
-
borderWidth: 1,
|
|
620
|
-
borderColor: 'white',
|
|
621
|
-
flexDirection: 'row',
|
|
622
|
-
borderRadius: 16,
|
|
623
|
-
height: 30,
|
|
624
|
-
alignItems: 'center',
|
|
625
|
-
}}
|
|
626
|
-
>
|
|
627
|
-
<TouchableOpacity
|
|
628
|
-
style={{
|
|
629
|
-
paddingHorizontal: 10,
|
|
630
|
-
}}
|
|
631
|
-
onPress={() => {
|
|
632
|
-
Linking.openURL(`tel:1900633688`);
|
|
633
|
-
}}
|
|
634
|
-
>
|
|
635
|
-
<Call />
|
|
636
|
-
</TouchableOpacity>
|
|
637
|
-
<View
|
|
638
|
-
style={{ width: 1, height: 30, backgroundColor: 'white' }}
|
|
639
|
-
/>
|
|
640
|
-
<TouchableOpacity
|
|
641
|
-
style={{
|
|
642
|
-
paddingHorizontal: 10,
|
|
643
|
-
}}
|
|
644
|
-
onPress={() => {
|
|
645
|
-
navigation.navigate('MyBank.Main');
|
|
646
|
-
}}
|
|
647
|
-
>
|
|
648
|
-
<CloseIcon />
|
|
649
|
-
</TouchableOpacity>
|
|
650
|
-
</View>
|
|
651
|
-
</View>
|
|
652
|
-
</View>
|
|
653
|
-
</LinearGradient>
|
|
548
|
+
<MHeader title="Vay Online 24/7" />
|
|
654
549
|
<ScrollView
|
|
655
550
|
refreshControl={
|
|
656
551
|
<RefreshControl
|