@transfergratis/react-native-sdk 0.1.4 → 0.1.5

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 (199) hide show
  1. package/build/api/axios.d.ts +30 -0
  2. package/build/api/axios.d.ts.map +1 -0
  3. package/build/api/axios.js +92 -0
  4. package/build/api/axios.js.map +1 -0
  5. package/build/components/EnhancedCameraView.d.ts +1 -41
  6. package/build/components/EnhancedCameraView.d.ts.map +1 -1
  7. package/build/components/EnhancedCameraView.js +75 -34
  8. package/build/components/EnhancedCameraView.js.map +1 -1
  9. package/build/components/EnhancedCameraView.web.d.ts +1 -41
  10. package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
  11. package/build/components/EnhancedCameraView.web.js +28 -4
  12. package/build/components/EnhancedCameraView.web.js.map +1 -1
  13. package/build/components/KYCElements/CountrySelectionTemplate.d.ts +2 -2
  14. package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  15. package/build/components/KYCElements/CountrySelectionTemplate.js +71 -114
  16. package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  17. package/build/components/KYCElements/FileUploadTemplate.d.ts.map +1 -1
  18. package/build/components/KYCElements/FileUploadTemplate.js +7 -3
  19. package/build/components/KYCElements/FileUploadTemplate.js.map +1 -1
  20. package/build/components/KYCElements/IDCardCapture.d.ts +7 -2
  21. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  22. package/build/components/KYCElements/IDCardCapture.js +253 -104
  23. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  24. package/build/components/KYCElements/InitializationStep.d.ts +5 -0
  25. package/build/components/KYCElements/InitializationStep.d.ts.map +1 -0
  26. package/build/components/KYCElements/InitializationStep.js +41 -0
  27. package/build/components/KYCElements/InitializationStep.js.map +1 -0
  28. package/build/components/KYCElements/LocationCaptureTemplate.d.ts.map +1 -1
  29. package/build/components/KYCElements/LocationCaptureTemplate.js +15 -13
  30. package/build/components/KYCElements/LocationCaptureTemplate.js.map +1 -1
  31. package/build/components/KYCElements/OrientationVideoCapture.d.ts +2 -2
  32. package/build/components/KYCElements/OrientationVideoCapture.d.ts.map +1 -1
  33. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  34. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts +2 -2
  35. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts.map +1 -1
  36. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  37. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts +2 -2
  38. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts.map +1 -1
  39. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  40. package/build/components/KYCElements/ReviewSubmitTemplate.d.ts +12 -0
  41. package/build/components/KYCElements/ReviewSubmitTemplate.d.ts.map +1 -0
  42. package/build/components/KYCElements/ReviewSubmitTemplate.js +171 -0
  43. package/build/components/KYCElements/ReviewSubmitTemplate.js.map +1 -0
  44. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts +6 -2
  45. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  46. package/build/components/KYCElements/SelfieCaptureTemplate.js +105 -35
  47. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  48. package/build/components/KYCElements/VerificationProgressTemplate.d.ts +12 -0
  49. package/build/components/KYCElements/VerificationProgressTemplate.d.ts.map +1 -0
  50. package/build/components/KYCElements/VerificationProgressTemplate.js +93 -0
  51. package/build/components/KYCElements/VerificationProgressTemplate.js.map +1 -0
  52. package/build/components/OverLay/IdCard.d.ts +1 -1
  53. package/build/components/OverLay/IdCard.d.ts.map +1 -1
  54. package/build/components/OverLay/IdCard.js +10 -6
  55. package/build/components/OverLay/IdCard.js.map +1 -1
  56. package/build/components/OverLay/SelfieOverlay.d.ts +1 -1
  57. package/build/components/OverLay/SelfieOverlay.d.ts.map +1 -1
  58. package/build/components/OverLay/SelfieOverlay.js +5 -4
  59. package/build/components/OverLay/SelfieOverlay.js.map +1 -1
  60. package/build/components/OverLay/type.d.ts +71 -1
  61. package/build/components/OverLay/type.d.ts.map +1 -1
  62. package/build/components/OverLay/type.js.map +1 -1
  63. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  64. package/build/components/TemplateKYCExample.js +72 -197
  65. package/build/components/TemplateKYCExample.js.map +1 -1
  66. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  67. package/build/components/TemplateKYCFlowRefactored.js +63 -39
  68. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  69. package/build/components/example/OrientationVideoExample.d.ts.map +1 -1
  70. package/build/components/example/OrientationVideoExample.js +1 -5
  71. package/build/components/example/OrientationVideoExample.js.map +1 -1
  72. package/build/config/countriesData.d.ts +3 -0
  73. package/build/config/countriesData.d.ts.map +1 -0
  74. package/build/config/countriesData.js +79 -0
  75. package/build/config/countriesData.js.map +1 -0
  76. package/build/config/region_mapping.d.ts +3 -0
  77. package/build/config/region_mapping.d.ts.map +1 -0
  78. package/build/config/region_mapping.js +687 -0
  79. package/build/config/region_mapping.js.map +1 -0
  80. package/build/hooks/useI18n.d.ts +11 -0
  81. package/build/hooks/useI18n.d.ts.map +1 -0
  82. package/build/hooks/useI18n.js +37 -0
  83. package/build/hooks/useI18n.js.map +1 -0
  84. package/build/hooks/useOrientationVideo.d.ts +1 -2
  85. package/build/hooks/useOrientationVideo.d.ts.map +1 -1
  86. package/build/hooks/useOrientationVideo.js +2 -1
  87. package/build/hooks/useOrientationVideo.js.map +1 -1
  88. package/build/hooks/useRealtimeVerifier.d.ts +28 -0
  89. package/build/hooks/useRealtimeVerifier.d.ts.map +1 -0
  90. package/build/hooks/useRealtimeVerifier.js +91 -0
  91. package/build/hooks/useRealtimeVerifier.js.map +1 -0
  92. package/build/hooks/useTemplateKYCFlow.d.ts +1 -0
  93. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  94. package/build/hooks/useTemplateKYCFlow.js +337 -38
  95. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  96. package/build/i18n/en/index.d.ts +168 -0
  97. package/build/i18n/en/index.d.ts.map +1 -0
  98. package/build/i18n/en/index.js +195 -0
  99. package/build/i18n/en/index.js.map +1 -0
  100. package/build/i18n/fr/index.d.ts +168 -0
  101. package/build/i18n/fr/index.d.ts.map +1 -0
  102. package/build/i18n/fr/index.js +194 -0
  103. package/build/i18n/fr/index.js.map +1 -0
  104. package/build/i18n/index.d.ts +10 -0
  105. package/build/i18n/index.d.ts.map +1 -0
  106. package/build/i18n/index.js +56 -0
  107. package/build/i18n/index.js.map +1 -0
  108. package/build/i18n/types.d.ts +153 -0
  109. package/build/i18n/types.d.ts.map +1 -0
  110. package/build/i18n/types.js +3 -0
  111. package/build/i18n/types.js.map +1 -0
  112. package/build/i18n/usage-example.d.ts +4 -0
  113. package/build/i18n/usage-example.d.ts.map +1 -0
  114. package/build/i18n/usage-example.js +189 -0
  115. package/build/i18n/usage-example.js.map +1 -0
  116. package/build/modules/api/CardAuthentification.d.ts +22 -0
  117. package/build/modules/api/CardAuthentification.d.ts.map +1 -0
  118. package/build/modules/api/CardAuthentification.js +107 -0
  119. package/build/modules/api/CardAuthentification.js.map +1 -0
  120. package/build/modules/api/KYCService.d.ts +57 -1
  121. package/build/modules/api/KYCService.d.ts.map +1 -1
  122. package/build/modules/api/KYCService.js +348 -27
  123. package/build/modules/api/KYCService.js.map +1 -1
  124. package/build/modules/api/SelfieVerification.d.ts +3 -0
  125. package/build/modules/api/SelfieVerification.d.ts.map +1 -0
  126. package/build/modules/api/SelfieVerification.js +9 -0
  127. package/build/modules/api/SelfieVerification.js.map +1 -0
  128. package/build/modules/api/backendApi.d.ts +2 -0
  129. package/build/modules/api/backendApi.d.ts.map +1 -0
  130. package/build/modules/api/backendApi.js +6 -0
  131. package/build/modules/api/backendApi.js.map +1 -0
  132. package/build/modules/api/types.d.ts +20 -0
  133. package/build/modules/api/types.d.ts.map +1 -0
  134. package/build/modules/api/types.js +2 -0
  135. package/build/modules/api/types.js.map +1 -0
  136. package/build/types/KYC.types.d.ts +59 -7
  137. package/build/types/KYC.types.d.ts.map +1 -1
  138. package/build/types/KYC.types.js +9 -1
  139. package/build/types/KYC.types.js.map +1 -1
  140. package/build/utils/cropByObb.d.ts +11 -0
  141. package/build/utils/cropByObb.d.ts.map +1 -0
  142. package/build/utils/cropByObb.js +78 -0
  143. package/build/utils/cropByObb.js.map +1 -0
  144. package/build/utils/get-document-type-info.d.ts +13 -0
  145. package/build/utils/get-document-type-info.d.ts.map +1 -0
  146. package/build/utils/get-document-type-info.js +59 -0
  147. package/build/utils/get-document-type-info.js.map +1 -0
  148. package/build/utils/pathToBase64.d.ts +3 -0
  149. package/build/utils/pathToBase64.d.ts.map +1 -0
  150. package/build/utils/pathToBase64.js +47 -0
  151. package/build/utils/pathToBase64.js.map +1 -0
  152. package/build/utils/remove-duplicate.d.ts +2 -0
  153. package/build/utils/remove-duplicate.d.ts.map +1 -0
  154. package/build/utils/remove-duplicate.js +4 -0
  155. package/build/utils/remove-duplicate.js.map +1 -0
  156. package/package.json +3 -1
  157. package/src/api/axios.ts +144 -0
  158. package/src/components/EnhancedCameraView.tsx +96 -78
  159. package/src/components/EnhancedCameraView.web.tsx +41 -40
  160. package/src/components/KYCElements/CountrySelectionTemplate.tsx +104 -136
  161. package/src/components/KYCElements/FileUploadTemplate.tsx +14 -8
  162. package/src/components/KYCElements/IDCardCapture.tsx +311 -115
  163. package/src/components/KYCElements/InitializationStep.tsx +53 -0
  164. package/src/components/KYCElements/LocationCaptureTemplate.tsx +17 -15
  165. package/src/components/KYCElements/OrientationVideoCapture.tsx +2 -2
  166. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +2 -2
  167. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +2 -2
  168. package/src/components/KYCElements/ReviewSubmitTemplate.tsx +201 -0
  169. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +140 -53
  170. package/src/components/KYCElements/VerificationProgressTemplate.tsx +123 -0
  171. package/src/components/OverLay/IdCard.tsx +17 -9
  172. package/src/components/OverLay/SelfieOverlay.tsx +6 -5
  173. package/src/components/OverLay/type.ts +64 -2
  174. package/src/components/TemplateKYCExample.tsx +76 -197
  175. package/src/components/TemplateKYCFlowRefactored.tsx +74 -46
  176. package/src/components/example/OrientationVideoExample.tsx +3 -7
  177. package/src/config/countriesData.ts +84 -0
  178. package/src/config/region_mapping.ts +688 -0
  179. package/src/hooks/useI18n.ts +53 -0
  180. package/src/hooks/useOrientationVideo.ts +2 -2
  181. package/src/hooks/useRealtimeVerifier.ts +128 -0
  182. package/src/hooks/useTemplateKYCFlow.tsx +375 -53
  183. package/src/i18n/README.md +288 -0
  184. package/src/i18n/en/index.ts +206 -0
  185. package/src/i18n/fr/index.ts +205 -0
  186. package/src/i18n/index.ts +65 -0
  187. package/src/i18n/types.ts +172 -0
  188. package/src/i18n/usage-example.tsx +202 -0
  189. package/src/modules/api/CardAuthentification.ts +114 -0
  190. package/src/modules/api/KYCService.ts +403 -30
  191. package/src/modules/api/SelfieVerification.ts +11 -0
  192. package/src/modules/api/backendApi.ts +8 -0
  193. package/src/modules/api/types.ts +24 -0
  194. package/src/types/KYC.types.ts +83 -14
  195. package/src/utils/cropByObb.ts +99 -0
  196. package/src/utils/get-document-type-info.ts +62 -0
  197. package/src/utils/pathToBase64.ts +47 -0
  198. package/src/utils/remove-duplicate.ts +3 -0
  199. package/src/types/nativewind.d.ts +0 -2
