@sanctum-key/react-native-sdk 1.0.10 → 1.0.12

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 (166) hide show
  1. package/README.md +3 -3
  2. package/android/build/.transforms/{c9d62bb333688ab562f51958998d5a48 → 9e34a0354bf8964d60c4c1392f5aa5b2}/transformed/classes/classes_dex/classes.dex +0 -0
  3. package/android/build/generated/source/buildConfig/debug/kyc/{SanctumKey → sanctumkey}/com/BuildConfig.java +2 -2
  4. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +1 -1
  5. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +1 -1
  6. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  7. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  8. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/xml_file_paths.xml.flat +0 -0
  9. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +2 -2
  10. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +1 -1
  11. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +1 -1
  12. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +1 -1
  13. package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +1 -1
  14. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/kyc/{SanctumKey → sanctumkey}/com/BuildConfig.class +0 -0
  15. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +42 -42
  16. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +1 -1
  17. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  18. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +1 -1
  19. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  20. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  21. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  22. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  23. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  24. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  25. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  26. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  27. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  28. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  29. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  30. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  31. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  32. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  33. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  34. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  35. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  36. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  37. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  38. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  39. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  40. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  41. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  42. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  43. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  44. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  45. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  46. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  47. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  48. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  49. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  50. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  51. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  52. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  53. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  54. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  55. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  56. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  57. package/android/build/outputs/logs/manifest-merger-debug-report.txt +52 -52
  58. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  59. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$1$5$1.class +0 -0
  60. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$1$5$2.class +0 -0
  61. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$1.class +0 -0
  62. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$2.class +0 -0
  63. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$3.class +0 -0
  64. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$4.class +0 -0
  65. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$5.class +0 -0
  66. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$6.class +0 -0
  67. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunctionWithPromise$1.class +0 -0
  68. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunctionWithPromise$2.class +0 -0
  69. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunctionWithPromise$3.class +0 -0
  70. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunctionWithPromise$4.class +0 -0
  71. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$$inlined$View$1.class +0 -0
  72. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$lambda$4$$inlined$Prop$1.class +0 -0
  73. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule$definition$lambda$5$lambda$4$$inlined$Prop$2.class +0 -0
  74. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkModule.class +0 -0
  75. package/android/build/tmp/kotlin-classes/debug/kyc/{SanctumKey → sanctumkey}/com/SanctumKeySdkView.class +0 -0
  76. package/android/build.gradle +2 -2
  77. package/android/src/main/AndroidManifest.xml +1 -1
  78. package/android/src/main/java/kyc/{transfergratis/com/TransfergratisSdkModule.kt → sanctumkey/com/SanctumKeySdkModule.kt} +21 -18
  79. package/android/src/main/java/kyc/{transfergratis/com/TransfergratisSdkView.kt → sanctumkey/com/SanctumKeySdkView.kt} +2 -2
  80. package/build/package.json +5 -5
  81. package/build/src/App.d.ts +2 -2
  82. package/build/src/App.d.ts.map +1 -1
  83. package/build/src/App.js +2 -2
  84. package/build/src/App.js.map +1 -1
  85. package/build/src/{TransfergratisSdk.types.d.ts → SanctumKeySdk.types.d.ts} +3 -3
  86. package/build/src/SanctumKeySdk.types.d.ts.map +1 -0
  87. package/build/src/SanctumKeySdk.types.js +2 -0
  88. package/build/src/SanctumKeySdk.types.js.map +1 -0
  89. package/build/src/{TransfergratisSdkModule.d.ts → SanctumKeySdkModule.d.ts} +4 -4
  90. package/build/src/SanctumKeySdkModule.d.ts.map +1 -0
  91. package/build/src/{TransfergratisSdkModule.js → SanctumKeySdkModule.js} +2 -2
  92. package/build/src/SanctumKeySdkModule.js.map +1 -0
  93. package/build/src/{TransfergratisSdkModule.web.d.ts → SanctumKeySdkModule.web.d.ts} +4 -4
  94. package/build/src/SanctumKeySdkModule.web.d.ts.map +1 -0
  95. package/build/src/{TransfergratisSdkModule.web.js → SanctumKeySdkModule.web.js} +3 -3
  96. package/build/src/SanctumKeySdkModule.web.js.map +1 -0
  97. package/build/src/SanctumKeySdkView.d.ts +4 -0
  98. package/build/src/SanctumKeySdkView.d.ts.map +1 -0
  99. package/build/src/SanctumKeySdkView.js +7 -0
  100. package/build/src/SanctumKeySdkView.js.map +1 -0
  101. package/build/src/SanctumKeySdkView.web.d.ts +4 -0
  102. package/build/src/SanctumKeySdkView.web.d.ts.map +1 -0
  103. package/build/src/{TransfergratisSdkView.web.js → SanctumKeySdkView.web.js} +2 -2
  104. package/build/src/SanctumKeySdkView.web.js.map +1 -0
  105. package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  106. package/build/src/components/KYCElements/IDCardCapture.js +132 -175
  107. package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
  108. package/build/src/components/NativeCameraView.js +1 -1
  109. package/build/src/components/NativeCameraView.js.map +1 -1
  110. package/build/src/components/TemplateKYCExample.d.ts +4 -3
  111. package/build/src/components/TemplateKYCExample.d.ts.map +1 -1
  112. package/build/src/components/TemplateKYCExample.js +2 -2
  113. package/build/src/components/TemplateKYCExample.js.map +1 -1
  114. package/build/src/config/allowedDomains.js +6 -6
  115. package/build/src/config/allowedDomains.js.map +1 -1
  116. package/build/src/index.d.ts +3 -3
  117. package/build/src/index.d.ts.map +1 -1
  118. package/build/src/index.js +3 -3
  119. package/build/src/index.js.map +1 -1
  120. package/build/src/modules/api/KYCService.d.ts.map +1 -1
  121. package/build/src/modules/api/KYCService.js +9 -4
  122. package/build/src/modules/api/KYCService.js.map +1 -1
  123. package/build/src/modules/camera/NativeCameraModule.js +17 -17
  124. package/build/src/modules/camera/NativeCameraModule.js.map +1 -1
  125. package/build/src/web/WebKYCEntry.d.ts +2 -2
  126. package/build/src/web/WebKYCEntry.d.ts.map +1 -1
  127. package/build/src/web/WebKYCEntry.js +3 -2
  128. package/build/src/web/WebKYCEntry.js.map +1 -1
  129. package/expo-module.config.json +3 -3
  130. package/ios/TransfergratisSdk.podspec +2 -2
  131. package/ios/TransfergratisSdkModule.swift +12 -12
  132. package/package.json +5 -5
  133. package/src/App.tsx +2 -2
  134. package/src/{TransfergratisSdk.types.ts → SanctumKeySdk.types.ts} +2 -2
  135. package/src/{TransfergratisSdkModule.ts → SanctumKeySdkModule.ts} +3 -3
  136. package/src/{TransfergratisSdkModule.web.ts → SanctumKeySdkModule.web.ts} +3 -3
  137. package/src/SanctumKeySdkView.tsx +11 -0
  138. package/src/{TransfergratisSdkView.web.tsx → SanctumKeySdkView.web.tsx} +2 -2
  139. package/src/components/KYCElements/IDCardCapture.tsx +227 -286
  140. package/src/components/NativeCameraView.tsx +1 -1
  141. package/src/components/TemplateKYCExample.tsx +23 -4
  142. package/src/config/allowedDomains.ts +6 -6
  143. package/src/i18n/README.md +1 -1
  144. package/src/index.ts +3 -3
  145. package/src/modules/api/KYCService.ts +10 -4
  146. package/src/modules/camera/NativeCameraModule.ts +17 -17
  147. package/src/web/WebKYCEntry.tsx +3 -3
  148. package/android/build/.transforms/ab90740579f5bd05b27b4343ada2d1c9/transformed/classes/classes_dex/classes.dex +0 -0
  149. package/android/build/.transforms/c9d62bb333688ab562f51958998d5a48/results.bin +0 -1
  150. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/BuildConfig.class.uniqueId0 +0 -0
  151. package/build/src/TransfergratisSdk.types.d.ts.map +0 -1
  152. package/build/src/TransfergratisSdk.types.js +0 -2
  153. package/build/src/TransfergratisSdk.types.js.map +0 -1
  154. package/build/src/TransfergratisSdkModule.d.ts.map +0 -1
  155. package/build/src/TransfergratisSdkModule.js.map +0 -1
  156. package/build/src/TransfergratisSdkModule.web.d.ts.map +0 -1
  157. package/build/src/TransfergratisSdkModule.web.js.map +0 -1
  158. package/build/src/TransfergratisSdkView.d.ts +0 -4
  159. package/build/src/TransfergratisSdkView.d.ts.map +0 -1
  160. package/build/src/TransfergratisSdkView.js +0 -7
  161. package/build/src/TransfergratisSdkView.js.map +0 -1
  162. package/build/src/TransfergratisSdkView.web.d.ts +0 -4
  163. package/build/src/TransfergratisSdkView.web.d.ts.map +0 -1
  164. package/build/src/TransfergratisSdkView.web.js.map +0 -1
  165. package/src/TransfergratisSdkView.tsx +0 -11
  166. /package/android/build/.transforms/{ab90740579f5bd05b27b4343ada2d1c9 → 9e34a0354bf8964d60c4c1392f5aa5b2}/results.bin +0 -0
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
- import { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator } from 'react-native';
2
+ import { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity } from 'react-native'; // 🚨 Added TouchableOpacity
3
3
  import { showAlert } from '../../utils/platformAlert';
