@transfergratis/react-native-sdk 0.1.24 → 0.1.26

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 (182) hide show
  1. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +12 -5
  2. package/android/build/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar +0 -0
  3. package/android/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt +0 -0
  4. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  5. package/android/build/intermediates/incremental/debug-mergeJavaRes/merge-state +0 -0
  6. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +61 -59
  7. package/android/build/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-transfergratis-react-native-sdk.jar +0 -0
  8. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +12 -5
  9. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  10. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  11. package/android/build/outputs/aar/transfergratis-react-native-sdk-debug.aar +0 -0
  12. package/android/build/outputs/logs/manifest-merger-debug-report.txt +26 -34
  13. package/android/src/main/AndroidManifest.xml +22 -7
  14. package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
  15. package/build/components/EnhancedCameraView.web.js +76 -21
  16. package/build/components/EnhancedCameraView.web.js.map +1 -1
  17. package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts +12 -0
  18. package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts.map +1 -0
  19. package/build/components/KYCElements/AdditionalDocumentsTemplate.js +283 -0
  20. package/build/components/KYCElements/AdditionalDocumentsTemplate.js.map +1 -0
  21. package/build/components/KYCElements/EmailVerificationTemplate.d.ts +12 -0
  22. package/build/components/KYCElements/EmailVerificationTemplate.d.ts.map +1 -0
  23. package/build/components/KYCElements/EmailVerificationTemplate.js +212 -0
  24. package/build/components/KYCElements/EmailVerificationTemplate.js.map +1 -0
  25. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  26. package/build/components/KYCElements/IDCardCapture.js +216 -14
  27. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  28. package/build/components/KYCElements/OrientationVideoCapture.d.ts +2 -0
  29. package/build/components/KYCElements/OrientationVideoCapture.d.ts.map +1 -1
  30. package/build/components/KYCElements/OrientationVideoCapture.js +2 -2
  31. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  32. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts +2 -0
  33. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts.map +1 -1
  34. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js +2 -2
  35. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  36. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts +2 -0
  37. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts.map +1 -1
  38. package/build/components/KYCElements/OrientationVideoCaptureFinal.js +2 -2
  39. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  40. package/build/components/KYCElements/PersonalInformationTemplate.d.ts +12 -0
  41. package/build/components/KYCElements/PersonalInformationTemplate.d.ts.map +1 -0
  42. package/build/components/KYCElements/PersonalInformationTemplate.js +120 -0
  43. package/build/components/KYCElements/PersonalInformationTemplate.js.map +1 -0
  44. package/build/components/KYCElements/PhoneVerificationTemplate.d.ts +12 -0
  45. package/build/components/KYCElements/PhoneVerificationTemplate.d.ts.map +1 -0
  46. package/build/components/KYCElements/PhoneVerificationTemplate.js +185 -0
  47. package/build/components/KYCElements/PhoneVerificationTemplate.js.map +1 -0
  48. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  49. package/build/components/KYCElements/SelfieCaptureTemplate.js +7 -3
  50. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  51. package/build/components/KYCElements/WelcomeTemplate.js +2 -1
  52. package/build/components/KYCElements/WelcomeTemplate.js.map +1 -1
  53. package/build/components/OverLay/type.d.ts +2 -0
  54. package/build/components/OverLay/type.d.ts.map +1 -1
  55. package/build/components/OverLay/type.js.map +1 -1
  56. package/build/components/TemplateKYCExample.d.ts +10 -0
  57. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  58. package/build/components/TemplateKYCExample.js +7 -30
  59. package/build/components/TemplateKYCExample.js.map +1 -1
  60. package/build/components/TemplateKYCFlowRefactored.d.ts +12 -0
  61. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  62. package/build/components/TemplateKYCFlowRefactored.js +25 -3
  63. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  64. package/build/config/KYCConfig.d.ts +14 -0
  65. package/build/config/KYCConfig.d.ts.map +1 -0
  66. package/build/config/KYCConfig.js +26 -0
  67. package/build/config/KYCConfig.js.map +1 -0
  68. package/build/config/allowedDomains.d.ts.map +1 -1
  69. package/build/config/allowedDomains.js +4 -19
  70. package/build/config/allowedDomains.js.map +1 -1
  71. package/build/hooks/useOrientationVideo.d.ts +2 -1
  72. package/build/hooks/useOrientationVideo.d.ts.map +1 -1
  73. package/build/hooks/useOrientationVideo.js +3 -3
  74. package/build/hooks/useOrientationVideo.js.map +1 -1
  75. package/build/hooks/useTemplateKYCFlow.d.ts +18 -1
  76. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  77. package/build/hooks/useTemplateKYCFlow.js +410 -56
  78. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  79. package/build/i18n/en/index.d.ts +42 -0
  80. package/build/i18n/en/index.d.ts.map +1 -1
  81. package/build/i18n/en/index.js +44 -2
  82. package/build/i18n/en/index.js.map +1 -1
  83. package/build/i18n/fr/index.d.ts +28 -0
  84. package/build/i18n/fr/index.d.ts.map +1 -1
  85. package/build/i18n/fr/index.js +30 -2
  86. package/build/i18n/fr/index.js.map +1 -1
  87. package/build/i18n/types.d.ts +2 -0
  88. package/build/i18n/types.d.ts.map +1 -1
  89. package/build/i18n/types.js.map +1 -1
  90. package/build/index.d.ts +1 -0
  91. package/build/index.d.ts.map +1 -1
  92. package/build/index.js +2 -0
  93. package/build/index.js.map +1 -1
  94. package/build/modules/api/CardAuthentification.d.ts +24 -3
  95. package/build/modules/api/CardAuthentification.d.ts.map +1 -1
  96. package/build/modules/api/CardAuthentification.js +90 -12
  97. package/build/modules/api/CardAuthentification.js.map +1 -1
  98. package/build/modules/api/KYCService.d.ts +17 -7
  99. package/build/modules/api/KYCService.d.ts.map +1 -1
  100. package/build/modules/api/KYCService.js +125 -37
  101. package/build/modules/api/KYCService.js.map +1 -1
  102. package/build/modules/api/SelfieVerification.d.ts +3 -1
  103. package/build/modules/api/SelfieVerification.d.ts.map +1 -1
  104. package/build/modules/api/SelfieVerification.js +17 -1
  105. package/build/modules/api/SelfieVerification.js.map +1 -1
  106. package/build/modules/api/TemplateService.d.ts +0 -1
  107. package/build/modules/api/TemplateService.d.ts.map +1 -1
  108. package/build/modules/api/TemplateService.js +3 -3
  109. package/build/modules/api/TemplateService.js.map +1 -1
  110. package/build/modules/camera/VisionCameraModule.web.d.ts.map +1 -1
  111. package/build/modules/camera/VisionCameraModule.web.js +27 -8
  112. package/build/modules/camera/VisionCameraModule.web.js.map +1 -1
  113. package/build/types/KYC.types.d.ts +130 -5
  114. package/build/types/KYC.types.d.ts.map +1 -1
  115. package/build/types/KYC.types.js.map +1 -1
  116. package/build/types/env.types.d.ts +13 -0
  117. package/build/types/env.types.d.ts.map +1 -0
  118. package/build/types/env.types.js +2 -0
  119. package/build/types/env.types.js.map +1 -0
  120. package/build/utils/cropByObb.d.ts +7 -0
  121. package/build/utils/cropByObb.d.ts.map +1 -1
  122. package/build/utils/cropByObb.js +20 -1
  123. package/build/utils/cropByObb.js.map +1 -1
  124. package/build/utils/deviceDetection.d.ts +6 -0
  125. package/build/utils/deviceDetection.d.ts.map +1 -0
  126. package/build/utils/deviceDetection.js +12 -0
  127. package/build/utils/deviceDetection.js.map +1 -0
  128. package/build/utils/platformAlert.d.ts.map +1 -1
  129. package/build/utils/platformAlert.js.map +1 -1
  130. package/build/utils/template-transformer.d.ts.map +1 -1
  131. package/build/utils/template-transformer.js +12 -0
  132. package/build/utils/template-transformer.js.map +1 -1
  133. package/build/web/WebKYCEntry.d.ts.map +1 -1
  134. package/build/web/WebKYCEntry.js +88 -38
  135. package/build/web/WebKYCEntry.js.map +1 -1
  136. package/package.json +1 -1
  137. package/plugin/build/index.d.ts +1 -0
  138. package/plugin/build/index.js +3 -1
  139. package/plugin/build/withRemovePermissions.d.ts +3 -0
  140. package/plugin/build/withRemovePermissions.js +67 -0
  141. package/plugin/build/withVisionCamera.js +3 -4
  142. package/plugin/src/index.ts +2 -1
  143. package/plugin/src/withRemovePermissions.js +85 -0
  144. package/plugin/src/withRemovePermissions.ts +83 -0
  145. package/plugin/src/withVisionCamera.js +3 -4
  146. package/plugin/src/withVisionCamera.ts +3 -4
  147. package/plugin/tsconfig.tsbuildinfo +1 -1
  148. package/plugin.js +6 -1
  149. package/src/components/EnhancedCameraView.web.tsx +76 -21
  150. package/src/components/KYCElements/AdditionalDocumentsTemplate.tsx +346 -0
  151. package/src/components/KYCElements/EmailVerificationTemplate.tsx +278 -0
  152. package/src/components/KYCElements/IDCardCapture.tsx +253 -21
  153. package/src/components/KYCElements/OrientationVideoCapture.tsx +4 -1
  154. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +4 -1
  155. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +4 -1
  156. package/src/components/KYCElements/PersonalInformationTemplate.tsx +158 -0
  157. package/src/components/KYCElements/PhoneVerificationTemplate.tsx +253 -0
  158. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +6 -3
  159. package/src/components/KYCElements/WelcomeTemplate.tsx +2 -1
  160. package/src/components/OverLay/type.ts +2 -0
  161. package/src/components/TemplateKYCExample.tsx +35 -46
  162. package/src/components/TemplateKYCFlowRefactored.tsx +46 -2
  163. package/src/config/KYCConfig.ts +34 -0
  164. package/src/config/allowedDomains.ts +7 -26
  165. package/src/hooks/useOrientationVideo.ts +5 -4
  166. package/src/hooks/useTemplateKYCFlow.tsx +443 -56
  167. package/src/i18n/en/index.ts +46 -3
  168. package/src/i18n/fr/index.ts +31 -2
  169. package/src/i18n/types.ts +2 -0
  170. package/src/index.ts +3 -0
  171. package/src/modules/api/CardAuthentification.ts +98 -12
  172. package/src/modules/api/KYCService.ts +158 -37
  173. package/src/modules/api/SelfieVerification.ts +25 -3
  174. package/src/modules/api/TemplateService.ts +4 -4
  175. package/src/modules/camera/VisionCameraModule.web.ts +30 -12
  176. package/src/types/KYC.types.ts +153 -6
  177. package/src/types/env.types.ts +13 -0
  178. package/src/utils/cropByObb.ts +20 -1
  179. package/src/utils/deviceDetection.ts +11 -0
  180. package/src/utils/platformAlert.ts +1 -0
  181. package/src/utils/template-transformer.ts +20 -8
  182. package/src/web/WebKYCEntry.tsx +123 -61
