@sanctum-key/react-native-sdk 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/package.json +1 -1
- package/build/src/components/EnhancedCameraView.d.ts.map +1 -1
- package/build/src/components/EnhancedCameraView.js +61 -12
- package/build/src/components/EnhancedCameraView.js.map +1 -1
- package/build/src/components/KYCElements/EmailVerificationTemplate.d.ts.map +1 -1
- package/build/src/components/KYCElements/EmailVerificationTemplate.js +32 -11
- package/build/src/components/KYCElements/EmailVerificationTemplate.js.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.js +1 -2
- package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/src/components/KYCElements/PhoneVerificationTemplate.d.ts.map +1 -1
- package/build/src/components/KYCElements/PhoneVerificationTemplate.js +30 -17
- package/build/src/components/KYCElements/PhoneVerificationTemplate.js.map +1 -1
- package/build/src/modules/api/KYCService.d.ts +2 -1
- package/build/src/modules/api/KYCService.d.ts.map +1 -1
- package/build/src/modules/api/KYCService.js +11 -10
- package/build/src/modules/api/KYCService.js.map +1 -1
- package/package.json +1 -1
- package/src/components/EnhancedCameraView.tsx +99 -34
- package/src/components/KYCElements/EmailVerificationTemplate.tsx +36 -10
- package/src/components/KYCElements/IDCardCapture.tsx +1 -1
- package/src/components/KYCElements/PhoneVerificationTemplate.tsx +36 -22
- package/src/modules/api/KYCService.ts +15 -14
package/build/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,
|
|
1
|
+
{"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA6MhE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { View, StyleSheet, Text, AppState } from 'react-native';
|
|
2
|
+
import { View, StyleSheet, Text, AppState, ActivityIndicator } from 'react-native';
|
|
3
3
|
import { Camera, useCameraDevice } from 'react-native-vision-camera';
|
|
4
4
|
import VisionCameraModule from '../modules/camera/VisionCameraModule';
|
|
5
5
|
import { useI18n } from '../hooks/useI18n';
|
|
@@ -10,10 +10,11 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
10
10
|
const isCapturingRef = useRef(false);
|
|
11
11
|
const isProcessingRef = useRef(isProcessing);
|
|
12
12
|
const [cameraType] = useState(initialCameraType);
|
|
13
|
-
// 🚨 BUG FIX: Initialize to null to prevent the "Flicker" on retake
|
|
14
13
|
const [hasPermission, setHasPermission] = useState(null);
|
|
15
14
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
16
15
|
const [refreshCamera, setRefreshCamera] = useState(false);
|
|
16
|
+
// 🚨 ADDED: A timeout state to show a refresh button if the camera gets stuck booting
|
|
17
|
+
const [showInitTimeout, setShowInitTimeout] = useState(false);
|
|
17
18
|
const device = useCameraDevice(cameraType);
|
|
18
19
|
useEffect(() => {
|
|
19
20
|
isProcessingRef.current = isProcessing;
|
|
@@ -37,8 +38,10 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
37
38
|
}
|
|
38
39
|
};
|
|
39
40
|
useEffect(() => {
|
|
40
|
-
if (showCamera)
|
|
41
|
+
if (showCamera) {
|
|
42
|
+
setIsInitialized(false); // Reset init state when checking permissions/refreshing
|
|
41
43
|
checkPermissions();
|
|
44
|
+
}
|
|
42
45
|
}, [showCamera, refreshCamera]);
|
|
43
46
|
useEffect(() => {
|
|
44
47
|
const subscription = AppState.addEventListener('change', nextAppState => {
|
|
@@ -48,7 +51,23 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
48
51
|
});
|
|
49
52
|
return () => subscription.remove();
|
|
50
53
|
}, [showCamera, hasPermission]);
|
|
51
|
-
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
let timer;
|
|
56
|
+
if (hasPermission && device && showCamera && !isInitialized) {
|
|
57
|
+
timer = setTimeout(() => setShowInitTimeout(true), 3000);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
setShowInitTimeout(false);
|
|
61
|
+
}
|
|
62
|
+
return () => {
|
|
63
|
+
if (timer)
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
};
|
|
66
|
+
}, [hasPermission, device, showCamera, isInitialized]);
|
|
67
|
+
const onInitialized = useCallback(() => {
|
|
68
|
+
setIsInitialized(true);
|
|
69
|
+
setShowInitTimeout(false);
|
|
70
|
+
}, []);
|
|
52
71
|
const onCameraError = useCallback((error) => {
|
|
53
72
|
onError?.({ message: error.message || t('camera.errorOccurred') });
|
|
54
73
|
}, [onError, t]);
|
|
@@ -76,7 +95,6 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
76
95
|
isCapturingRef.current = false;
|
|
77
96
|
}
|
|
78
97
|
}, [isInitialized, onSilentCapture, silentCaptureResult]);
|
|
79
|
-
// 🚨 BUG FIX: The Warm-up Timer (Fixes Blurry Images)
|
|
80
98
|
useEffect(() => {
|
|
81
99
|
if (!showCamera || !isInitialized || isProcessing)
|
|
82
100
|
return;
|
|
@@ -87,7 +105,7 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
87
105
|
return;
|
|
88
106
|
intervalId = setInterval(() => {
|
|
89
107
|
captureSilentPhoto();
|
|
90
|
-
}, 1500);
|
|
108
|
+
}, 1500);
|
|
91
109
|
}, 1000);
|
|
92
110
|
return () => {
|
|
93
111
|
isActive = false;
|
|
@@ -97,25 +115,56 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
97
115
|
};
|
|
98
116
|
}, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);
|
|
99
117
|
// --- RENDERERS ---
|
|
100
|
-
// 🚨 BUG FIX: Show nothing while checking permissions (Stops flicker)
|
|
101
118
|
if (hasPermission === null) {
|
|
102
119
|
return <View style={[styles.container, style]}/>;
|
|
103
120
|
}
|
|
104
121
|
if (hasPermission === false) {
|
|
105
|
-
return (<View style={[styles.container, style,
|
|
122
|
+
return (<View style={[styles.container, style, styles.centerContent]}>
|
|
106
123
|
<Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>
|
|
107
124
|
<Button title="Refresh Camera" onPress={() => setRefreshCamera(prev => !prev)} variant="primary"/>
|
|
108
125
|
</View>);
|
|
109
126
|
}
|
|
110
|
-
if
|
|
111
|
-
|
|
127
|
+
// 🚨 FIX: Don't return an invisible blank screen if the device is loading!
|
|
128
|
+
// Give them a UI and a way out.
|
|
129
|
+
if (!device || !showCamera) {
|
|
130
|
+
return (<View style={[styles.container, style, styles.centerContent]}>
|
|
131
|
+
<ActivityIndicator size="large" color="#2DBD60" style={{ marginBottom: 16 }}/>
|
|
132
|
+
<Text style={styles.permissionMessage}>Loading Camera Hardware...</Text>
|
|
133
|
+
<Button title="Refresh" onPress={() => setRefreshCamera(prev => !prev)} variant="outline"/>
|
|
134
|
+
</View>);
|
|
135
|
+
}
|
|
112
136
|
return (<View style={[styles.container, style]}>
|
|
113
|
-
<Camera
|
|
137
|
+
<Camera
|
|
138
|
+
// 🚨 FIX: This key forces the native component to completely remount
|
|
139
|
+
// when permissions are granted or when manually refreshed.
|
|
140
|
+
key={`cam-${hasPermission}-${refreshCamera ? '1' : '0'}`} ref={camera} style={StyleSheet.absoluteFill} device={device} isActive={showCamera && !isProcessing} photo={true} video={false} audio={false} onInitialized={onInitialized} onError={onCameraError}/>
|
|
141
|
+
|
|
142
|
+
{/* 🚨 FIX: Floating Refresh Button if the hardware freezes on a black screen */}
|
|
143
|
+
{!isInitialized && showInitTimeout && (<View style={styles.stuckOverlay}>
|
|
144
|
+
<ActivityIndicator size="large" color="#2DBD60" style={{ marginBottom: 16 }}/>
|
|
145
|
+
<Text style={{ color: 'white', marginBottom: 16, fontWeight: 'bold' }}>
|
|
146
|
+
Camera is taking a while to start...
|
|
147
|
+
</Text>
|
|
148
|
+
<Button title="Restart Camera" onPress={() => {
|
|
149
|
+
setIsInitialized(false);
|
|
150
|
+
setRefreshCamera(prev => !prev);
|
|
151
|
+
}} variant="primary"/>
|
|
152
|
+
</View>)}
|
|
153
|
+
|
|
114
154
|
{overlayComponent}
|
|
115
155
|
</View>);
|
|
116
156
|
};
|
|
117
157
|
const styles = StyleSheet.create({
|
|
118
158
|
container: { flex: 1, backgroundColor: 'black' },
|
|
119
|
-
|
|
159
|
+
centerContent: { justifyContent: 'center', alignItems: 'center', padding: 20 },
|
|
160
|
+
permissionMessage: { color: 'white', textAlign: 'center', marginBottom: 20, fontSize: 16, fontWeight: '600' },
|
|
161
|
+
stuckOverlay: {
|
|
162
|
+
...StyleSheet.absoluteFillObject,
|
|
163
|
+
justifyContent: 'center',
|
|
164
|
+
alignItems: 'center',
|
|
165
|
+
backgroundColor: 'rgba(0,0,0,0.85)',
|
|
166
|
+
zIndex: 1000,
|
|
167
|
+
padding: 20
|
|
168
|
+
}
|
|
120
169
|
});
|
|
121
170
|
//# sourceMappingURL=EnhancedCameraView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnhancedCameraView.js","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View, StyleSheet, Text, AppState } from 'react-native';\nimport { Camera, useCameraDevice } from 'react-native-vision-camera';\nimport VisionCameraModule from '../modules/camera/VisionCameraModule';\nimport { useI18n } from '../hooks/useI18n';\nimport { EnhancedCameraViewProps } from './OverLay/type';\nimport { Button } from './ui/Button';\n\nexport const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({ \n showCamera,\n cameraType: initialCameraType = 'front',\n style,\n onError,\n onSilentCapture, \n silentCaptureResult,\n isProcessing = false, \n overlayComponent,\n}) => {\n const { t } = useI18n();\n const camera = useRef<Camera>(null);\n \n const isCapturingRef = useRef(false);\n const isProcessingRef = useRef(isProcessing);\n\n const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n \n // 🚨 BUG FIX: Initialize to null to prevent the \"Flicker\" on retake\n const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [refreshCamera, setRefreshCamera] = useState(false);\n\n const device = useCameraDevice(cameraType);\n\n useEffect(() => {\n isProcessingRef.current = isProcessing;\n }, [isProcessing]);\n\n const checkPermissions = async () => {\n try {\n const hasAllPermissions = await VisionCameraModule.hasAllPermissions();\n if (!hasAllPermissions) {\n const granted = await VisionCameraModule.requestAllPermissions();\n if (!granted) {\n setHasPermission(false);\n onError?.({ message: t('camera.permissionRequired') });\n return;\n }\n }\n setHasPermission(true);\n } catch (error) {\n setHasPermission(false);\n onError?.({ message: t('camera.errorOccurred') });\n }\n };\n\n useEffect(() => {\n if (showCamera) checkPermissions();\n }, [showCamera, refreshCamera]);\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', nextAppState => {\n if (nextAppState === 'active' && showCamera && hasPermission === false) {\n checkPermissions();\n }\n });\n return () => subscription.remove();\n }, [showCamera, hasPermission]);\n\n const onInitialized = useCallback(() => setIsInitialized(true), []);\n const onCameraError = useCallback((error: any) => {\n onError?.({ message: error.message || t('camera.errorOccurred') });\n }, [onError, t]);\n\n const captureSilentPhoto = useCallback(async () => {\n if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;\n if (silentCaptureResult?.isAnalyzing) return;\n\n try {\n isCapturingRef.current = true; \n const photo = await camera.current.takePhoto({\n enableShutterSound: false, \n flash: 'off', \n });\n\n const result = await VisionCameraModule.processPhotoResult(photo);\n \n onSilentCapture?.({\n ...result,\n path: result.path || photo.path, \n });\n\n } catch (error) {\n // Silent background fail\n } finally {\n isCapturingRef.current = false; \n }\n }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n // 🚨 BUG FIX: The Warm-up Timer (Fixes Blurry Images)\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n \n let isActive = true;\n let intervalId: ReturnType<typeof setInterval>;\n\n const warmupTimer = setTimeout(() => {\n if (!isActive) return;\n intervalId = setInterval(() => {\n captureSilentPhoto();\n }, 1500); // 1.5s gives the hardware more time to stabilize between shots\n }, 1000); \n \n return () => {\n isActive = false;\n clearTimeout(warmupTimer);\n if (intervalId) clearInterval(intervalId);\n };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);\n\n // --- RENDERERS ---\n \n // 🚨 BUG FIX: Show nothing while checking permissions (Stops flicker)\n if (hasPermission === null) {\n return <View style={[styles.container, style]} />;\n }\n\n if (hasPermission === false) {\n return (\n <View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>\n <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>\n <Button \n title=\"Refresh Camera\" \n onPress={() => setRefreshCamera(prev => !prev)} \n variant=\"primary\"\n />\n </View>\n );\n }\n\n if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n return (\n <View style={[styles.container, style]}>\n <Camera\n ref={camera}\n style={StyleSheet.absoluteFill}\n device={device}\n isActive={showCamera && !isProcessing}\n photo={true}\n video={false} \n audio={false} \n onInitialized={onInitialized}\n onError={onCameraError}\n />\n {overlayComponent}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: { flex: 1, backgroundColor: 'black' },\n permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n});"]}
|
|
1
|
+
{"version":3,"file":"EnhancedCameraView.js","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View, StyleSheet, Text, AppState, ActivityIndicator } from 'react-native';\nimport { Camera, useCameraDevice } from 'react-native-vision-camera';\nimport VisionCameraModule from '../modules/camera/VisionCameraModule';\nimport { useI18n } from '../hooks/useI18n';\nimport { EnhancedCameraViewProps } from './OverLay/type';\nimport { Button } from './ui/Button';\n\nexport const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({\n showCamera,\n cameraType: initialCameraType = 'front',\n style,\n onError,\n onSilentCapture,\n silentCaptureResult,\n isProcessing = false,\n overlayComponent,\n}) => {\n const { t } = useI18n();\n const camera = useRef<Camera>(null);\n\n const isCapturingRef = useRef(false);\n const isProcessingRef = useRef(isProcessing);\n\n const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n\n const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [refreshCamera, setRefreshCamera] = useState(false);\n \n // 🚨 ADDED: A timeout state to show a refresh button if the camera gets stuck booting\n const [showInitTimeout, setShowInitTimeout] = useState(false);\n\n const device = useCameraDevice(cameraType);\n\n useEffect(() => {\n isProcessingRef.current = isProcessing;\n }, [isProcessing]);\n\n const checkPermissions = async () => {\n try {\n const hasAllPermissions = await VisionCameraModule.hasAllPermissions();\n if (!hasAllPermissions) {\n const granted = await VisionCameraModule.requestAllPermissions();\n if (!granted) {\n setHasPermission(false);\n onError?.({ message: t('camera.permissionRequired') });\n return;\n }\n }\n setHasPermission(true);\n } catch (error) {\n setHasPermission(false);\n onError?.({ message: t('camera.errorOccurred') });\n }\n };\n\n useEffect(() => {\n if (showCamera) {\n setIsInitialized(false); // Reset init state when checking permissions/refreshing\n checkPermissions();\n }\n }, [showCamera, refreshCamera]);\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', nextAppState => {\n if (nextAppState === 'active' && showCamera && hasPermission === false) {\n checkPermissions();\n }\n });\n return () => subscription.remove();\n }, [showCamera, hasPermission]);\n\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout>;\n\n if (hasPermission && device && showCamera && !isInitialized) {\n timer = setTimeout(() => setShowInitTimeout(true), 3000); \n } else {\n setShowInitTimeout(false);\n }\n\n return () => {\n if (timer) clearTimeout(timer);\n };\n }, [hasPermission, device, showCamera, isInitialized]);\n\n const onInitialized = useCallback(() => {\n setIsInitialized(true);\n setShowInitTimeout(false);\n }, []);\n\n const onCameraError = useCallback((error: any) => {\n onError?.({ message: error.message || t('camera.errorOccurred') });\n }, [onError, t]);\n\n const captureSilentPhoto = useCallback(async () => {\n if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;\n if (silentCaptureResult?.isAnalyzing) return;\n\n try {\n isCapturingRef.current = true;\n const photo = await camera.current.takePhoto({\n enableShutterSound: false,\n flash: 'off',\n });\n const result = await VisionCameraModule.processPhotoResult(photo);\n\n onSilentCapture?.({\n ...result,\n path: result.path || photo.path,\n });\n } catch (error) {\n // Silent background fail\n } finally {\n isCapturingRef.current = false;\n }\n }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n\n let isActive = true;\n let intervalId: ReturnType<typeof setInterval>;\n\n const warmupTimer = setTimeout(() => {\n if (!isActive) return;\n intervalId = setInterval(() => {\n captureSilentPhoto();\n }, 1500); \n }, 1000);\n\n return () => {\n isActive = false;\n clearTimeout(warmupTimer);\n if (intervalId) clearInterval(intervalId);\n };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);\n\n // --- RENDERERS ---\n\n if (hasPermission === null) {\n return <View style={[styles.container, style]} />;\n }\n\n if (hasPermission === false) {\n return (\n <View style={[styles.container, style, styles.centerContent]}>\n <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>\n <Button\n title=\"Refresh Camera\"\n onPress={() => setRefreshCamera(prev => !prev)}\n variant=\"primary\"\n />\n </View>\n );\n }\n\n // 🚨 FIX: Don't return an invisible blank screen if the device is loading! \n // Give them a UI and a way out.\n if (!device || !showCamera) {\n return (\n <View style={[styles.container, style, styles.centerContent]}>\n <ActivityIndicator size=\"large\" color=\"#2DBD60\" style={{ marginBottom: 16 }} />\n <Text style={styles.permissionMessage}>Loading Camera Hardware...</Text>\n <Button \n title=\"Refresh\" \n onPress={() => setRefreshCamera(prev => !prev)} \n variant=\"outline\" \n />\n </View>\n );\n }\n\n return (\n <View style={[styles.container, style]}>\n <Camera\n // 🚨 FIX: This key forces the native component to completely remount \n // when permissions are granted or when manually refreshed.\n key={`cam-${hasPermission}-${refreshCamera ? '1' : '0'}`} \n ref={camera}\n style={StyleSheet.absoluteFill}\n device={device}\n isActive={showCamera && !isProcessing}\n photo={true}\n video={false}\n audio={false}\n onInitialized={onInitialized}\n onError={onCameraError}\n />\n \n {/* 🚨 FIX: Floating Refresh Button if the hardware freezes on a black screen */}\n {!isInitialized && showInitTimeout && (\n <View style={styles.stuckOverlay}>\n <ActivityIndicator size=\"large\" color=\"#2DBD60\" style={{ marginBottom: 16 }} />\n <Text style={{ color: 'white', marginBottom: 16, fontWeight: 'bold' }}>\n Camera is taking a while to start...\n </Text>\n <Button \n title=\"Restart Camera\" \n onPress={() => {\n setIsInitialized(false);\n setRefreshCamera(prev => !prev);\n }} \n variant=\"primary\" \n />\n </View>\n )}\n\n {overlayComponent}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: { flex: 1, backgroundColor: 'black' },\n centerContent: { justifyContent: 'center', alignItems: 'center', padding: 20 },\n permissionMessage: { color: 'white', textAlign: 'center', marginBottom: 20, fontSize: 16, fontWeight: '600' },\n stuckOverlay: {\n ...StyleSheet.absoluteFillObject,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: 'rgba(0,0,0,0.85)',\n zIndex: 1000,\n padding: 20\n }\n});"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmailVerificationTemplate.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/EmailVerificationTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAiB,MAAM,uBAAuB,CAAC;AAMzE,UAAU,8BAA8B;IACpC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,aAAa,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,eAAO,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,8BAA8B,
|
|
1
|
+
{"version":3,"file":"EmailVerificationTemplate.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/EmailVerificationTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAiB,MAAM,uBAAuB,CAAC;AAMzE,UAAU,8BAA8B;IACpC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,aAAa,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,eAAO,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,8BAA8B,CAkP9E,CAAC"}
|
|
@@ -18,6 +18,8 @@ export const EmailVerificationTemplate = ({ component, value, onValueChange, err
|
|
|
18
18
|
const [otp, setOtp] = useState('');
|
|
19
19
|
const [localError, setLocalError] = useState(null);
|
|
20
20
|
const [isSimulating, setIsSimulating] = useState(false);
|
|
21
|
+
// 🚨 NEW: Track actual focus state for visual feedback
|
|
22
|
+
const [isInputFocused, setIsInputFocused] = useState(false);
|
|
21
23
|
const inputRef = useRef(null);
|
|
22
24
|
const title = getLocalizedText(component.labels);
|
|
23
25
|
const instructions = getLocalizedText(component.instructions);
|
|
@@ -31,6 +33,20 @@ export const EmailVerificationTemplate = ({ component, value, onValueChange, err
|
|
|
31
33
|
handleVerifyCode();
|
|
32
34
|
}
|
|
33
35
|
}, [otp]);
|
|
36
|
+
// --- AUTO FOCUS LOGIC ---
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
let focusTimer;
|
|
39
|
+
// Only attempt focus when we are on the OTP step AND the loading state is completely finished
|
|
40
|
+
if (step === 'otp' && !isSimulating) {
|
|
41
|
+
focusTimer = setTimeout(() => {
|
|
42
|
+
inputRef.current?.focus();
|
|
43
|
+
}, 100);
|
|
44
|
+
}
|
|
45
|
+
return () => {
|
|
46
|
+
if (focusTimer)
|
|
47
|
+
clearTimeout(focusTimer);
|
|
48
|
+
};
|
|
49
|
+
}, [step, isSimulating]);
|
|
34
50
|
const handleSendCode = async () => {
|
|
35
51
|
const trimmed = email.trim();
|
|
36
52
|
if (!trimmed || !isValidEmail(trimmed)) {
|
|
@@ -42,8 +58,7 @@ export const EmailVerificationTemplate = ({ component, value, onValueChange, err
|
|
|
42
58
|
try {
|
|
43
59
|
await kycService.sendEmailVerificationCode(trimmed, auth);
|
|
44
60
|
setStep('otp');
|
|
45
|
-
//
|
|
46
|
-
setTimeout(() => inputRef.current?.focus(), 100);
|
|
61
|
+
// Note: Removed the buggy setTimeout from here. The useEffect handles it now!
|
|
47
62
|
}
|
|
48
63
|
catch (err) {
|
|
49
64
|
const msg = errorMessage(err) ?? err?.message ?? (t('errors.sendCodeFailed') || 'Failed to send verification code');
|
|
@@ -69,8 +84,8 @@ export const EmailVerificationTemplate = ({ component, value, onValueChange, err
|
|
|
69
84
|
catch (err) {
|
|
70
85
|
const msg = errorMessage(err) ?? err?.message ?? (t('errors.wrongCode') || 'Invalid verification code');
|
|
71
86
|
setLocalError(typeof msg === 'string' ? msg : JSON.stringify(msg));
|
|
72
|
-
setOtp('');
|
|
73
|
-
inputRef.current?.focus();
|
|
87
|
+
setOtp('');
|
|
88
|
+
inputRef.current?.focus(); // Refocus on error
|
|
74
89
|
}
|
|
75
90
|
finally {
|
|
76
91
|
setIsSimulating(false);
|
|
@@ -98,12 +113,14 @@ export const EmailVerificationTemplate = ({ component, value, onValueChange, err
|
|
|
98
113
|
return (<Pressable style={styles.otpBoxesContainer} onPress={() => inputRef.current?.focus()}>
|
|
99
114
|
{boxes.map((_, index) => {
|
|
100
115
|
const digit = otp[index] || '';
|
|
101
|
-
const isCurrent = index === otp.length;
|
|
102
116
|
const isFilled = index < otp.length;
|
|
117
|
+
// 🚨 NEW: Only highlight if the input is ACTUALLY focused.
|
|
118
|
+
const isActiveIndex = index === otp.length || (index === CODE_LENGTH - 1 && otp.length === CODE_LENGTH);
|
|
119
|
+
const isCurrent = isInputFocused && isActiveIndex;
|
|
103
120
|
return (<View key={index} style={[
|
|
104
121
|
styles.otpBox,
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
isFilled && styles.otpBoxFilled,
|
|
123
|
+
isCurrent && styles.otpBoxActive // Active overrides filled
|
|
107
124
|
]}>
|
|
108
125
|
<Text style={styles.otpBoxText}>{digit}</Text>
|
|
109
126
|
</View>);
|
|
@@ -125,8 +142,10 @@ export const EmailVerificationTemplate = ({ component, value, onValueChange, err
|
|
|
125
142
|
|
|
126
143
|
<View style={styles.otpWrapper}>
|
|
127
144
|
{renderOtpBoxes()}
|
|
128
|
-
|
|
129
|
-
<TextInput ref={inputRef} style={styles.hiddenInput} value={otp} onChangeText={onChangeOtp} keyboardType="number-pad" maxLength={CODE_LENGTH} editable={!isSimulating} textContentType="oneTimeCode" caretHidden={true}
|
|
145
|
+
|
|
146
|
+
<TextInput ref={inputRef} style={styles.hiddenInput} value={otp} onChangeText={onChangeOtp} keyboardType="number-pad" maxLength={CODE_LENGTH} editable={!isSimulating} textContentType="oneTimeCode" caretHidden={true}
|
|
147
|
+
// 🚨 NEW: Track focus state
|
|
148
|
+
onFocus={() => setIsInputFocused(true)} onBlur={() => setIsInputFocused(false)}/>
|
|
130
149
|
</View>
|
|
131
150
|
|
|
132
151
|
<TouchableOpacity onPress={handleBackToEmail} style={styles.changeEmailLink} disabled={isSimulating}>
|
|
@@ -147,6 +166,8 @@ export const EmailVerificationTemplate = ({ component, value, onValueChange, err
|
|
|
147
166
|
try {
|
|
148
167
|
await kycService.sendEmailVerificationCode(email.trim(), auth);
|
|
149
168
|
Alert.alert(t('common.codeResent') || 'Code Resent', t('common.codeResentMessage', { email }) || 'Code resent to ' + email);
|
|
169
|
+
// Refocus after resending
|
|
170
|
+
inputRef.current?.focus();
|
|
150
171
|
}
|
|
151
172
|
catch (err) {
|
|
152
173
|
const msg = errorMessage(err) ?? err?.message ?? (t('errors.sendCodeFailed') || 'Failed to send code');
|
|
@@ -222,7 +243,7 @@ const styles = StyleSheet.create({
|
|
|
222
243
|
},
|
|
223
244
|
otpBox: {
|
|
224
245
|
width: '14%',
|
|
225
|
-
aspectRatio: 1,
|
|
246
|
+
aspectRatio: 1, // keeps it perfectly square
|
|
226
247
|
borderWidth: 1,
|
|
227
248
|
borderColor: '#e0e0e0',
|
|
228
249
|
borderRadius: 12,
|
|
@@ -250,7 +271,7 @@ const styles = StyleSheet.create({
|
|
|
250
271
|
left: 0,
|
|
251
272
|
width: '100%',
|
|
252
273
|
height: '100%',
|
|
253
|
-
opacity: 0,
|
|
274
|
+
opacity: 0, // completely invisible but handles native keyboard interactions perfectly
|
|
254
275
|
},
|
|
255
276
|
errorText: {
|
|
256
277
|
color: '#dc2626',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmailVerificationTemplate.js","sourceRoot":"","sources":["../../../../src/components/KYCElements/EmailVerificationTemplate.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { View, Text, StyleSheet, TextInput, TouchableOpacity, Alert, Pressable } from 'react-native';\nimport { TemplateComponent, LocalizedText } from '../../types/KYC.types';\nimport { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';\nimport { useI18n } from '../../hooks/useI18n';\nimport { Button } from '../ui/Button';\nimport kycService, { errorMessage } from '../../modules/api/KYCService';\n\ninterface EmailVerificationTemplateProps {\n component: TemplateComponent;\n value?: any;\n onValueChange: (data: any) => void;\n error?: string;\n language?: string;\n}\n\ntype VerificationStep = 'email' | 'otp';\nconst CODE_LENGTH = 6;\n\n/** RFC-style email validation: local@domain.tld */\nconst EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst isValidEmail = (value: string): boolean => EMAIL_REGEX.test((value || '').trim());\n\nexport const EmailVerificationTemplate: React.FC<EmailVerificationTemplateProps> = ({\n component,\n value,\n onValueChange,\n error: propError,\n}) => {\n const { actions, getLocalizedText, state, apiKey } = useTemplateKYCFlowContext();\n const { t } = useI18n();\n\n const auth = apiKey ? { apiKey } : (state.session.token ? { token: state.session.token } : undefined);\n\n // State\n const [step, setStep] = useState<VerificationStep>('email');\n const [email, setEmail] = useState('');\n const [otp, setOtp] = useState('');\n const [localError, setLocalError] = useState<string | null>(null);\n const [isSimulating, setIsSimulating] = useState(false);\n\n const inputRef = useRef<TextInput>(null);\n\n const title = getLocalizedText(component.labels as LocalizedText);\n const instructions = getLocalizedText(component.instructions as LocalizedText);\n\n // Determine button text based on step\n const verifyButtonText = getLocalizedText((component.ui as any).buttonText) || t('common.verify') || 'Verify';\n const sendButtonText = t('common.sendCode') || 'Send Verification Code';\n const buttonText = step === 'email' ? sendButtonText : verifyButtonText;\n\n // --- AUTO SUBMIT LOGIC ---\n useEffect(() => {\n if (otp.length === CODE_LENGTH && step === 'otp' && !isSimulating) {\n handleVerifyCode();\n }\n }, [otp]);\n\n const handleSendCode = async () => {\n const trimmed = email.trim();\n if (!trimmed || !isValidEmail(trimmed)) {\n setLocalError(t('errors.invalidEmail') || 'Please enter a valid email address');\n return;\n }\n\n setLocalError(null);\n setIsSimulating(true);\n\n try {\n await kycService.sendEmailVerificationCode(trimmed, auth);\n setStep('otp');\n // Auto-focus the OTP input shortly after switching steps\n setTimeout(() => inputRef.current?.focus(), 100);\n } catch (err: any) {\n const msg = errorMessage(err) ?? err?.message ?? (t('errors.sendCodeFailed') || 'Failed to send verification code');\n setLocalError(typeof msg === 'string' ? msg : JSON.stringify(msg));\n } finally {\n setIsSimulating(false);\n }\n };\n\n const handleVerifyCode = async () => {\n if (!otp || otp.length < CODE_LENGTH) {\n setLocalError(t('errors.invalidCode') || 'Please enter the 6-digit code');\n return;\n }\n\n setLocalError(null);\n setIsSimulating(true);\n\n try {\n await kycService.verifyEmailCode(otp.trim(), auth);\n const data = { email, otp, verified: true };\n onValueChange(data);\n actions.nextComponent(data);\n } catch (err: any) {\n const msg = errorMessage(err) ?? err?.message ?? (t('errors.wrongCode') || 'Invalid verification code');\n setLocalError(typeof msg === 'string' ? msg : JSON.stringify(msg));\n setOtp(''); // Clear the boxes on error so they can type again\n inputRef.current?.focus();\n } finally {\n setIsSimulating(false);\n }\n };\n\n const onChangeEmail = (text: string) => {\n setEmail(text);\n if (localError) setLocalError(null);\n };\n\n const onChangeOtp = (text: string) => {\n // Only allow numbers\n const cleaned = text.replace(/[^0-9]/g, '');\n setOtp(cleaned);\n if (localError) setLocalError(null);\n };\n\n const handleBackToEmail = () => {\n setStep('email');\n setOtp('');\n setLocalError(null);\n };\n\n const renderOtpBoxes = () => {\n const boxes = new Array(CODE_LENGTH).fill(0);\n return (\n <Pressable style={styles.otpBoxesContainer} onPress={() => inputRef.current?.focus()}>\n {boxes.map((_, index) => {\n const digit = otp[index] || '';\n const isCurrent = index === otp.length;\n const isFilled = index < otp.length;\n\n return (\n <View \n key={index} \n style={[\n styles.otpBox, \n isCurrent && styles.otpBoxActive,\n isFilled && styles.otpBoxFilled\n ]}\n >\n <Text style={styles.otpBoxText}>{digit}</Text>\n </View>\n );\n })}\n </Pressable>\n );\n };\n\n return (\n <View style={styles.container}>\n <Text style={styles.title}>{title}</Text>\n <Text style={styles.instructions}>\n {step === 'email' ? instructions : (t('kyc.enterCodeSent') || `Please enter the code sent to ${email}`)}\n </Text>\n\n <View style={styles.contentContainer}>\n {step === 'email' ? (\n <View style={styles.inputContainer}>\n <Text style={styles.label}>{t('common.email') || 'Email'}</Text>\n <TextInput\n style={styles.input}\n placeholder=\"name@example.com\"\n value={email}\n onChangeText={onChangeEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n autoCorrect={false}\n editable={!isSimulating}\n />\n </View>\n ) : (\n <View style={styles.inputContainer}>\n <Text style={styles.label}>{t('common.verificationCode') || 'Verification Code'}</Text>\n \n <View style={styles.otpWrapper}>\n {renderOtpBoxes()}\n {/* Hidden TextInput overlaid to handle native keyboard & pasting seamlessly */}\n <TextInput\n ref={inputRef}\n style={styles.hiddenInput}\n value={otp}\n onChangeText={onChangeOtp}\n keyboardType=\"number-pad\"\n maxLength={CODE_LENGTH}\n editable={!isSimulating}\n textContentType=\"oneTimeCode\"\n caretHidden={true}\n />\n </View>\n\n <TouchableOpacity onPress={handleBackToEmail} style={styles.changeEmailLink} disabled={isSimulating}>\n <Text style={styles.changeEmailText}>{t('common.changeEmail') || 'Change email'}</Text>\n </TouchableOpacity>\n </View>\n )}\n\n {(localError || propError) && (\n <Text style={styles.errorText}>{localError || propError}</Text>\n )}\n\n <Button\n title={isSimulating ? (t('common.processing') || 'Processing...') : buttonText}\n onPress={step === 'email' ? handleSendCode : handleVerifyCode}\n style={styles.button}\n disabled={\n isSimulating ||\n (step === 'email' ? !email : otp.length < CODE_LENGTH)\n }\n />\n\n {step === 'otp' && (\n <TouchableOpacity\n onPress={async () => {\n if (isSimulating) return;\n setLocalError(null);\n setIsSimulating(true);\n try {\n await kycService.sendEmailVerificationCode(email.trim(), auth);\n Alert.alert(\n t('common.codeResent') || 'Code Resent',\n t('common.codeResentMessage', { email }) || 'Code resent to ' + email\n );\n } catch (err: any) {\n const msg = errorMessage(err) ?? err?.message ?? (t('errors.sendCodeFailed') || 'Failed to send code');\n setLocalError(typeof msg === 'string' ? msg : JSON.stringify(msg));\n } finally {\n setIsSimulating(false);\n }\n }}\n style={styles.resendButton}\n disabled={isSimulating}\n >\n <Text style={styles.resendText}>{t('common.resendCode') || 'Resend Code'}</Text>\n </TouchableOpacity>\n )}\n </View>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {\n padding: 24,\n backgroundColor: 'white',\n borderRadius: 16,\n margin: 16,\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 4 },\n shadowOpacity: 0.1,\n shadowRadius: 12,\n elevation: 5,\n width: '95%',\n },\n title: {\n fontSize: 24,\n fontWeight: '700',\n marginBottom: 8,\n color: '#1a1a1a',\n textAlign: 'center',\n },\n instructions: {\n fontSize: 16,\n color: '#666',\n marginBottom: 32,\n lineHeight: 24,\n textAlign: 'center',\n },\n contentContainer: {},\n inputContainer: {\n marginBottom: 24,\n },\n label: {\n fontSize: 14,\n fontWeight: '600',\n color: '#333',\n marginBottom: 8,\n marginLeft: 4,\n },\n input: {\n borderWidth: 1,\n borderColor: '#e0e0e0',\n padding: 16,\n borderRadius: 12,\n fontSize: 16,\n backgroundColor: '#f8f9fa',\n color: '#333',\n },\n otpWrapper: {\n position: 'relative',\n width: '100%',\n height: 60,\n },\n otpBoxesContainer: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '100%',\n height: '100%',\n },\n otpBox: {\n width: '14%',\n aspectRatio: 1,\n borderWidth: 1,\n borderColor: '#e0e0e0',\n borderRadius: 12,\n backgroundColor: '#f8f9fa',\n justifyContent: 'center',\n alignItems: 'center',\n },\n otpBoxFilled: {\n borderColor: '#9ca3af',\n backgroundColor: '#ffffff',\n },\n otpBoxActive: {\n borderColor: '#2DBD60',\n borderWidth: 2,\n backgroundColor: '#ffffff',\n },\n otpBoxText: {\n fontSize: 24,\n fontWeight: '700',\n color: '#1a1a1a',\n },\n hiddenInput: {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n opacity: 0,\n },\n errorText: {\n color: '#dc2626',\n marginBottom: 16,\n fontSize: 14,\n textAlign: 'center',\n backgroundColor: '#fee2e2',\n padding: 8,\n borderRadius: 8,\n overflow: 'hidden',\n },\n button: {\n height: 50,\n borderRadius: 12,\n width: \"100%\",\n },\n changeEmailLink: {\n alignSelf: 'flex-end',\n marginTop: 12,\n },\n changeEmailText: {\n color: '#2DBD60',\n fontSize: 14,\n fontWeight: '500',\n },\n resendButton: {\n marginTop: 16,\n alignItems: 'center',\n width: \"100%\",\n },\n resendText: {\n color: '#666',\n fontSize: 14,\n textDecorationLine: 'underline',\n },\n});"]}
|
|
1
|
+
{"version":3,"file":"EmailVerificationTemplate.js","sourceRoot":"","sources":["../../../../src/components/KYCElements/EmailVerificationTemplate.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { View, Text, StyleSheet, TextInput, TouchableOpacity, Alert, Pressable } from 'react-native';\nimport { TemplateComponent, LocalizedText } from '../../types/KYC.types';\nimport { useTemplateKYCFlowContext } from '../../hooks/useTemplateKYCFlow';\nimport { useI18n } from '../../hooks/useI18n';\nimport { Button } from '../ui/Button';\nimport kycService, { errorMessage } from '../../modules/api/KYCService';\n\ninterface EmailVerificationTemplateProps {\n component: TemplateComponent;\n value?: any;\n onValueChange: (data: any) => void;\n error?: string;\n language?: string;\n}\n\ntype VerificationStep = 'email' | 'otp';\nconst CODE_LENGTH = 6;\n\n/** RFC-style email validation: local@domain.tld */\nconst EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst isValidEmail = (value: string): boolean => EMAIL_REGEX.test((value || '').trim());\n\nexport const EmailVerificationTemplate: React.FC<EmailVerificationTemplateProps> = ({\n component,\n value,\n onValueChange,\n error: propError,\n}) => {\n const { actions, getLocalizedText, state, apiKey } = useTemplateKYCFlowContext();\n const { t } = useI18n();\n\n const auth = apiKey ? { apiKey } : (state.session.token ? { token: state.session.token } : undefined);\n\n // State\n const [step, setStep] = useState<VerificationStep>('email');\n const [email, setEmail] = useState('');\n const [otp, setOtp] = useState('');\n const [localError, setLocalError] = useState<string | null>(null);\n const [isSimulating, setIsSimulating] = useState(false);\n \n // 🚨 NEW: Track actual focus state for visual feedback\n const [isInputFocused, setIsInputFocused] = useState(false);\n\n const inputRef = useRef<TextInput>(null);\n\n const title = getLocalizedText(component.labels as LocalizedText);\n const instructions = getLocalizedText(component.instructions as LocalizedText);\n\n // Determine button text based on step\n const verifyButtonText = getLocalizedText((component.ui as any).buttonText) || t('common.verify') || 'Verify';\n const sendButtonText = t('common.sendCode') || 'Send Verification Code';\n const buttonText = step === 'email' ? sendButtonText : verifyButtonText;\n\n // --- AUTO SUBMIT LOGIC ---\n useEffect(() => {\n if (otp.length === CODE_LENGTH && step === 'otp' && !isSimulating) {\n handleVerifyCode();\n }\n }, [otp]);\n\n // --- AUTO FOCUS LOGIC ---\n useEffect(() => {\n let focusTimer: ReturnType<typeof setTimeout>;\n \n // Only attempt focus when we are on the OTP step AND the loading state is completely finished\n if (step === 'otp' && !isSimulating) {\n focusTimer = setTimeout(() => {\n inputRef.current?.focus();\n }, 100); \n }\n \n return () => {\n if (focusTimer) clearTimeout(focusTimer);\n };\n }, [step, isSimulating]);\n\n const handleSendCode = async () => {\n const trimmed = email.trim();\n if (!trimmed || !isValidEmail(trimmed)) {\n setLocalError(t('errors.invalidEmail') || 'Please enter a valid email address');\n return;\n }\n\n setLocalError(null);\n setIsSimulating(true);\n\n try {\n await kycService.sendEmailVerificationCode(trimmed, auth);\n setStep('otp');\n // Note: Removed the buggy setTimeout from here. The useEffect handles it now!\n } catch (err: any) {\n const msg = errorMessage(err) ?? err?.message ?? (t('errors.sendCodeFailed') || 'Failed to send verification code');\n setLocalError(typeof msg === 'string' ? msg : JSON.stringify(msg));\n } finally {\n setIsSimulating(false);\n }\n };\n\n const handleVerifyCode = async () => {\n if (!otp || otp.length < CODE_LENGTH) {\n setLocalError(t('errors.invalidCode') || 'Please enter the 6-digit code');\n return;\n }\n\n setLocalError(null);\n setIsSimulating(true);\n\n try {\n await kycService.verifyEmailCode(otp.trim(), auth);\n const data = { email, otp, verified: true };\n onValueChange(data);\n actions.nextComponent(data);\n } catch (err: any) {\n const msg = errorMessage(err) ?? err?.message ?? (t('errors.wrongCode') || 'Invalid verification code');\n setLocalError(typeof msg === 'string' ? msg : JSON.stringify(msg));\n setOtp(''); \n inputRef.current?.focus(); // Refocus on error\n } finally {\n setIsSimulating(false);\n }\n };\n\n const onChangeEmail = (text: string) => {\n setEmail(text);\n if (localError) setLocalError(null);\n };\n\n const onChangeOtp = (text: string) => {\n // Only allow numbers\n const cleaned = text.replace(/[^0-9]/g, '');\n setOtp(cleaned);\n if (localError) setLocalError(null);\n };\n\n const handleBackToEmail = () => {\n setStep('email');\n setOtp('');\n setLocalError(null);\n };\n\n const renderOtpBoxes = () => {\n const boxes = new Array(CODE_LENGTH).fill(0);\n return (\n <Pressable style={styles.otpBoxesContainer} onPress={() => inputRef.current?.focus()}>\n {boxes.map((_, index) => {\n const digit = otp[index] || '';\n const isFilled = index < otp.length;\n \n // 🚨 NEW: Only highlight if the input is ACTUALLY focused. \n const isActiveIndex = index === otp.length || (index === CODE_LENGTH - 1 && otp.length === CODE_LENGTH);\n const isCurrent = isInputFocused && isActiveIndex;\n\n return (\n <View \n key={index} \n style={[\n styles.otpBox, \n isFilled && styles.otpBoxFilled,\n isCurrent && styles.otpBoxActive // Active overrides filled\n ]}\n >\n <Text style={styles.otpBoxText}>{digit}</Text>\n </View>\n );\n })}\n </Pressable>\n );\n };\n\n return (\n <View style={styles.container}>\n <Text style={styles.title}>{title}</Text>\n <Text style={styles.instructions}>\n {step === 'email' ? instructions : (t('kyc.enterCodeSent') || `Please enter the code sent to ${email}`)}\n </Text>\n\n <View style={styles.contentContainer}>\n {step === 'email' ? (\n <View style={styles.inputContainer}>\n <Text style={styles.label}>{t('common.email') || 'Email'}</Text>\n <TextInput\n style={styles.input}\n placeholder=\"name@example.com\"\n value={email}\n onChangeText={onChangeEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n autoCorrect={false}\n editable={!isSimulating}\n />\n </View>\n ) : (\n <View style={styles.inputContainer}>\n <Text style={styles.label}>{t('common.verificationCode') || 'Verification Code'}</Text>\n \n <View style={styles.otpWrapper}>\n {renderOtpBoxes()}\n \n <TextInput\n ref={inputRef}\n style={styles.hiddenInput}\n value={otp}\n onChangeText={onChangeOtp}\n keyboardType=\"number-pad\"\n maxLength={CODE_LENGTH}\n editable={!isSimulating}\n textContentType=\"oneTimeCode\"\n caretHidden={true}\n // 🚨 NEW: Track focus state\n onFocus={() => setIsInputFocused(true)}\n onBlur={() => setIsInputFocused(false)}\n />\n </View>\n\n <TouchableOpacity onPress={handleBackToEmail} style={styles.changeEmailLink} disabled={isSimulating}>\n <Text style={styles.changeEmailText}>{t('common.changeEmail') || 'Change email'}</Text>\n </TouchableOpacity>\n </View>\n )}\n\n {(localError || propError) && (\n <Text style={styles.errorText}>{localError || propError}</Text>\n )}\n\n <Button\n title={isSimulating ? (t('common.processing') || 'Processing...') : buttonText}\n onPress={step === 'email' ? handleSendCode : handleVerifyCode}\n style={styles.button}\n disabled={\n isSimulating ||\n (step === 'email' ? !email : otp.length < CODE_LENGTH)\n }\n />\n\n {step === 'otp' && (\n <TouchableOpacity\n onPress={async () => {\n if (isSimulating) return;\n setLocalError(null);\n setIsSimulating(true);\n try {\n await kycService.sendEmailVerificationCode(email.trim(), auth);\n Alert.alert(\n t('common.codeResent') || 'Code Resent',\n t('common.codeResentMessage', { email }) || 'Code resent to ' + email\n );\n // Refocus after resending\n inputRef.current?.focus();\n } catch (err: any) {\n const msg = errorMessage(err) ?? err?.message ?? (t('errors.sendCodeFailed') || 'Failed to send code');\n setLocalError(typeof msg === 'string' ? msg : JSON.stringify(msg));\n } finally {\n setIsSimulating(false);\n }\n }}\n style={styles.resendButton}\n disabled={isSimulating}\n >\n <Text style={styles.resendText}>{t('common.resendCode') || 'Resend Code'}</Text>\n </TouchableOpacity>\n )}\n </View>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {\n padding: 24,\n backgroundColor: 'white',\n borderRadius: 16,\n margin: 16,\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 4 },\n shadowOpacity: 0.1,\n shadowRadius: 12,\n elevation: 5,\n width: '95%',\n },\n title: {\n fontSize: 24,\n fontWeight: '700',\n marginBottom: 8,\n color: '#1a1a1a',\n textAlign: 'center',\n },\n instructions: {\n fontSize: 16,\n color: '#666',\n marginBottom: 32,\n lineHeight: 24,\n textAlign: 'center',\n },\n contentContainer: {},\n inputContainer: {\n marginBottom: 24,\n },\n label: {\n fontSize: 14,\n fontWeight: '600',\n color: '#333',\n marginBottom: 8,\n marginLeft: 4,\n },\n input: {\n borderWidth: 1,\n borderColor: '#e0e0e0',\n padding: 16,\n borderRadius: 12,\n fontSize: 16,\n backgroundColor: '#f8f9fa',\n color: '#333',\n },\n otpWrapper: {\n position: 'relative',\n width: '100%',\n height: 60,\n },\n otpBoxesContainer: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n width: '100%',\n height: '100%',\n },\n otpBox: {\n width: '14%',\n aspectRatio: 1, // keeps it perfectly square\n borderWidth: 1,\n borderColor: '#e0e0e0',\n borderRadius: 12,\n backgroundColor: '#f8f9fa',\n justifyContent: 'center',\n alignItems: 'center',\n },\n otpBoxFilled: {\n borderColor: '#9ca3af',\n backgroundColor: '#ffffff',\n },\n otpBoxActive: {\n borderColor: '#2DBD60',\n borderWidth: 2,\n backgroundColor: '#ffffff',\n },\n otpBoxText: {\n fontSize: 24,\n fontWeight: '700',\n color: '#1a1a1a',\n },\n hiddenInput: {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n opacity: 0, // completely invisible but handles native keyboard interactions perfectly\n },\n errorText: {\n color: '#dc2626',\n marginBottom: 16,\n fontSize: 14,\n textAlign: 'center',\n backgroundColor: '#fee2e2',\n padding: 8,\n borderRadius: 8,\n overflow: 'hidden',\n },\n button: {\n height: 50,\n borderRadius: 12,\n width: \"100%\",\n },\n changeEmailLink: {\n alignSelf: 'flex-end',\n marginTop: 12,\n },\n changeEmailText: {\n color: '#2DBD60',\n fontSize: 14,\n fontWeight: '500',\n },\n resendButton: {\n marginTop: 16,\n alignItems: 'center',\n width: \"100%\",\n },\n resendText: {\n color: '#666',\n fontSize: 14,\n textDecorationLine: 'underline',\n },\n});"]}
|
|
@@ -241,8 +241,7 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
241
241
|
if (showCamera) {
|
|
242
242
|
const isBusy = isProcessingCapture;
|
|
243
243
|
return (<View style={styles.cameraContainer}>
|
|
244
|
-
<EnhancedCameraView key={currentSide}
|
|
245
|
-
showCamera={true} isProcessing={isBusy} cameraType={cameraConfig.cameraType} style={styles.camera} onError={handleError} onSilentCapture={handleSilentCapture} silentCaptureResult={silentCaptureResult} overlayComponent={<>
|
|
244
|
+
<EnhancedCameraView key={currentSide} showCamera={true} isProcessing={isBusy} cameraType={cameraConfig.cameraType} style={styles.camera} onError={handleError} onSilentCapture={handleSilentCapture} silentCaptureResult={silentCaptureResult} overlayComponent={<>
|
|
246
245
|
{!isBusy && silentCaptureResult.isAnalyzing && (<View style={styles.topAnalyzingPillContainer}>
|
|
247
246
|
<View style={styles.topAnalyzingPill}>
|
|
248
247
|
<ActivityIndicator size="small" color="white"/>
|