onairos 2.0.4 → 2.0.6
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/package.json
CHANGED
|
@@ -1,43 +1,160 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const platforms = [
|
|
4
|
+
{ name: 'YouTube', icon: '📺', color: 'bg-red-500' },
|
|
5
|
+
{ name: 'Reddit', icon: '🔥', color: 'bg-orange-500' },
|
|
6
|
+
{ name: 'Instagram', icon: '📷', color: 'bg-pink-500' },
|
|
7
|
+
{ name: 'Pinterest', icon: '📌', color: 'bg-red-600' },
|
|
8
|
+
{ name: 'TikTok', icon: '🎵', color: 'bg-black' },
|
|
9
|
+
{ name: 'Twitter', icon: '🐦', color: 'bg-blue-500' },
|
|
10
|
+
{ name: 'LinkedIn', icon: '💼', color: 'bg-blue-700' },
|
|
11
|
+
{ name: 'Facebook', icon: '👥', color: 'bg-blue-600' }
|
|
12
|
+
];
|
|
2
13
|
|
|
3
14
|
/**
|
|
4
15
|
* UniversalOnboarding Component
|
|
5
16
|
* Displays an onboarding screen for applications requesting Onairos data
|
|
6
17
|
*/
|
|
7
|
-
|
|
18
|
+
export default function UniversalOnboarding({ onComplete, appIcon, appName = 'App' }) {
|
|
19
|
+
const [connectedAccounts, setConnectedAccounts] = useState({});
|
|
20
|
+
const [isConnecting, setIsConnecting] = useState(false);
|
|
21
|
+
|
|
22
|
+
const handleToggle = async (platformName) => {
|
|
23
|
+
if (isConnecting) return;
|
|
24
|
+
|
|
25
|
+
setIsConnecting(true);
|
|
26
|
+
|
|
27
|
+
// Simulate connection delay
|
|
28
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
29
|
+
|
|
30
|
+
setConnectedAccounts(prev => ({
|
|
31
|
+
...prev,
|
|
32
|
+
[platformName]: !prev[platformName]
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
setIsConnecting(false);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const handleContinue = () => {
|
|
39
|
+
const connected = Object.entries(connectedAccounts)
|
|
40
|
+
.filter(([platform, isConnected]) => isConnected)
|
|
41
|
+
.map(([platform]) => platform);
|
|
42
|
+
|
|
43
|
+
onComplete({
|
|
44
|
+
connectedAccounts: connected,
|
|
45
|
+
totalConnections: connected.length
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const connectedCount = Object.values(connectedAccounts).filter(Boolean).length;
|
|
50
|
+
|
|
8
51
|
return (
|
|
9
|
-
<div className="
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
52
|
+
<div className="max-w-md mx-auto bg-white p-6 min-h-[500px]">
|
|
53
|
+
{/* Header with App Logo and Arrow to Onairos */}
|
|
54
|
+
<div className="flex items-center justify-center mb-6">
|
|
55
|
+
<div className="flex items-center space-x-3">
|
|
56
|
+
<img
|
|
57
|
+
src={appIcon || "https://onairos.sirv.com/Images/OnairosBlack.png"}
|
|
58
|
+
alt={appName}
|
|
59
|
+
className="w-10 h-10 rounded-lg"
|
|
60
|
+
/>
|
|
61
|
+
<div className="flex items-center text-gray-400">
|
|
62
|
+
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
63
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
|
|
64
|
+
</svg>
|
|
14
65
|
</div>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
To share your data with {appName}, you need to create an Onairos Personality model first.
|
|
21
|
-
</p>
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
<div className="border-t border-gray-200 pt-4">
|
|
25
|
-
<a
|
|
26
|
-
href="https://onairos.uk/connections"
|
|
27
|
-
target="_blank"
|
|
28
|
-
rel="noopener noreferrer"
|
|
29
|
-
className="block w-full bg-black text-white rounded-md py-2 text-center font-medium hover:bg-black/90 transition-colors"
|
|
30
|
-
>
|
|
31
|
-
Create Personality Model
|
|
32
|
-
</a>
|
|
66
|
+
<img
|
|
67
|
+
src="https://onairos.sirv.com/Images/OnairosBlack.png"
|
|
68
|
+
alt="Onairos"
|
|
69
|
+
className="w-10 h-10 rounded-lg"
|
|
70
|
+
/>
|
|
33
71
|
</div>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div className="text-center mb-6">
|
|
75
|
+
<h2 className="text-xl font-bold text-gray-900 mb-2">Connect Your Accounts</h2>
|
|
76
|
+
<p className="text-gray-600 text-sm">
|
|
77
|
+
Choose which accounts to connect for a personalized experience
|
|
78
|
+
</p>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
{/* Privacy Notice */}
|
|
82
|
+
<div className="mb-6 p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
|
83
|
+
<p className="text-blue-800 text-sm">
|
|
84
|
+
🔒 Your data is never shared with anyone. It's only used to train your personal model and is stored securely.
|
|
37
85
|
</p>
|
|
38
86
|
</div>
|
|
87
|
+
|
|
88
|
+
{/* Platform List - Vertical Layout with Toggles */}
|
|
89
|
+
<div className="space-y-3 mb-6">
|
|
90
|
+
{platforms.map((platform) => {
|
|
91
|
+
const isConnected = connectedAccounts[platform.name] || false;
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<div
|
|
95
|
+
key={platform.name}
|
|
96
|
+
className="flex items-center justify-between p-4 border rounded-lg hover:bg-gray-50 transition-colors"
|
|
97
|
+
>
|
|
98
|
+
<div className="flex items-center space-x-3">
|
|
99
|
+
<div className={`w-10 h-10 rounded-lg ${platform.color} flex items-center justify-center text-white text-lg`}>
|
|
100
|
+
{platform.icon}
|
|
101
|
+
</div>
|
|
102
|
+
<div>
|
|
103
|
+
<h3 className="font-medium text-gray-900">{platform.name}</h3>
|
|
104
|
+
<p className="text-sm text-gray-500">
|
|
105
|
+
{isConnected ? 'Connected' : 'Not connected'}
|
|
106
|
+
</p>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
{/* Toggle Switch */}
|
|
111
|
+
<button
|
|
112
|
+
onClick={() => handleToggle(platform.name)}
|
|
113
|
+
disabled={isConnecting}
|
|
114
|
+
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${
|
|
115
|
+
isConnected ? 'bg-blue-600' : 'bg-gray-200'
|
|
116
|
+
} ${isConnecting ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`}
|
|
117
|
+
>
|
|
118
|
+
<span
|
|
119
|
+
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
|
|
120
|
+
isConnected ? 'translate-x-6' : 'translate-x-1'
|
|
121
|
+
}`}
|
|
122
|
+
/>
|
|
123
|
+
</button>
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
})}
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
{/* Connection Status */}
|
|
130
|
+
{connectedCount > 0 && (
|
|
131
|
+
<div className="mb-4 p-3 bg-green-50 border border-green-200 rounded-lg">
|
|
132
|
+
<p className="text-green-800 text-sm">
|
|
133
|
+
✅ {connectedCount} account{connectedCount > 1 ? 's' : ''} connected
|
|
134
|
+
</p>
|
|
135
|
+
</div>
|
|
136
|
+
)}
|
|
137
|
+
|
|
138
|
+
{/* Continue Button */}
|
|
139
|
+
<button
|
|
140
|
+
onClick={handleContinue}
|
|
141
|
+
disabled={connectedCount === 0}
|
|
142
|
+
className={`w-full py-3 px-4 rounded-lg font-semibold transition-colors ${
|
|
143
|
+
connectedCount > 0
|
|
144
|
+
? 'bg-blue-600 text-white hover:bg-blue-700'
|
|
145
|
+
: 'bg-gray-300 text-gray-500 cursor-not-allowed'
|
|
146
|
+
}`}
|
|
147
|
+
>
|
|
148
|
+
Continue {connectedCount > 0 ? `with ${connectedCount} account${connectedCount > 1 ? 's' : ''}` : ''}
|
|
149
|
+
</button>
|
|
150
|
+
|
|
151
|
+
{/* Skip Option */}
|
|
152
|
+
<button
|
|
153
|
+
onClick={() => onComplete({ connectedAccounts: [], totalConnections: 0 })}
|
|
154
|
+
className="w-full mt-2 py-2 text-gray-500 hover:text-gray-700 text-sm"
|
|
155
|
+
>
|
|
156
|
+
Skip for now
|
|
157
|
+
</button>
|
|
39
158
|
</div>
|
|
40
159
|
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default UniversalOnboarding;
|
|
160
|
+
}
|
package/src/onairosButton.jsx
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import React, { useEffect, useState
|
|
2
|
-
import { rsaEncrypt } from './RSA.jsx';
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
3
2
|
import EmailAuth from './components/EmailAuth.js';
|
|
4
3
|
import UniversalOnboarding from './components/UniversalOnboarding.js';
|
|
5
4
|
import PinSetup from './components/PinSetup.js';
|
|
6
5
|
import DataRequest from './components/DataRequest.js';
|
|
7
|
-
import {
|
|
8
|
-
openDataRequestPopup,
|
|
9
|
-
closeDataRequestPopup,
|
|
10
|
-
sendDataToPopup,
|
|
11
|
-
listenForPopupMessages
|
|
12
|
-
} from './iframe/dataRequestHandler.js';
|
|
13
6
|
|
|
14
7
|
export function OnairosButton({
|
|
15
8
|
requestData,
|
|
@@ -25,16 +18,13 @@ export function OnairosButton({
|
|
|
25
18
|
loginReturn = null,
|
|
26
19
|
loginType = 'signIn',
|
|
27
20
|
visualType = 'full',
|
|
28
|
-
appIcon = null,
|
|
21
|
+
appIcon = null,
|
|
29
22
|
}) {
|
|
30
23
|
|
|
31
24
|
const [showOverlay, setShowOverlay] = useState(false);
|
|
32
25
|
const [currentFlow, setCurrentFlow] = useState('email'); // 'email' | 'onboarding' | 'pin' | 'dataRequest'
|
|
33
26
|
const [userData, setUserData] = useState(null);
|
|
34
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
35
27
|
const [error, setError] = useState(null);
|
|
36
|
-
const [popupWindow, setPopupWindow] = useState(null);
|
|
37
|
-
const messageCleanup = useRef(null);
|
|
38
28
|
|
|
39
29
|
// Check for existing user session
|
|
40
30
|
useEffect(() => {
|
|
@@ -62,84 +52,15 @@ export function OnairosButton({
|
|
|
62
52
|
checkExistingSession();
|
|
63
53
|
}, []);
|
|
64
54
|
|
|
65
|
-
// Cleanup popup and message listeners on unmount
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
return () => {
|
|
68
|
-
if (popupWindow) {
|
|
69
|
-
closeDataRequestPopup(popupWindow);
|
|
70
|
-
}
|
|
71
|
-
if (messageCleanup.current) {
|
|
72
|
-
messageCleanup.current();
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}, [popupWindow]);
|
|
76
|
-
|
|
77
55
|
const openTerminal = async () => {
|
|
78
56
|
try {
|
|
79
57
|
console.log('🔥 openTerminal called');
|
|
80
|
-
|
|
81
|
-
// If user has completed all steps, open popup directly for data request
|
|
82
|
-
if (userData?.onboardingComplete && userData?.pinCreated) {
|
|
83
|
-
openDataRequestDirectly();
|
|
84
|
-
} else {
|
|
85
|
-
// Otherwise show the overlay for onboarding flow
|
|
86
|
-
setShowOverlay(true);
|
|
87
|
-
}
|
|
58
|
+
setShowOverlay(true);
|
|
88
59
|
} catch (error) {
|
|
89
60
|
console.error('Error in openTerminal:', error);
|
|
90
61
|
}
|
|
91
62
|
};
|
|
92
63
|
|
|
93
|
-
const openDataRequestDirectly = () => {
|
|
94
|
-
try {
|
|
95
|
-
// Open popup for data request
|
|
96
|
-
const popup = openDataRequestPopup({
|
|
97
|
-
requestData,
|
|
98
|
-
webpageName,
|
|
99
|
-
userData,
|
|
100
|
-
autoFetch,
|
|
101
|
-
proofMode,
|
|
102
|
-
appIcon // Pass the app icon to the data request popup
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
if (popup) {
|
|
106
|
-
setPopupWindow(popup);
|
|
107
|
-
|
|
108
|
-
// Set up message listener for popup communication
|
|
109
|
-
const cleanup = listenForPopupMessages(
|
|
110
|
-
handlePopupMessage,
|
|
111
|
-
{
|
|
112
|
-
autoFetch,
|
|
113
|
-
onApiResponse: handleApiResponse
|
|
114
|
-
}
|
|
115
|
-
);
|
|
116
|
-
messageCleanup.current = cleanup;
|
|
117
|
-
}
|
|
118
|
-
} catch (error) {
|
|
119
|
-
console.error('Error opening data request popup:', error);
|
|
120
|
-
setError('Failed to open data request popup');
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const handlePopupMessage = (data) => {
|
|
125
|
-
console.log('🔥 OnairosButton received popup message:', data);
|
|
126
|
-
|
|
127
|
-
if (data.type === 'dataRequestComplete') {
|
|
128
|
-
handleDataRequestComplete(data);
|
|
129
|
-
} else if (data.type === 'popupClosed') {
|
|
130
|
-
setPopupWindow(null);
|
|
131
|
-
if (messageCleanup.current) {
|
|
132
|
-
messageCleanup.current();
|
|
133
|
-
messageCleanup.current = null;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
const handleApiResponse = (apiResponse) => {
|
|
139
|
-
console.log('🔥 API Response received:', apiResponse);
|
|
140
|
-
// Additional handling for API response if needed
|
|
141
|
-
};
|
|
142
|
-
|
|
143
64
|
const handleCloseOverlay = () => {
|
|
144
65
|
setShowOverlay(false);
|
|
145
66
|
setError(null);
|
|
@@ -187,11 +108,8 @@ export function OnairosButton({
|
|
|
187
108
|
setUserData(updatedUserData);
|
|
188
109
|
localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));
|
|
189
110
|
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
setTimeout(() => {
|
|
193
|
-
openDataRequestDirectly();
|
|
194
|
-
}, 300);
|
|
111
|
+
// Move to data request flow within the same overlay
|
|
112
|
+
setCurrentFlow('dataRequest');
|
|
195
113
|
};
|
|
196
114
|
|
|
197
115
|
const handleDataRequestComplete = (requestResult) => {
|
|
@@ -205,11 +123,8 @@ export function OnairosButton({
|
|
|
205
123
|
setUserData(updatedUserData);
|
|
206
124
|
localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));
|
|
207
125
|
|
|
208
|
-
// Close
|
|
209
|
-
|
|
210
|
-
closeDataRequestPopup(popupWindow);
|
|
211
|
-
setPopupWindow(null);
|
|
212
|
-
}
|
|
126
|
+
// Close overlay
|
|
127
|
+
setShowOverlay(false);
|
|
213
128
|
|
|
214
129
|
// Call onComplete callback if provided
|
|
215
130
|
console.log('🔥 Calling onComplete callback with:', requestResult);
|
|
@@ -239,7 +154,7 @@ export function OnairosButton({
|
|
|
239
154
|
return (
|
|
240
155
|
<UniversalOnboarding
|
|
241
156
|
onComplete={handleOnboardingComplete}
|
|
242
|
-
appIcon="https://onairos.sirv.com/Images/OnairosBlack.png"
|
|
157
|
+
appIcon={appIcon || "https://onairos.sirv.com/Images/OnairosBlack.png"}
|
|
243
158
|
appName={webpageName}
|
|
244
159
|
/>
|
|
245
160
|
);
|
|
@@ -260,6 +175,7 @@ export function OnairosButton({
|
|
|
260
175
|
requestData={requestData}
|
|
261
176
|
appName={webpageName}
|
|
262
177
|
autoFetch={autoFetch}
|
|
178
|
+
appIcon={appIcon}
|
|
263
179
|
/>
|
|
264
180
|
);
|
|
265
181
|
|
|
@@ -300,60 +216,60 @@ export function OnairosButton({
|
|
|
300
216
|
case 'signOut':
|
|
301
217
|
return 'Sign Out of Onairos';
|
|
302
218
|
default:
|
|
303
|
-
return 'Sign In with Onairos';
|
|
304
|
-
}
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
return (
|
|
308
|
-
<>
|
|
309
|
-
<button
|
|
310
|
-
className={buttonClass}
|
|
311
|
-
onClick={openTerminal}
|
|
312
|
-
style={buttonStyle}
|
|
313
|
-
>
|
|
314
|
-
{(visualType === 'full' || visualType === 'icon') && (
|
|
315
|
-
<img
|
|
316
|
-
src={login ? "https://onairos.sirv.com/Images/OnairosWhite.png" : "https://onairos.sirv.com/Images/OnairosBlack.png"}
|
|
317
|
-
alt="Onairos Logo"
|
|
318
|
-
style={logoStyle}
|
|
319
|
-
/>
|
|
320
|
-
)}
|
|
321
|
-
{visualType !== 'icon' && (
|
|
322
|
-
<span className={`${textColor === 'black' ? 'text-black' : 'text-white'} ${visualType === 'icon' ? 'sr-only' : ''} ${textLayout === 'right' ? 'ml-2' : textLayout === 'left' ? 'mr-2' : ''}`}>
|
|
323
|
-
{getText()}
|
|
324
|
-
</span>
|
|
325
|
-
)}
|
|
326
|
-
</button>
|
|
327
|
-
|
|
328
|
-
{/*
|
|
329
|
-
{showOverlay && (
|
|
330
|
-
<div
|
|
331
|
-
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
|
|
332
|
-
onClick={handleBackdropClick}
|
|
333
|
-
>
|
|
334
|
-
<div
|
|
335
|
-
className="bg-white rounded-lg shadow-xl max-w-md w-full mx-4 max-h-[90vh] overflow-hidden relative"
|
|
336
|
-
onClick={(e) => e.stopPropagation()}
|
|
337
|
-
>
|
|
338
|
-
{/* Close button */}
|
|
339
|
-
<button
|
|
340
|
-
onClick={handleCloseOverlay}
|
|
341
|
-
className="absolute top-4 right-4 text-gray-400 hover:text-gray-600 z-10"
|
|
342
|
-
>
|
|
343
|
-
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
344
|
-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
345
|
-
</svg>
|
|
346
|
-
</button>
|
|
347
|
-
|
|
348
|
-
{/* Content */}
|
|
349
|
-
<div className="overflow-y-auto max-h-[90vh]">
|
|
350
|
-
{renderCurrentFlow()}
|
|
351
|
-
</div>
|
|
352
|
-
</div>
|
|
353
|
-
</div>
|
|
354
|
-
)}
|
|
355
|
-
</>
|
|
356
|
-
);
|
|
357
|
-
}
|
|
358
|
-
|
|
219
|
+
return 'Sign In with Onairos';
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<>
|
|
225
|
+
<button
|
|
226
|
+
className={buttonClass}
|
|
227
|
+
onClick={openTerminal}
|
|
228
|
+
style={buttonStyle}
|
|
229
|
+
>
|
|
230
|
+
{(visualType === 'full' || visualType === 'icon') && (
|
|
231
|
+
<img
|
|
232
|
+
src={login ? "https://onairos.sirv.com/Images/OnairosWhite.png" : "https://onairos.sirv.com/Images/OnairosBlack.png"}
|
|
233
|
+
alt="Onairos Logo"
|
|
234
|
+
style={logoStyle}
|
|
235
|
+
/>
|
|
236
|
+
)}
|
|
237
|
+
{visualType !== 'icon' && (
|
|
238
|
+
<span className={`${textColor === 'black' ? 'text-black' : 'text-white'} ${visualType === 'icon' ? 'sr-only' : ''} ${textLayout === 'right' ? 'ml-2' : textLayout === 'left' ? 'mr-2' : ''}`}>
|
|
239
|
+
{getText()}
|
|
240
|
+
</span>
|
|
241
|
+
)}
|
|
242
|
+
</button>
|
|
243
|
+
|
|
244
|
+
{/* Full-Screen Overlay (Plaid/SendPay Style) */}
|
|
245
|
+
{showOverlay && (
|
|
246
|
+
<div
|
|
247
|
+
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
|
|
248
|
+
onClick={handleBackdropClick}
|
|
249
|
+
>
|
|
250
|
+
<div
|
|
251
|
+
className="bg-white rounded-lg shadow-xl max-w-md w-full mx-4 max-h-[90vh] overflow-hidden relative"
|
|
252
|
+
onClick={(e) => e.stopPropagation()}
|
|
253
|
+
>
|
|
254
|
+
{/* Close button */}
|
|
255
|
+
<button
|
|
256
|
+
onClick={handleCloseOverlay}
|
|
257
|
+
className="absolute top-4 right-4 text-gray-400 hover:text-gray-600 z-10"
|
|
258
|
+
>
|
|
259
|
+
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
260
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
261
|
+
</svg>
|
|
262
|
+
</button>
|
|
263
|
+
|
|
264
|
+
{/* Content */}
|
|
265
|
+
<div className="overflow-y-auto max-h-[90vh]">
|
|
266
|
+
{renderCurrentFlow()}
|
|
267
|
+
</div>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
)}
|
|
271
|
+
</>
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
359
275
|
export default OnairosButton;
|