react-native-timacare 3.3.65 → 3.3.67

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 (64) hide show
  1. package/lib/commonjs/components/AlertLoan.js +1 -1
  2. package/lib/commonjs/components/AlertLoan.js.flow +1 -19
  3. package/lib/commonjs/components/AlertLoan.js.map +1 -1
  4. package/lib/commonjs/screens/motobike/InfoLoanMotobike.js +1 -1
  5. package/lib/commonjs/screens/motobike/InfoLoanMotobike.js.flow +3 -2
  6. package/lib/commonjs/screens/motobike/InfoLoanMotobike.js.map +1 -1
  7. package/lib/commonjs/screens/motobike/ReviewLoanMotobike.js +1 -1
  8. package/lib/commonjs/screens/motobike/ReviewLoanMotobike.js.flow +1 -0
  9. package/lib/commonjs/screens/motobike/ReviewLoanMotobike.js.map +1 -1
  10. package/lib/commonjs/screens/toan-trinh-so/ReviewInformation.js +1 -1
  11. package/lib/commonjs/screens/toan-trinh-so/ReviewInformation.js.flow +1 -0
  12. package/lib/commonjs/screens/toan-trinh-so/ReviewInformation.js.map +1 -1
  13. package/lib/commonjs/screens/toan-trinh-so/ReviewInformationOther.js +1 -1
  14. package/lib/commonjs/screens/toan-trinh-so/ReviewInformationOther.js.flow +1 -0
  15. package/lib/commonjs/screens/toan-trinh-so/ReviewInformationOther.js.map +1 -1
  16. package/lib/commonjs/screens/toan-trinh-so/ReviewLoan.js +1 -1
  17. package/lib/commonjs/screens/toan-trinh-so/ReviewLoan.js.flow +1 -0
  18. package/lib/commonjs/screens/toan-trinh-so/ReviewLoan.js.map +1 -1
  19. package/lib/commonjs/screens/toan-trinh-so/TTSSelfie.js +1 -1
  20. package/lib/commonjs/screens/toan-trinh-so/TTSSelfie.js.flow +189 -138
  21. package/lib/commonjs/screens/toan-trinh-so/TTSSelfie.js.map +1 -1
  22. package/lib/commonjs/screens/toan-trinh-so/TopupLoanInfo.js +1 -1
  23. package/lib/commonjs/screens/toan-trinh-so/TopupLoanInfo.js.flow +8 -5
  24. package/lib/commonjs/screens/toan-trinh-so/TopupLoanInfo.js.map +1 -1
  25. package/lib/commonjs/screens/v3/AssetInformation.js +1 -1
  26. package/lib/commonjs/screens/v3/AssetInformation.js.flow +1 -0
  27. package/lib/commonjs/screens/v3/AssetInformation.js.map +1 -1
  28. package/lib/commonjs/screens/v3/ReviewInfoLoanBuyCar.js +1 -1
  29. package/lib/commonjs/screens/v3/ReviewInfoLoanBuyCar.js.flow +1 -0
  30. package/lib/commonjs/screens/v3/ReviewInfoLoanBuyCar.js.map +1 -1
  31. package/lib/module/components/AlertLoan.js +1 -1
  32. package/lib/module/components/AlertLoan.js.map +1 -1
  33. package/lib/module/screens/motobike/InfoLoanMotobike.js +1 -1
  34. package/lib/module/screens/motobike/InfoLoanMotobike.js.map +1 -1
  35. package/lib/module/screens/motobike/ReviewLoanMotobike.js +1 -1
  36. package/lib/module/screens/motobike/ReviewLoanMotobike.js.map +1 -1
  37. package/lib/module/screens/toan-trinh-so/ReviewInformation.js +1 -1
  38. package/lib/module/screens/toan-trinh-so/ReviewInformation.js.map +1 -1
  39. package/lib/module/screens/toan-trinh-so/ReviewInformationOther.js +1 -1
  40. package/lib/module/screens/toan-trinh-so/ReviewInformationOther.js.map +1 -1
  41. package/lib/module/screens/toan-trinh-so/ReviewLoan.js +1 -1
  42. package/lib/module/screens/toan-trinh-so/ReviewLoan.js.map +1 -1
  43. package/lib/module/screens/toan-trinh-so/TTSSelfie.js +1 -1
  44. package/lib/module/screens/toan-trinh-so/TTSSelfie.js.map +1 -1
  45. package/lib/module/screens/toan-trinh-so/TopupLoanInfo.js +1 -1
  46. package/lib/module/screens/toan-trinh-so/TopupLoanInfo.js.map +1 -1
  47. package/lib/module/screens/v3/AssetInformation.js +1 -1
  48. package/lib/module/screens/v3/AssetInformation.js.map +1 -1
  49. package/lib/module/screens/v3/ReviewInfoLoanBuyCar.js +1 -1
  50. package/lib/module/screens/v3/ReviewInfoLoanBuyCar.js.map +1 -1
  51. package/lib/typescript/components/AlertLoan.d.ts.map +1 -1
  52. package/lib/typescript/screens/toan-trinh-so/TTSSelfie.d.ts.map +1 -1
  53. package/lib/typescript/screens/toan-trinh-so/TopupLoanInfo.d.ts.map +1 -1
  54. package/package.json +1 -1
  55. package/src/components/AlertLoan.tsx +1 -19
  56. package/src/screens/motobike/InfoLoanMotobike.tsx +3 -2
  57. package/src/screens/motobike/ReviewLoanMotobike.tsx +1 -0
  58. package/src/screens/toan-trinh-so/ReviewInformation.tsx +1 -0
  59. package/src/screens/toan-trinh-so/ReviewInformationOther.tsx +1 -0
  60. package/src/screens/toan-trinh-so/ReviewLoan.tsx +1 -0
  61. package/src/screens/toan-trinh-so/TTSSelfie.tsx +189 -138
  62. package/src/screens/toan-trinh-so/TopupLoanInfo.tsx +8 -5
  63. package/src/screens/v3/AssetInformation.tsx +1 -0
  64. package/src/screens/v3/ReviewInfoLoanBuyCar.tsx +1 -0