@@ -0,0 +1,144 @@
1
+ import axios, {
2
+ AxiosInstance,
3
+ AxiosRequestConfig,
4
+ InternalAxiosRequestConfig,
5
+ AxiosResponse,
6
+ } from 'axios';
7
+
8
+ export type ApiConfiguration = {
9
+ baseURL: string;
10
+ apiKey?: string;
11
+ authToken?: string;
12
+ timeoutMs?: number;
13
+ };
14
+
15
+ export type ApiErrorData = {
16
+ message?: string;
17
+ code?: string | number;
18
+ details?: unknown;
19
+ };
20
+
21
+ export class HttpClient {
22
+ private instance: AxiosInstance;
23
+ private apiKey?: string;
24
+ private authToken?: string;
25
+
26
+ constructor(configuration: ApiConfiguration) {
27
+ this.apiKey = configuration.apiKey;
28
+ this.authToken = configuration.authToken;
29
+ this.instance = axios.create({
30
+ baseURL: configuration.baseURL,
31
+ timeout: configuration.timeoutMs ?? 15000,
32
+ headers: {
33
+ Accept: 'application/json',
34
+ 'Content-Type': 'application/json',
35
+ },
36
+ });
37
+
38
+ this.instance.interceptors.request.use(
39
+ (request: InternalAxiosRequestConfig) => {
40
+ const headers = request.headers ?? {};
41
+ if (this.apiKey && !headers['x-api-key']) {
42
+ headers['x-api-key'] = this.apiKey;
43
+ }
44
+ if (this.authToken && !headers.Authorization) {
45
+ headers.Authorization = `Bearer ${this.authToken}`;
46
+ }
47
+ request.headers = headers;
48
+ return request;
49
+ },
50
+ (error) => Promise.reject(error)
51
+ );
52
+
53
+ this.instance.interceptors.response.use(
54
+ (response: AxiosResponse) => response,
55
+ (error) => {
56
+ if (!error.response) {
57
+ return Promise.reject({
58
+ message: 'Network error. Please check your connection.',
59
+ code: 'network_error',
60
+ details: error?.message,
61
+ } as ApiErrorData);
62
+ }
63
+ const { status, data } = error.response as AxiosResponse<ApiErrorData>;
64
+ if (status === 401) {
65
+ return Promise.reject({
66
+ message: data?.message || 'Unauthorized',
67
+ code: 401,
68
+ details: data,
69
+ } as ApiErrorData);
70
+ }
71
+ return Promise.reject({
72
+ message: data?.message || 'Request failed',
73
+ code: status,
74
+ details: data,
75
+ } as ApiErrorData);
76
+ }
77
+ );
78
+ }
79
+
80
+ setAuthToken(token?: string): void {
81
+ this.authToken = token;
82
+ }
83
+
84
+ setApiKey(key?: string): void {
85
+ this.apiKey = key;
86
+ }
87
+
88
+ setBaseURL(url: string): void {
89
+ this.instance.defaults.baseURL = url;
90
+ }
91
+
92
+ async get<T = unknown>(url: string, requestConfig?: AxiosRequestConfig): Promise<T> {
93
+ const res = await this.instance.get<T>(url, requestConfig);
94
+ return res.data as T;
95
+ }
96
+
97
+ async post<T = unknown, B = unknown>(
98
+ url: string,
99
+ body?: B,
100
+ requestConfig?: AxiosRequestConfig
101
+ ): Promise<T> {
102
+ const res = await this.instance.post<T>(url, body, requestConfig);
103
+ return res.data as T;
104
+ }
105
+
106
+ async put<T = unknown, B = unknown>(
107
+ url: string,
108
+ body?: B,
109
+ requestConfig?: AxiosRequestConfig
110
+ ): Promise<T> {
111
+ const res = await this.instance.put<T>(url, body, requestConfig);
112
+ return res.data as T;
113
+ }
114
+
115
+ async patch<T = unknown, B = unknown>(
116
+ url: string,
117
+ body?: B,
118
+ requestConfig?: AxiosRequestConfig
119
+ ): Promise<T> {
120
+ const res = await this.instance.patch<T>(url, body, requestConfig);
121
+ return res.data as T;
122
+ }
123
+
124
+ async delete<T = unknown>(url: string, requestConfig?: AxiosRequestConfig): Promise<T> {
125
+ const res = await this.instance.delete<T>(url, requestConfig);
126
+ return res.data as T;
127
+ }
128
+ }
129
+
130
+ export default HttpClient;
131
+
132
+
133
+ // ml service api
134
+ export const mlService = new HttpClient({
135
+ baseURL: 'https://api.ml.transfergratis.com',
136
+ apiKey: 'your-api-key',
137
+ });
138
+ // backedn service api
139
+ export const backendService = new HttpClient({
140
+ baseURL: 'https://api.backend.transfergratis.com',
141
+ apiKey: 'your-api-key',
142
+ });
143
+
144
+
@@ -1,39 +1,12 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { View, StyleSheet, TouchableOpacity, Text, ViewStyle } from 'react-native';
2
+ import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
3
3
  import { Camera, useCameraDevice } from 'react-native-vision-camera';
