@onairos/react-native 3.0.71 → 3.0.73
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/lib/commonjs/components/Onairos.js +294 -155
- package/lib/commonjs/components/Onairos.js.map +1 -1
- package/lib/commonjs/components/OnairosButton.js +1 -1
- package/lib/commonjs/components/OnairosButton.js.map +1 -1
- package/lib/commonjs/components/UniversalOnboarding.js +6 -6
- package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
- package/lib/commonjs/components/onboarding/OAuthWebView.js +188 -52
- package/lib/commonjs/components/onboarding/OAuthWebView.js.map +1 -1
- package/lib/commonjs/index.js +25 -440
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/services/apiKeyService.js +404 -0
- package/lib/commonjs/services/apiKeyService.js.map +1 -0
- package/lib/commonjs/services/platformAuthService.js +318 -113
- package/lib/commonjs/services/platformAuthService.js.map +1 -1
- package/lib/commonjs/types/index.js +4 -0
- package/lib/commonjs/types.js +12 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils/programmaticFlow.js +117 -0
- package/lib/commonjs/utils/programmaticFlow.js.map +1 -0
- package/lib/module/components/Onairos.js +297 -158
- package/lib/module/components/Onairos.js.map +1 -1
- package/lib/module/components/OnairosButton.js +1 -1
- package/lib/module/components/OnairosButton.js.map +1 -1
- package/lib/module/components/UniversalOnboarding.js +6 -6
- package/lib/module/components/UniversalOnboarding.js.map +1 -1
- package/lib/module/components/onboarding/OAuthWebView.js +188 -52
- package/lib/module/components/onboarding/OAuthWebView.js.map +1 -1
- package/lib/module/index.js +17 -61
- package/lib/module/index.js.map +1 -1
- package/lib/module/services/apiKeyService.js +389 -0
- package/lib/module/services/apiKeyService.js.map +1 -0
- package/lib/module/services/platformAuthService.js +311 -111
- package/lib/module/services/platformAuthService.js.map +1 -1
- package/lib/module/types/index.js +1 -1
- package/lib/module/types.js +8 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/programmaticFlow.js +111 -0
- package/lib/module/utils/programmaticFlow.js.map +1 -0
- package/lib/typescript/components/Onairos.d.ts +2 -29
- package/lib/typescript/components/Onairos.d.ts.map +1 -1
- package/lib/typescript/components/onboarding/OAuthWebView.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +10 -39
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/services/apiKeyService.d.ts +66 -0
- package/lib/typescript/services/apiKeyService.d.ts.map +1 -0
- package/lib/typescript/services/platformAuthService.d.ts +26 -0
- package/lib/typescript/services/platformAuthService.d.ts.map +1 -1
- package/lib/typescript/types/index.d.ts +144 -78
- package/lib/typescript/types/index.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +92 -3
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/utils/programmaticFlow.d.ts +23 -0
- package/lib/typescript/utils/programmaticFlow.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Onairos.tsx +330 -207
- package/src/components/OnairosButton.tsx +1 -1
- package/src/components/UniversalOnboarding.tsx +6 -6
- package/src/components/onboarding/OAuthWebView.tsx +236 -71
- package/src/index.ts +25 -115
- package/src/services/apiKeyService.ts +401 -0
- package/src/services/platformAuthService.ts +363 -126
- package/src/types/index.d.ts +110 -0
- package/src/types/index.ts +148 -74
- package/src/types.ts +99 -3
- package/src/utils/programmaticFlow.ts +113 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useImperativeHandle, useState, useCallback } from 'react';
|
|
1
|
+
import React, { forwardRef, useImperativeHandle, useState, useCallback, useEffect } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
StyleSheet,
|
|
4
4
|
View,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
TextStyle,
|
|
9
9
|
Platform,
|
|
10
10
|
Image,
|
|
11
|
+
Alert,
|
|
11
12
|
} from 'react-native';
|
|
12
13
|
import { UniversalOnboarding } from './UniversalOnboarding';
|
|
13
14
|
import { Overlay } from './Overlay';
|
|
@@ -15,255 +16,349 @@ import { COLORS } from '../constants';
|
|
|
15
16
|
import { hasCredentials, getCredentials, deleteCredentials } from '../utils/secureStorage';
|
|
16
17
|
import { onairosApi } from '../api';
|
|
17
18
|
import { Portal } from '../utils/Portal';
|
|
18
|
-
import { DataTier } from '../types';
|
|
19
|
+
import { DataTier, OnairosConfig, OnairosProps } from '../types';
|
|
20
|
+
import { initializeApiKey, isApiKeyInitialized, getApiConfig } from '../services/apiKeyService';
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
22
|
+
export const Onairos = forwardRef<any, OnairosProps>((props, ref) => {
|
|
23
|
+
const {
|
|
24
|
+
returnLink,
|
|
25
|
+
prefillUrl,
|
|
26
|
+
AppName,
|
|
27
|
+
buttonType = 'normal',
|
|
28
|
+
requestData,
|
|
29
|
+
buttonWidth = 200,
|
|
30
|
+
buttonHeight = 48,
|
|
31
|
+
hasStroke = false,
|
|
32
|
+
enabled = true,
|
|
33
|
+
buttonForm = 'default',
|
|
34
|
+
onRejection,
|
|
35
|
+
onResolved,
|
|
36
|
+
preCheck,
|
|
37
|
+
color = COLORS.primary,
|
|
38
|
+
debug = false,
|
|
39
|
+
darkMode = false,
|
|
40
|
+
preferredPlatform,
|
|
41
|
+
testMode = false,
|
|
42
|
+
// API Key props
|
|
43
|
+
apiKey,
|
|
44
|
+
environment = 'production',
|
|
45
|
+
enableLogging = true,
|
|
46
|
+
timeout = 30000,
|
|
47
|
+
retryAttempts = 3,
|
|
48
|
+
} = props;
|
|
47
49
|
|
|
48
|
-
export const Onairos = forwardRef<OnairosRef, OnairosProps>(({
|
|
49
|
-
returnLink,
|
|
50
|
-
prefillUrl,
|
|
51
|
-
AppName,
|
|
52
|
-
buttonType = 'normal',
|
|
53
|
-
requestData,
|
|
54
|
-
buttonWidth = 180,
|
|
55
|
-
buttonHeight,
|
|
56
|
-
hasStroke = false,
|
|
57
|
-
enabled = true,
|
|
58
|
-
buttonForm = 'default',
|
|
59
|
-
onRejection,
|
|
60
|
-
onResolved,
|
|
61
|
-
preCheck,
|
|
62
|
-
color,
|
|
63
|
-
debug = false,
|
|
64
|
-
darkMode = false,
|
|
65
|
-
preferredPlatform,
|
|
66
|
-
testMode = false,
|
|
67
|
-
}, ref) => {
|
|
68
|
-
const [showOnboarding, setShowOnboarding] = useState(false);
|
|
69
50
|
const [showOverlay, setShowOverlay] = useState(false);
|
|
70
|
-
const [
|
|
71
|
-
const [
|
|
72
|
-
const [
|
|
51
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
52
|
+
const [initializationError, setInitializationError] = useState<string | null>(null);
|
|
53
|
+
const [isInitializing, setIsInitializing] = useState(false);
|
|
73
54
|
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
await handlePress();
|
|
78
|
-
},
|
|
79
|
-
reset: async () => {
|
|
80
|
-
await deleteCredentials();
|
|
81
|
-
}
|
|
82
|
-
}));
|
|
55
|
+
// Initialize API key when component mounts or API key changes
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
let isMounted = true;
|
|
83
58
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
};
|
|
59
|
+
const initializeApi = async () => {
|
|
60
|
+
// Skip if already initializing
|
|
61
|
+
if (isInitializing) return;
|
|
62
|
+
|
|
63
|
+
setIsInitializing(true);
|
|
64
|
+
setInitializationError(null);
|
|
92
65
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (isPressed) {
|
|
100
|
-
return color ?
|
|
101
|
-
(typeof color === 'string' ? `${color}80` : color) :
|
|
102
|
-
(darkMode ? '#32323280' : '#f5f5f580');
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return color || (darkMode ? '#2A2A2A' : '#ffffff');
|
|
106
|
-
};
|
|
66
|
+
try {
|
|
67
|
+
console.log('🚀 Onairos SDK: Starting API key initialization...');
|
|
68
|
+
|
|
69
|
+
if (!apiKey) {
|
|
70
|
+
throw new Error('API key is required. Please provide a valid API key from your Onairos dashboard.');
|
|
71
|
+
}
|
|
107
72
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
73
|
+
const config: OnairosConfig = {
|
|
74
|
+
apiKey,
|
|
75
|
+
environment,
|
|
76
|
+
enableLogging,
|
|
77
|
+
timeout,
|
|
78
|
+
retryAttempts,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Initialize the API key service
|
|
82
|
+
await initializeApiKey(config);
|
|
83
|
+
|
|
84
|
+
if (isMounted) {
|
|
85
|
+
setIsInitialized(true);
|
|
86
|
+
setInitializationError(null);
|
|
87
|
+
|
|
88
|
+
if (enableLogging) {
|
|
89
|
+
console.log('✅ Onairos SDK: API key initialization completed successfully');
|
|
90
|
+
console.log('📊 Configuration:', {
|
|
91
|
+
environment,
|
|
92
|
+
enableLogging,
|
|
93
|
+
timeout,
|
|
94
|
+
retryAttempts,
|
|
95
|
+
apiKeyLength: apiKey.length,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown initialization error';
|
|
101
|
+
|
|
102
|
+
console.error('❌ Onairos SDK: API key initialization failed:', errorMessage);
|
|
103
|
+
|
|
104
|
+
if (isMounted) {
|
|
105
|
+
setIsInitialized(false);
|
|
106
|
+
setInitializationError(errorMessage);
|
|
107
|
+
|
|
108
|
+
// Show developer-friendly error
|
|
109
|
+
if (enableLogging) {
|
|
110
|
+
console.group('🔧 API Key Troubleshooting Guide');
|
|
111
|
+
console.log('1. Check that your API key is correct and not expired');
|
|
112
|
+
console.log('2. Verify you have the right permissions for your use case');
|
|
113
|
+
console.log('3. Ensure your environment setting matches your API key');
|
|
114
|
+
console.log('4. Check your internet connection');
|
|
115
|
+
console.log('5. Visit https://dashboard.onairos.uk to manage your API keys');
|
|
116
|
+
console.groupEnd();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Call rejection callback if provided
|
|
120
|
+
if (onRejection) {
|
|
121
|
+
onRejection(`SDK initialization failed: ${errorMessage}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} finally {
|
|
125
|
+
if (isMounted) {
|
|
126
|
+
setIsInitializing(false);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Only initialize if we have an API key and aren't already initialized correctly
|
|
132
|
+
if (apiKey && (!isApiKeyInitialized() || getApiConfig()?.apiKey !== apiKey)) {
|
|
133
|
+
initializeApi();
|
|
116
134
|
}
|
|
117
|
-
|
|
118
|
-
const bgColor = getBackgroundColor();
|
|
119
|
-
// Simple luminance check - in a real app, this would use a proper algorithm
|
|
120
|
-
return bgColor === '#ffffff' || bgColor === '#f5f5f580' || bgColor.includes('#f') ? '#000000' : '#FFFFFF';
|
|
121
|
-
};
|
|
122
135
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
return () => {
|
|
137
|
+
isMounted = false;
|
|
138
|
+
};
|
|
139
|
+
}, [apiKey, environment, enableLogging, timeout, retryAttempts, onRejection]);
|
|
140
|
+
|
|
141
|
+
// Imperative methods
|
|
142
|
+
useImperativeHandle(ref, () => ({
|
|
143
|
+
openOverlay: handleShowOverlay,
|
|
144
|
+
closeOverlay: handleCloseOverlay,
|
|
145
|
+
isInitialized: () => isInitialized,
|
|
146
|
+
getApiConfig: () => getApiConfig(),
|
|
147
|
+
}));
|
|
148
|
+
|
|
149
|
+
const handleShowOverlay = useCallback(async () => {
|
|
128
150
|
try {
|
|
151
|
+
// Check if SDK is initialized
|
|
152
|
+
if (!isInitialized) {
|
|
153
|
+
const errorMessage = initializationError || 'SDK not initialized. Please check your API key.';
|
|
154
|
+
console.error('❌ Cannot open overlay: SDK not initialized');
|
|
155
|
+
|
|
156
|
+
if (onRejection) {
|
|
157
|
+
onRejection(errorMessage);
|
|
158
|
+
} else {
|
|
159
|
+
Alert.alert(
|
|
160
|
+
'SDK Error',
|
|
161
|
+
errorMessage,
|
|
162
|
+
[{ text: 'OK' }]
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Run pre-check if provided
|
|
129
169
|
if (preCheck) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
170
|
+
if (enableLogging) {
|
|
171
|
+
console.log('🔍 Running pre-check validation...');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
const preCheckPassed = await preCheck();
|
|
176
|
+
if (!preCheckPassed) {
|
|
177
|
+
if (enableLogging) {
|
|
178
|
+
console.log('⛔ Pre-check failed, aborting overlay');
|
|
179
|
+
}
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (enableLogging) {
|
|
184
|
+
console.log('✅ Pre-check passed');
|
|
185
|
+
}
|
|
186
|
+
} catch (preCheckError) {
|
|
187
|
+
console.error('❌ Pre-check error:', preCheckError);
|
|
188
|
+
if (onRejection) {
|
|
189
|
+
onRejection(`Pre-check failed: ${preCheckError.message}`);
|
|
190
|
+
}
|
|
134
191
|
return;
|
|
135
192
|
}
|
|
136
193
|
}
|
|
137
194
|
|
|
138
|
-
// Check
|
|
139
|
-
|
|
195
|
+
// Check for existing credentials
|
|
196
|
+
if (enableLogging) {
|
|
197
|
+
console.log('🔍 Checking for existing credentials...');
|
|
198
|
+
}
|
|
140
199
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
// Invalid credentials, clear and start fresh
|
|
147
|
-
await deleteCredentials();
|
|
148
|
-
setShowOnboarding(true);
|
|
149
|
-
setIsLoading(false);
|
|
150
|
-
return;
|
|
200
|
+
const hasExistingCredentials = await hasCredentials();
|
|
201
|
+
|
|
202
|
+
if (hasExistingCredentials) {
|
|
203
|
+
if (enableLogging) {
|
|
204
|
+
console.log('🔑 Existing credentials found, attempting automatic resolution...');
|
|
151
205
|
}
|
|
152
206
|
|
|
153
207
|
try {
|
|
154
|
-
|
|
155
|
-
const isValid = await onairosApi.validateCredentials(credentials.username);
|
|
208
|
+
const credentials = await getCredentials();
|
|
156
209
|
|
|
157
|
-
if (
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
210
|
+
if (credentials && onResolved) {
|
|
211
|
+
// For existing users, we can resolve immediately with cached data
|
|
212
|
+
const mockApiUrl = 'https://api2.onairos.uk/user/data';
|
|
213
|
+
const mockToken = 'existing_user_token';
|
|
214
|
+
|
|
215
|
+
if (enableLogging) {
|
|
216
|
+
console.log('✅ Resolving with existing credentials');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
onResolved(mockApiUrl, mockToken, credentials);
|
|
162
220
|
return;
|
|
163
221
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
setShowOverlay(true);
|
|
168
|
-
} catch (validationError) {
|
|
169
|
-
console.warn('Validation error, proceeding to onboarding:', validationError);
|
|
170
|
-
setShowOnboarding(true);
|
|
222
|
+
} catch (credentialsError) {
|
|
223
|
+
console.warn('⚠️ Failed to retrieve existing credentials:', credentialsError);
|
|
224
|
+
// Continue with normal flow
|
|
171
225
|
}
|
|
172
|
-
} else {
|
|
173
|
-
// If no credentials, show onboarding
|
|
174
|
-
setShowOnboarding(true);
|
|
175
226
|
}
|
|
227
|
+
|
|
228
|
+
if (enableLogging) {
|
|
229
|
+
console.log('🎨 Opening Onairos overlay...');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
setShowOverlay(true);
|
|
176
233
|
} catch (error) {
|
|
177
|
-
console.error('Error
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
} finally {
|
|
182
|
-
setIsLoading(false);
|
|
234
|
+
console.error('❌ Error opening overlay:', error);
|
|
235
|
+
if (onRejection) {
|
|
236
|
+
onRejection(`Failed to open overlay: ${error.message}`);
|
|
237
|
+
}
|
|
183
238
|
}
|
|
184
|
-
};
|
|
239
|
+
}, [isInitialized, initializationError, preCheck, enableLogging, onRejection, onResolved]);
|
|
185
240
|
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
241
|
+
const handleCloseOverlay = useCallback((result?: any) => {
|
|
242
|
+
if (enableLogging) {
|
|
243
|
+
console.log('🔽 Closing Onairos overlay');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
setShowOverlay(false);
|
|
247
|
+
|
|
248
|
+
if (result && onResolved) {
|
|
249
|
+
onResolved(result.apiUrl, result.token, result.userData);
|
|
190
250
|
}
|
|
191
|
-
}, [onResolved]);
|
|
251
|
+
}, [enableLogging, onResolved]);
|
|
192
252
|
|
|
193
|
-
const
|
|
253
|
+
const handleOverlayRejection = useCallback((error?: string) => {
|
|
254
|
+
if (enableLogging) {
|
|
255
|
+
console.log('❌ Overlay rejected:', error);
|
|
256
|
+
}
|
|
257
|
+
|
|
194
258
|
setShowOverlay(false);
|
|
195
|
-
|
|
196
|
-
|
|
259
|
+
|
|
260
|
+
if (onRejection) {
|
|
261
|
+
onRejection(error);
|
|
197
262
|
}
|
|
198
|
-
}, [
|
|
263
|
+
}, [enableLogging, onRejection]);
|
|
264
|
+
|
|
265
|
+
// Show error state if initialization failed
|
|
266
|
+
if (initializationError && !isInitializing) {
|
|
267
|
+
return (
|
|
268
|
+
<View style={styles.errorContainer}>
|
|
269
|
+
<TouchableOpacity
|
|
270
|
+
style={[styles.errorButton, { backgroundColor: '#FF6B6B' }]}
|
|
271
|
+
onPress={() => {
|
|
272
|
+
Alert.alert(
|
|
273
|
+
'SDK Error',
|
|
274
|
+
`Onairos SDK initialization failed:\n\n${initializationError}\n\nPlease check your API key and try again.`,
|
|
275
|
+
[{ text: 'OK' }]
|
|
276
|
+
);
|
|
277
|
+
}}
|
|
278
|
+
>
|
|
279
|
+
<Text style={styles.errorButtonText}>⚠️ SDK Error</Text>
|
|
280
|
+
</TouchableOpacity>
|
|
281
|
+
</View>
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Show loading state while initializing
|
|
286
|
+
if (isInitializing || !isInitialized) {
|
|
287
|
+
return (
|
|
288
|
+
<View style={styles.loadingContainer}>
|
|
289
|
+
<TouchableOpacity
|
|
290
|
+
style={[styles.loadingButton, { backgroundColor: '#999' }]}
|
|
291
|
+
disabled={true}
|
|
292
|
+
>
|
|
293
|
+
<Text style={styles.loadingButtonText}>🔄 Initializing...</Text>
|
|
294
|
+
</TouchableOpacity>
|
|
295
|
+
</View>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
199
298
|
|
|
200
|
-
//
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
{
|
|
299
|
+
// Get button style based on type
|
|
300
|
+
const getButtonStyle = (): ViewStyle => {
|
|
301
|
+
const baseStyle: ViewStyle = {
|
|
204
302
|
width: buttonWidth,
|
|
205
|
-
height: buttonHeight
|
|
206
|
-
backgroundColor:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
303
|
+
height: buttonHeight,
|
|
304
|
+
backgroundColor: color,
|
|
305
|
+
borderRadius: buttonType === 'pill' ? buttonHeight / 2 : 8,
|
|
306
|
+
alignItems: 'center',
|
|
307
|
+
justifyContent: 'center',
|
|
308
|
+
flexDirection: 'row',
|
|
309
|
+
opacity: enabled ? 1 : 0.6,
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
if (hasStroke) {
|
|
313
|
+
baseStyle.borderWidth = 2;
|
|
314
|
+
baseStyle.borderColor = darkMode ? '#fff' : '#000';
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return baseStyle;
|
|
318
|
+
};
|
|
212
319
|
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
320
|
+
const getButtonText = (): string => {
|
|
321
|
+
switch (buttonForm) {
|
|
322
|
+
case 'connect':
|
|
323
|
+
return 'Connect with Onairos';
|
|
324
|
+
default:
|
|
325
|
+
return 'Continue with Onairos';
|
|
326
|
+
}
|
|
217
327
|
};
|
|
218
328
|
|
|
219
329
|
return (
|
|
220
330
|
<>
|
|
221
331
|
<TouchableOpacity
|
|
222
|
-
style={
|
|
223
|
-
onPress={
|
|
224
|
-
disabled={!enabled ||
|
|
225
|
-
|
|
226
|
-
onPressIn={() => setIsPressed(true)}
|
|
227
|
-
onPressOut={() => setIsPressed(false)}
|
|
332
|
+
style={getButtonStyle()}
|
|
333
|
+
onPress={handleShowOverlay}
|
|
334
|
+
disabled={!enabled || isInitializing || !isInitialized}
|
|
335
|
+
activeOpacity={0.8}
|
|
228
336
|
>
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
</
|
|
337
|
+
<Image
|
|
338
|
+
source={require('../assets/images/onairos_logo.png')}
|
|
339
|
+
style={styles.logo}
|
|
340
|
+
resizeMode="contain"
|
|
341
|
+
/>
|
|
342
|
+
<Text style={[styles.buttonText, { color: darkMode ? '#000' : '#fff' }]}>
|
|
343
|
+
{getButtonText()}
|
|
344
|
+
</Text>
|
|
237
345
|
</TouchableOpacity>
|
|
238
346
|
|
|
239
|
-
{
|
|
240
|
-
{showOnboarding && (
|
|
241
|
-
<UniversalOnboarding
|
|
242
|
-
visible={showOnboarding}
|
|
243
|
-
onClose={() => {
|
|
244
|
-
setShowOnboarding(false);
|
|
245
|
-
onRejection?.('User closed onboarding');
|
|
246
|
-
}}
|
|
247
|
-
AppName={AppName}
|
|
248
|
-
requestData={requestData as any}
|
|
249
|
-
returnLink={returnLink || ''}
|
|
250
|
-
onComplete={handleOnboardingComplete}
|
|
251
|
-
debug={debug}
|
|
252
|
-
test={testMode}
|
|
253
|
-
preferredPlatform={preferredPlatform}
|
|
254
|
-
/>
|
|
255
|
-
)}
|
|
256
|
-
|
|
257
|
-
{/* Overlay rendered through Portal to ensure it appears at root level */}
|
|
258
|
-
{showOverlay && storedCredentials && (
|
|
347
|
+
{showOverlay && (
|
|
259
348
|
<Portal>
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
349
|
+
<UniversalOnboarding
|
|
350
|
+
visible={showOverlay}
|
|
351
|
+
onClose={handleCloseOverlay}
|
|
352
|
+
AppName={AppName}
|
|
353
|
+
requestData={requestData || {}}
|
|
354
|
+
returnLink={returnLink}
|
|
355
|
+
prefillUrl={prefillUrl}
|
|
356
|
+
onComplete={handleCloseOverlay}
|
|
357
|
+
embedd={false}
|
|
358
|
+
debug={debug}
|
|
359
|
+
testMode={testMode}
|
|
360
|
+
preferredPlatform={preferredPlatform}
|
|
361
|
+
config={getApiConfig() || undefined}
|
|
267
362
|
/>
|
|
268
363
|
</Portal>
|
|
269
364
|
)}
|
|
@@ -299,4 +394,32 @@ const styles = StyleSheet.create({
|
|
|
299
394
|
fontWeight: '600',
|
|
300
395
|
textAlign: 'center',
|
|
301
396
|
},
|
|
397
|
+
errorContainer: {
|
|
398
|
+
flex: 1,
|
|
399
|
+
justifyContent: 'center',
|
|
400
|
+
alignItems: 'center',
|
|
401
|
+
},
|
|
402
|
+
errorButton: {
|
|
403
|
+
padding: 16,
|
|
404
|
+
borderRadius: 8,
|
|
405
|
+
},
|
|
406
|
+
errorButtonText: {
|
|
407
|
+
fontSize: 16,
|
|
408
|
+
fontWeight: '600',
|
|
409
|
+
color: '#fff',
|
|
410
|
+
},
|
|
411
|
+
loadingContainer: {
|
|
412
|
+
flex: 1,
|
|
413
|
+
justifyContent: 'center',
|
|
414
|
+
alignItems: 'center',
|
|
415
|
+
},
|
|
416
|
+
loadingButton: {
|
|
417
|
+
padding: 16,
|
|
418
|
+
borderRadius: 8,
|
|
419
|
+
},
|
|
420
|
+
loadingButtonText: {
|
|
421
|
+
fontSize: 16,
|
|
422
|
+
fontWeight: '600',
|
|
423
|
+
color: '#fff',
|
|
424
|
+
},
|
|
302
425
|
});
|
|
@@ -288,7 +288,7 @@ export const OnairosButton = forwardRef<OnairosButtonRef, OnairosButtonProps>(({
|
|
|
288
288
|
returnLink={returnLink || ''}
|
|
289
289
|
onComplete={handleOnboardingComplete}
|
|
290
290
|
debug={debug}
|
|
291
|
-
|
|
291
|
+
testMode={testMode}
|
|
292
292
|
preferredPlatform={preferredPlatform}
|
|
293
293
|
/>
|
|
294
294
|
)}
|
|
@@ -56,7 +56,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
56
56
|
onComplete,
|
|
57
57
|
embedd = false,
|
|
58
58
|
debug = false,
|
|
59
|
-
|
|
59
|
+
testMode = false,
|
|
60
60
|
preferredPlatform,
|
|
61
61
|
inferenceData,
|
|
62
62
|
auto = false,
|
|
@@ -93,8 +93,8 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
// Parse test mode options
|
|
96
|
-
const testModeOptions = typeof
|
|
97
|
-
const isTestMode =
|
|
96
|
+
const testModeOptions = typeof testMode === 'object' ? testMode : {} as any;
|
|
97
|
+
const isTestMode = testMode === true || (typeof testMode === 'object' && testMode !== null);
|
|
98
98
|
const showTestControls = (debug || isTestMode) && requestData;
|
|
99
99
|
|
|
100
100
|
// Simple 2-flow system
|
|
@@ -169,7 +169,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
169
169
|
});
|
|
170
170
|
|
|
171
171
|
// Pre-populate with mock connections in debug mode
|
|
172
|
-
if (
|
|
172
|
+
if (testMode || Platform.OS === 'web') {
|
|
173
173
|
setConnections({
|
|
174
174
|
instagram: { userName: 'instagram_user', connected: true },
|
|
175
175
|
youtube: { userName: 'youtube_user', connected: true },
|
|
@@ -573,7 +573,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
573
573
|
Alert.alert('Error', 'An unexpected error occurred. Please try again.');
|
|
574
574
|
}
|
|
575
575
|
}
|
|
576
|
-
}, [email, isVerifyingCode, debug,
|
|
576
|
+
}, [email, isVerifyingCode, debug, testMode]);
|
|
577
577
|
|
|
578
578
|
// Function to handle verification code submission
|
|
579
579
|
const handleVerificationSubmit = useCallback(async () => {
|
|
@@ -1157,7 +1157,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
1157
1157
|
<Text style={styles.privacyMessage}>
|
|
1158
1158
|
None of your app data is shared with ANYONE
|
|
1159
1159
|
</Text>
|
|
1160
|
-
{(debug ||
|
|
1160
|
+
{(debug || testMode) && (
|
|
1161
1161
|
<Text style={styles.developmentNote}>
|
|
1162
1162
|
🧪 Test Mode: You can proceed without connecting any platforms
|
|
1163
1163
|
</Text>
|