astra-sdk-web 1.1.3 → 1.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.
- package/dist/astra-sdk.cjs.js +141 -58
- package/dist/astra-sdk.cjs.js.map +1 -1
- package/dist/astra-sdk.css +46 -0
- package/dist/astra-sdk.css.map +1 -1
- package/dist/astra-sdk.es.js +141 -58
- package/dist/astra-sdk.es.js.map +1 -1
- package/dist/components.cjs.js +141 -58
- package/dist/components.cjs.js.map +1 -1
- package/dist/components.css +46 -0
- package/dist/components.css.map +1 -1
- package/dist/components.d.cts +1 -0
- package/dist/components.d.ts +1 -0
- package/dist/components.es.js +141 -58
- package/dist/components.es.js.map +1 -1
- package/package.json +1 -1
- package/src/components/KycFlow.tsx +10 -1
- package/src/pages/FaceScanModal.tsx +30 -0
- package/src/pages/MobileRoute.tsx +64 -2
- package/src/pages/QRCodePage.tsx +27 -7
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ export interface KycFlowProps {
|
|
|
10
10
|
deviceType?: string;
|
|
11
11
|
startAtQr?: boolean;
|
|
12
12
|
onClose?: () => void;
|
|
13
|
+
mobileBaseUrl?: string;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
type KycFlowView = 'qr' | 'mobileroute';
|
|
@@ -21,6 +22,7 @@ export const KycFlow: React.FC<KycFlowProps> = ({
|
|
|
21
22
|
deviceType,
|
|
22
23
|
startAtQr = true,
|
|
23
24
|
onClose,
|
|
25
|
+
mobileBaseUrl = 'https://astra-sdk-rebuild.vercel.app',
|
|
24
26
|
}) => {
|
|
25
27
|
const [currentView, setCurrentView] = useState<KycFlowView>(startAtQr ? 'qr' : 'mobileroute');
|
|
26
28
|
|
|
@@ -42,7 +44,14 @@ export const KycFlow: React.FC<KycFlowProps> = ({
|
|
|
42
44
|
deviceType={deviceType}
|
|
43
45
|
>
|
|
44
46
|
{currentView === 'qr' ? (
|
|
45
|
-
<QRCodePage
|
|
47
|
+
<QRCodePage
|
|
48
|
+
onClose={handleClose}
|
|
49
|
+
onNavigate={handleNavigate}
|
|
50
|
+
mobileBaseUrl={mobileBaseUrl}
|
|
51
|
+
sessionId={sessionId}
|
|
52
|
+
apiBaseUrl={apiBaseUrl}
|
|
53
|
+
serverKey={serverKey}
|
|
54
|
+
/>
|
|
46
55
|
) : (
|
|
47
56
|
<MobileRoute onClose={handleClose} onNavigate={handleNavigate} />
|
|
48
57
|
)}
|
|
@@ -58,6 +58,36 @@ function FaceScanModal({ onComplete }: FaceScanModalProps) {
|
|
|
58
58
|
setState(prev => ({ ...prev, cameraReady }));
|
|
59
59
|
}, [cameraReady, setState]);
|
|
60
60
|
|
|
61
|
+
// Log session info and call status API when camera opens
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (cameraReady && apiService) {
|
|
64
|
+
// Get config from apiService to log session info
|
|
65
|
+
const config = apiService.getConfig();
|
|
66
|
+
if (config) {
|
|
67
|
+
console.log('=== Camera Opened ===');
|
|
68
|
+
console.log('Session ID:', config.sessionId);
|
|
69
|
+
console.log('Server Key:', config.serverKey);
|
|
70
|
+
console.log('API Base URL:', config.apiBaseUrl);
|
|
71
|
+
console.log('Device Type:', config.deviceType || 'auto-detected');
|
|
72
|
+
|
|
73
|
+
// Call status API
|
|
74
|
+
apiService.getSessionStatus()
|
|
75
|
+
.then((statusResponse) => {
|
|
76
|
+
console.log('=== Session Status API Response ===');
|
|
77
|
+
console.log('Full Response:', statusResponse);
|
|
78
|
+
console.log('Session Status:', statusResponse.data?.status);
|
|
79
|
+
console.log('Session ID:', statusResponse.data?.session_id);
|
|
80
|
+
console.log('Completed Steps:', statusResponse.data?.completed_steps);
|
|
81
|
+
console.log('Next Step:', statusResponse.data?.next_step);
|
|
82
|
+
})
|
|
83
|
+
.catch((error) => {
|
|
84
|
+
console.error('=== Session Status API Error ===');
|
|
85
|
+
console.error('Error fetching session status:', error);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}, [cameraReady, apiService]);
|
|
90
|
+
|
|
61
91
|
const handleRetry = () => {
|
|
62
92
|
stopCamera();
|
|
63
93
|
setState({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
2
|
import { isMobileDevice } from '../utils/deviceDetection';
|
|
3
3
|
import FaceScanModal from './FaceScanModal';
|
|
4
|
+
import { KycProvider } from '../contexts/KycContext';
|
|
4
5
|
import '../index.css';
|
|
5
6
|
|
|
6
7
|
interface MobileRouteProps {
|
|
@@ -8,12 +9,41 @@ interface MobileRouteProps {
|
|
|
8
9
|
onNavigate?: (view: 'qr' | 'mobileroute') => void;
|
|
9
10
|
}
|
|
10
11
|
|
|
12
|
+
// Inner component that uses the context
|
|
13
|
+
function MobileRouteContent({ onClose, onComplete }: { onClose?: () => void; onComplete?: (image: string) => void }) {
|
|
14
|
+
return <FaceScanModal onClose={onClose} onComplete={onComplete} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
function MobileRoute({ onClose, onNavigate }: MobileRouteProps = {}) {
|
|
18
|
+
const [config, setConfig] = useState<{
|
|
19
|
+
apiBaseUrl: string;
|
|
20
|
+
sessionId: string;
|
|
21
|
+
serverKey: string;
|
|
22
|
+
} | null>(null);
|
|
23
|
+
|
|
12
24
|
useEffect(() => {
|
|
13
25
|
if (!isMobileDevice() && onNavigate) {
|
|
14
26
|
onNavigate('qr');
|
|
15
27
|
return;
|
|
16
28
|
}
|
|
29
|
+
|
|
30
|
+
// If accessed standalone (via URL), get config from URL params
|
|
31
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
32
|
+
const sessionId = searchParams.get('sessionId');
|
|
33
|
+
const apiBaseUrl = searchParams.get('apiBaseUrl') || searchParams.get('apiUrl') || '';
|
|
34
|
+
const serverKey = searchParams.get('serverKey') || '';
|
|
35
|
+
|
|
36
|
+
if (sessionId && apiBaseUrl && serverKey) {
|
|
37
|
+
setConfig({
|
|
38
|
+
apiBaseUrl,
|
|
39
|
+
sessionId,
|
|
40
|
+
serverKey,
|
|
41
|
+
});
|
|
42
|
+
} else if (sessionId) {
|
|
43
|
+
// Try to get from localStorage or use defaults
|
|
44
|
+
// For now, we'll need these to be passed via URL
|
|
45
|
+
console.error('Missing required parameters: apiBaseUrl and serverKey must be in URL');
|
|
46
|
+
}
|
|
17
47
|
}, [onNavigate]);
|
|
18
48
|
|
|
19
49
|
const handleClose = () => {
|
|
@@ -32,7 +62,39 @@ function MobileRoute({ onClose, onNavigate }: MobileRouteProps = {}) {
|
|
|
32
62
|
return null;
|
|
33
63
|
}
|
|
34
64
|
|
|
35
|
-
|
|
65
|
+
// If we have config from URL (standalone mode), wrap in provider
|
|
66
|
+
if (config) {
|
|
67
|
+
return (
|
|
68
|
+
<KycProvider
|
|
69
|
+
apiBaseUrl={config.apiBaseUrl}
|
|
70
|
+
sessionId={config.sessionId}
|
|
71
|
+
serverKey={config.serverKey}
|
|
72
|
+
deviceType="mobile"
|
|
73
|
+
>
|
|
74
|
+
<MobileRouteContent onClose={handleClose} onComplete={handleComplete} />
|
|
75
|
+
</KycProvider>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// If used within SDK (has onNavigate), it should already be wrapped in provider
|
|
80
|
+
// But we'll still wrap it to be safe
|
|
81
|
+
if (onNavigate) {
|
|
82
|
+
// This means it's being used within the SDK component
|
|
83
|
+
// The provider should already be there, but we'll render the content directly
|
|
84
|
+
return <MobileRouteContent onClose={handleClose} onComplete={handleComplete} />;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Fallback: show error if no config
|
|
88
|
+
return (
|
|
89
|
+
<div className="fixed inset-0 flex items-center justify-center bg-black/50 z-[1000]">
|
|
90
|
+
<div className="bg-white p-6 rounded-lg text-center max-w-md mx-4">
|
|
91
|
+
<p className="text-red-600 mb-2">Missing Configuration</p>
|
|
92
|
+
<p className="text-sm text-gray-600">
|
|
93
|
+
Please ensure the URL includes sessionId, apiBaseUrl, and serverKey parameters.
|
|
94
|
+
</p>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
36
98
|
}
|
|
37
99
|
|
|
38
100
|
export default MobileRoute;
|
package/src/pages/QRCodePage.tsx
CHANGED
|
@@ -5,23 +5,37 @@ import '../index.css';
|
|
|
5
5
|
interface QRCodePageProps {
|
|
6
6
|
onClose?: () => void;
|
|
7
7
|
onNavigate?: (view: 'qr' | 'mobileroute') => void;
|
|
8
|
+
mobileBaseUrl?: string;
|
|
9
|
+
sessionId?: string;
|
|
10
|
+
apiBaseUrl?: string;
|
|
11
|
+
serverKey?: string;
|
|
8
12
|
}
|
|
9
13
|
|
|
10
|
-
function QRCodePage({ onClose, onNavigate }: QRCodePageProps = {}) {
|
|
14
|
+
function QRCodePage({ onClose, onNavigate, mobileBaseUrl = 'https://astra-sdk-rebuild.vercel.app', sessionId, apiBaseUrl, serverKey }: QRCodePageProps = {}) {
|
|
11
15
|
const [qrUrl, setQrUrl] = useState<string>('');
|
|
12
16
|
const [copied, setCopied] = useState<boolean>(false);
|
|
13
17
|
|
|
14
18
|
useEffect(() => {
|
|
15
|
-
const currentUrl = window.location.origin;
|
|
16
|
-
|
|
17
19
|
// Get search params from current URL
|
|
18
20
|
const searchParams = new URLSearchParams(window.location.search);
|
|
21
|
+
|
|
22
|
+
// Add required params to query string for mobile route
|
|
23
|
+
if (sessionId) {
|
|
24
|
+
searchParams.set('sessionId', sessionId);
|
|
25
|
+
}
|
|
26
|
+
if (apiBaseUrl) {
|
|
27
|
+
searchParams.set('apiBaseUrl', apiBaseUrl);
|
|
28
|
+
}
|
|
29
|
+
if (serverKey) {
|
|
30
|
+
searchParams.set('serverKey', serverKey);
|
|
31
|
+
}
|
|
32
|
+
|
|
19
33
|
const mobileRoute = '/mobileroute';
|
|
20
34
|
const queryString = searchParams.toString();
|
|
21
|
-
const fullUrl = `${
|
|
35
|
+
const fullUrl = `${mobileBaseUrl}${mobileRoute}${queryString ? `?${queryString}` : ''}`;
|
|
22
36
|
|
|
23
37
|
setQrUrl(fullUrl);
|
|
24
|
-
}, []);
|
|
38
|
+
}, [mobileBaseUrl, sessionId, apiBaseUrl, serverKey]);
|
|
25
39
|
|
|
26
40
|
const handleCopyUrl = async () => {
|
|
27
41
|
if (qrUrl) {
|
|
@@ -46,8 +60,14 @@ function QRCodePage({ onClose, onNavigate }: QRCodePageProps = {}) {
|
|
|
46
60
|
};
|
|
47
61
|
|
|
48
62
|
return (
|
|
49
|
-
<div className="fixed inset-0 flex items-center justify-center bg-black p-4 sm:p-6 md:p-8 z-[1000]">
|
|
50
|
-
|
|
63
|
+
<div className="fixed inset-0 flex items-center justify-center bg-gradient-to-br from-gray-900 via-gray-800 to-black p-4 sm:p-6 md:p-8 z-[1000]">
|
|
64
|
+
{/* Background pattern overlay */}
|
|
65
|
+
<div className="absolute inset-0 opacity-10" style={{
|
|
66
|
+
backgroundImage: `radial-gradient(circle at 2px 2px, rgba(255,255,255,0.15) 1px, transparent 0)`,
|
|
67
|
+
backgroundSize: '40px 40px'
|
|
68
|
+
}}></div>
|
|
69
|
+
|
|
70
|
+
<div className="relative bg-[rgba(20,20,20,0.95)] backdrop-blur-sm rounded-2xl p-5 sm:p-6 md:p-7 max-w-[450px] w-full h-[80vh] flex flex-col text-center shadow-[0_8px_32px_rgba(0,0,0,0.5)] border border-white/10">
|
|
51
71
|
<button
|
|
52
72
|
className="absolute top-5 right-5 bg-transparent border-none text-white cursor-pointer p-2 flex items-center justify-center rounded transition-colors hover:bg-white/10 active:bg-white/20"
|
|
53
73
|
onClick={handleClose}
|