react-native-timacare 3.3.51 → 3.3.53

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 (51) hide show
  1. package/README.md +166 -104
  2. package/lib/commonjs/assets/v3/13.svg +19 -0
  3. package/lib/commonjs/assets/v3/14.svg +24 -0
  4. package/lib/commonjs/assets/v3/index.js +1 -1
  5. package/lib/commonjs/assets/v3/index.js.flow +4 -0
  6. package/lib/commonjs/assets/v3/index.js.map +1 -1
  7. package/lib/commonjs/components/ItemTimaOneV3.js +1 -1
  8. package/lib/commonjs/components/ItemTimaOneV3.js.flow +574 -946
  9. package/lib/commonjs/components/ItemTimaOneV3.js.map +1 -1
  10. package/lib/commonjs/screens/detail-loan/Payment.js +1 -1
  11. package/lib/commonjs/screens/detail-loan/Payment.js.flow +211 -234
  12. package/lib/commonjs/screens/detail-loan/Payment.js.map +1 -1
  13. package/lib/commonjs/screens/home/DigitalTopupItem.js +1 -1
  14. package/lib/commonjs/screens/home/DigitalTopupItem.js.flow +565 -822
  15. package/lib/commonjs/screens/home/DigitalTopupItem.js.map +1 -1
  16. package/lib/commonjs/screens/home/ItemMotoBikeLoan.js +1 -1
  17. package/lib/commonjs/screens/home/ItemMotoBikeLoan.js.flow +499 -705
  18. package/lib/commonjs/screens/home/ItemMotoBikeLoan.js.map +1 -1
  19. package/lib/commonjs/screens/home/index.js +1 -1
  20. package/lib/commonjs/screens/home/index.js.flow +26 -16
  21. package/lib/commonjs/screens/home/index.js.map +1 -1
  22. package/lib/module/assets/v3/13.svg +19 -0
  23. package/lib/module/assets/v3/14.svg +24 -0
  24. package/lib/module/assets/v3/index.js +1 -1
  25. package/lib/module/assets/v3/index.js.map +1 -1
  26. package/lib/module/components/ItemTimaOneV3.js +1 -1
  27. package/lib/module/components/ItemTimaOneV3.js.map +1 -1
  28. package/lib/module/screens/detail-loan/Payment.js +1 -1
  29. package/lib/module/screens/detail-loan/Payment.js.map +1 -1
  30. package/lib/module/screens/home/DigitalTopupItem.js +1 -1
  31. package/lib/module/screens/home/DigitalTopupItem.js.map +1 -1
  32. package/lib/module/screens/home/ItemMotoBikeLoan.js +1 -1
  33. package/lib/module/screens/home/ItemMotoBikeLoan.js.map +1 -1
  34. package/lib/module/screens/home/index.js +1 -1
  35. package/lib/module/screens/home/index.js.map +1 -1
  36. package/lib/typescript/assets/v3/index.d.ts +3 -1
  37. package/lib/typescript/assets/v3/index.d.ts.map +1 -1
  38. package/lib/typescript/components/ItemTimaOneV3.d.ts.map +1 -1
  39. package/lib/typescript/screens/detail-loan/Payment.d.ts.map +1 -1
  40. package/lib/typescript/screens/home/DigitalTopupItem.d.ts.map +1 -1
  41. package/lib/typescript/screens/home/ItemMotoBikeLoan.d.ts.map +1 -1
  42. package/lib/typescript/screens/home/index.d.ts.map +1 -1
  43. package/package.json +1 -1
  44. package/src/assets/v3/13.svg +19 -0
  45. package/src/assets/v3/14.svg +24 -0
  46. package/src/assets/v3/index.tsx +4 -0
  47. package/src/components/ItemTimaOneV3.tsx +574 -946
  48. package/src/screens/detail-loan/Payment.tsx +211 -234
  49. package/src/screens/home/DigitalTopupItem.tsx +565 -822
  50. package/src/screens/home/ItemMotoBikeLoan.tsx +499 -705
  51. package/src/screens/home/index.tsx +26 -16
@@ -1,15 +1,16 @@
1
1
  //@ts-nocheck
2
2
  import React, { useEffect } from 'react';
3
- import { Alert, Image, TouchableOpacity, View } from 'react-native';
3
+ import { Alert, Image, StyleSheet, TouchableOpacity, View } from 'react-native';
4
4
  import LinearGradient from 'react-native-linear-gradient';
5
5
  import { IconMoney2, IconQuestion } from '../../assets/svgs';
6
6
  import { MText } from '../../components/MText';
7
7
  import { formatMoney } from '../../utils';
