@transfergratis/react-native-sdk 0.1.22 → 0.1.24

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 (142) hide show
  1. package/android/src/main/AndroidManifest.xml +9 -4
  2. package/build/components/EnhancedCameraView.d.ts.map +1 -1
  3. package/build/components/EnhancedCameraView.js +26 -3
  4. package/build/components/EnhancedCameraView.js.map +1 -1
  5. package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
  6. package/build/components/EnhancedCameraView.web.js +21 -0
  7. package/build/components/EnhancedCameraView.web.js.map +1 -1
  8. package/build/components/KYCElements/CameraCapture.d.ts.map +1 -1
  9. package/build/components/KYCElements/CameraCapture.js +4 -3
  10. package/build/components/KYCElements/CameraCapture.js.map +1 -1
  11. package/build/components/KYCElements/CountrySelectionTemplate.d.ts +5 -2
  12. package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  13. package/build/components/KYCElements/CountrySelectionTemplate.js +360 -101
  14. package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  15. package/build/components/KYCElements/FileUpload.d.ts.map +1 -1
  16. package/build/components/KYCElements/FileUpload.js +5 -4
  17. package/build/components/KYCElements/FileUpload.js.map +1 -1
  18. package/build/components/KYCElements/FileUploadTemplate.d.ts.map +1 -1
  19. package/build/components/KYCElements/FileUploadTemplate.js +5 -4
  20. package/build/components/KYCElements/FileUploadTemplate.js.map +1 -1
  21. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  22. package/build/components/KYCElements/IDCardCapture.js +193 -237
  23. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  24. package/build/components/KYCElements/LocationCaptureTemplate.d.ts.map +1 -1
  25. package/build/components/KYCElements/LocationCaptureTemplate.js +78 -37
  26. package/build/components/KYCElements/LocationCaptureTemplate.js.map +1 -1
  27. package/build/components/KYCElements/OrientationVideoCapture.js +3 -2
  28. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  29. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js +3 -2
  30. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  31. package/build/components/KYCElements/OrientationVideoCaptureFinal.js +3 -2
  32. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  33. package/build/components/KYCElements/SelfieCapture.d.ts.map +1 -1
  34. package/build/components/KYCElements/SelfieCapture.js +4 -3
  35. package/build/components/KYCElements/SelfieCapture.js.map +1 -1
  36. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  37. package/build/components/KYCElements/SelfieCaptureTemplate.js +182 -39
  38. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  39. package/build/components/KYCElements/WelcomeTemplate.d.ts +12 -0
  40. package/build/components/KYCElements/WelcomeTemplate.d.ts.map +1 -0
  41. package/build/components/KYCElements/WelcomeTemplate.js +243 -0
  42. package/build/components/KYCElements/WelcomeTemplate.js.map +1 -0
  43. package/build/components/TemplateKYCExample.d.ts +4 -2
  44. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  45. package/build/components/TemplateKYCExample.js +5 -68
  46. package/build/components/TemplateKYCExample.js.map +1 -1
  47. package/build/components/TemplateKYCFlowRefactored.d.ts +2 -1
  48. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  49. package/build/components/TemplateKYCFlowRefactored.js +95 -9
  50. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  51. package/build/components/example/DynamicTemplateExample.d.ts +10 -0
  52. package/build/components/example/DynamicTemplateExample.d.ts.map +1 -0
  53. package/build/components/example/DynamicTemplateExample.js +241 -0
  54. package/build/components/example/DynamicTemplateExample.js.map +1 -0
  55. package/build/config/allowedDomains.d.ts +30 -0
  56. package/build/config/allowedDomains.d.ts.map +1 -0
  57. package/build/config/allowedDomains.js +127 -0
  58. package/build/config/allowedDomains.js.map +1 -0
  59. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  60. package/build/hooks/useTemplateKYCFlow.js +68 -43
  61. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  62. package/build/hooks/useTemplateLoader.d.ts +14 -0
  63. package/build/hooks/useTemplateLoader.d.ts.map +1 -0
  64. package/build/hooks/useTemplateLoader.js +85 -0
  65. package/build/hooks/useTemplateLoader.js.map +1 -0
  66. package/build/i18n/en/index.d.ts +9 -0
  67. package/build/i18n/en/index.d.ts.map +1 -1
  68. package/build/i18n/en/index.js +9 -0
  69. package/build/i18n/en/index.js.map +1 -1
  70. package/build/i18n/fr/index.d.ts +9 -0
  71. package/build/i18n/fr/index.d.ts.map +1 -1
  72. package/build/i18n/fr/index.js +9 -0
  73. package/build/i18n/fr/index.js.map +1 -1
  74. package/build/index.d.ts +5 -0
  75. package/build/index.d.ts.map +1 -1
  76. package/build/index.js +8 -0
  77. package/build/index.js.map +1 -1
  78. package/build/modules/api/CardAuthentification.js +1 -0
  79. package/build/modules/api/CardAuthentification.js.map +1 -1
  80. package/build/modules/api/KYCService.d.ts +4 -1
  81. package/build/modules/api/KYCService.d.ts.map +1 -1
  82. package/build/modules/api/KYCService.js +17 -5
  83. package/build/modules/api/KYCService.js.map +1 -1
  84. package/build/modules/api/TemplateService.d.ts +45 -0
  85. package/build/modules/api/TemplateService.d.ts.map +1 -0
  86. package/build/modules/api/TemplateService.js +145 -0
  87. package/build/modules/api/TemplateService.js.map +1 -0
  88. package/build/modules/api/types.d.ts +1 -0
  89. package/build/modules/api/types.d.ts.map +1 -1
  90. package/build/modules/api/types.js.map +1 -1
  91. package/build/types/KYC.types.d.ts +144 -4
  92. package/build/types/KYC.types.d.ts.map +1 -1
  93. package/build/types/KYC.types.js +15 -0
  94. package/build/types/KYC.types.js.map +1 -1
  95. package/build/utils/cropByObb.d.ts +1 -0
  96. package/build/utils/cropByObb.d.ts.map +1 -1
  97. package/build/utils/cropByObb.js +70 -0
  98. package/build/utils/cropByObb.js.map +1 -1
  99. package/build/utils/platformAlert.d.ts +20 -0
  100. package/build/utils/platformAlert.d.ts.map +1 -0
  101. package/build/utils/platformAlert.js +67 -0
  102. package/build/utils/platformAlert.js.map +1 -0
  103. package/build/utils/template-transformer.d.ts +10 -0
  104. package/build/utils/template-transformer.d.ts.map +1 -0
  105. package/build/utils/template-transformer.js +353 -0
  106. package/build/utils/template-transformer.js.map +1 -0
  107. package/build/web/WebKYCEntry.d.ts.map +1 -1
  108. package/build/web/WebKYCEntry.js +102 -20
  109. package/build/web/WebKYCEntry.js.map +1 -1
  110. package/package.json +1 -1
  111. package/src/components/EnhancedCameraView.tsx +31 -2
  112. package/src/components/EnhancedCameraView.web.tsx +24 -0
  113. package/src/components/KYCElements/CameraCapture.tsx +4 -3
  114. package/src/components/KYCElements/CountrySelectionTemplate.tsx +410 -113
  115. package/src/components/KYCElements/FileUpload.tsx +5 -4
  116. package/src/components/KYCElements/FileUploadTemplate.tsx +5 -4
  117. package/src/components/KYCElements/IDCardCapture.tsx +196 -254
  118. package/src/components/KYCElements/LocationCaptureTemplate.tsx +95 -44
  119. package/src/components/KYCElements/OrientationVideoCapture.tsx +2 -2
  120. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +2 -2
  121. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +2 -2
  122. package/src/components/KYCElements/SelfieCapture.tsx +4 -3
  123. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +195 -41
  124. package/src/components/KYCElements/WelcomeTemplate.tsx +289 -0
  125. package/src/components/TemplateKYCExample.tsx +16 -71
  126. package/src/components/TemplateKYCFlowRefactored.tsx +121 -11
  127. package/src/components/example/DynamicTemplateExample.tsx +289 -0
  128. package/src/config/allowedDomains.ts +152 -0
  129. package/src/hooks/useTemplateKYCFlow.tsx +71 -46
  130. package/src/hooks/useTemplateLoader.ts +102 -0
  131. package/src/i18n/en/index.ts +10 -0
  132. package/src/i18n/fr/index.ts +9 -0
  133. package/src/index.ts +11 -0
  134. package/src/modules/api/CardAuthentification.ts +1 -1
  135. package/src/modules/api/KYCService.ts +18 -8
  136. package/src/modules/api/TemplateService.ts +167 -0
  137. package/src/modules/api/types.ts +1 -0
  138. package/src/types/KYC.types.ts +188 -3
  139. package/src/utils/cropByObb.ts +83 -3
  140. package/src/utils/platformAlert.ts +85 -0
  141. package/src/utils/template-transformer.ts +433 -0
  142. package/src/web/WebKYCEntry.tsx +122 -24