4
4
  import VisionCameraModule from '../modules/camera/VisionCameraModule';
5
+ import { useI18n } from '../hooks/useI18n';
6
+ import { EnhancedCameraViewProps } from './OverLay/type';
7
+
8
+
5
9
 
6
- export interface EnhancedCameraViewProps {
7
- instructions?: string;
8
- showCamera: boolean;
9
- cameraType?: 'front' | 'back';
10
- style?: ViewStyle;
11
- onCapture?: (result: { success: boolean; path?: string; error?: string }) => void;
12
- onError?: (event: { message: string }) => void;
13
- onClose?: () => void;
14
- enableFlash?: boolean;
15
- enableHdr?: boolean;
16
- quality?: 'low' | 'medium' | 'high';
17
- showCaptureButton?: boolean;
18
- showSwitchCamera?: boolean;
19
- overlayComponent?: React.ReactNode;
20
- bbox?: {
21
- xMin: number;
22
- yMin: number;
23
- xMax: number;
24
- yMax: number;
25
- borderColor?: string;
26
- borderWidth?: number;
27
- cornerRadius?: number;
28
- };
29
- canFlip?: boolean;
30
- // Video recording props
31
- enableVideo?: boolean;
32
- isRecording?: boolean;
33
- onVideoRecordingStart?: () => void;
34
- onVideoRecordingStop?: (result: { success: boolean; path?: string; error?: string }) => void;
35
- videoDuration?: number;
36
- }
37
10
 