8
8
  import {
9
- Icon1,
10
9
  Icon10,
11
10
  Icon11,
12
11
  Icon12,
12
+ Icon13,
13
+ Icon14,
13
14
  Icon2,
14
15
  Icon3,
15
16
  Icon4,
@@ -20,13 +21,7 @@ import {
20
21
  IconSuccess,
21
22
  } from '../../assets/v3';
22
23
  import { ScreenNames } from '../../navigation';
23
- import {
24
- CheckBox,
25
- CheckBoxActive,
26
- Close2Icon,
27
- IconCheck,
28
- Info,
29
- } from '../../assets/icons';
24
+ import { CheckBox, CheckBoxActive, Close2Icon, Info } from '../../assets/icons';
30
25
  import Modal from 'react-native-modal';
31
26
  import { Api } from '../../services/api';
32
27
 
@@ -35,6 +30,59 @@ interface IProps {
35
30
  navigation?: any;
36
31
  callback: () => void;
37
32
  }
33
+
34
+ const GRADIENT_ORANGE = ['#FF8E4F', '#EF592E'];
35
+ const GRADIENT_GREEN = ['#28A745', '#28A745'];
36
+ const GRADIENT_GRAY = ['#C7C7CC', '#C7C7CC'];
37
+ const GRADIENT_DISABLED = ['#E0E0E0', '#E0E0E0'];
38
+
39
+ const GUIDE_STEPS = [
40
+ {
41
+ icon: Icon3,
42
+ title: 'CẬP NHẬT THÔNG TIN CÁ NHÂN',
43
+ description: 'Giấy tờ CCCD/CC, ảnh chân dung, thông tin cá nhân',
44
+ },
45
+ {
46
+ icon: Icon5,
47
+ title: 'CẬP NHẬT THÔNG TIN XE',
48
+ description: 'Giấy tờ Đăng ký xe, thông tin xe',
49
+ },
50
+ { icon: Icon13, title: 'XÁC NHẬN ĐỒNG Ý ĐIỀU KIỆN ĐIỀU KHOẢN' },
51
+ { icon: Icon14, title: 'CHỜ PHÊ DUYỆT' },
52
+ { icon: Icon2, title: 'NHẬN TIỀN GIẢI NGÂN' },
53
+ ];
54
+
55
+ const LEGEND_ROWS = [
56
+ { label: 'Đang cần thực hiện', icons: [Icon2, Icon3, Icon4, Icon5] },
57
+ { label: 'Chưa thể thực hiện', icons: [Icon7, Icon8, Icon9, Icon10] },
58
+ { label: 'Đã hoàn thành', icons: [IconSuccess] },
59
+ ];
60
+
61
+ const StepButton = ({
62
+ badge,
63
+ label,
64
+ icon,
65
+ colors,
66
+ backgroundColor,
67
+ borderColor,
68
+ disabled,
69
+ onPress,
70
+ }: any) => (
71
+ <TouchableOpacity
72
+ disabled={disabled}
73
+ onPress={onPress}
74
+ style={[styles.stepButton, { backgroundColor, borderColor }]}
75
+ >
76
+ <LinearGradient colors={colors} style={styles.stepBadge}>
77
+ <MText style={styles.stepBadgeText}>{badge}</MText>
78
+ </LinearGradient>
79
+ <View style={styles.stepLabelRow}>
80
+ {icon}
81
+ <MText style={styles.stepLabelText}>{label}</MText>
82
+ </View>
83
+ </TouchableOpacity>
84
+ );
85
+
38
86
  export default function ItemMotoBikeLoan({
39
87
  item,
40
88
  navigation,
@@ -46,6 +94,27 @@ export default function ItemMotoBikeLoan({
46
94
  const [showModal2, setShowModal2] = React.useState(false);
47
95
  const [isLoading, setIsLoading] = React.useState(false);
48
96
 
97
+ const step = item?.step;
98
+ const stepOneActive = step === 0 || step === 1;
99
+ const stepOnePending = step <= 1;
100
+ const stepTwoActive = step === 2 || step === 3;
101
+
102
+ const goToStep1 = () => {
103
+ if (step === 0) {
104
+ navigation.push(ScreenNames.OCR, { loan: item, front: true });
105
+ } else {
106
+ navigation.push(ScreenNames.InfoLoanMotobike, { loan: item });
107
+ }
108
+ };
109
+
110
+ const goToStep2 = () => {
111
+ if (step === 2) {
112
+ navigation.push(ScreenNames.VehicleCamera, { loan: item, front: true });
113
+ } else {
114
+ navigation.push(ScreenNames.ReviewLoanMotobike, { loan: item });
115
+ }
116
+ };
117
+
49
118
  const confirm = async () => {
50
119
  try {
51
120
  setIsLoading(true);
@@ -63,476 +132,154 @@ export default function ItemMotoBikeLoan({
63
132
  );
64
133
  }
65
134
  } catch (error) {
66
- Alert.alert('Thông báo', 'Có lỗi xảy ra, vui lòng thử lại sau');
135
+ Alert.alert('Thông báo', ' lỗi xảy ra, vui lòng thử lại sau');
67
136
  } finally {
68
137
  setIsLoading(false);
69
138
  }
70
139
  };
71
140
 
72
141
  useEffect(() => {
142
+ let timer;
73
143
  if (item?.step === 4) {
74
- setTimeout(() => {
75
- setShowPolicy(true);
76
- }, 300);
144
+ timer = setTimeout(() => setShowPolicy(true), 300);
77
145
  } else if (item?.step === 5) {
78
- setTimeout(() => {
79
- setShowModal2(true);
80
- }, 300);
146
+ timer = setTimeout(() => setShowModal2(true), 300);
81
147
  }
148
+ return () => clearTimeout(timer);
82
149
  }, [item]);
83
150
 
84
151
  return (
85
152
  <View>
86
- <View
87
- style={{
88
- backgroundColor: '#FFFFFF',
89
- paddingHorizontal: 16,
90
- marginBottom: 16,
91
- borderRadius: 8,
92
- borderWidth: 0.5,
93
- borderColor: '#E0E0E0',
94
- }}
95
- >
96
- <LinearGradient
97
- colors={['#FF8E4F', '#EF592E']}
98
- style={{
99
- borderTopLeftRadius: 8,
100
- borderTopRightRadius: 8,
101
- marginHorizontal: -16,
102
- }}
103
- >
104
- <View
105
- style={{
106
- flexDirection: 'row',
107
- justifyContent: 'space-between',
108
- alignItems: 'center',
109
- paddingHorizontal: 16,
110
- paddingVertical: 8,
111
- }}
112
- >
113
- <View
114
- style={{
115
- flexDirection: 'row',
116
- alignItems: 'center',
117
- gap: 8,
118
- }}
119
- >
153
+ <View style={styles.card}>
154
+ <LinearGradient colors={GRADIENT_ORANGE} style={styles.headerGradient}>
155
+ <View style={styles.headerRow}>
156
+ <View style={styles.headerLeft}>
120
157
  <IconMoney2 />
121
- <MText
122
- style={{
123
- fontSize: 12,
124
- color: 'white',
125
- }}
126
- >
127
- HD-{item?.id}
128
- </MText>
158
+ <MText style={styles.headerText}>HD-{item?.id}</MText>
129
159
  </View>
130
- <MText
131
- style={{
132
- fontSize: 12,
133
- color: 'white',
134
- fontWeight: 'bold',
135
- }}
136
- >
160
+ <MText style={styles.headerAmount}>
137
161
  {formatMoney(item?.loanAmount)}đ
138
162
  </MText>
139
163
  </View>
140
164
  </LinearGradient>
141
- <View
142
- style={{
143
- flexDirection: 'row',
144
- paddingVertical: 16,
145
- alignItems: 'center',
146
- gap: 16,
147
- }}
148
- >
149
- <TouchableOpacity
150
- disabled={item?.step > 1 ? true : false}
151
- onPress={() => {
152
- if (item?.step === 0) {
153
- navigation.push(ScreenNames.OCR, {
154
- loan: item,
155
- front: true,
156
- });
157
- } else {
158
- navigation.push(ScreenNames.InfoLoanMotobike, {
159
- loan: item,
160
- });
161
- }
162
- }}
163
- style={{
164
- backgroundColor:
165
- item?.step === 0 || item?.step === 1 ? '#FFF3E3' : '#ECFFE8',
166
- borderRadius: 8,
167
- paddingVertical: 8,
168
- paddingHorizontal: 12,
169
- flex: 1,
170
- borderWidth: 1,
171
- borderColor:
172
- item?.step === 0 || item?.step === 1 ? '#FFF3E3' : '#B1EB95',
173
- }}
174
- >
175
- <LinearGradient
176
- colors={
177
- item?.step === 0 || item?.step === 1
178
- ? ['#FF8E4F', '#EF592E']
179
- : ['#28A745', '#28A745']
180
- }
181
- style={{
182
- paddingVertical: 2,
183
- borderRadius: 40,
184
- flexDirection: 'row',
185
- alignItems: 'center',
186
- justifyContent: 'center',
187
- width: 50,
188
- }}
189
- >
190
- <MText style={{ fontSize: 8, color: 'white' }}>Bước 1</MText>
191
- </LinearGradient>
192
- <View
193
- style={{
194
- marginTop: 8,
195
- flexDirection: 'row',
196
- alignItems: 'center',
197
- gap: 4,
198
- }}
199
- >
200
- {item?.step === 0 || item?.step === 1 ? (
201
- <Icon3 />
202
- ) : (
203
- <IconSuccess />
204
- )}
205
- <MText
206
- style={{
207
- fontSize: 10,
208
- }}
209
- >
210
- Thông tin cá nhân
211
- </MText>
212
- </View>
213
- </TouchableOpacity>
214
- <TouchableOpacity
215
- onPress={() => {
216
- if (item?.step === 2) {
217
- navigation.push(ScreenNames.VehicleCamera, {
218
- loan: item,
219
- front: true,
220
- });
221
- } else {
222
- navigation.push(ScreenNames.ReviewLoanMotobike, {
223
- loan: item,
224
- });
225
- }
226
- }}
227
- disabled={item?.step === 2 || item?.step === 3 ? false : true}
228
- style={{
229
- backgroundColor:
230
- item?.step < 2
231
- ? '#FFFFFF'
232
- : item?.step === 2 || item?.step === 3
233
- ? '#FFF3E3'
234
- : '#ECFFE8',
235
- borderRadius: 8,
236
- paddingVertical: 8,
237
- paddingHorizontal: 12,
238
- flex: 1,
239
- borderWidth: 1,
240
- borderColor:
241
- item?.step < 2
242
- ? '#F2F2F7'
243
- : item?.step === 2 || item?.step === 3
244
- ? '#FFF3E3'
245
- : '#B1EB95',
246
- }}
247
- >
248
- <LinearGradient
249
- colors={
250
- item?.step < 2
251
- ? ['#C7C7CC', '#C7C7CC']
252
- : item?.step === 2 || item?.step === 3
253
- ? ['#FF8E4F', '#EF592E']
254
- : ['#28A745', '#28A745']
255
- }
256
- style={{
257
- paddingVertical: 2,
258
- borderRadius: 40,
259
- flexDirection: 'row',
260
- alignItems: 'center',
261
- justifyContent: 'center',
262
- width: 50,
263
- }}
264
- >
265
- <MText style={{ fontSize: 8, color: 'white' }}>Bước 2</MText>
266
- </LinearGradient>
267
- <View
268
- style={{
269
- marginTop: 8,
270
- flexDirection: 'row',
271
- alignItems: 'center',
272
- gap: 4,
273
- }}
274
- >
275
- {item?.step < 2 ? (
165
+ <View style={styles.stepsRow}>
166
+ <StepButton
167
+ badge="Bước 1"
168
+ label="Thông tin cá nhân"
169
+ icon={stepOneActive ? <Icon3 /> : <IconSuccess />}
170
+ colors={stepOneActive ? GRADIENT_ORANGE : GRADIENT_GREEN}
171
+ backgroundColor={stepOneActive ? '#FFF3E3' : '#ECFFE8'}
172
+ borderColor={stepOneActive ? '#FFF3E3' : '#B1EB95'}
173
+ disabled={step > 1}
174
+ onPress={goToStep1}
175
+ />
176
+ <StepButton
177
+ badge="Bước 2"
178
+ label="Thông tin xe máy"
179
+ icon={
180
+ step < 2 ? (
276
181
  <Icon11 />
277
- ) : item?.step === 2 || item?.step === 3 ? (
182
+ ) : stepTwoActive ? (
278
183
  <Icon12 />
279
184
  ) : (
280
185
  <IconSuccess />
281
- )}
282
- <MText
283
- style={{
284
- fontSize: 10,
285
- }}
286
- >
287
- Thông tin xe máy
288
- </MText>
289
- </View>
290
- </TouchableOpacity>
186
+ )
187
+ }
188
+ colors={
189
+ step < 2
190
+ ? GRADIENT_GRAY
191
+ : stepTwoActive
192
+ ? GRADIENT_ORANGE
193
+ : GRADIENT_GREEN
194
+ }
195
+ backgroundColor={
196
+ step < 2 ? '#FFFFFF' : stepTwoActive ? '#FFF3E3' : '#ECFFE8'
197
+ }
198
+ borderColor={
199
+ step < 2 ? '#F2F2F7' : stepTwoActive ? '#FFF3E3' : '#B1EB95'
200
+ }
201
+ disabled={!stepTwoActive}
202
+ onPress={goToStep2}
203
+ />
291
204
  </View>
292
205
 
293
- <View
294
- style={{
295
- backgroundColor: '#EEF7FF',
296
- flexDirection: 'row',
297
- alignItems: 'center',
298
- gap: 4,
299
- borderRadius: 4,
300
- paddingHorizontal: 8,
301
- paddingVertical: 10,
302
- }}
303
- >
206
+ <View style={styles.guideBanner}>
304
207
  <IconQuestion />
305
- <MText
306
- style={{
307
- fontSize: 10,
308
- flex: 1,
309
- }}
310
- >
208
+ <MText style={styles.guideBannerText}>
311
209
  Hướng dẫn các bước hoàn thiện đơn vay
312
210
  </MText>
313
211
  <TouchableOpacity onPress={() => setShowModal(true)}>
314
- <MText
315
- style={{
316
- fontSize: 10,
317
- color: '#2F80ED',
318
- textDecorationLine: 'underline',
319
- }}
320
- >
321
- Xem thêm
322
- </MText>
212
+ <MText style={styles.linkText}>Xem thêm</MText>
323
213
  </TouchableOpacity>
324
214
  </View>
325
- <View
326
- style={{
327
- flexDirection: 'row',
328
- paddingBottom: 16,
329
- marginTop: 16,
330
- }}
331
- >
332
- <View style={{ flex: 1, paddingRight: 24 }}>
333
- <MText
334
- style={{
335
- color: '#999999',
336
- fontSize: 12,
337
- }}
338
- >
339
- Trạng thái
340
- </MText>
341
- <MText
342
- style={{
343
- fontSize: 12,
344
- fontWeight: 'bold',
345
- }}
346
- >
347
- {item?.step <= 1
215
+ <View style={styles.statusSection}>
216
+ <View style={styles.statusLeft}>
217
+ <MText style={styles.statusLabel}>Trạng thái</MText>
218
+ <MText style={styles.statusValue}>
219
+ {stepOnePending
348
220
  ? 'Chờ cập nhật thông tin cá nhân'
349
- : item?.step === 2 || item?.step === 3
350
- ? `Chờ cập nhật thông tin xe máy`
221
+ : stepTwoActive
222
+ ? 'Chờ cập nhật thông tin xe máy'
351
223
  : 'Đơn vay đang chờ phê duyệt'}
352
224
  </MText>
353
225
  </View>
354
- {item?.step <= 1 ? (
355
- <TouchableOpacity
356
- onPress={() => {
357
- if (item?.step === 0) {
358
- navigation.push(ScreenNames.OCR, {
359
- loan: item,
360
- front: true,
361
- });
362
- } else {
363
- navigation.push(ScreenNames.InfoLoanMotobike, {
364
- loan: item,
365
- });
366
- }
367
- }}
368
- >
369
- <LinearGradient
370
- colors={['#FF8E4F', '#EF592E']}
371
- style={{
372
- height: 30,
373
- alignItems: 'center',
374
- justifyContent: 'center',
375
- borderRadius: 24,
376
- paddingHorizontal: 10,
377
- }}
378
- >
379
- <MText
380
- style={{
381
- color: 'white',
382
- fontSize: 12,
383
- }}
384
- >
385
- Cập nhật
386
- </MText>
387
- </LinearGradient>
388
- </TouchableOpacity>
389
- ) : item?.step === 2 || item?.step === 3 ? (
390
- <TouchableOpacity
391
- onPress={() => {
392
- if (item?.step === 2) {
393
- navigation.push(ScreenNames.VehicleCamera, {
394
- loan: item,
395
- front: true,
396
- });
397
- } else {
398
- navigation.push(ScreenNames.ReviewLoanMotobike, {
399
- loan: item,
400
- });
401
- }
402
- }}
403
- >
226
+ {(stepOnePending || stepTwoActive) && (
227
+ <TouchableOpacity onPress={stepOnePending ? goToStep1 : goToStep2}>
404
228
  <LinearGradient
405
- colors={['#FF8E4F', '#EF592E']}
406
- style={{
407
- height: 30,
408
- alignItems: 'center',
409
- justifyContent: 'center',
410
- borderRadius: 24,
411
- paddingHorizontal: 10,
412
- }}
229
+ colors={GRADIENT_ORANGE}
230
+ style={styles.updateButton}
413
231
  >
414
- <MText
415
- style={{
416
- color: 'white',
417
- fontSize: 12,
418
- }}
419
- >
420
- Cập nhật
421
- </MText>
232
+ <MText style={styles.updateButtonText}>Cập nhật</MText>
422
233
  </LinearGradient>
423
234
  </TouchableOpacity>
424
- ) : (
425
- <></>
426
235
  )}
427
236
  </View>
428
- {item?.step !== 5 ? (
429
- <View
430
- style={{
431
- flexDirection: 'row',
432
- alignItems: 'center',
433
- gap: 8,
434
- backgroundColor: '#FFF2F2',
435
- marginHorizontal: -16,
436
- paddingVertical: 10,
437
- borderBottomRightRadius: 8,
438
- borderBottomLeftRadius: 8,
439
- paddingHorizontal: 10,
440
- }}
441
- >
237
+ {step !== 5 && (
238
+ <View style={styles.warningBanner}>
442
239
  <Info />
443
- <MText
444
- style={[
445
- {
446
- fontSize: 10,
447
- color: '#E40010',
448
- flex: 1,
449
- },
450
- ]}
451
- >
452
- {item?.step <= 1
240
+ <MText style={styles.warningText}>
241
+ {stepOnePending
453
242
  ? 'Vui lòng cập nhật thông tin cá nhân để được giải ngân sớm nhất!'
454
- : item?.step === 2 || item?.step === 3
455
- ? `Vui lòng cập nhật thông tin xe để được giải ngân sớm nhất!`
243
+ : stepTwoActive
244
+ ? 'Vui lòng cập nhật thông tin xe để được giải ngân sớm nhất!'
456
245
  : 'Đơn vay đang chờ phê duyệt'}
457
246
  </MText>
458
247
  </View>
459
- ) : (
460
- <></>
461
248
  )}
462
249
  </View>
463
250
 
464
251
  <Modal isVisible={showPolicy} backdropColor="#000" backdropOpacity={0.5}>
465
- <View
466
- style={{
467
- borderRadius: 12,
468
- backgroundColor: 'white',
469
- padding: 16,
470
- }}
471
- >
472
- <View
473
- style={{
474
- flexDirection: 'row-reverse',
475
- }}
476
- >
252
+ <View style={styles.modalCard}>
253
+ <View style={styles.closeRow}>
477
254
  <TouchableOpacity
478
255
  onPress={() => setShowPolicy(false)}
479
- style={{
480
- width: 30,
481
- height: 30,
482
- alignItems: 'center',
483
- justifyContent: 'center',
484
- }}
256
+ style={styles.closeButton}
485
257
  >
486
258
  <Close2Icon />
487
259
  </TouchableOpacity>
488
260
  </View>
489
- <MText
490
- style={{ fontSize: 16, fontWeight: 'bold', textAlign: 'center' }}
491
- >
492
- Xác nhận chia sẻ dữ liệu
493
- </MText>
494
- <View
495
- style={{
496
- marginTop: 16,
497
- alignItems: 'center',
498
- }}
499
- >
261
+ <MText style={styles.modalTitle}>Xác nhận chia sẻ dữ liệu</MText>
262
+ <View style={styles.f88Wrap}>
500
263
  <Image
501
264
  source={require('../../assets/tts/f88.png')}
502
- style={{
503
- height: 60,
504
- resizeMode: 'contain',
505
- }}
265
+ style={styles.f88Image}
506
266
  />
507
267
  </View>
508
- <MText
509
- style={{ color: '#828282', textAlign: 'center', marginTop: 16 }}
510
- >
268
+ <MText style={styles.policyBody}>
511
269
  Tima sẽ chuyển thông tin của bạn đến Công ty Cổ phần Kinh doanh F88
512
270
  (F88) để xem xét phê duyệt khoản vay. Khi chọn "Đồng ý & Tiếp tục",
513
271
  bạn đồng ý cho các bên liên quan thu thập, sử dụng, xử lý và chia sẻ
514
272
  dữ liệu cá nhân theo quy định của pháp luật. Sau khi chuyển giao dữ
515
273
  liệu, Tima là bên kiểm soát và xử lý dữ liệu cá nhân.
516
274
  </MText>
517
- <View
518
- style={{
519
- flexDirection: 'row',
520
- alignItems: 'center',
521
- marginTop: 24,
522
- gap: 8,
523
- }}
524
- >
525
- <TouchableOpacity
526
- onPress={() => {
527
- setCheck(!check);
528
- }}
529
- >
275
+ <View style={styles.checkboxRow}>
276
+ <TouchableOpacity onPress={() => setCheck(!check)}>
530
277
  {check ? <CheckBoxActive /> : <CheckBox />}
531
278
  </TouchableOpacity>
532
279
  <MText>
533
280
  Tôi đồng ý với{' '}
534
281
  <MText
535
- style={{ color: '#2F80ED' }}
282
+ style={styles.termsLink}
536
283
  onPress={() => {
537
284
  setShowPolicy(false);
538
285
  navigation.navigate(ScreenNames.PolicyF88, { item });
@@ -542,119 +289,42 @@ export default function ItemMotoBikeLoan({
542
289
  </MText>
543
290
  </MText>
544
291
  </View>
545
- <View>
546
- <TouchableOpacity
547
- disabled={check || isLoading ? false : true}
548
- onPress={() => {
549
- confirm();
550
- }}
292
+ <TouchableOpacity disabled={!check || isLoading} onPress={confirm}>
293
+ <LinearGradient
294
+ colors={check ? GRADIENT_ORANGE : GRADIENT_DISABLED}
295
+ style={styles.confirmButton}
551
296
  >
552
- <LinearGradient
553
- colors={check ? ['#FF8E4F', '#EF592E'] : ['#E0E0E0', '#E0E0E0']}
554
- style={{
555
- height: 40,
556
- alignItems: 'center',
557
- justifyContent: 'center',
558
- borderRadius: 24,
559
- paddingHorizontal: 10,
560
- marginTop: 24,
561
- }}
562
- >
563
- <MText
564
- style={{
565
- color: 'white',
566
- fontWeight: 'bold',
567
- }}
568
- >
569
- Đồng ý & Tiếp tục
570
- </MText>
571
- </LinearGradient>
572
- </TouchableOpacity>
573
- </View>
297
+ <MText style={styles.confirmButtonText}>Đồng ý & Tiếp tục</MText>
298
+ </LinearGradient>
299
+ </TouchableOpacity>
574
300
  </View>
575
301
  </Modal>
576
302
 
577
303
  <Modal isVisible={showModal2} backdropColor="#000" backdropOpacity={0.5}>
578
- <View
579
- style={{
580
- borderRadius: 12,
581
- backgroundColor: 'white',
582
- }}
583
- >
584
- <View
585
- style={{
586
- flexDirection: 'row-reverse',
587
- }}
588
- >
304
+ <View style={styles.modalCardPlain}>
305
+ <View style={styles.closeRow}>
589
306
  <TouchableOpacity
590
307
  onPress={() => setShowModal2(false)}
591
- style={{
592
- width: 30,
593
- height: 30,
594
- alignItems: 'center',
595
- justifyContent: 'center',
596
- }}
308
+ style={styles.closeButton}
597
309
  >
598
310
  <Close2Icon />
599
311
  </TouchableOpacity>
600
312
  </View>
601
313
  <Image
602
314
  source={require('../../assets/img/Frame1000011990.png')}
603
- style={{
604
- height: 230,
605
- resizeMode: 'contain',
606
- width: '100%',
607
- }}
315
+ style={styles.approvalImage}
608
316
  />
609
- <View
610
- style={{
611
- paddingHorizontal: 24,
612
- marginTop: 24,
613
- flexDirection: 'column',
614
- gap: 8,
615
- alignItems: 'center',
616
- }}
617
- >
618
- <MText
619
- style={{
620
- fontSize: 16,
621
- fontWeight: 'bold',
622
- textAlign: 'center',
623
- }}
624
- >
625
- Đơn vay đang chờ phê duyệt
626
- </MText>
627
- <MText
628
- style={{
629
- fontSize: 14,
630
- textAlign: 'center',
631
- color: '#828282',
632
- }}
633
- >
317
+ <View style={styles.approvalBody}>
318
+ <MText style={styles.modalTitle}>Đơn vay đang chờ phê duyệt</MText>
319
+ <MText style={styles.approvalDesc}>
634
320
  Vui lòng chờ ít phút sau đó thực hiện eKYC để hoàn thiện khoản
635
321
  vay!
636
322
  </MText>
637
323
  <TouchableOpacity
638
324
  onPress={() => setShowModal2(false)}
639
- style={{
640
- borderWidth: 1,
641
- borderColor: '#EF592E',
642
- borderRadius: 24,
643
- height: 40,
644
- alignItems: 'center',
645
- justifyContent: 'center',
646
- paddingHorizontal: 50,
647
- marginBottom: 24,
648
- marginTop: 16,
649
- }}
325
+ style={styles.understoodButton}
650
326
  >
651
- <MText
652
- style={{
653
- color: '#EF592E',
654
- }}
655
- >
656
- Đã hiểu
657
- </MText>
327
+ <MText style={styles.understoodText}>Đã hiểu</MText>
658
328
  </TouchableOpacity>
659
329
  </View>
660
330
  </View>
@@ -666,217 +336,48 @@ export default function ItemMotoBikeLoan({
666
336
  backdropOpacity={0.5}
667
337
  onBackdropPress={() => setShowModal(false)}
668
338
  >
669
- <View
670
- style={{
671
- borderRadius: 12,
672
- backgroundColor: 'white',
673
- padding: 16,
674
- }}
675
- >
676
- <MText
677
- style={{
678
- fontSize: 16,
679
- fontWeight: 'bold',
680
- textAlign: 'center',
681
- marginTop: 16,
682
- }}
683
- >
684
- Các bước hoàn thiện khoản vay
685
- </MText>
686
- <MText
687
- style={{
688
- textAlign: 'center',
689
- color: '#828282',
690
- }}
691
- >
692
- Thực hiện theo các bước sau
339
+ <View style={styles.modalCard}>
340
+ <MText style={[styles.modalTitle, styles.guideTitle]}>
341
+ Các bước hoàn thiện đơn vay
693
342
  </MText>
694
- <View>
695
- <View
696
- style={{
697
- flexDirection: 'row',
698
- alignItems: 'center',
699
- gap: 8,
700
- marginTop: 16,
701
- }}
702
- >
703
- <View
704
- style={{
705
- width: 30,
706
- height: 30,
707
- borderRadius: 4,
708
- backgroundColor: '#FFF2F2',
709
- alignItems: 'center',
710
- justifyContent: 'center',
711
- }}
712
- >
713
- <Icon3 />
714
- </View>
715
- <View>
716
- <MText
717
- style={{ fontWeight: 'bold', fontSize: 8, color: '#EF592E' }}
718
- >
719
- Bước 1
720
- </MText>
721
- <MText style={{ fontWeight: 'bold', fontSize: 10 }}>
722
- THÔNG TIN CÁ NHÂN
723
- </MText>
343
+ {GUIDE_STEPS.map(({ icon: StepIcon, title, description }, index) => (
344
+ <React.Fragment key={title}>
345
+ <View style={styles.guideStepRow}>
346
+ <View style={styles.guideStepIconBox}>
347
+ <StepIcon />
348
+ </View>
349
+ <View>
350
+ <MText style={styles.guideStepBadge}>Bước {index + 1}</MText>
351
+ <MText style={styles.guideStepTitle}>{title}</MText>
352
+ {!!description && (
353
+ <MText style={styles.guideStepDesc}>{description}</MText>
354
+ )}
355
+ </View>
724
356
  </View>
725
- </View>
726
- <MText style={{ fontSize: 10, marginTop: 5 }}>
727
- Thực hiện OCR giấy tờ CCCD/CC và chụp 1 ảnh chân dung
728
- </MText>
729
- </View>
730
- <View>
731
- <View
732
- style={{
733
- flexDirection: 'row',
734
- alignItems: 'center',
735
- gap: 8,
736
- marginTop: 16,
737
- }}
738
- >
739
- <View
740
- style={{
741
- width: 30,
742
- height: 30,
743
- borderRadius: 4,
744
- backgroundColor: '#FFF2F2',
745
- alignItems: 'center',
746
- justifyContent: 'center',
747
- }}
748
- >
749
- <Icon2 />
750
- </View>
751
- <View>
752
- <MText
753
- style={{ fontWeight: 'bold', fontSize: 8, color: '#EF592E' }}
754
- >
755
- Bước 2
756
- </MText>
757
- <MText style={{ fontWeight: 'bold', fontSize: 10 }}>
758
- THÔNG TIN XE MÁY
759
- </MText>
760
- </View>
761
- </View>
762
- <MText style={{ fontSize: 10, marginTop: 5 }}>
763
- Chụp 2 mặt hình ảnh Đăng ký xe
764
- </MText>
765
- </View>
357
+ {index < GUIDE_STEPS.length - 1 && (
358
+ <View style={styles.dashedDivider}>
359
+ <View style={styles.dashedDividerInner} />
360
+ </View>
361
+ )}
362
+ </React.Fragment>
363
+ ))}
766
364
 
767
- <View>
768
- <View
769
- style={{
770
- flexDirection: 'row',
771
- alignItems: 'center',
772
- gap: 8,
773
- marginTop: 16,
774
- }}
775
- >
776
- <View
777
- style={{
778
- width: 30,
779
- height: 30,
780
- borderRadius: 4,
781
- backgroundColor: '#FFF2F2',
782
- alignItems: 'center',
783
- justifyContent: 'center',
784
- }}
785
- >
786
- <Icon2 />
787
- </View>
788
- <View>
789
- <MText
790
- style={{ fontWeight: 'bold', fontSize: 8, color: '#EF592E' }}
791
- >
792
- Bước 3
793
- </MText>
794
- <MText style={{ fontWeight: 'bold', fontSize: 10 }}>
795
- NỘP HỒ SƠ VAY
796
- </MText>
365
+ <View style={styles.legendBox}>
366
+ <MText style={styles.legendTitle}>Ý nghĩa biểu tượng</MText>
367
+ {LEGEND_ROWS.map(({ label, icons }) => (
368
+ <View key={label} style={styles.legendRow}>
369
+ <MText style={styles.legendLabel}>{label}</MText>
370
+ <View style={styles.legendIcons}>
371
+ {icons.map((LegendIcon, index) => (
372
+ <LegendIcon key={index} />
373
+ ))}
374
+ </View>
797
375
  </View>
798
- </View>
799
- <MText style={{ fontSize: 10, marginTop: 5 }}>
800
- Xác nhận T&C{' '}
801
- <MText style={{ fontSize: 10, color: '#EF592E' }}>
802
- (Điều kiện & điều khoản)
803
- </MText>{' '}
804
- và nộp hồ sơ vay
805
- </MText>
806
- </View>
807
-
808
- <View
809
- style={{
810
- backgroundColor: '#FFF8F2',
811
- padding: 12,
812
- borderRadius: 8,
813
- marginTop: 16,
814
- }}
815
- >
816
- <MText style={{ fontSize: 12, fontWeight: 'bold' }}>
817
- Ý nghĩa biểu tượng
818
- </MText>
819
- <View
820
- style={{
821
- flexDirection: 'row',
822
- alignItems: 'center',
823
- gap: 16,
824
- marginTop: 8,
825
- }}
826
- >
827
- <MText style={{ fontSize: 10, width: '35%' }}>
828
- Đang cần thực hiện
829
- </MText>
830
- <View
831
- style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}
832
- >
833
- <Icon2 />
834
- <Icon3 />
835
- <Icon4 />
836
- <Icon5 />
837
- </View>
838
- </View>
839
- <View
840
- style={{
841
- flexDirection: 'row',
842
- alignItems: 'center',
843
- gap: 16,
844
- marginTop: 8,
845
- }}
846
- >
847
- <MText style={{ fontSize: 10, width: '35%' }}>
848
- Chưa thể thực hiện
849
- </MText>
850
- <View
851
- style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}
852
- >
853
- <Icon7 />
854
- <Icon8 />
855
- <Icon9 />
856
- <Icon10 />
857
- </View>
858
- </View>
859
- <View
860
- style={{
861
- flexDirection: 'row',
862
- alignItems: 'center',
863
- gap: 16,
864
- marginTop: 8,
865
- }}
866
- >
867
- <MText style={{ fontSize: 10, width: '35%' }}>
868
- Đã hoàn thành
869
- </MText>
870
- <View
871
- style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}
872
- >
873
- <IconSuccess />
874
- </View>
875
- </View>
376
+ ))}
876
377
  </View>
877
378
 
878
379
  <TouchableOpacity
879
- style={{ position: 'absolute', top: 16, right: 16 }}
380
+ style={styles.guideClose}
880
381
  onPress={() => setShowModal(false)}
881
382
  >
882
383
  <Close2Icon />
@@ -886,3 +387,296 @@ export default function ItemMotoBikeLoan({
886
387
  </View>
887
388
  );
888
389
  }
390
+
391
+ const styles = StyleSheet.create({
392
+ card: {
393
+ backgroundColor: '#FFFFFF',
394
+ paddingHorizontal: 16,
395
+ marginBottom: 16,
396
+ borderRadius: 8,
397
+ borderWidth: 0.5,
398
+ borderColor: '#E0E0E0',
399
+ },
400
+ headerGradient: {
401
+ borderTopLeftRadius: 8,
402
+ borderTopRightRadius: 8,
403
+ marginHorizontal: -16,
404
+ },
405
+ headerRow: {
406
+ flexDirection: 'row',
407
+ justifyContent: 'space-between',
408
+ alignItems: 'center',
409
+ paddingHorizontal: 16,
410
+ paddingVertical: 8,
411
+ },
412
+ headerLeft: {
413
+ flexDirection: 'row',
414
+ alignItems: 'center',
415
+ gap: 8,
416
+ },
417
+ headerText: {
418
+ fontSize: 12,
419
+ color: 'white',
420
+ },
421
+ headerAmount: {
422
+ fontSize: 12,
423
+ color: 'white',
424
+ fontWeight: 'bold',
425
+ },
426
+ stepsRow: {
427
+ flexDirection: 'row',
428
+ paddingVertical: 16,
429
+ alignItems: 'center',
430
+ gap: 16,
431
+ },
432
+ stepButton: {
433
+ borderRadius: 8,
434
+ paddingVertical: 8,
435
+ paddingHorizontal: 12,
436
+ flex: 1,
437
+ borderWidth: 1,
438
+ },
439
+ stepBadge: {
440
+ paddingVertical: 2,
441
+ borderRadius: 40,
442
+ flexDirection: 'row',
443
+ alignItems: 'center',
444
+ justifyContent: 'center',
445
+ width: 50,
446
+ },
447
+ stepBadgeText: {
448
+ fontSize: 8,
449
+ color: 'white',
450
+ },
451
+ stepLabelRow: {
452
+ marginTop: 8,
453
+ flexDirection: 'row',
454
+ alignItems: 'center',
455
+ gap: 4,
456
+ },
457
+ stepLabelText: {
458
+ fontSize: 10,
459
+ },
460
+ guideBanner: {
461
+ backgroundColor: '#EEF7FF',
462
+ flexDirection: 'row',
463
+ alignItems: 'center',
464
+ gap: 4,
465
+ borderRadius: 4,
466
+ paddingHorizontal: 8,
467
+ paddingVertical: 10,
468
+ },
469
+ guideBannerText: {
470
+ fontSize: 10,
471
+ flex: 1,
472
+ },
473
+ linkText: {
474
+ fontSize: 10,
475
+ color: '#2F80ED',
476
+ textDecorationLine: 'underline',
477
+ },
478
+ statusSection: {
479
+ flexDirection: 'row',
480
+ paddingBottom: 16,
481
+ marginTop: 16,
482
+ },
483
+ statusLeft: {
484
+ flex: 1,
485
+ paddingRight: 24,
486
+ },
487
+ statusLabel: {
488
+ color: '#999999',
489
+ fontSize: 12,
490
+ },
491
+ statusValue: {
492
+ fontSize: 12,
493
+ fontWeight: 'bold',
494
+ },
495
+ updateButton: {
496
+ height: 30,
497
+ alignItems: 'center',
498
+ justifyContent: 'center',
499
+ borderRadius: 24,
500
+ paddingHorizontal: 10,
501
+ },
502
+ updateButtonText: {
503
+ color: 'white',
504
+ fontSize: 12,
505
+ },
506
+ warningBanner: {
507
+ flexDirection: 'row',
508
+ alignItems: 'center',
509
+ gap: 8,
510
+ backgroundColor: '#FFF2F2',
511
+ marginHorizontal: -16,
512
+ paddingVertical: 10,
513
+ borderBottomRightRadius: 8,
514
+ borderBottomLeftRadius: 8,
515
+ paddingHorizontal: 10,
516
+ },
517
+ warningText: {
518
+ fontSize: 10,
519
+ color: '#E40010',
520
+ flex: 1,
521
+ },
522
+ modalCard: {
523
+ borderRadius: 12,
524
+ backgroundColor: 'white',
525
+ padding: 16,
526
+ },
527
+ modalCardPlain: {
528
+ borderRadius: 12,
529
+ backgroundColor: 'white',
530
+ },
531
+ closeRow: {
532
+ flexDirection: 'row-reverse',
533
+ },
534
+ closeButton: {
535
+ width: 30,
536
+ height: 30,
537
+ alignItems: 'center',
538
+ justifyContent: 'center',
539
+ },
540
+ modalTitle: {
541
+ fontSize: 16,
542
+ fontWeight: 'bold',
543
+ textAlign: 'center',
544
+ },
545
+ f88Wrap: {
546
+ marginTop: 16,
547
+ alignItems: 'center',
548
+ },
549
+ f88Image: {
550
+ height: 60,
551
+ resizeMode: 'contain',
552
+ },
553
+ policyBody: {
554
+ color: '#828282',
555
+ textAlign: 'center',
556
+ marginTop: 16,
557
+ },
558
+ checkboxRow: {
559
+ flexDirection: 'row',
560
+ alignItems: 'center',
561
+ marginTop: 24,
562
+ gap: 8,
563
+ },
564
+ termsLink: {
565
+ color: '#2F80ED',
566
+ },
567
+ confirmButton: {
568
+ height: 40,
569
+ alignItems: 'center',
570
+ justifyContent: 'center',
571
+ borderRadius: 24,
572
+ paddingHorizontal: 10,
573
+ marginTop: 24,
574
+ },
575
+ confirmButtonText: {
576
+ color: 'white',
577
+ fontWeight: 'bold',
578
+ },
579
+ approvalImage: {
580
+ height: 230,
581
+ resizeMode: 'contain',
582
+ width: '100%',
583
+ },
584
+ approvalBody: {
585
+ paddingHorizontal: 24,
586
+ marginTop: 24,
587
+ flexDirection: 'column',
588
+ gap: 8,
589
+ alignItems: 'center',
590
+ },
591
+ approvalDesc: {
592
+ fontSize: 14,
593
+ textAlign: 'center',
594
+ color: '#828282',
595
+ },
596
+ understoodButton: {
597
+ borderWidth: 1,
598
+ borderColor: '#EF592E',
599
+ borderRadius: 24,
600
+ height: 40,
601
+ alignItems: 'center',
602
+ justifyContent: 'center',
603
+ paddingHorizontal: 50,
604
+ marginBottom: 24,
605
+ marginTop: 16,
606
+ },
607
+ understoodText: {
608
+ color: '#EF592E',
609
+ },
610
+ guideTitle: {
611
+ marginTop: 16,
612
+ },
613
+ guideStepRow: {
614
+ flexDirection: 'row',
615
+ alignItems: 'flex-start',
616
+ gap: 8,
617
+ marginTop: 16,
618
+ },
619
+ dashedDivider: {
620
+ height: 1,
621
+ marginTop: 16,
622
+ overflow: 'hidden',
623
+ },
624
+ dashedDividerInner: {
625
+ height: 2,
626
+ borderWidth: 1,
627
+ borderColor: '#E5E5E5',
628
+ borderStyle: 'dashed',
629
+ },
630
+ guideStepIconBox: {
631
+ width: 30,
632
+ height: 30,
633
+ borderRadius: 4,
634
+ backgroundColor: '#FFF2F2',
635
+ alignItems: 'center',
636
+ justifyContent: 'center',
637
+ },
638
+ guideStepBadge: {
639
+ fontWeight: 'bold',
640
+ fontSize: 8,
641
+ color: '#EF592E',
642
+ },
643
+ guideStepTitle: {
644
+ fontWeight: 'bold',
645
+ fontSize: 10,
646
+ marginTop: 5,
647
+ },
648
+ guideStepDesc: {
649
+ fontSize: 10,
650
+ marginTop: 5,
651
+ },
652
+ legendBox: {
653
+ backgroundColor: '#FFF8F2',
654
+ padding: 12,
655
+ borderRadius: 8,
656
+ marginTop: 16,
657
+ },
658
+ legendTitle: {
659
+ fontSize: 12,
660
+ fontWeight: 'bold',
661
+ },
662
+ legendRow: {
663
+ flexDirection: 'row',
664
+ alignItems: 'center',
665
+ gap: 16,
666
+ marginTop: 8,
667
+ },
668
+ legendLabel: {
669
+ fontSize: 10,
670
+ width: '35%',
671
+ },
672
+ legendIcons: {
673
+ flexDirection: 'row',
674
+ alignItems: 'center',
675
+ gap: 8,
676
+ },
677
+ guideClose: {
678
+ position: 'absolute',
679
+ top: 16,
680
+ right: 16,
681
+ },
682
+ });