@@ -0,0 +1,289 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { View, Text, StyleSheet } from 'react-native';
3
+ import { TemplateComponent, WelcomeConfig, LocalizedText } from '../../types/KYC.types';
4
+ import { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';
5
+ import { useI18n } from '../../hooks/useI18n';
6
+ import { Button } from '../ui/Button';
7
+ import ShieldIcon from '../Svgs/Schield';
8
+
9
+ interface WelcomeTemplateProps {
10
+ component: TemplateComponent;
11
+ value?: any;
12
+ onValueChange: (data: any) => void;
13
+ error?: string;
14
+ language?: string;
15
+ }
16
+
17
+ export const WelcomeTemplate: React.FC<WelcomeTemplateProps> = ({
18
+ component,
19
+ value,
20
+ onValueChange,
21
+ error,
22
+ }) => {
23
+ const { t } = useI18n();
24
+ const { getLocalizedText, actions } = useTemplateKYCFlowContext();
25
+ const config = component.config as WelcomeConfig;
26
+
27
+ // Consentements cochés par défaut
28
+ const privacyConsent = true;
29
+ const termsConsent = true;
30
+ const [shouldProceed, setShouldProceed] = useState(false);
31
+
32
+ // Get localized text
33
+ const title = getLocalizedText(component.labels as LocalizedText);
34
+ const description = getLocalizedText(component.instructions as LocalizedText);
35
+ const welcomeMessage = config.welcomeMessage || description;
36
+ const buttonText = config.buttonText || getLocalizedText((component.ui as any).buttonText || { en: 'Get Started', fr: 'Commencer' });
37
+
38
+ // Passer à l'étape suivante après que les données sont mises à jour
39
+ useEffect(() => {
40
+ if (shouldProceed && value && value.consentGiven) {
41
+ // Petit délai pour s'assurer que le state est bien mis à jour
42
+ const timer = setTimeout(() => {
43
+ actions.nextComponent();
44
+ setShouldProceed(false);
45
+ }, 100);
46
+
47
+ return () => clearTimeout(timer);
48
+ }
49
+ return undefined;
50
+ }, [value, shouldProceed, actions]);
51
+
52
+ const handleGetStarted = () => {
53
+ // Mark component as complete
54
+ const consentData = { consentGiven: true, privacyConsent, termsConsent };
55
+ onValueChange(consentData);
56
+ setShouldProceed(true);
57
+ };
58
+
59
+ return (
60
+ <View style={styles.container}>
61
+ <View style={{ flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
62
+ {/* Icon Section */}
63
+ <View style={{ position: 'relative', width: 70 }}>
64
+ <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center', width: 60, height: 60, backgroundColor: '#2DBE60', borderRadius: 100 }}>
65
+ <ShieldIcon />
66
+ </View>
67
+ <View style={{ position: 'absolute', top: '60%', right: 0, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', width: 40, height: 40, backgroundColor: 'white', borderRadius: 100, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.15, shadowRadius: 1.84, elevation: 5 }}>
68
+ <Text style={{ fontSize: 20, color: '#2DBE60' }}>✓</Text>
69
+ </View>
70
+ </View>
71
+
72
+ {/* Title and Description */}
73
+ <View style={{ flexDirection: 'column', alignItems: 'center', justifyContent: 'center', marginTop: 36 }}>
74
+ <Text style={styles.title}>{title}</Text>
75
+ {welcomeMessage && (
76
+ <Text style={styles.description}>
77
+ {welcomeMessage}
78
+ </Text>
79
+ )}
80
+ </View>
81
+
82
+ {/* Requirements List */}
83
+ {config.requirements && config.requirements.length > 0 && (
84
+ <View style={styles.requirementsSection}>
85
+ <Text style={styles.sectionTitle}>
86
+ {t('kyc.welcome.requirements') || `What you'll need:`}
87
+ </Text>
88
+ {config.requirements.map((requirement, index) => (
89
+ <View key={index} style={styles.requirementItem}>
90
+ <Text style={styles.checkmark}>✓</Text>
91
+ <Text style={styles.requirementText}>{requirement}</Text>
92
+ </View>
93
+ ))}
94
+ </View>
95
+ )}
96
+
97
+ {/* Estimated Time */}
98
+ {config.showEstimatedTime !== false && config.estimatedTime && (
99
+ <View style={styles.timeSection}>
100
+ <Text style={styles.timeLabel}>
101
+ {t('kyc.welcome.estimatedTime') || 'Estimated time:'}
102
+ </Text>
103
+ <Text style={styles.timeValue}>{config.estimatedTime}</Text>
104
+ </View>
105
+ )}
106
+
107
+ {/* Consent Options - Hidden by default as they're pre-checked */}
108
+ {(config.consentOptions?.showPrivacyPolicy || config.consentOptions?.showTermsOfService || config.consentOptions?.showMarketingConsent) && (
109
+ <View style={styles.consentSection}>
110
+ {config.consentOptions.showPrivacyPolicy && (
111
+ <View style={styles.consentItem}>
112
+ <View style={[styles.checkbox, styles.checkboxChecked]}>
113
+ <Text style={styles.checkmarkSmall}>✓</Text>
114
+ </View>
115
+ <Text style={styles.consentText}>
116
+ {t('kyc.welcome.privacyPolicy') || 'I agree to the Privacy Policy'}
117
+ </Text>
118
+ </View>
119
+ )}
120
+
121
+ {config.consentOptions.showTermsOfService && (
122
+ <View style={styles.consentItem}>
123
+ <View style={[styles.checkbox, styles.checkboxChecked]}>
124
+ <Text style={styles.checkmarkSmall}>✓</Text>
125
+ </View>
126
+ <Text style={styles.consentText}>
127
+ {t('kyc.welcome.termsOfService') || 'I agree to the Terms of Service'}
128
+ </Text>
129
+ </View>
130
+ )}
131
+
132
+ {config.consentOptions.showMarketingConsent && (
133
+ <View style={styles.consentItem}>
134
+ <View style={[styles.checkbox, styles.checkboxChecked]}>
135
+ <Text style={styles.checkmarkSmall}>✓</Text>
136
+ </View>
137
+ <Text style={styles.consentText}>
138
+ {t('kyc.welcome.marketingConsent') || 'I agree to receive marketing communications'}
139
+ </Text>
140
+ </View>
141
+ )}
142
+ </View>
143
+ )}
144
+
145
+ {error && (
146
+ <View style={styles.errorContainer}>
147
+ <Text style={styles.errorText}>{error}</Text>
148
+ </View>
149
+ )}
150
+
151
+ {/* Get Started Button */}
152
+ <Button
153
+ title={buttonText}
154
+ fullWidth
155
+ onPress={handleGetStarted}
156
+ style={{ paddingVertical: 20, marginTop: 36 }}
157
+ />
158
+
159
+ <View style={{ height: 12 }} />
160
+ </View>
161
+ </View>
162
+ );
163
+ };
164
+
165
+ const styles = StyleSheet.create({
166
+ container: {
167
+ padding: 16,
168
+ backgroundColor: 'white',
169
+ marginHorizontal: 12,
170
+ marginTop: 12,
171
+ borderRadius: 12,
172
+ shadowColor: '#000',
173
+ shadowOffset: { width: 0, height: 2 },
174
+ shadowOpacity: 0.15,
175
+ shadowRadius: 1.84,
176
+ elevation: 3,
177
+ maxWidth: 760,
178
+ },
179
+ title: {
180
+ fontSize: 24,
181
+ fontWeight: 'bold',
182
+ color: '#333',
183
+ marginBottom: 8,
184
+ textAlign: 'center',
185
+ },
186
+ description: {
187
+ fontSize: 16,
188
+ color: '#666',
189
+ textAlign: 'center',
190
+ marginBottom: 24,
191
+ lineHeight: 22,
192
+ },
193
+ requirementsSection: {
194
+ backgroundColor: '#F9FAFB',
195
+ padding: 12,
196
+ borderRadius: 12,
197
+ width: '100%',
198
+ marginTop: 24,
199
+ },
200
+ sectionTitle: {
201
+ fontSize: 16,
202
+ fontWeight: 'bold',
203
+ color: 'black',
204
+ marginBottom: 12,
205
+ textAlign: 'left',
206
+ },
207
+ requirementItem: {
208
+ flexDirection: 'row',
209
+ alignItems: 'center',
210
+ marginBottom: 8,
211
+ },
212
+ checkmark: {
213
+ fontSize: 18,
214
+ color: '#2DBD60',
215
+ marginRight: 12,
216
+ fontWeight: 'bold',
217
+ },
218
+ requirementText: {
219
+ flex: 1,
220
+ fontSize: 16,
221
+ color: '#666',
222
+ textAlign: 'left',
223
+ lineHeight: 22,
224
+ },
225
+ timeSection: {
226
+ backgroundColor: '#F9FAFB',
227
+ padding: 12,
228
+ borderRadius: 12,
229
+ marginTop: 16,
230
+ alignItems: 'center',
231
+ width: '100%',
232
+ },
233
+ timeLabel: {
234
+ fontSize: 14,
235
+ color: '#666',
236
+ marginBottom: 4,
237
+ },
238
+ timeValue: {
239
+ fontSize: 20,
240
+ fontWeight: 'bold',
241
+ color: '#2DBD60',
242
+ },
243
+ consentSection: {
244
+ width: '100%',
245
+ marginTop: 24,
246
+ },
247
+ consentItem: {
248
+ flexDirection: 'row',
249
+ alignItems: 'center',
250
+ marginBottom: 12,
251
+ },
252
+ checkbox: {
253
+ width: 20,
254
+ height: 20,
255
+ borderWidth: 2,
256
+ borderColor: '#ddd',
257
+ borderRadius: 4,
258
+ marginRight: 12,
259
+ alignItems: 'center',
260
+ justifyContent: 'center',
261
+ },
262
+ checkboxChecked: {
263
+ backgroundColor: '#2DBD60',
264
+ borderColor: '#2DBD60',
265
+ },
266
+ checkmarkSmall: {
267
+ fontSize: 14,
268
+ color: 'white',
269
+ fontWeight: 'bold',
270
+ },
271
+ consentText: {
272
+ flex: 1,
273
+ fontSize: 15,
274
+ color: '#333',
275
+ lineHeight: 22,
276
+ },
277
+ errorContainer: {
278
+ backgroundColor: '#fee',
279
+ padding: 12,
280
+ borderRadius: 8,
281
+ marginTop: 16,
282
+ width: '100%',
283
+ },
284
+ errorText: {
285
+ color: '#dc2626',
286
+ fontSize: 14,
287
+ textAlign: 'center',
288
+ },
289
+ });
@@ -103,74 +103,7 @@ const advancedVerificationTemplate: KYCTemplate = {
103
103
  allowed_formats: ["jpg", "png"],
104
104
  max_size_mb: 5,
105
105
  document_types: ["drivers_licence", "passport", "drivers_licence", "national_id"],
106
- bbox_configs: {
107
- drivers_licence: {
108
- xMin: 20,
109
- yMin: 140,
110
- xMax: 370,
111
- yMax: 340,
112
- borderColor: "#2DBD60",
113
- borderWidth: 4,
114
- cornerRadius: 12
115
- },
116
- passport: {
117
- xMin: 15,
118
- yMin: 130,
119
- xMax: 375,
120
- yMax: 350,
121
- borderColor: "#007AFF",
122
- borderWidth: 4,
123
- cornerRadius: 8
124
- },
125
- identity_card: {
126
- xMin: 20,
127
- yMin: 140,
128
- xMax: 370,
129
- yMax: 340,
130
- borderColor: "#2DBD60",
131
- borderWidth: 4,
132
- cornerRadius: 12
133
- },
134
- health_insurance_card: {
135
- xMin: 20,
136
- yMin: 140,
137
- xMax: 370,
138
- yMax: 340,
139
- borderColor: "#2DBD60",
140
- borderWidth: 4,
141
- cornerRadius: 12
142
- },
143
- national_id: {
144
- xMin: 20,
145
- yMin: 140,
146
- xMax: 370,
147
- yMax: 340,
148
- borderColor: "#5856D6",
149
- borderWidth: 4,
150
- cornerRadius: 12
151
- },
152
- permanent_residence: {
153
- xMin: 20,
154
- yMin: 140,
155
- xMax: 370,
156
- yMax: 340,
157
- borderColor: "#2DBD60",
158
- borderWidth: 4,
159
- cornerRadius: 12
160
- },
161
-
162
-
163
- work_permit: {
164
- xMin: 20,
165
- yMin: 140,
166
- xMax: 370,
167
- yMax: 340,
168
- borderColor: "#2DBD60",
169
- borderWidth: 4,
170
- cornerRadius: 12
171
- },
172
-
173
- }
106
+
174
107
  } as const
175
108
  },
176
109
  {
@@ -224,7 +157,15 @@ const advancedVerificationTemplate: KYCTemplate = {
224
157
  ]
225
158
  };
226
159
 
227
- export const TemplateKYCExample: React.FC<{ onComplete: (data: VerificationState) => void, onCancel: () => void, onError: (error: string) => void, language: string, API_KEY: string|undefined }> = ({ onComplete, onCancel, onError, language, API_KEY }) => {
160
+ export const TemplateKYCExample: React.FC<{
161
+ onComplete: (data: VerificationState) => void;
162
+ onCancel: () => void;
163
+ onError: (error: string) => void;
164
+ language: string;
165
+ API_KEY?: string;
166
+ templateId?: string;
167
+ template?: KYCTemplate;
168
+ }> = ({ onComplete, onCancel, onError, language, API_KEY, templateId, template }) => {
228
169
  const handleComplete = (data: VerificationState) => {
229
170
  console.log('KYC Template completed with data:', data);
230
171
  onComplete(data);
@@ -238,14 +179,18 @@ export const TemplateKYCExample: React.FC<{ onComplete: (data: VerificationState
238
179
 
239
180
  const handleError = (error: string) => {
240
181
  console.error('KYC Template error:', error);
241
- // Gérer l'erreur
182
+ onError(error);
242
183
  };
243
184
 
185
+ // Determine which template to use: prefer templateId for dynamic loading, then template prop, then fallback to hardcoded
186
+ const templateToUse = templateId ? undefined : (template || advancedVerificationTemplate);
187
+
244
188
  return (
245
189
  <SafeAreaView style={{ flex: 1 , paddingVertical:25}}>
246
190
  <View style={{ flex: 1 }}>
247
191
  <TemplateKYCFlow
248
- template={advancedVerificationTemplate}
192
+ template={templateToUse}
193
+ templateId={templateId}
249
194
  onComplete={handleComplete}
250
195
  onError={handleError}
251
196
  onCancel={handleCancel}
@@ -1,8 +1,9 @@
1
- import React from 'react';
2
- import { View, Text, StyleSheet, SafeAreaView, TouchableOpacity, ActivityIndicator, Dimensions, Alert } from 'react-native';
1
+ import React, { useEffect } from 'react';
2
+ import { View, Text, StyleSheet, SafeAreaView, TouchableOpacity, ActivityIndicator, Dimensions, ScrollView, Platform } from 'react-native';
3
3
  import { KYCTemplate, VerificationState } from '../types/KYC.types';
4
4
  import { TemplateKYCFlowProvider, useTemplateKYCFlowContext } from '../hooks/useTemplateKYCFlow';
5
5
  import { useI18n } from '../hooks/useI18n';
6
+ import { showAlert } from '../utils/platformAlert';
6
7
  import { IDCardCapture } from './KYCElements/IDCardCapture';
7
8
  import { SelfieCaptureTemplate } from './KYCElements/SelfieCaptureTemplate';
8
9
  import { FileUploadTemplate } from './KYCElements/FileUploadTemplate';
@@ -11,18 +12,22 @@ import { CountrySelectionTemplate } from './KYCElements/CountrySelectionTemplate
11
12
  import { InitializationStep } from './KYCElements/InitializationStep';
12
13
  import { ReviewSubmitTemplate } from './KYCElements/ReviewSubmitTemplate';
13
14
  import { VerificationProgressTemplate } from './KYCElements/VerificationProgressTemplate';
15
+ import { useTemplateLoader } from '../hooks/useTemplateLoader';
16
+ import { WelcomeTemplate } from './KYCElements/WelcomeTemplate';
14
17
 
15
18
  interface TemplateKYCFlowProps {
16
- template: KYCTemplate;
19
+ template?: KYCTemplate; // Format SDK direct (existing, now optional)
20
+ templateId?: string; // New: ID to load from API
17
21
  onComplete?: (data: VerificationState) => void;
18
22
  onError?: (error: string) => void;
19
23
  language?: string;
20
24
  onCancel?: () => void;
21
- API_KEY?: string;
25
+ API_KEY?: string; // Required if templateId is used
22
26
  }
23
27
 
24
28
  export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
25
- template,
29
+ template: providedTemplate,
30
+ templateId,
26
31
  onComplete,
27
32
  onError,
28
33
  language = 'fr',
@@ -30,9 +35,33 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
30
35
  API_KEY,
31
36
  }) => {
32
37
  const { t } = useI18n();
38
+ const { template: loadedTemplate, isLoading, error, loadTemplate } = useTemplateLoader();
39
+
40
+ // Validate props
41
+ useEffect(() => {
42
+ if (!providedTemplate && !templateId) {
43
+ const errorMsg = 'Either template or templateId must be provided';
44
+ onError?.(errorMsg);
45
+ return;
46
+ }
47
+
48
+ if (templateId && !API_KEY) {
49
+ // Try to load without API key (will use token authentication)
50
+ loadTemplate(templateId);
51
+ } else if (templateId && API_KEY) {
52
+ loadTemplate(templateId, API_KEY);
53
+ }
54
+ }, [templateId, API_KEY, providedTemplate, loadTemplate, onError]);
55
+
56
+ // Handle loading errors
57
+ useEffect(() => {
58
+ if (error) {
59
+ onError?.(error);
60
+ }
61
+ }, [error, onError]);
33
62
 
34
63
  const OnCancel = () => {
35
- Alert.alert(
64
+ showAlert(
36
65
  t('kyc.cancelConfirmation.title'),
37
66
  t('kyc.cancelConfirmation.message'),
38
67
  [
@@ -46,6 +75,46 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
46
75
  ]
47
76
  );
48
77
  };
78
+
79
+ // Determine which template to use
80
+ const template = providedTemplate || loadedTemplate;
81
+
82
+ // Show loading state while fetching template
83
+ if (templateId && isLoading && !template) {
84
+ return (
85
+ <View style={styles.loadingContainer}>
86
+ <ActivityIndicator size="large" color="#2DBD60" />
87
+ <Text style={styles.loadingText}>{t('common.loading') || 'Loading template...'}</Text>
88
+ </View>
89
+ );
90
+ }
91
+
92
+ // Show error state if template failed to load
93
+ if (templateId && error && !template) {
94
+ return (
95
+ <View style={styles.errorContainer}>
96
+ <Text style={styles.errorText}>{error}</Text>
97
+ <TouchableOpacity
98
+ style={styles.retryButton}
99
+ onPress={() => loadTemplate(templateId, API_KEY)}
100
+ >
101
+ <Text style={styles.retryButtonText}>{t('common.retry') || 'Retry'}</Text>
102
+ </TouchableOpacity>
103
+ </View>
104
+ );
105
+ }
106
+
107
+ // Show error if no template available
108
+ if (!template) {
109
+ return (
110
+ <View style={styles.errorContainer}>
111
+ <Text style={styles.errorText}>
112
+ {t('errors.unknownError') || 'Template not available'}
113
+ </Text>
114
+ </View>
115
+ );
116
+ }
117
+
49
118
  return (
50
119
  <TemplateKYCFlowProvider
51
120
  template={template}
@@ -97,6 +166,9 @@ const TemplateKYCFlowContent: React.FC<{ onCancel?: () => void }> = ({ onCancel
97
166
  }
98
167
 
99
168
  switch (currentComponent.type) {
169
+ case 'welcome':
170
+ return <WelcomeTemplate {...commonProps} />;
171
+
100
172
  case 'id_card':
101
173
  return <IDCardCapture {...commonProps} />;
102
174
 
@@ -166,9 +238,14 @@ const TemplateKYCFlowContent: React.FC<{ onCancel?: () => void }> = ({ onCancel
166
238
  ) : null}
167
239
 
168
240
  {/* Contenu principal */}
169
- <View style={styles.content}>
241
+ <ScrollView
242
+ style={styles.scrollView}
243
+ contentContainerStyle={styles.content}
244
+ showsVerticalScrollIndicator={Platform.OS === 'web'}
245
+ bounces={false}
246
+ >
170
247
  {renderCurrentComponent()}
171
- </View>
248
+ </ScrollView>
172
249
 
173
250
  {state.isProcessing && (
174
251
  <View style={styles.processingContainer}>
@@ -253,11 +330,13 @@ const styles = StyleSheet.create({
253
330
  color: '#666',
254
331
  lineHeight: 20,
255
332
  },
256
- content: {
333
+ scrollView: {
257
334
  flex: 1,
258
- // justifyContent: 'center',
335
+ },
336
+ content: {
337
+ flexGrow: 1,
259
338
  alignItems: 'center',
260
- // paddingTop: Dimensions.get('window').height > 760 ? 12 : 0,
339
+ paddingBottom: 20, // Add padding for better mobile scrolling
261
340
  },
262
341
  navigation: {
263
342
  flexDirection: 'row',
@@ -316,4 +395,35 @@ const styles = StyleSheet.create({
316
395
  fontWeight: 'bold',
317
396
  marginBottom: 10,
318
397
  },
398
+ loadingContainer: {
399
+ flex: 1,
400
+ justifyContent: 'center',
401
+ alignItems: 'center',
402
+ backgroundColor: '#f5f5f5',
403
+ },
404
+ loadingText: {
405
+ marginTop: 16,
406
+ fontSize: 16,
407
+ color: '#666',
408
+ textAlign: 'center',
409
+ },
410
+ errorContainer: {
411
+ flex: 1,
412
+ justifyContent: 'center',
413
+ alignItems: 'center',
414
+ backgroundColor: '#f5f5f5',
415
+ padding: 20,
416
+ },
417
+ retryButton: {
418
+ marginTop: 20,
419
+ paddingHorizontal: 24,
420
+ paddingVertical: 12,
421
+ backgroundColor: '#2DBD60',
422
+ borderRadius: 8,
423
+ },
424
+ retryButtonText: {
425
+ color: '#fff',
426
+ fontSize: 16,
427
+ fontWeight: '600',
428
+ },
319
429
  });