38
11
  export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
39
12
  instructions = 'Position yourself in the frame and tap the capture button',
@@ -56,7 +29,10 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
56
29
  onVideoRecordingStart,
57
30
  onVideoRecordingStop,
58
31
  videoDuration = 10,
32
+ onSilentCapture,
33
+ silentCaptureResult,
59
34
  }) => {
35
+ const { t } = useI18n();
60
36
  const camera = useRef<Camera>(null);
61
37
  const [cameraType, setCameraType] = useState<'front' | 'back'>(initialCameraType);
62
38
  const [hasPermission, setHasPermission] = useState(false);
@@ -64,6 +40,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
64
40
  const [flash, setFlash] = useState<'off' | 'on' | 'auto'>('off');
65
41
 
66
42
  const device = useCameraDevice(cameraType);
43
+ console.log({ setCameraType, setFlash });
67
44
 
68
45
  // Check permissions on component mount
69
46
  useEffect(() => {
@@ -78,14 +55,14 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
78
55
  if (!hasAllPermissions) {
79
56
  const granted = await VisionCameraModule.requestAllPermissions();
80
57
  if (!granted) {
81
- onError?.({ message: 'Camera permissions not granted' });
58
+ onError?.({ message: t('camera.permissionRequired') });
82
59
  return;
83
60
  }
84
61
  }
85
62
  setHasPermission(true);
86
63
  } catch (error) {
87
64
  console.error('Error checking permissions:', error);
88
- onError?.({ message: 'Error checking camera permissions' });
65
+ onError?.({ message: t('camera.errorOccurred') });
89
66
  }
90
67
  };
91
68
 
@@ -96,13 +73,48 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
96
73
 
97
74
  const onCameraError = useCallback((error: any) => {
98
75
  console.error('Camera error:', error);
99
- onError?.({ message: error.message || 'Camera error occurred' });
100
- }, [onError]);
76
+ onError?.({ message: error.message || t('camera.errorOccurred') });
77
+ }, [onError, t]);
78
+
79
+ const captureSilentPhoto = useCallback(async () => {
80
+ if (!camera.current || !isInitialized) {
81
+ onError?.({ message: t('camera.notReady') });
82
+ return;
83
+ }
84
+ console.log('silentCaptureResult', silentCaptureResult);
85
+ if (silentCaptureResult?.isAnalyzing || silentCaptureResult?.success) {
86
+ return;
87
+ }
88
+ try {
89
+ const photo = await camera.current.takePhoto({
90
+ enableShutterSound: true,
91
+ flash: enableFlash ? flash : 'off',
92
+ });
93
+
94
+ const result = await VisionCameraModule.processPhotoResult(photo);
95
+ onSilentCapture?.(result);
96
+ } catch (error) {
97
+
98
+ }
99
+ }, [isInitialized, onError, onSilentCapture]);
100
+
101
+ // Automatically take a silent photo every 5 seconds when ready
102
+ useEffect(() => {
103
+ if (!showCamera || !isInitialized) {
104
+ return;
105
+ }
106
+
107
+ const intervalId = setInterval(() => {
108
+ captureSilentPhoto();
109
+ }, 5000);
110
+
111
+ return () => clearInterval(intervalId);
112
+ }, [showCamera, isInitialized, captureSilentPhoto]);
101
113
 
