@transfergratis/react-native-sdk 0.1.28 → 0.1.30
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/build/components/EnhancedCameraView.js +1 -1
- package/build/components/EnhancedCameraView.js.map +1 -1
- package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/CountrySelectionTemplate.js +13 -42
- package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
- package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/components/KYCElements/IDCardCapture.js +113 -49
- package/build/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/components/KYCElements/SelfieCaptureTemplate.js +2 -2
- package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
- package/build/hooks/useTemplateKYCFlow.js +1 -1
- package/build/hooks/useTemplateKYCFlow.js.map +1 -1
- package/build/modules/api/CardAuthentification.d.ts +15 -7
- package/build/modules/api/CardAuthentification.d.ts.map +1 -1
- package/build/modules/api/CardAuthentification.js +360 -104
- package/build/modules/api/CardAuthentification.js.map +1 -1
- package/build/modules/api/KYCService.d.ts +3 -1
- package/build/modules/api/KYCService.d.ts.map +1 -1
- package/build/modules/api/KYCService.js +25 -24
- package/build/modules/api/KYCService.js.map +1 -1
- package/build/modules/camera/VisionCameraModule.js +2 -2
- package/build/modules/camera/VisionCameraModule.js.map +1 -1
- package/build/utils/cropByObb.d.ts +8 -0
- package/build/utils/cropByObb.d.ts.map +1 -1
- package/build/utils/cropByObb.js +20 -3
- package/build/utils/cropByObb.js.map +1 -1
- package/build/utils/pathToBase64.js +1 -1
- package/build/utils/pathToBase64.js.map +1 -1
- package/package.json +1 -1
- package/src/components/EnhancedCameraView.tsx +1 -1
- package/src/components/KYCElements/CountrySelectionTemplate.tsx +24 -52
- package/src/components/KYCElements/IDCardCapture.tsx +179 -109
- package/src/components/KYCElements/SelfieCaptureTemplate.tsx +2 -2
- package/src/hooks/useTemplateKYCFlow.tsx +1 -1
- package/src/modules/api/CardAuthentification.ts +450 -113
- package/src/modules/api/KYCService.ts +52 -39
- package/src/modules/camera/VisionCameraModule.ts +2 -2
- package/src/utils/cropByObb.ts +22 -3
- package/src/utils/pathToBase64.ts +1 -1
|
@@ -43,9 +43,8 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
43
43
|
const { t, locale } = useI18n();
|
|
44
44
|
const [showCamera, setShowCamera] = useState(false);
|
|
45
45
|
const [capturedImages, setCapturedImages] = useState<Record<string, IIDCardPayload>>(value || {});
|
|
46
|
-
const [cropImageUri, setCropImageUri] = useState<string>('');
|
|
47
|
-
const [currentSide, setCurrentSide] = useState<
|
|
48
|
-
// Stocker les bbox par côté pour pouvoir restaurer les images croppées
|
|
46
|
+
// const [cropImageUri, setCropImageUri] = useState<string>('');
|
|
47
|
+
const [currentSide, setCurrentSide] = useState<'front' | 'back'>('front');
|
|
49
48
|
const [bboxBySide, setBboxBySide] = useState<Record<string, IBbox>>({});
|
|
50
49
|
const [silentCaptureResult, setSilentCaptureResult] = useState<ISilentCaptureResult>({ success: false, isAnalyzing: false });
|
|
51
50
|
const [showQRModal, setShowQRModal] = useState(false);
|
|
@@ -97,6 +96,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
97
96
|
return countrySelectionData;
|
|
98
97
|
}, [countrySelectionData]);
|
|
99
98
|
|
|
99
|
+
// console.log();
|
|
100
100
|
|
|
101
101
|
// Synchroniser capturedImages avec value quand les données sont chargées (ex: reprise de session)
|
|
102
102
|
useEffect(() => {
|
|
@@ -131,7 +131,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
131
131
|
logger.log("cropImageUri", JSON.stringify(truncateFields({ box: silentCaptureResult }), null, 2));
|
|
132
132
|
if (capturedImages[currentSide]?.dir && silentCaptureResult?.bbox) {
|
|
133
133
|
cropImageWithBBox(capturedImages[currentSide].dir, silentCaptureResult.bbox)?.then((uri) => {
|
|
134
|
-
setCropImageUri(uri);
|
|
134
|
+
// setCropImageUri(uri);
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
137
|
}, [capturedImages[currentSide]?.dir, silentCaptureResult?.bbox])
|
|
@@ -145,9 +145,11 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
145
145
|
|
|
146
146
|
return {
|
|
147
147
|
aspectRatio: 4 / 3,
|
|
148
|
-
quality: 0.
|
|
148
|
+
quality: 0.7,
|
|
149
149
|
flashMode: 'auto' as const,
|
|
150
150
|
cameraType: 'back' as const,
|
|
151
|
+
autoFocus: 'on',
|
|
152
|
+
whiteBalance: 'auto',
|
|
151
153
|
allowRetake: true,
|
|
152
154
|
maxRetakes: 3,
|
|
153
155
|
overlay: {
|
|
@@ -166,13 +168,34 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
166
168
|
};
|
|
167
169
|
}, [selectedDocumentType, locale, component.instructions]);
|
|
168
170
|
|
|
169
|
-
const retakePicture = (
|
|
171
|
+
const retakePicture = (sideToRetake: 'front' | 'back') => {
|
|
172
|
+
// 1. Turn the camera back on and hide the stepper
|
|
170
173
|
setShowCamera(true);
|
|
171
174
|
actions.showCustomStepper(false);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
175
|
+
|
|
176
|
+
// 2. WIPE LOCAL STATE: Use functional update to prevent stale closures
|
|
177
|
+
setCapturedImages((prev) => {
|
|
178
|
+
const newState = { ...prev };
|
|
179
|
+
delete newState[sideToRetake];
|
|
180
|
+
return newState;
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
setSilentCaptureResult({
|
|
184
|
+
path: '',
|
|
185
|
+
success: false,
|
|
186
|
+
isAnalyzing: false,
|
|
187
|
+
error: '',
|
|
188
|
+
templatePath: '',
|
|
189
|
+
mrz: '',
|
|
190
|
+
bbox: undefined,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
if (value) {
|
|
195
|
+
const newValue = { ...value };
|
|
196
|
+
delete newValue[sideToRetake];
|
|
197
|
+
onValueChange(newValue);
|
|
198
|
+
}
|
|
176
199
|
};
|
|
177
200
|
|
|
178
201
|
|
|
@@ -301,26 +324,33 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
301
324
|
};
|
|
302
325
|
console.log("frontVerification params", verificationParams);
|
|
303
326
|
console.log("About to call frontVerification function");
|
|
327
|
+
|
|
304
328
|
const promise = frontVerification(verificationParams, env);
|
|
305
329
|
console.log("frontVerification promise created", promise);
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
330
|
+
|
|
331
|
+
promise.then((res: any) => {
|
|
332
|
+
logger.log("front verification result", truncateFields(res));
|
|
333
|
+
const bbox = res?.bbox || templateBbox;
|
|
334
|
+
|
|
309
335
|
setSilentCaptureResult((prev) => ({
|
|
310
336
|
...prev,
|
|
311
337
|
path: result.path,
|
|
312
338
|
templatePath: templatePath,
|
|
313
|
-
bbox: bbox,
|
|
314
|
-
|
|
339
|
+
bbox: bbox,
|
|
340
|
+
success: true,
|
|
341
|
+
mrz: res?.mrz ? JSON.stringify(res.mrz) : "",
|
|
342
|
+
isAnalyzing: false,
|
|
315
343
|
country: countryData?.code,
|
|
316
344
|
documentType: selectedDocumentType.type,
|
|
317
|
-
})
|
|
318
|
-
|
|
345
|
+
}));
|
|
346
|
+
|
|
319
347
|
// Stocker le bbox pour ce côté
|
|
320
348
|
if (bbox && typeof bbox === 'object') {
|
|
321
349
|
setBboxBySide((prev) => ({ ...prev, [currentSide]: bbox }));
|
|
322
350
|
}
|
|
323
351
|
|
|
352
|
+
}).catch((e: any) => {
|
|
353
|
+
|
|
324
354
|
}).catch((e: any) => {
|
|
325
355
|
console.log("error front verification", e);
|
|
326
356
|
logger.log("error front verification", truncateFields(e));
|
|
@@ -340,6 +370,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
340
370
|
} else {
|
|
341
371
|
const backRegionMappings = getCurrentSideVerification(currentSide);
|
|
342
372
|
logger.log("Calling backVerification", { templatePath, selectedDocumentType: selectedDocumentType.type, backRegionMappings });
|
|
373
|
+
|
|
343
374
|
backVerification({
|
|
344
375
|
path: result.path,
|
|
345
376
|
regionMapping: {
|
|
@@ -351,16 +382,21 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
351
382
|
currentSide: currentSide,
|
|
352
383
|
templatePath: templatePath,
|
|
353
384
|
mrzType: getCorrespondingMrzType(templatePath, backRegionMappings.regionMapping, backRegionMappings.key || '') || '',
|
|
354
|
-
}, env).then((
|
|
355
|
-
logger.log("back verification result", truncateFields(
|
|
356
|
-
const bbox =
|
|
385
|
+
}, env).then((res: any) => {
|
|
386
|
+
logger.log("back verification result", truncateFields(res));
|
|
387
|
+
const bbox = res?.bbox || templateBbox;
|
|
388
|
+
|
|
357
389
|
setSilentCaptureResult((prev) => ({
|
|
358
|
-
...prev,
|
|
359
|
-
|
|
390
|
+
...prev,
|
|
391
|
+
path: result.path,
|
|
392
|
+
bbox: bbox,
|
|
393
|
+
success: true,
|
|
394
|
+
mrz: res?.mrz ? JSON.stringify(res.mrz) : "",
|
|
395
|
+
isAnalyzing: false,
|
|
360
396
|
country: countryData?.code,
|
|
361
397
|
documentType: selectedDocumentType.type,
|
|
362
|
-
|
|
363
398
|
}));
|
|
399
|
+
|
|
364
400
|
// Stocker le bbox pour ce côté
|
|
365
401
|
if (bbox && typeof bbox === 'object') {
|
|
366
402
|
setBboxBySide((prev) => ({ ...prev, [currentSide]: bbox }));
|
|
@@ -375,37 +411,38 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
375
411
|
? t('kyc.idCardCapture.cardNotFullyInFrame')
|
|
376
412
|
: (e?.message || 'Erreur de détection du MRZ');
|
|
377
413
|
setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, templatePath: templatePath, success: false, error: errorMessage }));
|
|
378
|
-
})
|
|
414
|
+
});
|
|
379
415
|
}
|
|
380
416
|
|
|
381
417
|
}
|
|
382
418
|
}
|
|
383
419
|
|
|
384
|
-
// Handle capture
|
|
385
420
|
const handleCapture = async (result: { success: boolean; path?: string; error?: string }) => {
|
|
386
|
-
console.log("handleCapture", JSON.stringify(truncateFields({ result, silentCaptureResult }), null, 2));
|
|
387
|
-
|
|
388
421
|
if (silentCaptureResult.path) {
|
|
389
|
-
// Créer une image rognée avec tolérance de 10% pour l'envoi
|
|
390
422
|
let imagePathForUpload = silentCaptureResult.path;
|
|
391
423
|
if (silentCaptureResult.bbox) {
|
|
392
424
|
try {
|
|
393
|
-
logger.log("Début du rognage avec tolérance, URI original:", silentCaptureResult.path);
|
|
394
425
|
imagePathForUpload = await cropImageWithBBoxWithTolerance(silentCaptureResult.path, silentCaptureResult.bbox, 0.05);
|
|
395
|
-
logger.log("Image rognée avec tolérance créée pour l'envoi, URI final:", imagePathForUpload);
|
|
396
426
|
} catch (error) {
|
|
397
|
-
logger.log("Erreur lors du rognage avec tolérance, utilisation de l'image originale:", truncateFields(error));
|
|
398
|
-
// En cas d'erreur, on utilise l'image originale
|
|
399
427
|
imagePathForUpload = silentCaptureResult.path;
|
|
400
428
|
}
|
|
401
429
|
}
|
|
402
430
|
|
|
403
431
|
const base64 = await pathToBase64(imagePathForUpload);
|
|
404
432
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
433
|
+
// ✅ FIX: Use 'imagePathForUpload' (the cropped image) for the local display directory!
|
|
434
|
+
const newImages = {
|
|
435
|
+
...capturedImages,
|
|
436
|
+
[currentSide]: {
|
|
437
|
+
dir: imagePathForUpload, // <--- CHANGED THIS LINE
|
|
438
|
+
file: base64,
|
|
439
|
+
mrz: silentCaptureResult.mrz || "",
|
|
440
|
+
templatePath: silentCaptureResult.templatePath
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
|
|
408
444
|
setCapturedImages(newImages);
|
|
445
|
+
|
|
409
446
|
if (silentCaptureResult.country && silentCaptureResult.documentType) {
|
|
410
447
|
onValueChange({
|
|
411
448
|
...newImages,
|
|
@@ -425,10 +462,6 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
425
462
|
setShowCamera(false);
|
|
426
463
|
};
|
|
427
464
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
465
|
useEffect(() => {
|
|
433
466
|
actions.showCustomStepper(!showCamera);
|
|
434
467
|
}, [showCamera]);
|
|
@@ -531,7 +564,6 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
531
564
|
|
|
532
565
|
|
|
533
566
|
if (showCamera) {
|
|
534
|
-
|
|
535
567
|
return (
|
|
536
568
|
<View style={styles.cameraContainer}>
|
|
537
569
|
<EnhancedCameraView
|
|
@@ -548,54 +580,63 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
548
580
|
silentCaptureResult={silentCaptureResult}
|
|
549
581
|
captureStabilizationDelayMs={3000}
|
|
550
582
|
enableFlash={cameraConfig.flashMode === 'auto' || cameraConfig.flashMode === 'on'}
|
|
551
|
-
overlayComponent={
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
583
|
+
overlayComponent={
|
|
584
|
+
<IdCardOverlay
|
|
585
|
+
xMin={cameraConfig.overlay.bbox.xMin}
|
|
586
|
+
yMin={cameraConfig.overlay.bbox.yMin}
|
|
587
|
+
xMax={cameraConfig.overlay.bbox.xMax}
|
|
588
|
+
yMax={cameraConfig.overlay.bbox.yMax}
|
|
589
|
+
instructions={cameraConfig.overlay.guideText}
|
|
590
|
+
cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0 as number}
|
|
591
|
+
isSuccess={silentCaptureResult.success}
|
|
592
|
+
language={state.currentLanguage}
|
|
593
|
+
stepperProps={{
|
|
594
|
+
back: () => {
|
|
595
|
+
if (currentSide === 'back') {
|
|
596
|
+
setCurrentSide('front');
|
|
597
|
+
setShowCamera(false);
|
|
598
|
+
// Si une image front existe, on la restaure pour l'afficher
|
|
599
|
+
if (capturedImages['front']?.dir) {
|
|
600
|
+
// Restaurer l'état de capture du front pour afficher l'image
|
|
601
|
+
const frontImage = capturedImages['front'];
|
|
602
|
+
const frontBbox = bboxBySide['front'];
|
|
603
|
+
setSilentCaptureResult((prev) => ({
|
|
604
|
+
path: frontImage.dir,
|
|
605
|
+
success: true,
|
|
606
|
+
isAnalyzing: false,
|
|
607
|
+
error: '',
|
|
608
|
+
mrz: frontImage.mrz || '',
|
|
609
|
+
templatePath: frontImage.templatePath || '',
|
|
610
|
+
country: silentCaptureResult.country,
|
|
611
|
+
documentType: silentCaptureResult.documentType,
|
|
612
|
+
bbox: frontBbox // Restaurer le bbox pour recalculer le cropImageUri
|
|
613
|
+
}));
|
|
614
|
+
} else {
|
|
615
|
+
// Pas d'image front, on réinitialise
|
|
616
|
+
setSilentCaptureResult((prev) => ({ path: '', success: false, isAnalyzing: false, error: '', templatePath: '' }));
|
|
617
|
+
}
|
|
582
618
|
} else {
|
|
583
|
-
//
|
|
584
|
-
|
|
619
|
+
// Retour au composant précédent (country_selection)
|
|
620
|
+
actions.previousComponent();
|
|
585
621
|
}
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
totalSteps: state.template.components.length,
|
|
594
|
-
side: currentSide,
|
|
595
|
-
}}
|
|
596
|
-
/>
|
|
622
|
+
},
|
|
623
|
+
selectedDocumentType: selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : '',
|
|
624
|
+
step: state.currentComponentIndex + 1,
|
|
625
|
+
totalSteps: state.template.components.length,
|
|
626
|
+
side: currentSide,
|
|
627
|
+
}}
|
|
628
|
+
/>
|
|
597
629
|
}
|
|
598
630
|
/>
|
|
631
|
+
|
|
632
|
+
{silentCaptureResult.error ? (
|
|
633
|
+
<View style={styles.floatingErrorBanner}>
|
|
634
|
+
<Text style={styles.floatingErrorText}>
|
|
635
|
+
{silentCaptureResult.error}
|
|
636
|
+
</Text>
|
|
637
|
+
</View>
|
|
638
|
+
) : null}
|
|
639
|
+
|
|
599
640
|
</View>
|
|
600
641
|
);
|
|
601
642
|
}
|
|
@@ -614,57 +655,62 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
614
655
|
</Text>
|
|
615
656
|
|
|
616
657
|
<View style={{ alignItems: 'center', justifyContent: 'center', flexDirection: "column", gap: 16 }}>
|
|
617
|
-
|
|
658
|
+
{silentCaptureResult?.error === 'TOO_FAR_AWAY' && (
|
|
659
|
+
<View style={{
|
|
660
|
+
backgroundColor: '#FF9500',
|
|
661
|
+
padding: 12,
|
|
662
|
+
borderRadius: 8,
|
|
663
|
+
width: '100%',
|
|
664
|
+
shadowColor: '#000',
|
|
665
|
+
shadowOffset: { width: 0, height: 2 },
|
|
666
|
+
shadowOpacity: 0.2,
|
|
667
|
+
shadowRadius: 4,
|
|
668
|
+
elevation: 4
|
|
669
|
+
}}>
|
|
670
|
+
<Text style={{ color: 'white', fontWeight: 'bold', textAlign: 'center', fontSize: 16 }}>
|
|
671
|
+
{state.currentLanguage === "en"
|
|
672
|
+
? "Move the document closer to the camera."
|
|
673
|
+
: "Veuillez rapprocher le document de la caméra."}
|
|
674
|
+
</Text>
|
|
675
|
+
</View>
|
|
676
|
+
)}
|
|
677
|
+
|
|
678
|
+
<View
|
|
618
679
|
style={{
|
|
619
680
|
width: '100%',
|
|
620
681
|
height: 200,
|
|
621
682
|
borderRadius: 12,
|
|
622
683
|
padding: 1,
|
|
623
684
|
overflow: 'hidden',
|
|
624
|
-
// Shadow for iOS
|
|
625
685
|
shadowColor: '#000',
|
|
626
686
|
shadowOffset: { width: 0, height: 4 },
|
|
627
687
|
shadowOpacity: 0.18,
|
|
628
688
|
shadowRadius: 8,
|
|
629
|
-
// Shadow for Android
|
|
630
689
|
elevation: 8,
|
|
631
|
-
backgroundColor: '#
|
|
690
|
+
backgroundColor: '#000',
|
|
632
691
|
}}
|
|
633
692
|
>
|
|
634
|
-
{
|
|
693
|
+
{capturedImages[currentSide]?.dir ? (
|
|
635
694
|
<Image
|
|
636
|
-
source={{ uri:
|
|
695
|
+
source={{ uri: capturedImages[currentSide].dir }}
|
|
637
696
|
style={{
|
|
638
697
|
width: '100%',
|
|
639
|
-
height:
|
|
698
|
+
height: '100%',
|
|
640
699
|
borderRadius: 12,
|
|
641
|
-
resizeMode: '
|
|
700
|
+
resizeMode: 'contain',
|
|
642
701
|
}}
|
|
643
702
|
/>
|
|
644
|
-
) :
|
|
645
|
-
{!cropImageUri && silentCaptureResult.path ? (
|
|
703
|
+
) : silentCaptureResult.path ? (
|
|
646
704
|
<Image
|
|
647
705
|
source={{ uri: silentCaptureResult.path }}
|
|
648
706
|
style={{
|
|
649
707
|
width: '100%',
|
|
650
|
-
height:
|
|
651
|
-
borderRadius: 12,
|
|
652
|
-
resizeMode: 'cover',
|
|
653
|
-
}}
|
|
654
|
-
/>
|
|
655
|
-
) : null}
|
|
656
|
-
{!cropImageUri && !silentCaptureResult.path && capturedImages[currentSide]?.dir ? (
|
|
657
|
-
<Image
|
|
658
|
-
source={{ uri: capturedImages[currentSide].dir }}
|
|
659
|
-
style={{
|
|
660
|
-
width: '100%',
|
|
661
|
-
height: 200,
|
|
708
|
+
height: '100%',
|
|
662
709
|
borderRadius: 12,
|
|
663
|
-
resizeMode: '
|
|
710
|
+
resizeMode: 'contain',
|
|
664
711
|
}}
|
|
665
712
|
/>
|
|
666
713
|
) : null}
|
|
667
|
-
|
|
668
714
|
</View>
|
|
669
715
|
{/* Capture button si aucune image n'a été capturée */}
|
|
670
716
|
{!capturedImages[currentSide]?.dir && (
|
|
@@ -701,7 +747,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({
|
|
|
701
747
|
setShowCamera(true);
|
|
702
748
|
setCurrentSide('back');
|
|
703
749
|
setSilentCaptureResult((prev) => ({ path: '', success: false, isAnalyzing: false, error: '', mrz: '', templatePath: '' }));
|
|
704
|
-
setCropImageUri('');
|
|
750
|
+
// setCropImageUri('');
|
|
705
751
|
}
|
|
706
752
|
}}
|
|
707
753
|
variant="primary"
|
|
@@ -980,4 +1026,28 @@ const styles = StyleSheet.create({
|
|
|
980
1026
|
color: '#666',
|
|
981
1027
|
fontWeight: '600',
|
|
982
1028
|
},
|
|
1029
|
+
floatingErrorBanner: {
|
|
1030
|
+
position: 'absolute',
|
|
1031
|
+
top: 60, // Pushes it down slightly from the very top of the screen
|
|
1032
|
+
left: '10%',
|
|
1033
|
+
right: '10%',
|
|
1034
|
+
backgroundColor: 'rgba(220, 38, 38, 0.95)', // Bright red
|
|
1035
|
+
paddingVertical: 12,
|
|
1036
|
+
paddingHorizontal: 16,
|
|
1037
|
+
borderRadius: 8,
|
|
1038
|
+
alignItems: 'center',
|
|
1039
|
+
justifyContent: 'center',
|
|
1040
|
+
shadowColor: '#000',
|
|
1041
|
+
shadowOffset: { width: 0, height: 4 },
|
|
1042
|
+
shadowOpacity: 0.3,
|
|
1043
|
+
shadowRadius: 5,
|
|
1044
|
+
elevation: 8,
|
|
1045
|
+
zIndex: 100,
|
|
1046
|
+
},
|
|
1047
|
+
floatingErrorText: {
|
|
1048
|
+
color: 'white',
|
|
1049
|
+
fontSize: 14,
|
|
1050
|
+
fontWeight: '700',
|
|
1051
|
+
textAlign: 'center',
|
|
1052
|
+
},
|
|
983
1053
|
});
|
|
@@ -76,9 +76,9 @@ export const SelfieCaptureTemplate: React.FC<SelfieCaptureTemplateProps> = ({
|
|
|
76
76
|
const getOrientationLabel = (orientation: OrientationType): string => {
|
|
77
77
|
switch (orientation) {
|
|
78
78
|
case 'center':
|
|
79
|
-
return state.currentLanguage === "en" ? "Front
|
|
79
|
+
return state.currentLanguage === "en" ? "Front Profile Selfie" : "Selfie de face";
|
|
80
80
|
case 'left':
|
|
81
|
-
return state.currentLanguage === "en" ? "Left
|
|
81
|
+
return state.currentLanguage === "en" ? "Left Profile Selfie" : "Selfie profil gauche";
|
|
82
82
|
case 'right':
|
|
83
83
|
return state.currentLanguage === "en" ? "Right Profile Selfie" : "Selfie profil droit";
|
|
84
84
|
default:
|
|
@@ -822,7 +822,7 @@ export const useTemplateKYCFlow = (
|
|
|
822
822
|
isProcessing: false,
|
|
823
823
|
errors: {
|
|
824
824
|
...prev.errors,
|
|
825
|
-
[currentComp.id]: state.currentLanguage === "en" ? "please complete this step before
|
|
825
|
+
[currentComp.id]: state.currentLanguage === "en" ? "please complete this step before moving on" : " 'Veuillez compléter cette étape avant de continuer'"
|
|
826
826
|
}
|
|
827
827
|
}));
|
|
828
828
|
return;
|