4
4
  import { EnhancedCameraView } from '../EnhancedCameraView';
5
5
  import { GovernmentDocumentTypeShorted, GovernmentDocumentTypeBackend } from '../../types/KYC.types';
@@ -13,12 +13,7 @@ import { getDocumentTypeInfo } from '../../utils/get-document-type-info';
13
13
  import pathToBase64 from '../../utils/pathToBase64';
14
14
  import { cropByObb, cropImageWithBBoxWithTolerance, getObbConfidence, OBB_CONFIDENCE_THRESHOLD } from '../../utils/cropByObb';
15
15
  import REGION_MAPPING from '../../config/region_mapping.json';
16
- // 🌍 Map ISO codes to exact JSON root keys to ensure perfect dictionary lookups
17
- const ISO_TO_COUNTRY_NAME = {
18
- 'KE': 'Kenya', 'CM': 'Cameroon', 'NG': 'Nigeria', 'CA': 'Canada',
19
- 'FR': 'France', 'GH': 'Ghana', 'ZA': 'South Africa', 'GB': 'Britain',
20
- 'CI': 'Ivory Coast', 'SN': 'Senegal', 'TG': 'Togo', 'ML': 'Mali'
21
- };
16
+ const ISO_TO_COUNTRY_NAME = { 'KE': 'Kenya', 'CM': 'Cameroon', 'NG': 'Nigeria', 'CA': 'Canada', 'FR': 'France', 'GH': 'Ghana', 'ZA': 'South Africa', 'GB': 'Britain', 'CI': 'Ivory Coast', 'SN': 'Senegal', 'TG': 'Togo', 'ML': 'Mali' };
22
17
  export const IDCardCapture = ({ component, value = {}, onValueChange, error, language = 'en' }) => {
23
18
  const { t, locale } = useI18n();
24
19
  const [showCamera, setShowCamera] = useState(false);
@@ -28,10 +23,9 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
28
23
  const [silentCaptureResult, setSilentCaptureResult] = useState({ success: false, isAnalyzing: false });
29
24
  const [isProcessingCapture, setIsProcessingCapture] = useState(false);
30
25
  const [processingImagePath, setProcessingImagePath] = useState(null);
31
- const documentTypeMapping = {
32
- 'nationalId': 'national_id', 'passport': 'passport', 'driversLicense': 'drivers_licence',
33
- 'residencePermit': 'permanent_residence', 'healthInsuranceCard': 'health_insurance_card',
34
- };
26
+ // 🚨 ADDED: Key to force camera re-mount
27
+ const [cameraKey, setCameraKey] = useState(0);
28
+ const documentTypeMapping = { 'nationalId': 'national_id', 'passport': 'passport', 'driversLicense': 'drivers_licence', 'residencePermit': 'permanent_residence', 'healthInsuranceCard': 'health_insurance_card', };
35
29
  const { actions, state, env } = useTemplateKYCFlowContext();
36
30
  const getLocalizedText = (text) => {
37
31
  if (text && typeof text[currentSide] === 'object' && text[currentSide][locale])
@@ -50,6 +44,14 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
50
44
  return { type: mappedType, region: countrySelectionData.region || 'root' };
51
45
  }, [countrySelectionData, documentTypeMapping]);
