@sanctum-key/react-native-sdk 1.0.27 → 1.0.28
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/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.js +156 -48
- package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/src/components/TemplateKYCExample.d.ts +2 -1
- package/build/src/components/TemplateKYCExample.d.ts.map +1 -1
- package/build/src/components/TemplateKYCExample.js +2 -2
- package/build/src/components/TemplateKYCExample.js.map +1 -1
- package/build/src/components/TemplateKYCFlowRefactored.d.ts +1 -0
- package/build/src/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
- package/build/src/components/TemplateKYCFlowRefactored.js +2 -2
- package/build/src/components/TemplateKYCFlowRefactored.js.map +1 -1
- package/build/src/hooks/useTemplateKYCFlow.d.ts +1 -0
- package/build/src/hooks/useTemplateKYCFlow.d.ts.map +1 -1
- package/build/src/hooks/useTemplateKYCFlow.js +31 -17
- package/build/src/hooks/useTemplateKYCFlow.js.map +1 -1
- package/build/src/modules/api/KYCService.d.ts +8 -0
- package/build/src/modules/api/KYCService.d.ts.map +1 -1
- package/build/src/modules/api/KYCService.js +30 -0
- package/build/src/modules/api/KYCService.js.map +1 -1
- package/package.json +1 -1
- package/src/components/KYCElements/IDCardCapture.tsx +198 -77
- package/src/components/TemplateKYCExample.tsx +7 -3
- package/src/components/TemplateKYCFlowRefactored.tsx +3 -0
- package/src/hooks/useTemplateKYCFlow.tsx +65 -34
- package/src/modules/api/KYCService.ts +41 -0
package/build/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAsB5L,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACvC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAUD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAsB5L,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACvC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAUD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA0jCtD,CAAC"}
|
|
@@ -47,6 +47,58 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
47
47
|
const [scanPhase, setScanPhase] = useState('image');
|
|
48
48
|
const [pendingCAImage, setPendingCAImage] = useState(null);
|
|
49
49
|
const scannedBarcodeRef = useRef(null);
|
|
50
|
+
// 🚨 NEW: State for the expiring link code
|
|
51
|
+
const [generatedCode, setGeneratedCode] = useState(null);
|
|
52
|
+
const [isGeneratingCode, setIsGeneratingCode] = useState(false);
|
|
53
|
+
const [codeTimeLeft, setCodeTimeLeft] = useState(0);
|
|
54
|
+
// 🚨 NEW: Countdown Timer Effect
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (codeTimeLeft <= 0) {
|
|
57
|
+
if (generatedCode)
|
|
58
|
+
setGeneratedCode(null); // Clear the code when timer hits 0
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const timer = setInterval(() => {
|
|
62
|
+
setCodeTimeLeft((prev) => prev - 1);
|
|
63
|
+
}, 1000);
|
|
64
|
+
return () => clearInterval(timer);
|
|
65
|
+
}, [codeTimeLeft, generatedCode]);
|
|
66
|
+
// 🚨 NEW: Formatting helper
|
|
67
|
+
const formatTime = (seconds) => {
|
|
68
|
+
const m = Math.floor(seconds / 60);
|
|
69
|
+
const s = seconds % 60;
|
|
70
|
+
return `${m}:${s.toString().padStart(2, '0')}`;
|
|
71
|
+
};
|
|
72
|
+
const handleGenerateCode = async () => {
|
|
73
|
+
if (isGeneratingCode)
|
|
74
|
+
return;
|
|
75
|
+
setIsGeneratingCode(true);
|
|
76
|
+
try {
|
|
77
|
+
const apiKey = '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';
|
|
78
|
+
if (!apiKey) {
|
|
79
|
+
showAlert('Error', 'API Key is missing.');
|
|
80
|
+
setIsGeneratingCode(false);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// 🚨 Pass the apiKey as the strictly required second parameter
|
|
84
|
+
const res = await kycService.generateReferralCode({ session_id: state.session.session_id }, apiKey);
|
|
85
|
+
// Extract the code from the response
|
|
86
|
+
const newCode = res.code || res.referral_code || res?.data?.code || res?.data?.referral_code;
|
|
87
|
+
if (newCode) {
|
|
88
|
+
setGeneratedCode(newCode);
|
|
89
|
+
setCodeTimeLeft(300); // 300 seconds = 5 minutes
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
showAlert('Error', 'Failed to parse code from server response.');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
showAlert('Error', error.message || 'Failed to generate code');
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
setIsGeneratingCode(false);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
50
102
|
useEffect(() => {
|
|
51
103
|
if (typeof window !== 'undefined' && window.location)
|
|
52
104
|
setCurrentUrl(window.location.href);
|
|
@@ -814,62 +866,71 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
814
866
|
</View>
|
|
815
867
|
|
|
816
868
|
{showQRModal && Platform.OS === 'web' && (<View style={styles.qrModalOverlay}>
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
869
|
+
<View style={styles.qrModalContainer}>
|
|
870
|
+
<View style={styles.qrModalHeader}>
|
|
871
|
+
<Text style={styles.qrModalTitle}>
|
|
872
|
+
{state.currentLanguage === 'en' ? 'Continue on your phone' : 'Continuer sur votre téléphone'}
|
|
873
|
+
</Text>
|
|
874
|
+
<Text style={styles.qrModalText}>
|
|
875
|
+
{state.currentLanguage === 'en'
|
|
824
876
|
? "Scan the QR code to download our mobile app and complete the scanning process securely."
|
|
825
877
|
: "Scannez le code QR pour télécharger notre application et terminer la numérisation en toute sécurité."}
|
|
826
|
-
|
|
827
|
-
|
|
878
|
+
</Text>
|
|
879
|
+
</View>
|
|
828
880
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
881
|
+
<View style={styles.qrToggleContainer}>
|
|
882
|
+
<TouchableOpacity style={[styles.qrToggleButton, qrPlatform === 'android' && styles.qrToggleButtonActive]} onPress={() => setQrPlatform('android')}>
|
|
883
|
+
<Text style={[styles.qrToggleText, qrPlatform === 'android' && styles.qrToggleTextActive]}>
|
|
884
|
+
Android
|
|
885
|
+
</Text>
|
|
886
|
+
</TouchableOpacity>
|
|
887
|
+
<TouchableOpacity style={[styles.qrToggleButton, qrPlatform === 'ios' && styles.qrToggleButtonActive]} onPress={() => setQrPlatform('ios')}>
|
|
888
|
+
<Text style={[styles.qrToggleText, qrPlatform === 'ios' && styles.qrToggleTextActive]}>
|
|
889
|
+
iOS (Apple)
|
|
890
|
+
</Text>
|
|
891
|
+
</TouchableOpacity>
|
|
892
|
+
</View>
|
|
841
893
|
|
|
842
|
-
|
|
843
|
-
|
|
894
|
+
<View style={styles.qrCodeWrapper}>
|
|
895
|
+
<QRCode value={qrPlatform === 'android'
|
|
844
896
|
? 'https://play.google.com/store/apps/details?id=transfergratis.com&hl=en_CA&gl=US'
|
|
845
|
-
: 'https://apps.apple.com/ca/app/transfergratis-money-transfer/id1605411731'} size={
|
|
846
|
-
|
|
847
|
-
</View>
|
|
897
|
+
: 'https://apps.apple.com/ca/app/transfergratis-money-transfer/id1605411731'} size={180} backgroundColor="#FFFFFF" color="#0F172A"/>
|
|
898
|
+
</View>
|
|
848
899
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
900
|
+
<View style={styles.linkCodeSection}>
|
|
901
|
+
<Text style={styles.linkCodeHeader}>
|
|
902
|
+
{state.currentLanguage === 'en' ? 'Use code below to proceed on the Sanctum Key App.' : 'Vous avez déjà l\'application ? Liez-la :'}
|
|
903
|
+
</Text>
|
|
904
|
+
|
|
905
|
+
{generatedCode && codeTimeLeft > 0 ? (<View style={styles.activeCodeContainer}>
|
|
906
|
+
<Text style={styles.activeCodeText}>{generatedCode}</Text>
|
|
907
|
+
<Text style={styles.timerText}>
|
|
908
|
+
{state.currentLanguage === 'en' ? `Expires in ${formatTime(codeTimeLeft)}` : `Expire dans ${formatTime(codeTimeLeft)}`}
|
|
909
|
+
</Text>
|
|
910
|
+
</View>) : (<TouchableOpacity style={styles.generateCodeButton} onPress={handleGenerateCode} disabled={isGeneratingCode}>
|
|
911
|
+
{isGeneratingCode ? (<ActivityIndicator size="small" color="#0F172A"/>) : (<Text style={styles.generateCodeButtonText}>
|
|
912
|
+
{state.currentLanguage === 'en' ? 'Generate 5-Digit Link Code' : 'Générer un code à 5 chiffres'}
|
|
913
|
+
</Text>)}
|
|
914
|
+
</TouchableOpacity>)}
|
|
915
|
+
</View>
|
|
862
916
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
917
|
+
{isWebScanningRestricted && (<View style={styles.storeLinksContainer}>
|
|
918
|
+
<Text style={styles.storeLinksTitle}>
|
|
919
|
+
{state.currentLanguage === 'en' ? 'Or click to open directly:' : 'Ou cliquez pour ouvrir directement :'}
|
|
920
|
+
</Text>
|
|
921
|
+
<View style={styles.storeButtonsRow}>
|
|
922
|
+
<TouchableOpacity style={styles.storeButton} onPress={() => window.open('https://play.google.com/store/apps/details?id=transfergratis.com&hl=en_CA&gl=US', '_blank')}>
|
|
923
|
+
<Text style={styles.storeButtonText}>Google Play</Text>
|
|
924
|
+
</TouchableOpacity>
|
|
925
|
+
<TouchableOpacity style={styles.storeButton} onPress={() => window.open('https://apps.apple.com/ca/app/transfergratis-money-transfer/id1605411731', '_blank')}>
|
|
926
|
+
<Text style={styles.storeButtonText}>App Store</Text>
|
|
927
|
+
</TouchableOpacity>
|
|
928
|
+
</View>
|
|
929
|
+
</View>)}
|
|
869
930
|
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
931
|
+
<Button title={state.currentLanguage === 'en' ? "Cancel & Stay on Laptop" : "Annuler et rester sur l'ordinateur"} onPress={() => setShowQRModal(false)} variant="outline" fullWidth/>
|
|
932
|
+
</View>
|
|
933
|
+
</View>)}
|
|
873
934
|
</View>);
|
|
874
935
|
};
|
|
875
936
|
const styles = StyleSheet.create({
|
|
@@ -986,5 +1047,52 @@ const styles = StyleSheet.create({
|
|
|
986
1047
|
qrToggleTextActive: {
|
|
987
1048
|
color: '#0F172A', // Active text color
|
|
988
1049
|
},
|
|
1050
|
+
linkCodeSection: {
|
|
1051
|
+
width: '100%',
|
|
1052
|
+
alignItems: 'center',
|
|
1053
|
+
backgroundColor: '#F8FAFC', // Very light slate
|
|
1054
|
+
borderRadius: 16,
|
|
1055
|
+
padding: 16,
|
|
1056
|
+
marginBottom: 20,
|
|
1057
|
+
borderWidth: 1,
|
|
1058
|
+
borderColor: '#E2E8F0',
|
|
1059
|
+
},
|
|
1060
|
+
linkCodeHeader: {
|
|
1061
|
+
fontSize: 13,
|
|
1062
|
+
color: '#475569',
|
|
1063
|
+
fontWeight: '600',
|
|
1064
|
+
marginBottom: 12,
|
|
1065
|
+
},
|
|
1066
|
+
generateCodeButton: {
|
|
1067
|
+
backgroundColor: '#E2E8F0',
|
|
1068
|
+
paddingVertical: 12,
|
|
1069
|
+
paddingHorizontal: 20,
|
|
1070
|
+
borderRadius: 10,
|
|
1071
|
+
width: '100%',
|
|
1072
|
+
alignItems: 'center',
|
|
1073
|
+
justifyContent: 'center',
|
|
1074
|
+
height: 44, // Fixed height to prevent jumping during loading state
|
|
1075
|
+
},
|
|
1076
|
+
generateCodeButtonText: {
|
|
1077
|
+
color: '#0F172A',
|
|
1078
|
+
fontWeight: '700',
|
|
1079
|
+
fontSize: 14,
|
|
1080
|
+
},
|
|
1081
|
+
activeCodeContainer: {
|
|
1082
|
+
alignItems: 'center',
|
|
1083
|
+
width: '100%',
|
|
1084
|
+
},
|
|
1085
|
+
activeCodeText: {
|
|
1086
|
+
fontSize: 32,
|
|
1087
|
+
fontWeight: '900',
|
|
1088
|
+
color: '#2DBD60',
|
|
1089
|
+
letterSpacing: 4,
|
|
1090
|
+
marginBottom: 4,
|
|
1091
|
+
},
|
|
1092
|
+
timerText: {
|
|
1093
|
+
fontSize: 12,
|
|
1094
|
+
color: '#EF4444', // Red to indicate urgency
|
|
1095
|
+
fontWeight: '600',
|
|
1096
|
+
},
|
|
989
1097
|
});
|
|
990
1098
|
//# sourceMappingURL=IDCardCapture.js.map
|