102
114
  const capturePhoto = useCallback(async () => {
103
115
  try {
104
116
  if (!camera.current || !isInitialized) {
105
- onError?.({ message: 'Camera not ready' });
117
+ onError?.({ message: t('camera.notReady') });
106
118
  return;
107
119
  }
108
120
 
@@ -111,13 +123,13 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
111
123
  flash: enableFlash ? flash : 'off',
112
124
  });
113
125
 
114
- const result = await VisionCameraModule.processPhotoResult(photo);
126
+ const result = await VisionCameraModule.processPhotoResult(photo);
115
127
  onCapture?.(result);
116
128
  } catch (error) {
117
129
  console.error('Error taking photo:', error);
118
130
  onCapture?.({
119
131
  success: false,
120
- error: error instanceof Error ? error.message : 'Failed to capture photo',
132
+ error: error instanceof Error ? error.message : t('camera.failedToCapture'),
121
133
  });
122
134
  }
123
135
  }, [isInitialized, quality, flash, enableFlash, onCapture, onError]);
@@ -125,7 +137,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
125
137
  const startVideoRecording = useCallback(async () => {
126
138
  try {
127
139
  if (!camera.current || !isInitialized) {
128
- onError?.({ message: 'Camera not ready' });
140
+ onError?.({ message: t('camera.notReady') });
129
141
  return;
130
142
  }
131
143
 
@@ -140,7 +152,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
140
152
  console.error('Recording error:', error);
141
153
  onVideoRecordingStop?.({
142
154
  success: false,
143
- error: error.message || 'Failed to record video',
155
+ error: error.message || t('camera.failedToStartRecording'),
144
156
  });
145
157
  },
146
158
  });