52
46
  const countryData = useMemo(() => countrySelectionData, [countrySelectionData]);
47
+ const [isRebootingCamera, setIsRebootingCamera] = useState(false);
48
+ const refreshCamera = () => {
49
+ setIsRebootingCamera(true);
50
+ setTimeout(() => {
51
+ setCameraKey(prev => prev + 1);
52
+ setIsRebootingCamera(false);
53
+ }, 500);
54
+ };
53
55
  useEffect(() => {
54
56
  if (value && Object.keys(value).length > 0) {
55
57
  if (JSON.stringify(value) !== JSON.stringify(capturedImages)) {
@@ -58,21 +60,14 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
58
60
  const currentImageData = updatedImages[currentSide];
59
61
  if (currentImageData?.dir) {
60
62
  setSilentCaptureResult(prev => ({
61
- ...prev,
62
- path: currentImageData.dir,
63
- success: true,
64
- isAnalyzing: false,
65
- mrz: currentImageData.mrz || '',
66
- templatePath: currentImageData.templatePath || '',
63
+ ...prev, path: currentImageData.dir, success: true, isAnalyzing: false, mrz: currentImageData.mrz || '', templatePath: currentImageData.templatePath || '',
67
64
  }));
68
65
  }
69
66
  }
70
67
  }
71
68
  }, [value, currentSide]);