@@ -11,6 +11,7 @@ import { showAlert } from '../../utils/platformAlert';
11
11
  import Svg, { Rect, Path, Mask, Defs } from 'react-native-svg';
12
12
  import { Camera, useCameraDevice } from 'react-native-vision-camera';
13
13
  import { OrientationVideoConfig, OrientationVideoState } from '../../types/KYC.types';
14
+ import { KycEnvironment } from '../../types/env.types';
14
15
  import kycService from '../../modules/api/KYCService';
15
16
  import VisionCameraModule from '../../modules/camera/VisionCameraModule';
16
17
  import SideSelfieIcon from '../Svgs/sideSelfieIcon';
@@ -20,6 +21,7 @@ interface OrientationVideoCaptureProps {
20
21
  onComplete: (result: any) => void;
21
22
  onError: (error: string) => void;
22
23
  kycService: typeof kycService;
24
+ env?: KycEnvironment;
23
25
  }
24
26
 
25
27
  const defaultConfig: OrientationVideoConfig = {
@@ -42,6 +44,7 @@ export const OrientationVideoCapture: React.FC<OrientationVideoCaptureProps> = (
42
44
  onComplete,
43
45
  onError,
44
46
  kycService,
47
+ env = 'PRODUCTION',
45
48
  }) => {
46
49
  const finalConfig = { ...defaultConfig, ...config };
47
50
 
@@ -174,7 +177,7 @@ export const OrientationVideoCapture: React.FC<OrientationVideoCaptureProps> = (
174
177
  setState(prev => ({ ...prev, isProcessing: true, error: null }));
175
178
 
176
179
  try {
177
- const result = await kycService.processOrientationVideo(videoUri);
180
+ const result = await kycService.processOrientationVideo(videoUri, env);
178
181
 
179
182
  if (result.success && result.data) {
180
183
  setState(prev => ({
@@ -12,6 +12,7 @@ import { showAlert } from '../../utils/platformAlert';
12
12
  import Svg, { Rect, Path, Mask, Defs } from 'react-native-svg';
13
13
  import { EnhancedCameraView } from '../EnhancedCameraView';
14
14
  import { OrientationVideoConfig, OrientationVideoState } from '../../types/KYC.types';
15
+ import { KycEnvironment } from '../../types/env.types';
15
16
  import kycService from '../../modules/api/KYCService';
16
17
  import FrontSelfieIcon from '../Svgs/frontSelfieIcon';
17
18
  import ScanningLine from '../Svgs/scanningLine';
@@ -21,6 +22,7 @@ interface OrientationVideoCaptureEnhancedProps {
21
22
  onComplete: (result: any) => void;
22
23
  onError: (error: string) => void;
23
24
  kycService: typeof kycService;
25
+ env?: KycEnvironment;
24
26
  }
25
27
 
26
28
  const defaultConfig: OrientationVideoConfig = {
@@ -43,6 +45,7 @@ export const OrientationVideoCaptureEnhanced: React.FC<OrientationVideoCaptureEn
43
45
  onComplete,
44
46
  onError,
45
47
  kycService,
48
+ env = 'PRODUCTION',
46
49
  }) => {
47
50
  const finalConfig = { ...defaultConfig, ...config };
48
51
  const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
@@ -153,7 +156,7 @@ export const OrientationVideoCaptureEnhanced: React.FC<OrientationVideoCaptureEn
153
156
  setState(prev => ({ ...prev, isProcessing: true, error: null }));
154
157
 
155
158
  try {
156
- const result = await kycService.processOrientationVideo(videoUri);
159
+ const result = await kycService.processOrientationVideo(videoUri, env);
157
160
 
158
161
  if (result.success && result.data) {
159
162
  setState(prev => ({
@@ -11,6 +11,7 @@ import { showAlert } from '../../utils/platformAlert';
11
11
  import Svg, { Rect, Path, Mask, Defs } from 'react-native-svg';
12
12
  import { EnhancedCameraView } from '../EnhancedCameraView';
13
13
  import { OrientationVideoConfig, OrientationVideoState } from '../../types/KYC.types';
14
+ import { KycEnvironment } from '../../types/env.types';
14
15
  import SideSelfieIcon from '../Svgs/sideSelfieIcon';
15
16
  import kycService from '../../modules/api/KYCService';
16
17
 
@@ -19,6 +20,7 @@ interface OrientationVideoCaptureFinalProps {
19
20
  onComplete: (result: any) => void;
20
21
  onError: (error: string) => void;
21
22
  kycService: typeof kycService;
23
+ env?: KycEnvironment;
22
24
  }
23
25
 
24
26
  const defaultConfig: OrientationVideoConfig = {
@@ -41,6 +43,7 @@ export const OrientationVideoCaptureFinal: React.FC<OrientationVideoCaptureFinal
41
43
  onComplete,
42
44
  onError,
43
45
  kycService,
46
+ env = 'PRODUCTION',
44
47
  }) => {
45
48
  const finalConfig = { ...defaultConfig, ...config };
46
49
 
@@ -127,7 +130,7 @@ export const OrientationVideoCaptureFinal: React.FC<OrientationVideoCaptureFinal
127
130
  setState(prev => ({ ...prev, isProcessing: true, error: null }));
128
131
 
129
132
  try {
130
- const result = await kycService.processOrientationVideo(videoUri);
133
+ const result = await kycService.processOrientationVideo(videoUri, env);
131
134
 
132
135
  if (result.success && result.data) {
133
136
  setState(prev => ({
@@ -0,0 +1,158 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { View, Text, StyleSheet, TextInput, KeyboardAvoidingView, Platform, ScrollView } from 'react-native';
3
+ import { TemplateComponent, PersonalInformationConfig, LocalizedText } from '../../types/KYC.types';
4
+ import { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';
5
+ import { useI18n } from '../../hooks/useI18n';
6
+ import { Button } from '../ui/Button';
7
+
8
+ interface PersonalInformationTemplateProps {
9
+ component: TemplateComponent;
10
+ value?: any;
11
+ onValueChange: (data: any) => void;
12
+ error?: string;
13
+ language?: string;
14
+ }
15
+
16
+ export const PersonalInformationTemplate: React.FC<PersonalInformationTemplateProps> = ({
17
+ component,
18
+ value,
19
+ onValueChange,
20
+ error,
21
+ }) => {
22
+ const { actions, getLocalizedText } = useTemplateKYCFlowContext();
23
+ const { t } = useI18n();
24
+ const config = component.config as PersonalInformationConfig;
25
+ const [formData, setFormData] = useState<Record<string, string>>({});
26
+
27
+ const title = getLocalizedText(component.labels as LocalizedText);
28
+ const instructions = getLocalizedText(component.instructions as LocalizedText);
29
+ const buttonText = getLocalizedText((component.ui as any).buttonText) || t('common.submit');
30
+
31
+ useEffect(() => {
32
+ if (value) {
33
+ setFormData(value);
34
+ }
35
+ }, [value]);
36
+
37
+ const handleChange = (fieldId: string, text: string) => {
38
+ const newData = { ...formData, [fieldId]: text };
39
+ setFormData(newData);
40
+ onValueChange(newData);
41
+ };
42
+
43
+ const handleCreate = () => {
44
+ actions.nextComponent();
45
+ };
46
+
47
+ const isFormValid = () => {
48
+ if (!config.fields) return true;
49
+ return config.fields.every(field => {
50
+ if (field.required && !formData[field.id]) return false;
51
+ return true;
52
+ });
53
+ };
54
+
55
+ return (
56
+ <KeyboardAvoidingView
57
+ behavior={Platform.OS === "ios" ? "padding" : "height"}
58
+ style={styles.keyboardAvoidingView}
59
+ >
60
+ <ScrollView contentContainerStyle={styles.scrollContainer} showsVerticalScrollIndicator={false}>
61
+ <View style={styles.container}>
62
+ <Text style={styles.title}>{title}</Text>
63
+ <Text style={styles.instructions}>{instructions}</Text>
64
+
65
+ <View style={styles.formContainer}>
66
+ {config.fields && config.fields.map((field) => (
67
+ <View key={field.id} style={styles.fieldContainer}>
68
+ <Text style={styles.label}>
69
+ {field.label} {field.type === 'date' && field.dateFormat ? `(${field.dateFormat})` : ''} {field.required && '*'}
70
+ </Text>
71
+ <TextInput
72
+ style={styles.input}
73
+ placeholder={field.placeholder || field.label}
74
+ value={formData[field.id] || ''}
75
+ onChangeText={(text) => handleChange(field.id, text)}
76
+ autoCapitalize="words"
77
+ />
78
+ </View>
79
+ ))}
80
+ </View>
81
+
82
+ {error && <Text style={styles.errorText}>{error}</Text>}
83
+
84
+ <Button
85
+ title={buttonText}
86
+ onPress={handleCreate}
87
+ fullWidth
88
+ style={styles.button}
89
+ disabled={!isFormValid()}
90
+ />
91
+ </View>
92
+ </ScrollView>
93
+ </KeyboardAvoidingView>
94
+ );
95
+ };
96
+
97
+ const styles = StyleSheet.create({
98
+ keyboardAvoidingView: {
99
+ flex: 1,
100
+ width: '100%',
101
+ },
102
+ scrollContainer: {
103
+ flexGrow: 1,
104
+ justifyContent: 'center',
105
+ paddingBottom: 20,
106
+ },
107
+ container: {
108
+ padding: 20,
109
+ backgroundColor: 'white',
110
+ borderRadius: 12,
111
+ margin: 16,
112
+ shadowColor: '#000',
113
+ shadowOffset: { width: 0, height: 2 },
114
+ shadowOpacity: 0.1,
115
+ shadowRadius: 4,
116
+ elevation: 3,
117
+ width: '95%',
118
+ },
119
+ title: {
120
+ fontSize: 22,
121
+ fontWeight: 'bold',
122
+ marginBottom: 10,
123
+ color: '#333',
124
+ },
125
+ instructions: {
126
+ fontSize: 16,
127
+ color: '#666',
128
+ marginBottom: 20,
129
+ lineHeight: 22,
130
+ },
131
+ formContainer: {
132
+ marginBottom: 20,
133
+ },
134
+ fieldContainer: {
135
+ marginBottom: 16,
136
+ },
137
+ label: {
138
+ fontSize: 14,
139
+ fontWeight: '600',
140
+ color: '#333',
141
+ marginBottom: 6,
142
+ },
143
+ input: {
144
+ borderWidth: 1,
145
+ borderColor: '#ddd',
146
+ padding: 12,
147
+ borderRadius: 8,
148
+ fontSize: 16,
149
+ backgroundColor: '#f9f9f9',
150
+ },
151
+ errorText: {
152
+ color: 'red',
153
+ marginBottom: 10,
154
+ },
155
+ button: {
156
+ marginTop: 10,
157
+ },
158
+ });
@@ -0,0 +1,253 @@
1
+ import React, { useState } from 'react';
2
+ import { View, Text, StyleSheet, TextInput, TouchableOpacity, Alert } from 'react-native';
3
+ import { TemplateComponent, LocalizedText } from '../../types/KYC.types';
4
+ import { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';
5
+ import { useI18n } from '../../hooks/useI18n';
6
+ import { Button } from '../ui/Button';
7
+
8
+ interface PhoneVerificationTemplateProps {
9
+ component: TemplateComponent;
10
+ value?: any;
11
+ onValueChange: (data: any) => void;
12
+ error?: string;
13
+ language?: string;
14
+ }
15
+
16
+ type VerificationStep = 'phone' | 'otp';
17
+
18
+ export const PhoneVerificationTemplate: React.FC<PhoneVerificationTemplateProps> = ({
19
+ component,
20
+ value,
21
+ onValueChange,
22
+ error: propError,
23
+ }) => {
24
+ const { actions, getLocalizedText } = useTemplateKYCFlowContext();
25
+ const { t } = useI18n();
26
+ // const config = component.config as PhoneVerificationConfig;
27
+
28
+ // State
29
+ const [step, setStep] = useState<VerificationStep>('phone');
30
+ const [phone, setPhone] = useState('');
31
+ const [otp, setOtp] = useState('');
32
+ const [localError, setLocalError] = useState<string | null>(null);
33
+ const [isSimulating, setIsSimulating] = useState(false);
34
+
35
+ const title = getLocalizedText(component.labels as LocalizedText);
36
+ const instructions = getLocalizedText(component.instructions as LocalizedText);
37
+
38
+ // Determine button text based on step
39
+ const verifyButtonText = getLocalizedText((component.ui as any).buttonText) || t('common.verify') || 'Verify';
40
+ const sendButtonText = t('common.sendCode') || 'Send Verification Code';
41
+ const buttonText = step === 'phone' ? sendButtonText : verifyButtonText;
42
+
43
+ const handleSendCode = () => {
44
+ if (!phone || phone.length < 5) {
45
+ setLocalError(t('errors.invalidPhone') || 'Please enter a valid phone number');
46
+ return;
47
+ }
48
+
49
+ setLocalError(null);
50
+ setIsSimulating(true);
51
+
52
+ // Simulate API call to send code
53
+ setTimeout(() => {
54
+ setIsSimulating(false);
55
+ setStep('otp');
56
+ }, 1500);
57
+ };
58
+
59
+ const handleVerifyCode = () => {
60
+ if (!otp || otp.length < 4) {
61
+ setLocalError(t('errors.invalidCode') || 'Please enter the 6-digit code');
62
+ return;
63
+ }
64
+
65
+ setLocalError(null);
66
+ setIsSimulating(true);
67
+
68
+ // Simulate verification API
69
+ setTimeout(() => {
70
+ setIsSimulating(false);
71
+
72
+ // Mock validation logic
73
+ if (otp === '123456') {
74
+ onValueChange({ phone, otp, verified: true });
75
+ actions.nextComponent();
76
+ } else {
77
+ setLocalError(t('errors.wrongCode') || 'Invalid verification code. Try 123456');
78
+ }
79
+ }, 1500);
80
+ };
81
+
82
+ const onChangePhone = (text: string) => {
83
+ setPhone(text);
84
+ if (localError) setLocalError(null);
85
+ };
86
+
87
+ const onChangeOtp = (text: string) => {
88
+ setOtp(text);
89
+ if (localError) setLocalError(null);
90
+ };
91
+
92
+ const handleBackToPhone = () => {
93
+ setStep('phone');
94
+ setOtp('');
95
+ setLocalError(null);
96
+ };
97
+
98
+ return (
99
+ <View style={styles.container}>
100
+ <Text style={styles.title}>{title}</Text>
101
+ <Text style={styles.instructions}>
102
+ {step === 'phone' ? instructions : (t('kyc.enterCodeSent') || `Please enter the code sent to ${phone}`)}
103
+ </Text>
104
+
105
+ <View style={styles.contentContainer}>
106
+ {step === 'phone' ? (
107
+ <View style={styles.inputContainer}>
108
+ <Text style={styles.label}>{t('common.phone') || 'Phone Number'}</Text>
109
+ <TextInput
110
+ style={styles.input}
111
+ placeholder="+1234567890"
112
+ value={phone}
113
+ onChangeText={onChangePhone}
114
+ keyboardType="phone-pad"
115
+ autoComplete="tel"
116
+ editable={!isSimulating}
117
+ />
118
+ </View>
119
+ ) : (
120
+ <View style={styles.inputContainer}>
121
+ <Text style={styles.label}>{t('common.verificationCode') || 'Verification Code'}</Text>
122
+ <TextInput
123
+ style={styles.input}
124
+ placeholder="123456"
125
+ value={otp}
126
+ onChangeText={onChangeOtp}
127
+ keyboardType="number-pad"
128
+ maxLength={6}
129
+ editable={!isSimulating}
130
+ />
131
+ <TouchableOpacity onPress={handleBackToPhone} style={styles.changeLink}>
132
+ <Text style={styles.changeText}>{t('common.back') || 'Change number'}</Text>
133
+ </TouchableOpacity>
134
+ </View>
135
+ )}
136
+
137
+ {(localError || propError) && (
138
+ <Text style={styles.errorText}>{localError || propError}</Text>
139
+ )}
140
+
141
+ <Button
142
+ title={isSimulating ? (t('common.processing') || 'Processing...') : buttonText}
143
+ onPress={step === 'phone' ? handleSendCode : handleVerifyCode}
144
+ style={styles.button}
145
+ disabled={
146
+ isSimulating ||
147
+ (step === 'phone' ? !phone : !otp)
148
+ }
149
+ />
150
+
151
+ {step === 'otp' && (
152
+ <TouchableOpacity
153
+ onPress={() => {
154
+ // Resend logic
155
+ Alert.alert(
156
+ t('common.codeResent') || 'Code Resent',
157
+ t('common.codeResentMessage', { email: phone }) || 'Code resent to ' + phone
158
+ );
159
+ }}
160
+ style={styles.resendButton}
161
+ disabled={isSimulating}
162
+ >
163
+ <Text style={styles.resendText}>{t('common.resendCode') || 'Resend Code'}</Text>
164
+ </TouchableOpacity>
165
+ )}
166
+ </View>
167
+ </View>
168
+ );
169
+ };
170
+
171
+ const styles = StyleSheet.create({
172
+ container: {
173
+ padding: 24,
174
+ backgroundColor: 'white',
175
+ borderRadius: 16,
176
+ margin: 16,
177
+ shadowColor: '#000',
178
+ shadowOffset: { width: 0, height: 4 },
179
+ shadowOpacity: 0.1,
180
+ shadowRadius: 12,
181
+ elevation: 5,
182
+ width: '95%',
183
+ },
184
+ title: {
185
+ fontSize: 24,
186
+ fontWeight: '700',
187
+ marginBottom: 8,
188
+ color: '#1a1a1a',
189
+ textAlign: 'center',
190
+ },
191
+ instructions: {
192
+ fontSize: 16,
193
+ color: '#666',
194
+ marginBottom: 32,
195
+ lineHeight: 24,
196
+ textAlign: 'center',
197
+ },
198
+ contentContainer: {
199
+ // width: '100%',
200
+ },
201
+ inputContainer: {
202
+ marginBottom: 24,
203
+ },
204
+ label: {
205
+ fontSize: 14,
206
+ fontWeight: '600',
207
+ color: '#333',
208
+ marginBottom: 8,
209
+ marginLeft: 4,
210
+ },
211
+ input: {
212
+ borderWidth: 1,
213
+ borderColor: '#e0e0e0',
214
+ padding: 16,
215
+ borderRadius: 12,
216
+ fontSize: 16,
217
+ backgroundColor: '#f8f9fa',
218
+ color: '#333',
219
+ },
220
+ errorText: {
221
+ color: '#dc2626',
222
+ marginBottom: 16,
223
+ fontSize: 14,
224
+ textAlign: 'center',
225
+ backgroundColor: '#fee2e2',
226
+ padding: 8,
227
+ borderRadius: 8,
228
+ overflow: 'hidden',
229
+ },
230
+ button: {
231
+ height: 50,
232
+ borderRadius: 12,
233
+ width: "100%"
234
+ },
235
+ changeLink: {
236
+ alignSelf: 'flex-end',
237
+ marginTop: 8,
238
+ },
239
+ changeText: {
240
+ color: '#2DBD60',
241
+ fontSize: 14,
242
+ fontWeight: '500',
243
+ },
244
+ resendButton: {
245
+ marginTop: 16,
246
+ alignItems: 'center',
247
+ },
248
+ resendText: {
249
+ color: '#666',
250
+ fontSize: 14,
251
+ textDecorationLine: 'underline',
252
+ },
253
+ });
@@ -33,7 +33,7 @@ export const SelfieCaptureTemplate: React.FC<SelfieCaptureTemplateProps> = ({
33
33
  const { t } = useI18n();
34
34
  // const config = component.config as SelfieConfig;
35
35
  const orientations: OrientationType[] = (['center','left','right']) as OrientationType[];
36
- const { actions, state, } = useTemplateKYCFlowContext();
36
+ const { actions, state, env } = useTemplateKYCFlowContext();
37
37
 
38
38
  const [silentCaptureResult, setSilentCaptureResult] = useState<ISilentCaptureResult>({ success: false, isAnalyzing: false });
39
39
 
@@ -152,10 +152,13 @@ export const SelfieCaptureTemplate: React.FC<SelfieCaptureTemplateProps> = ({
152
152
  }
153
153
  if (result.success && result.path) {
154
154
  setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: true, success: false, error: '' }));
155
- selfieVerification(result.path).then((response) => {
155
+ selfieVerification(result.path, env).then((response) => {
156
156
  if (response.length > 0) {
157
157
  const res = response[0];
158
- if (res?.orientation_direction === getOrientationOpposite(currentOrientation) && res?.capture) {
158
+ // In SANDBOX mode, always accept the result regardless of orientation
159
+ if (env === 'SANDBOX' && res?.capture) {
160
+ setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: true, error: '', path: result.path }));
161
+ } else if (res?.orientation_direction === getOrientationOpposite(currentOrientation) && res?.capture) {
159
162
  setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: true, error: '', path: result.path }));
160
163
  } else {
161
164
  setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: false, success: false, error: 'Le selfie n\'est pas correct' }));
@@ -150,7 +150,7 @@ export const WelcomeTemplate: React.FC<WelcomeTemplateProps> = ({
150
150
 
151
151
  {/* Get Started Button */}
152
152
  <Button
153
- title={buttonText}
153
+ title={buttonText?.length === 0 ? t('kyc.welcome.getStarted') || 'Get Started' : buttonText}
154
154
  fullWidth
155
155
  onPress={handleGetStarted}
156
156
  style={{ paddingVertical: 20, marginTop: 36 }}
@@ -175,6 +175,7 @@ const styles = StyleSheet.create({
175
175
  shadowRadius: 1.84,
176
176
  elevation: 3,
177
177
  maxWidth: 760,
178
+ width: '94%',
178
179
  },
179
180
  title: {
180
181
  fontSize: 24,
@@ -81,6 +81,8 @@ export interface EnhancedCameraViewProps {
81
81
  onVideoRecordingStart?: () => void;
82
82
  onVideoRecordingStop?: (result: { success: boolean; path?: string; error?: string }) => void;
83
83
  videoDuration?: number;
84
+ /** Delay in ms before first auto-capture (lets camera focus and user position document). Recommended 2500–3000 for ID/document capture. */
85
+ captureStabilizationDelayMs?: number;
84
86
  }
85
87
 
86
88
  export interface CheckTemplateTypeResponse {
@@ -2,8 +2,11 @@ import React from 'react';
2
2
  import { View, SafeAreaView } from 'react-native';
3
3
  import { TemplateKYCFlow } from './TemplateKYCFlowRefactored';
4
4
  import { KYCTemplate, VerificationState } from '../types/KYC.types';
5
+ import { KycEnvironment, BackendEnvironment } from '../types/env.types';
6
+
7
+
8
+
5
9
 
6
- // Template JSON basé sur votre exemple
7
10
  const advancedVerificationTemplate: KYCTemplate = {
8
11
  id: 1,
9
12
  name: {
@@ -103,7 +106,7 @@ const advancedVerificationTemplate: KYCTemplate = {
103
106
  allowed_formats: ["jpg", "png"],
104
107
  max_size_mb: 5,
105
108
  document_types: ["drivers_licence", "passport", "drivers_licence", "national_id"],
106
-
109
+
107
110
  } as const
108
111
  },
109
112
  {
@@ -130,42 +133,23 @@ const advancedVerificationTemplate: KYCTemplate = {
130
133
  orientations: ["center", "left", "right"]
131
134
  } as const
132
135
  },
133
- // {
134
- // id: 4,
135
- // type: "file_upload" as const,
136
- // order: 6,
137
- // labels: {
138
- // en: "Upload proof of address",
139
- // fr: "Téléversez un justificatif de domicile"
140
- // },
141
- // instructions: {
142
- // en: "Upload a recent utility bill or bank statement (PDF, JPG, PNG).",
143
- // fr: "Téléversez une facture récente ou un relevé bancaire (PDF, JPG, PNG)."
144
- // },
145
- // ui: {
146
- // icon: "file-upload-icon.png",
147
- // themeColor: "#2DBD60",
148
- // buttonText: { en: "Upload", fr: "Téléverser" }
149
- // },
150
- // config: {
151
- // allowed_formats: ["pdf", "jpg", "png"],
152
- // max_size_mb: 10,
153
- // required: true
154
- // } as const
155
- // },
156
-
157
136
  ]
158
137
  };
159
138
 
160
- export const TemplateKYCExample: React.FC<{
161
- onComplete: (data: VerificationState) => void;
162
- onCancel: () => void;
163
- onError: (error: string) => void;
164
- language: string;
139
+ export const TemplateKYCExample: React.FC<{
140
+ onComplete: (data: VerificationState) => void;
141
+ onCancel: () => void;
142
+ onError: (error: string) => void;
143
+ language: string;
165
144
  API_KEY?: string;
166
145
  templateId?: string;
167
146
  template?: KYCTemplate;
168
- }> = ({ onComplete, onCancel, onError, language, API_KEY, templateId, template }) => {
147
+ env?: KycEnvironment; // Flow execution: PRODUCTION (full AI) or SANDBOX (skip AI)
148
+ serverEnv?: BackendEnvironment; // Backend to call: PRODUCTION or TEST (API URL)
149
+ existingSessionId?: string;
150
+ initialComponentIndex?: number;
151
+ initialCountryResume?: { code: string; documentType: string; region?: string };
152
+ }> = ({ onComplete, onCancel, onError, language, API_KEY, templateId, template, env = 'PRODUCTION', serverEnv, existingSessionId, initialComponentIndex, initialCountryResume }) => {
169
153
  const handleComplete = (data: VerificationState) => {
170
154
  console.log('KYC Template completed with data:', data);
171
155
  onComplete(data);
@@ -182,24 +166,29 @@ export const TemplateKYCExample: React.FC<{
182
166
  onError(error);
183
167
  };
184
168
 
169
+ // Transform backend template to SDK format
185
170
  // Determine which template to use: prefer templateId for dynamic loading, then template prop, then fallback to hardcoded
186
171
  const templateToUse = templateId ? undefined : (template || advancedVerificationTemplate);
187
172
 
188
173
  return (
189
- <SafeAreaView style={{ flex: 1 , paddingVertical:25}}>
190
- <View style={{ flex: 1 }}>
191
- <TemplateKYCFlow
192
- template={templateToUse}
193
- templateId={templateId}
194
- onComplete={handleComplete}
195
- onError={handleError}
196
- onCancel={handleCancel}
197
- language={language} // ou "en" pour l'anglais
198
- API_KEY={API_KEY}
199
- />
200
- </View>
201
- </SafeAreaView>
174
+ <SafeAreaView style={{ flex: 1, paddingVertical: 25 }}>
175
+ <View style={{ flex: 1 }}>
176
+ <TemplateKYCFlow
177
+ template={templateToUse}
178
+ templateId={templateId}
179
+ onComplete={handleComplete}
180
+ onError={handleError}
181
+ onCancel={handleCancel}
182
+ language={language} // ou "en" pour l'anglais
183
+ API_KEY={API_KEY}
184
+ env={env}
185
+ serverEnv={serverEnv}
186
+ existingSessionId={existingSessionId}
187
+ initialComponentIndex={initialComponentIndex}
188
+ initialCountryResume={initialCountryResume}
189
+ />
190
+ </View>
191
+ </SafeAreaView>
202
192
  );
203
193
  };
204
194
 
205
-