@onairos/react-native 3.0.71 → 3.0.72
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 +66 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/services/apiKeyService.js +325 -0
- package/lib/commonjs/services/apiKeyService.js.map +1 -0
- package/lib/commonjs/services/platformAuthService.js +104 -113
- package/lib/commonjs/services/platformAuthService.js.map +1 -1
- 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 +4 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/services/apiKeyService.js +310 -0
- package/lib/module/services/apiKeyService.js.map +1 -0
- package/lib/module/services/platformAuthService.js +104 -113
- package/lib/module/services/platformAuthService.js.map +1 -1
- package/lib/typescript/components/Onairos.d.ts +6 -5
- 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 +3 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/services/apiKeyService.d.ts +48 -0
- package/lib/typescript/services/apiKeyService.d.ts.map +1 -0
- package/lib/typescript/services/platformAuthService.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +36 -3
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Onairos.tsx +336 -184
- 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 +19 -0
- package/src/services/apiKeyService.ts +325 -0
- package/src/services/platformAuthService.ts +111 -130
- package/src/types.ts +40 -3
|
@@ -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,7 +16,8 @@ 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 } from '../types';
|
|
20
|
+
import { initializeApiKey, isApiKeyInitialized, getApiConfig } from '../services/apiKeyService';
|
|
19
21
|
|
|
20
22
|
interface OnairosProps {
|
|
21
23
|
returnLink?: string;
|
|
@@ -38,232 +40,354 @@ interface OnairosProps {
|
|
|
38
40
|
darkMode?: boolean;
|
|
39
41
|
preferredPlatform?: string;
|
|
40
42
|
testMode?: boolean;
|
|
43
|
+
// API Key Configuration (REQUIRED)
|
|
44
|
+
apiKey: string;
|
|
45
|
+
environment?: 'production' | 'staging' | 'development';
|
|
46
|
+
enableLogging?: boolean;
|
|
47
|
+
timeout?: number;
|
|
48
|
+
retryAttempts?: number;
|
|
41
49
|
}
|
|
42
50
|
|
|
43
|
-
export
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
export const Onairos = forwardRef<any, OnairosProps>((props, ref) => {
|
|
52
|
+
const {
|
|
53
|
+
returnLink,
|
|
54
|
+
prefillUrl,
|
|
55
|
+
AppName,
|
|
56
|
+
buttonType = 'normal',
|
|
57
|
+
requestData,
|
|
58
|
+
buttonWidth = 200,
|
|
59
|
+
buttonHeight = 48,
|
|
60
|
+
hasStroke = false,
|
|
61
|
+
enabled = true,
|
|
62
|
+
buttonForm = 'default',
|
|
63
|
+
onRejection,
|
|
64
|
+
onResolved,
|
|
65
|
+
preCheck,
|
|
66
|
+
color = COLORS.primary,
|
|
67
|
+
debug = false,
|
|
68
|
+
darkMode = false,
|
|
69
|
+
preferredPlatform,
|
|
70
|
+
testMode = false,
|
|
71
|
+
// API Key props
|
|
72
|
+
apiKey,
|
|
73
|
+
environment = 'production',
|
|
74
|
+
enableLogging = true,
|
|
75
|
+
timeout = 30000,
|
|
76
|
+
retryAttempts = 3,
|
|
77
|
+
} = props;
|
|
47
78
|
|
|
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
79
|
const [showOverlay, setShowOverlay] = useState(false);
|
|
70
|
-
const [
|
|
71
|
-
const [
|
|
72
|
-
const [
|
|
80
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
81
|
+
const [initializationError, setInitializationError] = useState<string | null>(null);
|
|
82
|
+
const [isInitializing, setIsInitializing] = useState(false);
|
|
73
83
|
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
await handlePress();
|
|
78
|
-
},
|
|
79
|
-
reset: async () => {
|
|
80
|
-
await deleteCredentials();
|
|
81
|
-
}
|
|
82
|
-
}));
|
|
84
|
+
// Initialize API key when component mounts or API key changes
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
let isMounted = true;
|
|
83
87
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
};
|
|
88
|
+
const initializeApi = async () => {
|
|
89
|
+
// Skip if already initializing
|
|
90
|
+
if (isInitializing) return;
|
|
91
|
+
|
|
92
|
+
setIsInitializing(true);
|
|
93
|
+
setInitializationError(null);
|
|
92
94
|
|
|
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
|
-
};
|
|
95
|
+
try {
|
|
96
|
+
console.log('🚀 Onairos SDK: Starting API key initialization...');
|
|
97
|
+
|
|
98
|
+
if (!apiKey) {
|
|
99
|
+
throw new Error('API key is required. Please provide a valid API key from your Onairos dashboard.');
|
|
100
|
+
}
|
|
107
101
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
102
|
+
const config: OnairosConfig = {
|
|
103
|
+
apiKey,
|
|
104
|
+
environment,
|
|
105
|
+
enableLogging,
|
|
106
|
+
timeout,
|
|
107
|
+
retryAttempts,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Initialize the API key service
|
|
111
|
+
await initializeApiKey(config);
|
|
112
|
+
|
|
113
|
+
if (isMounted) {
|
|
114
|
+
setIsInitialized(true);
|
|
115
|
+
setInitializationError(null);
|
|
116
|
+
|
|
117
|
+
if (enableLogging) {
|
|
118
|
+
console.log('✅ Onairos SDK: API key initialization completed successfully');
|
|
119
|
+
console.log('📊 Configuration:', {
|
|
120
|
+
environment,
|
|
121
|
+
enableLogging,
|
|
122
|
+
timeout,
|
|
123
|
+
retryAttempts,
|
|
124
|
+
apiKeyLength: apiKey.length,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown initialization error';
|
|
130
|
+
|
|
131
|
+
console.error('❌ Onairos SDK: API key initialization failed:', errorMessage);
|
|
132
|
+
|
|
133
|
+
if (isMounted) {
|
|
134
|
+
setIsInitialized(false);
|
|
135
|
+
setInitializationError(errorMessage);
|
|
136
|
+
|
|
137
|
+
// Show developer-friendly error
|
|
138
|
+
if (enableLogging) {
|
|
139
|
+
console.group('🔧 API Key Troubleshooting Guide');
|
|
140
|
+
console.log('1. Check that your API key is correct and not expired');
|
|
141
|
+
console.log('2. Verify you have the right permissions for your use case');
|
|
142
|
+
console.log('3. Ensure your environment setting matches your API key');
|
|
143
|
+
console.log('4. Check your internet connection');
|
|
144
|
+
console.log('5. Visit https://dashboard.onairos.uk to manage your API keys');
|
|
145
|
+
console.groupEnd();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Call rejection callback if provided
|
|
149
|
+
if (onRejection) {
|
|
150
|
+
onRejection(`SDK initialization failed: ${errorMessage}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
} finally {
|
|
154
|
+
if (isMounted) {
|
|
155
|
+
setIsInitializing(false);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Only initialize if we have an API key and aren't already initialized correctly
|
|
161
|
+
if (apiKey && (!isApiKeyInitialized() || getApiConfig()?.apiKey !== apiKey)) {
|
|
162
|
+
initializeApi();
|
|
116
163
|
}
|
|
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
164
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
165
|
+
return () => {
|
|
166
|
+
isMounted = false;
|
|
167
|
+
};
|
|
168
|
+
}, [apiKey, environment, enableLogging, timeout, retryAttempts, onRejection]);
|
|
169
|
+
|
|
170
|
+
// Imperative methods
|
|
171
|
+
useImperativeHandle(ref, () => ({
|
|
172
|
+
openOverlay: handleShowOverlay,
|
|
173
|
+
closeOverlay: handleCloseOverlay,
|
|
174
|
+
isInitialized: () => isInitialized,
|
|
175
|
+
getApiConfig: () => getApiConfig(),
|
|
176
|
+
}));
|
|
177
|
+
|
|
178
|
+
const handleShowOverlay = useCallback(async () => {
|
|
128
179
|
try {
|
|
180
|
+
// Check if SDK is initialized
|
|
181
|
+
if (!isInitialized) {
|
|
182
|
+
const errorMessage = initializationError || 'SDK not initialized. Please check your API key.';
|
|
183
|
+
console.error('❌ Cannot open overlay: SDK not initialized');
|
|
184
|
+
|
|
185
|
+
if (onRejection) {
|
|
186
|
+
onRejection(errorMessage);
|
|
187
|
+
} else {
|
|
188
|
+
Alert.alert(
|
|
189
|
+
'SDK Error',
|
|
190
|
+
errorMessage,
|
|
191
|
+
[{ text: 'OK' }]
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Run pre-check if provided
|
|
129
198
|
if (preCheck) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
199
|
+
if (enableLogging) {
|
|
200
|
+
console.log('🔍 Running pre-check validation...');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
const preCheckPassed = await preCheck();
|
|
205
|
+
if (!preCheckPassed) {
|
|
206
|
+
if (enableLogging) {
|
|
207
|
+
console.log('⛔ Pre-check failed, aborting overlay');
|
|
208
|
+
}
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (enableLogging) {
|
|
213
|
+
console.log('✅ Pre-check passed');
|
|
214
|
+
}
|
|
215
|
+
} catch (preCheckError) {
|
|
216
|
+
console.error('❌ Pre-check error:', preCheckError);
|
|
217
|
+
if (onRejection) {
|
|
218
|
+
onRejection(`Pre-check failed: ${preCheckError.message}`);
|
|
219
|
+
}
|
|
134
220
|
return;
|
|
135
221
|
}
|
|
136
222
|
}
|
|
137
223
|
|
|
138
|
-
// Check
|
|
139
|
-
|
|
224
|
+
// Check for existing credentials
|
|
225
|
+
if (enableLogging) {
|
|
226
|
+
console.log('🔍 Checking for existing credentials...');
|
|
227
|
+
}
|
|
140
228
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
// Invalid credentials, clear and start fresh
|
|
147
|
-
await deleteCredentials();
|
|
148
|
-
setShowOnboarding(true);
|
|
149
|
-
setIsLoading(false);
|
|
150
|
-
return;
|
|
229
|
+
const hasExistingCredentials = await hasCredentials();
|
|
230
|
+
|
|
231
|
+
if (hasExistingCredentials) {
|
|
232
|
+
if (enableLogging) {
|
|
233
|
+
console.log('🔑 Existing credentials found, attempting automatic resolution...');
|
|
151
234
|
}
|
|
152
235
|
|
|
153
236
|
try {
|
|
154
|
-
|
|
155
|
-
const isValid = await onairosApi.validateCredentials(credentials.username);
|
|
237
|
+
const credentials = await getCredentials();
|
|
156
238
|
|
|
157
|
-
if (
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
239
|
+
if (credentials && onResolved) {
|
|
240
|
+
// For existing users, we can resolve immediately with cached data
|
|
241
|
+
const mockApiUrl = 'https://api2.onairos.uk/user/data';
|
|
242
|
+
const mockToken = 'existing_user_token';
|
|
243
|
+
|
|
244
|
+
if (enableLogging) {
|
|
245
|
+
console.log('✅ Resolving with existing credentials');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
onResolved(mockApiUrl, mockToken, credentials);
|
|
162
249
|
return;
|
|
163
250
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
setShowOverlay(true);
|
|
168
|
-
} catch (validationError) {
|
|
169
|
-
console.warn('Validation error, proceeding to onboarding:', validationError);
|
|
170
|
-
setShowOnboarding(true);
|
|
251
|
+
} catch (credentialsError) {
|
|
252
|
+
console.warn('⚠️ Failed to retrieve existing credentials:', credentialsError);
|
|
253
|
+
// Continue with normal flow
|
|
171
254
|
}
|
|
172
|
-
} else {
|
|
173
|
-
// If no credentials, show onboarding
|
|
174
|
-
setShowOnboarding(true);
|
|
175
255
|
}
|
|
256
|
+
|
|
257
|
+
if (enableLogging) {
|
|
258
|
+
console.log('🎨 Opening Onairos overlay...');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
setShowOverlay(true);
|
|
176
262
|
} catch (error) {
|
|
177
|
-
console.error('Error
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
} finally {
|
|
182
|
-
setIsLoading(false);
|
|
263
|
+
console.error('❌ Error opening overlay:', error);
|
|
264
|
+
if (onRejection) {
|
|
265
|
+
onRejection(`Failed to open overlay: ${error.message}`);
|
|
266
|
+
}
|
|
183
267
|
}
|
|
184
|
-
};
|
|
268
|
+
}, [isInitialized, initializationError, preCheck, enableLogging, onRejection, onResolved]);
|
|
185
269
|
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
270
|
+
const handleCloseOverlay = useCallback((result?: any) => {
|
|
271
|
+
if (enableLogging) {
|
|
272
|
+
console.log('🔽 Closing Onairos overlay');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
setShowOverlay(false);
|
|
276
|
+
|
|
277
|
+
if (result && onResolved) {
|
|
278
|
+
onResolved(result.apiUrl, result.token, result.userData);
|
|
190
279
|
}
|
|
191
|
-
}, [onResolved]);
|
|
280
|
+
}, [enableLogging, onResolved]);
|
|
192
281
|
|
|
193
|
-
const
|
|
282
|
+
const handleOverlayRejection = useCallback((error?: string) => {
|
|
283
|
+
if (enableLogging) {
|
|
284
|
+
console.log('❌ Overlay rejected:', error);
|
|
285
|
+
}
|
|
286
|
+
|
|
194
287
|
setShowOverlay(false);
|
|
195
|
-
|
|
196
|
-
|
|
288
|
+
|
|
289
|
+
if (onRejection) {
|
|
290
|
+
onRejection(error);
|
|
197
291
|
}
|
|
198
|
-
}, [
|
|
292
|
+
}, [enableLogging, onRejection]);
|
|
293
|
+
|
|
294
|
+
// Show error state if initialization failed
|
|
295
|
+
if (initializationError && !isInitializing) {
|
|
296
|
+
return (
|
|
297
|
+
<View style={styles.errorContainer}>
|
|
298
|
+
<TouchableOpacity
|
|
299
|
+
style={[styles.errorButton, { backgroundColor: '#FF6B6B' }]}
|
|
300
|
+
onPress={() => {
|
|
301
|
+
Alert.alert(
|
|
302
|
+
'SDK Error',
|
|
303
|
+
`Onairos SDK initialization failed:\n\n${initializationError}\n\nPlease check your API key and try again.`,
|
|
304
|
+
[{ text: 'OK' }]
|
|
305
|
+
);
|
|
306
|
+
}}
|
|
307
|
+
>
|
|
308
|
+
<Text style={styles.errorButtonText}>⚠️ SDK Error</Text>
|
|
309
|
+
</TouchableOpacity>
|
|
310
|
+
</View>
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Show loading state while initializing
|
|
315
|
+
if (isInitializing || !isInitialized) {
|
|
316
|
+
return (
|
|
317
|
+
<View style={styles.loadingContainer}>
|
|
318
|
+
<TouchableOpacity
|
|
319
|
+
style={[styles.loadingButton, { backgroundColor: '#999' }]}
|
|
320
|
+
disabled={true}
|
|
321
|
+
>
|
|
322
|
+
<Text style={styles.loadingButtonText}>🔄 Initializing...</Text>
|
|
323
|
+
</TouchableOpacity>
|
|
324
|
+
</View>
|
|
325
|
+
);
|
|
326
|
+
}
|
|
199
327
|
|
|
200
|
-
//
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
{
|
|
328
|
+
// Get button style based on type
|
|
329
|
+
const getButtonStyle = (): ViewStyle => {
|
|
330
|
+
const baseStyle: ViewStyle = {
|
|
204
331
|
width: buttonWidth,
|
|
205
|
-
height: buttonHeight
|
|
206
|
-
backgroundColor:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
332
|
+
height: buttonHeight,
|
|
333
|
+
backgroundColor: color,
|
|
334
|
+
borderRadius: buttonType === 'pill' ? buttonHeight / 2 : 8,
|
|
335
|
+
alignItems: 'center',
|
|
336
|
+
justifyContent: 'center',
|
|
337
|
+
flexDirection: 'row',
|
|
338
|
+
opacity: enabled ? 1 : 0.6,
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
if (hasStroke) {
|
|
342
|
+
baseStyle.borderWidth = 2;
|
|
343
|
+
baseStyle.borderColor = darkMode ? '#fff' : '#000';
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return baseStyle;
|
|
347
|
+
};
|
|
212
348
|
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
349
|
+
const getButtonText = (): string => {
|
|
350
|
+
switch (buttonForm) {
|
|
351
|
+
case 'connect':
|
|
352
|
+
return 'Connect with Onairos';
|
|
353
|
+
default:
|
|
354
|
+
return 'Continue with Onairos';
|
|
355
|
+
}
|
|
217
356
|
};
|
|
218
357
|
|
|
219
358
|
return (
|
|
220
359
|
<>
|
|
221
360
|
<TouchableOpacity
|
|
222
|
-
style={
|
|
223
|
-
onPress={
|
|
224
|
-
disabled={!enabled ||
|
|
225
|
-
|
|
226
|
-
onPressIn={() => setIsPressed(true)}
|
|
227
|
-
onPressOut={() => setIsPressed(false)}
|
|
361
|
+
style={getButtonStyle()}
|
|
362
|
+
onPress={handleShowOverlay}
|
|
363
|
+
disabled={!enabled || isInitializing || !isInitialized}
|
|
364
|
+
activeOpacity={0.8}
|
|
228
365
|
>
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
</
|
|
366
|
+
<Image
|
|
367
|
+
source={require('../assets/images/onairos_logo.png')}
|
|
368
|
+
style={styles.logo}
|
|
369
|
+
resizeMode="contain"
|
|
370
|
+
/>
|
|
371
|
+
<Text style={[styles.buttonText, { color: darkMode ? '#000' : '#fff' }]}>
|
|
372
|
+
{getButtonText()}
|
|
373
|
+
</Text>
|
|
237
374
|
</TouchableOpacity>
|
|
238
375
|
|
|
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 && (
|
|
376
|
+
{showOverlay && (
|
|
259
377
|
<Portal>
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
378
|
+
<UniversalOnboarding
|
|
379
|
+
visible={showOverlay}
|
|
380
|
+
onClose={handleCloseOverlay}
|
|
381
|
+
AppName={AppName}
|
|
382
|
+
requestData={requestData || {}}
|
|
383
|
+
returnLink={returnLink}
|
|
384
|
+
prefillUrl={prefillUrl}
|
|
385
|
+
onComplete={handleCloseOverlay}
|
|
386
|
+
embedd={false}
|
|
387
|
+
debug={debug}
|
|
388
|
+
testMode={testMode}
|
|
389
|
+
preferredPlatform={preferredPlatform}
|
|
390
|
+
config={getApiConfig() || undefined}
|
|
267
391
|
/>
|
|
268
392
|
</Portal>
|
|
269
393
|
)}
|
|
@@ -299,4 +423,32 @@ const styles = StyleSheet.create({
|
|
|
299
423
|
fontWeight: '600',
|
|
300
424
|
textAlign: 'center',
|
|
301
425
|
},
|
|
426
|
+
errorContainer: {
|
|
427
|
+
flex: 1,
|
|
428
|
+
justifyContent: 'center',
|
|
429
|
+
alignItems: 'center',
|
|
430
|
+
},
|
|
431
|
+
errorButton: {
|
|
432
|
+
padding: 16,
|
|
433
|
+
borderRadius: 8,
|
|
434
|
+
},
|
|
435
|
+
errorButtonText: {
|
|
436
|
+
fontSize: 16,
|
|
437
|
+
fontWeight: '600',
|
|
438
|
+
color: '#fff',
|
|
439
|
+
},
|
|
440
|
+
loadingContainer: {
|
|
441
|
+
flex: 1,
|
|
442
|
+
justifyContent: 'center',
|
|
443
|
+
alignItems: 'center',
|
|
444
|
+
},
|
|
445
|
+
loadingButton: {
|
|
446
|
+
padding: 16,
|
|
447
|
+
borderRadius: 8,
|
|
448
|
+
},
|
|
449
|
+
loadingButtonText: {
|
|
450
|
+
fontSize: 16,
|
|
451
|
+
fontWeight: '600',
|
|
452
|
+
color: '#fff',
|
|
453
|
+
},
|
|
302
454
|
});
|
|
@@ -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>
|