@@ -150,7 +162,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
150
162
  console.error('Error starting video recording:', error);
151
163
  onVideoRecordingStop?.({
152
164
  success: false,
153
- error: error instanceof Error ? error.message : 'Failed to start video recording',
165
+ error: error instanceof Error ? error.message : t('camera.failedToStartRecording'),
154
166
  });
155
167
  }
156
168
  }, [isInitialized, onVideoRecordingStart, onVideoRecordingStop, onError]);
@@ -158,37 +170,37 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
158
170
  const stopVideoRecording = useCallback(async () => {
159
171
  try {
160
172
  if (!camera.current) {
161
- onError?.({ message: 'Camera not ready' });
173
+ onError?.({ message: t('camera.notReady') });
162
174
  return;
163
175
  }
164
176
 
165
177
  await camera.current.stopRecording();
166
178
  } catch (error) {
167
179
  console.error('Error stopping video recording:', error);
168
- onError?.({ message: 'Failed to stop video recording' });
180
+ onError?.({ message: t('camera.failedToStopRecording') });
169
181
  }
170
182
  }, [onError]);
171
183
 
172
- const switchCamera = useCallback(() => {
173
- setCameraType(current => current === 'front' ? 'back' : 'front');
174
- }, []);
184
+ // const switchCamera = useCallback(() => {
185
+ // setCameraType(current => current === 'front' ? 'back' : 'front');
186
+ // }, []);
175
187
 
176
- const toggleFlash = useCallback(() => {
177
- setFlash(current => {
178
- switch (current) {
179
- case 'off': return 'on';
180
- case 'on': return 'auto';
181
- case 'auto': return 'off';
182
- default: return 'off';
183
- }
184
- });
185
- }, []);
188
+ // const toggleFlash = useCallback(() => {
189
+ // setFlash(current => {
190
+ // switch (current) {
191
+ // case 'off': return 'on';
192
+ // case 'on': return 'auto';
193
+ // case 'auto': return 'off';
194
+ // default: return 'off';
195
+ // }
196
+ // });
197
+ // }, []);
186
198
 