72
69
  const cameraConfig = useMemo(() => {
73
- const instructions = selectedDocumentType
74
- ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).instructions.en : getDocumentTypeInfo(selectedDocumentType.type).instructions.fr)
75
- : getLocalizedText(component.instructions);
70
+ const instructions = selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).instructions.en : getDocumentTypeInfo(selectedDocumentType.type).instructions.fr) : getLocalizedText(component.instructions);
76
71
  return {
77
72
  cameraType: 'back', flashMode: 'auto',
78
73
  overlay: { guideText: instructions, bbox: { xMin: 15, yMin: 20, xMax: 85, yMax: 70, borderColor: '#2DBD60', borderWidth: 3, cornerRadius: 8 } }
@@ -99,7 +94,6 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
99
94
  const rawCountryName = ISO_TO_COUNTRY_NAME[countryData?.code || ''] || countryData?.code || countryKey;
100
95
  const baseMapping = REGION_MAPPING.regionMapping || REGION_MAPPING;
101
96
  let countryMapping = baseMapping[rawCountryName];
102
- // Fallback search in case of case mismatches
103
97
  if (!countryMapping) {
104
98
  const foundKey = Object.keys(baseMapping).find(k => k.toLowerCase() === rawCountryName.toLowerCase() || k.toLowerCase() === countryKey.toLowerCase());
105
99
  if (foundKey)
@@ -194,7 +188,6 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
194
188
  return;
195
189
  if (result.success && result.path) {
196
190
  setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: true, success: false, error: '' }));
197
- // 🚨 Force a template fetch if we haven't successfully saved the current side yet
198
191
  let templatePath = capturedImages[currentSide]?.templatePath || '';
199
192
  let templateBbox;
200
193
  let templateResponse;
@@ -235,19 +228,7 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
235
228
  matchedBackAuthMethod = 'MRZ';
236
229
  }
237
230
  const backMrzType = getCorrespondingMrzType(templatePath, regionMappings.regionMapping, regionMappings.key || '') || 'TD1';
238
- verificationRes = await backVerification({
239
- path: result.path,
240
- regionMapping: {
241
- authMethod: matchedBackAuthMethod ? [matchedBackAuthMethod] : regionMappings.authMethod,
242
- mrzTypes: regionMappings.mrzTypes
243
- },
244
- selectedDocumentType: GovernmentDocumentTypeShorted[selectedDocumentType.type] || '',
245
- code: countryData?.code || '',
246
- currentSide,
247
- templatePath,
248
- mrzType: backMrzType,
249
- templateResponse
250
- }, env);
231
+ verificationRes = await backVerification({ path: result.path, regionMapping: { authMethod: matchedBackAuthMethod ? [matchedBackAuthMethod] : regionMappings.authMethod, mrzTypes: regionMappings.mrzTypes }, selectedDocumentType: GovernmentDocumentTypeShorted[selectedDocumentType.type] || '', code: countryData?.code || '', currentSide, templatePath, mrzType: backMrzType, templateResponse }, env);
251
232
  }
252
233
  const bbox = verificationRes?.bbox || templateBbox;