@@ -1,41 +1,57 @@
1
1
  // @ts-nocheck
2
2
  import React, { useEffect, useRef, useState } from 'react';
3
- import { Dimensions, Platform, View } from 'react-native';
3
+ import {
4
+ ActivityIndicator,
5
+ Dimensions,
6
+ Platform,
7
+ StyleSheet,
8
+ View,
9
+ } from 'react-native';
4
10
  import { useNavigation, useIsFocused } from '@react-navigation/native';
11
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
12
  import {
6
13
  request,
7
14
  PERMISSIONS,
8
15
  RESULTS,
9
16
  openSettings,
10
17
  } from 'react-native-permissions';
18
+ import {
19
+ Camera,
20
+ useCameraDevice,
21
+ useCameraFormat,
22
+ } from 'react-native-vision-camera';
23
+ import { Svg, Ellipse, Path } from 'react-native-svg';
11
24
  import { MText } from '../../components/MText';
12
25
  import MButton from '../../components/MButton';
13
26
  import { commonStyles } from '../CommonStyles';
14
- import { IconBackWhite, TakePhotoSvg } from '../../assets/icons';
27
+ import { IconBack, TakePhotoSvg } from '../../assets/icons';
15
28
  import Loading from '../../components/Loading';
16
29
  import { Api } from '../../services/api';
17
30
  import { ScreenNames } from '../../navigation';
18
31
  import appStore from '../../AppStore';
19
32
  import { logEvent, logEventFb } from '../../utils';
20
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
21
- import {
22
- Camera,
23
- useCameraDevice,
24
- useCameraFormat,
25
- } from 'react-native-vision-camera';
26
33
  import { AlertGlobal } from '../../components/ModalNotification/AlertGlobal';
27
34
 