187
199
  if (!hasPermission) {
188
200
  return (
189
201
  <View style={[styles.container, style]}>
190
202
  <Text style={styles.permissionMessage}>
191
- Camera permission required. Please grant permission to continue.
203
+ {t('camera.permissionRequired')}
192
204
  </Text>
193
205
  </View>
194
206
  );
@@ -198,7 +210,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
198
210
  return (
199
211
  <View style={[styles.container, style]}>
200
212
  <Text style={styles.errorMessage}>
201
- Camera device not available
213
+ {t('camera.deviceNotAvailable')}
202
214
  </Text>
203
215
  </View>
204
216
  );
@@ -235,20 +247,20 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
235
247
  {/* Bounding box overlay */}
236
248
  {bbox && (
237
249
  <View style={styles.bboxOverlay}>
238
- <View
239
- style={[
240
- styles.bbox,
241
- {
242
- left: `${bbox.xMin}%`,
243
- top: `${bbox.yMin}%`,
244
- width: `${bbox.xMax - bbox.xMin}%`,
245
- height: `${bbox.yMax - bbox.yMin}%`,
246
- borderColor: bbox.borderColor || '#2DBD60',
247
- borderWidth: bbox.borderWidth || 3,
248
- borderRadius: bbox.cornerRadius || 8,
249
- }
250
- ]}
251
- />
250
+ <View
251
+ style={[
252
+ styles.bbox,
253
+ {
254
+ left: `${bbox.xMin}%`,
255
+ top: `${bbox.yMin}%`,
256
+ width: `${bbox.xMax - bbox.xMin}%`,
257
+ height: `${bbox.yMax - bbox.yMin}%`,
258
+ borderColor: bbox.borderColor || '#2DBD60',
259
+ borderWidth: bbox.borderWidth || 3,
260
+ borderRadius: bbox.cornerRadius || 8,
261
+ }
262
+ ]}
263
+ />
252
264
  </View>
253
265
  )}
254
266
 
@@ -256,16 +268,16 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
256
268
  {/* Camera controls */}
257
269
  <View style={styles.controlsContainer}>
258
270
  {/* Flash button */}
259
- {enableFlash && (
271
+ {/* {enableFlash && (
260
272
  <TouchableOpacity style={styles.controlButton} onPress={toggleFlash}>
261
273
  <Text style={styles.controlButtonText}>
262
274
  {flash === 'off' ? '⚡' : flash === 'on' ? '⚡️' : '✨'}
263
275
  </Text>
264
276
  </TouchableOpacity>
265
- )}
277
+ )} */}
266
278
 
267
279
  {/* Capture button */}
268
- {showCaptureButton && !enableVideo && (
280
+ {showCaptureButton && !enableVideo && silentCaptureResult?.success && (
269
281
  <TouchableOpacity
270
282
  style={styles.captureButton}
271
283
  onPress={capturePhoto}
@@ -279,7 +291,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
279
291
  )}
280
292
 
281
293
  {/* Video recording button */}
282
- {showCaptureButton && enableVideo && (
294
+ {showCaptureButton && enableVideo && silentCaptureResult?.success && (
283
295
  <TouchableOpacity
284
296
  style={[
285
297
  styles.captureButton,
@@ -297,10 +309,16 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
297
309
  )}
298
310
 
299
311
  {/* Switch camera button */}
300
- {showSwitchCamera && canFlip && (
312
+ {/* {showSwitchCamera && canFlip && (
301
313
  <TouchableOpacity style={styles.controlButton} onPress={switchCamera}>
302
314
  <Text style={styles.controlButtonText}>🔄</Text>
303
315
  </TouchableOpacity>
316
+ )} */}
317
+
318
+ {silentCaptureResult?.isAnalyzing && (
319
+ <View style={{ backgroundColor: 'rgba(0, 0, 0, 0.7)', padding: 10, borderRadius: 10 }}>
320
+ <Text style={{ color: 'white', fontSize: 16, fontWeight: 'bold' }}>{t('camera.analyzing')}</Text>
321
+ </View>
304
322
  )}
305
323
  </View>
306
324
  </View>
@@ -1,37 +1,7 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { View, StyleSheet, TouchableOpacity, Text, ViewStyle, Platform } from 'react-native';
3
-
4
- export interface EnhancedCameraViewProps {
5
- instructions?: string;
6
- showCamera: boolean;
7
- cameraType?: 'front' | 'back';
8
- style?: ViewStyle;
9
- onCapture?: (result: { success: boolean; path?: string; error?: string }) => void;
10
- onError?: (event: { message: string }) => void;
11
- onClose?: () => void;
12
- enableFlash?: boolean;
13
- enableHdr?: boolean;
14
- quality?: 'low' | 'medium' | 'high';
15
- showCaptureButton?: boolean;
16
- showSwitchCamera?: boolean;
17
- overlayComponent?: React.ReactNode;
18
- bbox?: {
19
- xMin: number;
20
- yMin: number;
21
- xMax: number;
22
- yMax: number;
23
- borderColor?: string;
24
- borderWidth?: number;
25
- cornerRadius?: number;
26
- };
27
- canFlip?: boolean;
28
- // Video recording props
29
- enableVideo?: boolean;
30
- isRecording?: boolean;
31
- onVideoRecordingStart?: () => void;
32
- onVideoRecordingStop?: (result: { success: boolean; path?: string; error?: string }) => void;
33
- videoDuration?: number;
34
- }
2
+ import { View, StyleSheet, TouchableOpacity, Text, Platform } from 'react-native';
3
+ import { EnhancedCameraViewProps } from './OverLay/type';
4
+
35
5
 
36
6
  export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
37
7
  instructions = 'Position yourself in the frame and tap the capture button',
@@ -54,6 +24,8 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
54
24
  onVideoRecordingStart,
55
25
  onVideoRecordingStop,
56
26
  videoDuration = 10,
27
+ onSilentCapture,
28
+ silentCaptureResult,
57
29
  }) => {
58
30
  // Vérification de plateforme - ce composant est uniquement pour le web
59
31
  if (Platform.OS !== 'web') {
@@ -98,7 +70,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
98
70
  // Test camera permission
99
71
  const stream = await navigator.mediaDevices.getUserMedia({ video: true });
100
72
  stream.getTracks().forEach(track => track.stop());
101
-
73
+
102
74
  setHasPermission(true);
103
75
  await startCamera();
104
76
  } catch (error) {
@@ -150,6 +122,21 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
150
122
  console.log('isInitialized', onInitialized, onCameraError);
151
123
 
152
124
  const capturePhoto = useCallback(async () => {
125
+ try {
126
+ onCapture && onCapture({
127
+ success: true
128
+ })
129
+ } catch (error) {
130
+ console.error('Error taking photo:', error);
131
+ onCapture?.({
132
+ success: false,
133
+ error: error instanceof Error ? error.message : 'Failed to capture photo',
134
+ });
135
+ }
136
+ }, [isInitialized, onCapture, onError]);
137
+
138
+
139
+ const captureSilentPhoto = useCallback(async () => {
153
140
  try {
154
141
  if (!videoRef.current || !canvasRef.current || !isInitialized) {
155
142
  onError?.({ message: 'Camera not ready' });
@@ -174,8 +161,8 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
174
161
 
175
162
  // Convert to base64
176
163
  const imageDataUrl = canvas.toDataURL('image/jpeg', 0.8);
177
-
178
- onCapture?.({
164
+
165
+ onSilentCapture?.({
179
166
  success: true,
180
167
  path: imageDataUrl,
181
168
  });
@@ -186,7 +173,21 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
186
173
  error: error instanceof Error ? error.message : 'Failed to capture photo',
187
174
  });
188
175
  }
189
- }, [isInitialized, onCapture, onError]);
176
+ }, [isInitialized, onError, onSilentCapture]);
177
+
178
+
179
+ // Automatically take a silent photo every 5 seconds when ready
180
+ useEffect(() => {
181
+ if (!showCamera || !isInitialized) {
182
+ return;
183
+ }
184
+
185
+ const intervalId = setInterval(() => {
186
+ captureSilentPhoto();
187
+ }, 5000);
188
+
189
+ return () => clearInterval(intervalId);
190
+ }, [showCamera, isInitialized, captureSilentPhoto]);
190
191
 
191
192
  const startVideoRecording = useCallback(async () => {
192
193
  try {
@@ -211,12 +212,12 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
211
212
  recorder.onstop = () => {
212
213
  const blob = new Blob(chunks, { type: 'video/webm' });
213
214
  const url = URL.createObjectURL(blob);
214
-
215
+
215
216
  onVideoRecordingStop?.({
216
217
  success: true,
217
218
  path: url,
218
219
  });
219
-
220
+
220
221
  setRecordedChunks([]);
221
222
  setIsRecordingVideo(false);
222
223
  };
@@ -361,7 +362,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
361
362
  )}
362
363
 
363
364
  {/* Capture button */}
364
- {showCaptureButton && !enableVideo && (
365
+ {showCaptureButton && !enableVideo && silentCaptureResult?.success && (
365
366
  <TouchableOpacity
366
367
  style={styles.captureButton}
367
368
  onPress={capturePhoto}