253
234
  const mrz = verificationRes?.mrz ? JSON.stringify(verificationRes.mrz) : "";
@@ -269,7 +250,9 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
269
250
  setShowCamera(false);
270
251
  setIsProcessingCapture(false);
271
252
  };
272
- useEffect(() => { actions.showCustomStepper(!showCamera); }, [showCamera]);
253
+ useEffect(() => {
254
+ actions.showCustomStepper(!showCamera);
255
+ }, [showCamera]);
273
256
  if (!countrySelectionData || !selectedDocumentType) {
274
257
  return (<View style={styles.root}>
275
258
  <View style={styles.previewContainer}>
@@ -283,41 +266,31 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
283
266
  // --- CAMERA RENDER ---
284
267
  if (showCamera) {
285
268
  const isBusy = isProcessingCapture;
269
+ if (isRebootingCamera) {
270
+ return (<View style={[styles.root, { justifyContent: 'center', alignItems: 'center', backgroundColor: '#000' }]}>
271
+ <ActivityIndicator size="large" color="#2DBD60"/>
272
+ <Text style={{ color: 'white', marginTop: 20, fontSize: 16 }}>Initializing Camera...</Text>
273
+ </View>);
274
+ }
286
275
  return (<View style={styles.root}>
287
- <View style={styles.cameraWrapper}>
288
-
289
- {/* Web/Desktop Clean Header */}
290
- <View style={styles.headerContainer}>
291
- <Text style={styles.headerTitle}>
292
- {selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : ''}
276
+ <View style={[styles.cameraWrapper, { flex: 1, minHeight: 400 }]}>
277
+
278
+ <View style={styles.headerContainer}>
279
+ <Text style={styles.headerTitle}>
280
+ {selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : ''}
281
+ </Text>
282
+ <View style={styles.stepBadge}>
283
+ <Text style={styles.stepText}>
284
+ {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}
293
285
  </Text>
294
- <View style={styles.stepBadge}>
295
- <Text style={styles.stepText}>
296
- {t('kyc.idCardCapture.captureTitle', { side: currentSide === 'front' ? locale === 'en' ? 'Front' : 'Recto' : locale === 'en' ? 'Back' : 'Verso' })}
297
- </Text>
298
- </View>
299
286
  </View>
300
-
301
- <View style={styles.cameraFeedContainer}>
302
- <EnhancedCameraView key={currentSide} showCamera={true} isProcessing={isBusy} cameraType={cameraConfig.cameraType} style={styles.camera} onError={handleError} onSilentCapture={handleSilentCapture} silentCaptureResult={silentCaptureResult} overlayComponent={<>
303
- {!isBusy && silentCaptureResult.isAnalyzing && (<View style={styles.topAnalyzingPillContainer}>
304
- <View style={styles.topAnalyzingPill}>
305
- <ActivityIndicator size="small" color="white"/>
306
- <Text style={styles.analyzingPillText}>
307
- {state.currentLanguage === 'en' ? 'Scanning...' : 'Analyse...'}
308
- </Text>
309
- </View>
310
- </View>)}
311
- {isBusy && (<View style={StyleSheet.absoluteFillObject}>
312
- {processingImagePath && (<Image source={{ uri: processingImagePath.startsWith('file://') ? processingImagePath : `file://${processingImagePath}` }} style={StyleSheet.absoluteFillObject} resizeMode="cover"/>)}
313
- <View style={styles.processingOverlay}>
314
- <ActivityIndicator size="large" color="#2DBD60"/>
315
- <Text style={styles.processingText}>
316
- {state.currentLanguage === 'en' ? 'Perfect!\nProcessing Document...' : 'Parfait!\nTraitement du document...'}
317
- </Text>
318
- </View>
319
- </View>)}
320
- <IdCardOverlay xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax} instructions={cameraConfig.overlay.guideText} cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0} isSuccess={silentCaptureResult.success} language={state.currentLanguage} stepperProps={{
287
+ </View>
288
+
289
+ <View style={[styles.cameraFeedContainer, { flex: 1, backgroundColor: '#000' }]}>
290
+
291
+ <EnhancedCameraView key={`${currentSide}-${cameraKey}`} showCamera={true} isProcessing={isBusy} cameraType={cameraConfig.cameraType} style={styles.absoluteFillObject} onError={handleError} onSilentCapture={handleSilentCapture} silentCaptureResult={silentCaptureResult} overlayComponent={<>
292
+ {/* We ONLY put the ID frame here, because if the camera fails, we don't care if the frame fails too */}
293
+ <IdCardOverlay xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax} instructions={cameraConfig.overlay.guideText} cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0} isSuccess={silentCaptureResult.success} language={state.currentLanguage} stepperProps={{
321
294
  back: () => {
322
295
  if (currentSide === 'back') {
323
296
  setCurrentSide('front');
@@ -339,14 +312,46 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
339
312
  selectedDocumentType: selectedDocumentType ? (locale === 'en' ? getDocumentTypeInfo(selectedDocumentType.type).name.en : getDocumentTypeInfo(selectedDocumentType.type).name.fr) : '',
340
313
  step: state.currentComponentIndex + 1, totalSteps: state.template.components.length, side: currentSide,
341
314
  }}/>
342
- </>}/>
343
- {/* Elegant Floating Error Banner below the cutout */}
344
- {silentCaptureResult.error && !isBusy ? (<View style={styles.floatingErrorBanner}>
345
- <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>
346
- </View>) : null}
347
- </View>
315
+ </>}/>
316
+
317
+
318
+ {!isBusy && silentCaptureResult.isAnalyzing && (<View style={styles.topAnalyzingPillContainer}>
319
+ <View style={styles.topAnalyzingPill}>
320
+ <ActivityIndicator size="small" color="white"/>
321
+ <Text style={styles.analyzingPillText}>
322
+ {state.currentLanguage === 'en' ? 'Scanning...' : 'Analyse...'}
323
+ </Text>
324
+ </View>
325
+ </View>)}
326
+
327
+ {isBusy && (<View style={[StyleSheet.absoluteFillObject, { zIndex: 9999 }]}>
328
+ {processingImagePath && (<Image source={{ uri: processingImagePath.startsWith('file://') ? processingImagePath : `file://${processingImagePath}` }} style={StyleSheet.absoluteFillObject} resizeMode="cover"/>)}
329
+ <View style={styles.processingOverlay}>
330
+ <ActivityIndicator size="large" color="#2DBD60"/>
331
+ <Text style={styles.processingText}>
332
+ {state.currentLanguage === 'en' ? 'Perfect!\nProcessing Document...' : 'Parfait!\nTraitement du document...'}
333
+ </Text>
334
+ </View>
335
+ </View>)}
336
+
337
+ {!isBusy && (<View style={styles.escapeHatchContainer}>
338
+ {/* Refresh Button */}
339
+ <TouchableOpacity style={styles.fallbackRefreshButton} onPress={refreshCamera}>
340
+ <Text style={styles.fallbackRefreshText}>↻ Refresh Camera</Text>
341
+ </TouchableOpacity>
342
+
343
+ <TouchableOpacity style={[styles.fallbackRefreshButton, { marginTop: 15, backgroundColor: 'rgba(220, 38, 38, 0.8)', borderColor: '#DC2626' }]} onPress={() => setShowCamera(false)}>
344
+ <Text style={styles.fallbackRefreshText}>Cancel / Go Back</Text>
345
+ </TouchableOpacity>
346
+ </View>)}
347
+
348
+ {silentCaptureResult.error && !isBusy ? (<View style={[styles.floatingErrorBanner, { zIndex: 10000 }]}>
349
+ <Text style={styles.floatingErrorText}>⚠️ {silentCaptureResult.error}</Text>
350
+ </View>) : null}
351
+
348
352
  </View>
349
- </View>);
353
+ </View>
354
+ </View>);
350
355
  }
351
356
  return (<View style={styles.root}>
352
357
  <View style={styles.previewContainer}>
@@ -395,121 +400,39 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
395
400
  };
396
401
  const styles = StyleSheet.create({
397
402
  root: {
398
- flex: 1,
399
- width: '100%',
400
- backgroundColor: 'transparent',
401
- alignSelf: 'center',
402
- ...(Platform.OS === 'web'
403
- ? {
404
- minHeight: '85vh',
405
- justifyContent: 'center',
406
- alignItems: 'center',
407
- // Note: backdropFilter is valid in React Native Web but TS might complain, cast safely
408
- backdropFilter: 'blur(8px)'
409
- }
410
- : {})
403
+ flex: 1, width: '100%', backgroundColor: 'transparent', alignSelf: 'center',
404
+ ...(Platform.OS === 'web' ? { minHeight: '85vh', justifyContent: 'center', alignItems: 'center', backdropFilter: 'blur(8px)' } : {})
411
405
  },
412
406
  cameraWrapper: {
413
- width: '100%',
414
- backgroundColor: '#FFFFFF',
415
- overflow: 'hidden',
416
- ...(Platform.OS === 'web'
417
- ? {
418
- maxWidth: 500,
419
- height: 700,
420
- maxHeight: '90vh', // TypeScript will now ignore this thanks to the cast below
421
- borderRadius: 24,
422
- shadowColor: '#000',
423
- shadowOffset: { width: 0, height: 20 },
424
- shadowOpacity: 0.25,
425
- shadowRadius: 35,
426
- elevation: 24,
427
- } // 🚨 CAST TO ANY
428
- : {
429
- flex: 1,
430
- })
407
+ width: '100%', backgroundColor: '#FFFFFF', overflow: 'hidden',
408
+ ...(Platform.OS === 'web' ? { maxWidth: 500, height: 700, maxHeight: '90vh', borderRadius: 24, shadowColor: '#000', shadowOffset: { width: 0, height: 20 }, shadowOpacity: 0.25, shadowRadius: 35, elevation: 24, } : { flex: 1, })
431
409
  },
432
410
  headerContainer: {
433
- flexDirection: 'row',
434
- alignItems: 'center',
435
- justifyContent: 'space-between',
436
- paddingHorizontal: 24,
437
- paddingVertical: 18,
438
- backgroundColor: '#FFFFFF',
439
- borderBottomWidth: 1,
440
- borderBottomColor: '#F1F5F9',
441
- zIndex: 10,
442
- // Mobile hidden, Web visible to replace floating text
411
+ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 24, paddingVertical: 18, backgroundColor: '#FFFFFF', borderBottomWidth: 1, borderBottomColor: '#F1F5F9', zIndex: 10,
443
412
  ...(Platform.OS !== 'web' ? { display: 'none' } : {})
444
413
  },
445
- headerTitle: {
446
- fontSize: 18,
447
- fontWeight: '700',
448
- color: '#0F172A',
449
- },
450
- stepBadge: {
451
- backgroundColor: '#F1F5F9',
452
- paddingHorizontal: 12,
453
- paddingVertical: 6,
454
- borderRadius: 20,
455
- },
456
- stepText: {
457
- fontSize: 13,
458
- fontWeight: '600',
459
- color: '#64748B',
460
- },
461
- cameraFeedContainer: {
462
- flex: 1,
463
- position: 'relative',
464
- backgroundColor: '#000',
465
- },
466
- camera: {
467
- flex: 1,
414
+ headerTitle: { fontSize: 18, fontWeight: '700', color: '#0F172A', },
415
+ stepBadge: { backgroundColor: '#F1F5F9', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 20, },
416
+ stepText: { fontSize: 13, fontWeight: '600', color: '#64748B', },
417
+ cameraFeedContainer: { flex: 1, position: 'relative', backgroundColor: '#000', },
418
+ camera: { flex: 1, },
419
+ refreshButton: {
420
+ position: 'absolute', bottom: 100, alignSelf: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 12, paddingHorizontal: 24, borderRadius: 24, zIndex: 500
468
421
  },
422
+ refreshButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },
469
423
  previewContainer: {
470
- width: '100%',
471
- backgroundColor: 'white',
472
- borderRadius: 12,
473
- paddingVertical: 24,
474
- paddingHorizontal: 20,
475
- shadowColor: '#000',
476
- shadowOffset: { width: 0, height: 4 },
477
- shadowOpacity: 0.1,
478
- shadowRadius: 12,
479
- elevation: 8,
424
+ width: '100%', backgroundColor: 'white', borderRadius: 12, paddingVertical: 24, paddingHorizontal: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 12, elevation: 8,
480
425
  ...(Platform.OS === 'web' ? { alignSelf: 'center', maxWidth: 600 } : { margin: 10, width: '95%' })
481
426
  },
482
- previewItemContainer: {
483
- flexGrow: 1,
484
- },
427
+ previewItemContainer: { flexGrow: 1, },
485
428
  title: { fontSize: 24, fontWeight: 'bold', color: '#333', marginBottom: 8, textAlign: 'center' },
486
429
  description: { fontSize: 16, color: '#666', textAlign: 'center', marginBottom: 24, lineHeight: 22 },
487
430
  sideContainer: { marginBottom: 24 },
488
431
  sideTitle: { fontSize: 25, fontWeight: 'bold', color: '#000', marginBottom: 12, textAlign: 'center' },
489
- imagePreviewWrapper: {
490
- width: '100%', height: 220, borderRadius: 12, padding: 1, overflow: 'hidden',
491
- shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.18, shadowRadius: 8, elevation: 8, backgroundColor: '#f0f0f0'
492
- },
432
+ imagePreviewWrapper: { width: '100%', height: 220, borderRadius: 12, padding: 1, overflow: 'hidden', shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.18, shadowRadius: 8, elevation: 8, backgroundColor: '#f0f0f0' },
493
433
  previewImage: { width: '100%', height: '100%', borderRadius: 12, resizeMode: 'cover' },
494
434
  floatingErrorBanner: {
495
- position: 'absolute',
496
- bottom: 30, // Pushed to the bottom for professional feel
497
- left: 24,
498
- right: 24,
499
- backgroundColor: '#FEF2F2',
500
- borderWidth: 1,
501
- borderColor: '#FCA5A5',
502
- paddingVertical: 12,
503
- paddingHorizontal: 16,
504
- borderRadius: 12,
505
- alignItems: 'center',
506
- justifyContent: 'center',
507
- shadowColor: '#DC2626',
508
- shadowOffset: { width: 0, height: 4 },
509
- shadowOpacity: 0.1,
510
- shadowRadius: 8,
511
- elevation: 8,
512
- zIndex: 100
435
+ position: 'absolute', bottom: 30, left: 24, right: 24, backgroundColor: '#FEF2F2', borderWidth: 1, borderColor: '#FCA5A5', paddingVertical: 12, paddingHorizontal: 16, borderRadius: 12, alignItems: 'center', justifyContent: 'center', shadowColor: '#DC2626', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 8, zIndex: 100
513
436
  },
514
437
  floatingErrorText: { color: '#991B1B', fontSize: 14, fontWeight: '700', textAlign: 'center' },
515
438
  processingOverlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.6)', justifyContent: 'center', alignItems: 'center', zIndex: 9999 },
@@ -519,6 +442,40 @@ const styles = StyleSheet.create({
519
442
  errorText: { color: '#dc2626', fontSize: 14, marginTop: 8, textAlign: 'center' },
520
443
  topAnalyzingPillContainer: { position: 'absolute', top: Platform.OS === 'android' ? 60 : 50, left: 0, right: 0, alignItems: 'center', zIndex: 100 },
521
444
  topAnalyzingPill: { flexDirection: 'row', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.6)', paddingVertical: 8, paddingHorizontal: 16, borderRadius: 20, gap: 8 },
522
- analyzingPillText: { color: 'white', fontSize: 14, fontWeight: 'bold' }
445
+ analyzingPillText: { color: 'white', fontSize: 14, fontWeight: 'bold' },
446
+ escapeHatchContainer: {
447
+ position: 'absolute',
448
+ bottom: 40,
449
+ left: 0,
450
+ right: 0,
451
+ alignItems: 'center',
452
+ justifyContent: 'center',
453
+ zIndex: 99999, // Guarantees it is the top-most element
454
+ },
455
+ fallbackRefreshButton: {
456
+ backgroundColor: 'rgba(0, 0, 0, 0.8)', // Darker so it's visible on white or black
457
+ borderWidth: 1,
458
+ borderColor: 'rgba(255, 255, 255, 0.5)',
459
+ paddingVertical: 12,
460
+ paddingHorizontal: 24,
461
+ borderRadius: 24,
462
+ shadowColor: '#000',
463
+ shadowOffset: { width: 0, height: 4 },
464
+ shadowOpacity: 0.3,
465
+ shadowRadius: 5,
466
+ elevation: 8,
467
+ },
468
+ fallbackRefreshText: {
469
+ color: '#FFFFFF',
470
+ fontWeight: 'bold',
471
+ fontSize: 16,
472
+ },
473
+ absoluteFillObject: {
474
+ position: 'absolute',
475
+ top: 0,
476
+ left: 0,
477
+ right: 0,
478
+ bottom: 0,
479
+ },
523
480
  });
524
481
  //# sourceMappingURL=IDCardCapture.js.map