35
+ const ORANGE = '#F05123';
36
+ const SCREEN_WIDTH = Dimensions.get('window').width;
37
+ // Khung oval: rộng ~72% màn hình, cao gấp 1.33 lần chiều rộng (tỉ lệ khuôn mặt)
38
+ const OVAL_WIDTH = Math.round(SCREEN_WIDTH * 0.72);
39
+ const OVAL_HEIGHT = Math.round(OVAL_WIDTH * 1.33);
40
+
28
41
  export default function TTSSelfie(props: any) {
29
42
  const insets = useSafeAreaInsets();
30
43
  const isFocused = useIsFocused();
31
- const [shouldRenderCamera, setShouldRenderCamera] = useState(false);
32
44
  const navigation = useNavigation();
45
+ const myCamera = useRef(null);
46
+ const takingRef = useRef(false);
47
+ const [passPermission, setPassPermission] = useState(false);
48
+ const [shouldRenderCamera, setShouldRenderCamera] = useState(false);
33
49
  const [taking, setTaking] = useState(false);
34
50
  const [isLoading, setIsLoading] = useState(false);
35
- const [passPermission, setPassPermission] = useState(false);
36
- const device = useCameraDevice('front');
37
- const myCamera = useRef(null);
51
+ // Kích thước vùng preview để vẽ mặt nạ oval đúng tâm
52
+ const [stage, setStage] = useState({ width: SCREEN_WIDTH, height: 0 });
38
53
 
54
+ const device = useCameraDevice('front');
39
55
  const format = useCameraFormat(device, [
40
56
  { photoResolution: { width: 1280, height: 1280 } },
41
57
  ]);
@@ -48,9 +64,6 @@ export default function TTSSelfie(props: any) {
48
64
  ).then((result) => {
49
65
  switch (result) {
50
66
  case RESULTS.UNAVAILABLE:
51
- console.log(
52
- 'This feature is not available (on this device / in this context)'
53
- );
54
67
  AlertGlobal.show({
55
68
  type: 'warning',
56
69
  title: 'Thông báo',
@@ -60,9 +73,6 @@ export default function TTSSelfie(props: any) {
60
73
  });
61
74
  break;
62
75
  case RESULTS.DENIED:
63
- console.log(
64
- 'The permission has not been requested / is denied but requestable'
65
- );
66
76
  AlertGlobal.show({
67
77
  type: 'warning',
68
78
  title: 'Thông báo',
@@ -79,7 +89,6 @@ export default function TTSSelfie(props: any) {
79
89
  });
80
90
  break;
81
91
  case RESULTS.LIMITED:
82
- console.log('The permission is limited: some actions are possible');
83
92
  AlertGlobal.show({
84
93
  type: 'warning',
85
94
  title: 'Thông báo',
@@ -96,24 +105,16 @@ export default function TTSSelfie(props: any) {
96
105
  });
97
106
  break;
98
107
  case RESULTS.GRANTED:
99
- console.log('The permission is granted');
100
108
  setPassPermission(true);
101
109
  break;
102
110
  case RESULTS.BLOCKED:
103
- console.log('The permission is denied and not requestable anymore');
104
111
  AlertGlobal.show({
105
112
  type: 'warning',
106
113
  title: 'Thông báo',
107
114
  message:
108
115
  'Bạn đã từ chối quyền máy ảnh. Vui lòng cấp quyền máy ảnh để tiếp tục!',
109
116
  primaryText: 'Đồng ý',
110
- onPrimaryPress: () => {
111
- if (Platform.OS === 'ios') {
112
- openSettings();
113
- } else {
114
- openSettings();
115
- }
116
- },
117
+ onPrimaryPress: () => openSettings(),
117
118
  });
118
119
  break;
119
120
  }
@@ -137,30 +138,34 @@ export default function TTSSelfie(props: any) {
137
138
 
138
139
  useEffect(() => {
139
140
  let timeout: NodeJS.Timeout;
140
-
141
141
  if (isFocused) {
142
142
  // Delay mounting camera to give Android time to release the previous one
143
143
  timeout = setTimeout(() => {
144
144
  setShouldRenderCamera(true);
145
- }, 500); // thử 300ms–500ms nếu cần
145
+ }, 500);
146
146
  } else {
147
147
  setShouldRenderCamera(false);
148
148
  }
149
-
150
149
  return () => clearTimeout(timeout);
151
150
  }, [isFocused]);
152
151
 
153
152
  const takePhoto = async () => {
154
- if (myCamera.current == null || taking) return;
153
+ if (myCamera.current == null || takingRef.current) return;
154
+ takingRef.current = true;
155
155
  setTaking(true);
156
- const data = await myCamera.current.takePhoto({
157
- qualityPrioritization: 'speed',
158
- });
159
- setTaking(false);
160
- if (data) {
156
+ try {
157
+ const data = await myCamera.current.takePhoto({
158
+ qualityPrioritization: 'speed',
159
+ });
160
+ setTaking(false);
161
+ if (!data) {
162
+ takingRef.current = false;
163
+ return;
164
+ }
161
165
  setIsLoading(true);
166
+ const loan = props?.route?.params?.loan;
162
167
  const formData = new FormData();
163
- formData.append('LoanBriefId', props?.route?.params?.loan?.id);
168
+ formData.append('LoanBriefId', loan?.id);
164
169
  formData.append('TypeDocumentId', 125); // Anh selfie
165
170
  formData.append('image', {
166
171
  uri: 'file://' + data.path,
@@ -169,23 +174,17 @@ export default function TTSSelfie(props: any) {
169
174
  });
170
175
  const response = await Api.getInstance().uploadImageAutoDE(formData);
171
176
  setIsLoading(false);
177
+ takingRef.current = false;
172
178
  if (response.kind === 'ok') {
173
179
  if (response.data?.meta.errorCode === 200) {
174
- if (
175
- props?.route?.params?.loan?.typeLoan === 6 ||
176
- props?.route?.params?.loan?.typeLoan === 4
177
- ) {
178
- navigation.push(ScreenNames.TopupLoanInfo, {
179
- loan: props?.route?.params?.loan,
180
- });
181
- } else if (props?.route?.params?.loan?.typeLoan === 8) {
182
- navigation.push(ScreenNames.InfoLoanMotobike, {
183
- loan: props?.route?.params?.loan,
184
- });
180
+ if (loan?.typeLoan === 6 || loan?.typeLoan === 4) {
181
+ navigation.push(ScreenNames.TopupLoanInfo, { loan });
182
+ } else if (loan?.typeLoan === 8) {
183
+ navigation.push(ScreenNames.InfoLoanMotobike, { loan });
184
+ } else if (loan?.typeLoan === 7) {
185
+ navigation.push(ScreenNames.ReviewInfoLoanBuyCar, { loan });
185
186
  } else {
186
- navigation.push(ScreenNames.ReviewInformation, {
187
- loan: props?.route?.params?.loan,
188
- });
187
+ navigation.push(ScreenNames.ReviewInformation, { loan });
189
188
  }
190
189
  } else {
191
190
  AlertGlobal.show({
@@ -203,109 +202,161 @@ export default function TTSSelfie(props: any) {
203
202
  primaryText: 'Đóng',
204
203
  });
205
204
  }
205
+ } catch (err) {
206
+ console.log('takePhoto error', err);
207
+ setTaking(false);
208
+ setIsLoading(false);
209
+ takingRef.current = false;
206
210
  }
207
211
  };
208
212
 
213
+ // Mặt nạ: phủ trắng toàn bộ vùng preview, khoét một lỗ hình oval ở giữa
214
+ // (fillRule evenodd) -> chỉ nhìn thấy camera bên trong oval.
215
+ const renderOvalMask = () => {
216
+ const { width: w, height: h } = stage;
217
+ if (!w || !h) return null;
218
+ const cx = w / 2;
219
+ const cy = h / 2;
220
+ const rx = OVAL_WIDTH / 2;
221
+ const ry = Math.min(OVAL_HEIGHT, h - 16) / 2;
222
+ const hole = `M ${cx - rx} ${cy} a ${rx} ${ry} 0 1 0 ${
223
+ rx * 2
224
+ } 0 a ${rx} ${ry} 0 1 0 ${-rx * 2} 0 Z`;
225
+ return (
226
+ <Svg
227
+ pointerEvents="none"
228
+ style={StyleSheet.absoluteFill}
229
+ width={w}
230
+ height={h}
231
+ >
232
+ <Path
233
+ d={`M 0 0 H ${w} V ${h} H 0 Z ${hole}`}
234
+ fill="#FFFFFF"
235
+ fillRule="evenodd"
236
+ />
237
+ {/* Vòng ngoài mờ tạo chiều sâu cho khung, vòng trong nét đứt là mốc căn mặt */}
238
+ <Ellipse
239
+ cx={cx}
240
+ cy={cy}
241
+ rx={rx + 8}
242
+ ry={ry + 8}
243
+ stroke={ORANGE}
244
+ strokeWidth={1}
245
+ strokeOpacity={0.25}
246
+ fill="none"
247
+ />
248
+ <Ellipse
249
+ cx={cx}
250
+ cy={cy}
251
+ rx={rx}
252
+ ry={ry}
253
+ stroke={ORANGE}
254
+ strokeWidth={2}
255
+ strokeDasharray="6 5"
256
+ strokeLinecap="round"
257
+ fill="none"
258
+ />
259
+ </Svg>
260
+ );
261
+ };
262
+
209
263
  return (
210
- <View
211
- style={{ flex: 1, backgroundColor: 'black' }}
212
- pointerEvents={'box-none'}
213
- >
214
- {passPermission && shouldRenderCamera ? (
215
- <View
216
- style={[
217
- commonStyles.fill,
218
- {
219
- width: Dimensions.get('window').width,
220
- height: Dimensions.get('window').height,
221
- },
222
- ]}
223
- >
224
- <View
225
- style={{
226
- marginVertical: 24,
227
- flexDirection: 'row',
228
- alignItems: 'center',
229
- justifyContent: 'center',
230
- marginTop: insets.top + 16,
231
- }}
232
- >
233
- <MButton
234
- onPress={() => {
235
- navigation.goBack();
236
- }}
237
- style={{
238
- position: 'absolute',
239
- left: 16,
240
- }}
241
- >
242
- <IconBackWhite />
243
- </MButton>
244
- <MText
245
- style={{
246
- color: 'white',
247
- fontWeight: 'bold',
248
- textAlgin: 'center',
249
- }}
250
- >
251
- Xác thực khuôn mặt
252
- </MText>
253
- </View>
264
+ <View style={styles.container}>
265
+ <View style={[styles.header, { paddingTop: insets.top + 12 }]}>
266
+ <MButton onPress={() => navigation.goBack()} style={styles.backButton}>
267
+ <IconBack />
268
+ </MButton>
269
+ <View style={styles.titleWrap}>
270
+ <MText style={styles.headerTitle}>Xác thực khuôn mặt</MText>
271
+ </View>
272
+ </View>
254
273
 
274
+ <View
275
+ style={styles.stage}
276
+ onLayout={(e) => setStage(e.nativeEvent.layout)}
277
+ >
278
+ {passPermission && shouldRenderCamera && device ? (
255
279
  <Camera
256
- style={{
257
- width: Dimensions.get('window').width,
258
- height: (Dimensions.get('window').width * 4) / 3.1,
259
- }}
260
280
  ref={myCamera}
281
+ style={StyleSheet.absoluteFill}
261
282
  device={device}
262
- isActive={true}
283
+ isActive={isFocused}
263
284
  photo={true}
264
285
  format={format}
265
286
  />
266
-
287
+ ) : (
267
288
  <View
268
- style={{
269
- position: 'absolute',
270
- bottom: 20,
271
- left: 0,
272
- right: 0,
273
- }}
289
+ style={[
290
+ StyleSheet.absoluteFill,
291
+ commonStyles.alignCenter,
292
+ commonStyles.justifyCenter,
293
+ ]}
274
294
  >
275
- {!taking && (
276
- <>
277
- <MText
278
- style={{
279
- color: 'white',
280
- textAlign: 'center',
281
- fontSize: 14,
282
- paddingHorizontal: 24,
283
- }}
284
- >
285
- Xin vui lòng nhìn thẳng, khuôn mặt ở trong khung hình, ánh
286
- sáng đủ rõ nét khuôn mặt
287
- </MText>
288
- <View
289
- style={{
290
- alignItems: 'center',
291
- marginVertical: 24,
292
- }}
293
- >
294
- <MButton
295
- onPress={() => {
296
- takePhoto();
297
- }}
298
- >
299
- <TakePhotoSvg />
300
- </MButton>
301
- </View>
302
- </>
303
- )}
295
+ <ActivityIndicator color={ORANGE} size="large" />
304
296
  </View>
297
+ )}
298
+ {renderOvalMask()}
299
+ </View>
300
+
301
+ <MText style={styles.instruction}>
302
+ Xin vui lòng nhìn thẳng, khuôn mặt ở trong khung hình, ánh sáng đủ rõ
303
+ nét khuôn mặt
304
+ </MText>
305
+
306
+ <View style={[styles.captureWrap, { marginBottom: insets.bottom + 24 }]}>
307
+ {/* Quầng cam nhạt quanh nút chụp: tách nút khỏi nền trắng, đúng thiết kế */}
308
+ <View style={styles.captureHalo}>
309
+ {taking ? (
310
+ <ActivityIndicator color={ORANGE} size="large" />
311
+ ) : (
312
+ <MButton onPress={takePhoto}>
313
+ <TakePhotoSvg />
314
+ </MButton>
315
+ )}
305
316
  </View>
306
- ) : null}
317
+ </View>
307
318
 
308
319
  <Loading isLoading={isLoading} />
309
320
  </View>
310
321
  );
311
322
  }
323
+
324
+ const styles = StyleSheet.create({
325
+ container: { flex: 1, backgroundColor: '#FFFFFF' },
326
+ header: {
327
+ flexDirection: 'row',
328
+ alignItems: 'center',
329
+ paddingHorizontal: 16,
330
+ paddingBottom: 8,
331
+ },
332
+ backButton: { width: 32, height: 32, justifyContent: 'center' },
333
+ titleWrap: {
334
+ flex: 1,
335
+ alignItems: 'center',
336
+ justifyContent: 'center',
337
+ marginRight: 32,
338
+ },
339
+ headerTitle: { color: '#333333', fontSize: 16, fontWeight: '600' },
340
+ stage: {
341
+ flex: 1,
342
+ overflow: 'hidden',
343
+ backgroundColor: '#FFFFFF',
344
+ },
345
+ instruction: {
346
+ textAlign: 'center',
347
+ color: '#333333',
348
+ fontSize: 14,
349
+ lineHeight: 20,
350
+ paddingHorizontal: 32,
351
+ marginTop: 16,
352
+ },
353
+ captureWrap: { alignItems: 'center', marginTop: 24 },
354
+ captureHalo: {
355
+ width: 88,
356
+ height: 88,
357
+ borderRadius: 44,
358
+ alignItems: 'center',
359
+ justifyContent: 'center',
360
+ backgroundColor: 'rgba(240, 81, 35, 0.10)',
361
+ },
362
+ });
@@ -220,7 +220,9 @@ export default function TopupLoanInfo(props) {
220
220
  validateOnBlur={false}
221
221
  validateOnChange={false}
222
222
  validationSchema={yup.object().shape({
223
- dateNationalId: yup.string().required('Vui lòng chọn ngày cấp CCCD'),
223
+ dateNationalId: yup
224
+ .string()
225
+ .required('Vui lòng chọn ngày cấp CCCD'),
224
226
  bankName: yup.string().required('Vui lòng chọn ngân hàng'),
225
227
  bankAccountName: yup.string().required('Vui lòng nhập chủ thẻ'),
226
228
  bankAccountNumber: yup
@@ -293,8 +295,8 @@ export default function TopupLoanInfo(props) {
293
295
  {values.gender === 0
294
296
  ? 'Nam'
295
297
  : values.gender === 1
296
- ? 'Nữ'
297
- : ''}
298
+ ? 'Nữ'
299
+ : ''}
298
300
  </MText>
299
301
  <DropDown2 />
300
302
  </TouchableOpacity>
@@ -346,8 +348,8 @@ export default function TopupLoanInfo(props) {
346
348
  </MText>
347
349
  </TouchableOpacity>
348
350
  {errors && errors.dateNationalId && (
349
- <MText style={$error}>{errors.dateNationalId}</MText>
350
- )}
351
+ <MText style={$error}>{errors.dateNationalId}</MText>
352
+ )}
351
353
  </View>
352
354
 
353
355
  <DatePicker
@@ -500,6 +502,7 @@ const $textInput: ViewStyle = {
500
502
  height: 40,
501
503
  paddingHorizontal: 8,
502
504
  fontFamily: 'BeVietnamPro-Medium',
505
+ fontSize: 14,
503
506
  };
504
507
 
505
508
  const $label: TextStyle = {
@@ -701,4 +701,5 @@ const $textInput: ViewStyle = {
701
701
  height: 40,
702
702
  paddingHorizontal: 8,
703
703
  fontFamily: 'BeVietnamPro-Medium',
704
+ fontSize: 14,
704
705
  };
@@ -462,6 +462,7 @@ const $textInput: ViewStyle = {
462
462
  height: 40,
463
463
  paddingHorizontal: 8,
464
464
  fontFamily: 'BeVietnamPro-Medium',
465
+ fontSize: 14,
465
466
  };
466
467
 
467
468
  const $label: TextStyle = {