onairos 3.5.5 → 3.5.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/dist/575.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"575.js","mappings":"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","sources":["webpack://OnairosLaravel/./src/components/WelcomeScreen.jsx","webpack://OnairosLaravel/./src/theme/colors.js","webpack://OnairosLaravel/./src/components/ui/PrimaryButton.jsx","webpack://OnairosLaravel/./src/config/api-config.js","webpack://OnairosLaravel/./src/components/EmailAuth.js","webpack://OnairosLaravel/./src/utils/extensionDetection.js","webpack://OnairosLaravel/./src/components/ExtensionInstallPrompt.jsx","webpack://OnairosLaravel/./src/components/LLMConnectorManager.jsx","webpack://OnairosLaravel/./src/components/UniversalOnboarding.jsx","webpack://OnairosLaravel/./src/components/PinSetup.js","webpack://OnairosLaravel/./src/components/DataRequest.js","webpack://OnairosLaravel/./src/components/TrainingComponent.jsx","webpack://OnairosLaravel/./src/components/LoadingScreen.jsx","webpack://OnairosLaravel/./src/utils/responseFormatter.js","webpack://OnairosLaravel/./src/components/ui/PageLayout.jsx","webpack://OnairosLaravel/./src/onairosButton.jsx","webpack://OnairosLaravel/./src/utils/userDataFormatter.js"],"sourcesContent":["import React, { useEffect } from 'react';\r\nimport { COLORS } from '../theme/colors.js';\r\n\r\nexport default function WelcomeScreen({ onContinue, onClose }) {\r\n // Load Sirv script for responsive images\r\n useEffect(() => {\r\n const script = document.createElement('script');\r\n script.src = 'https://scripts.sirv.com/sirvjs/v3/sirv.js';\r\n script.async = true;\r\n document.head.appendChild(script);\r\n \r\n return () => {\r\n const existingScript = document.querySelector('script[src=\"https://scripts.sirv.com/sirvjs/v3/sirv.js\"]');\r\n if (existingScript) {\r\n document.head.removeChild(existingScript);\r\n }\r\n };\r\n }, []);\r\n\r\n return (\r\n <div className=\"w-full flex flex-col\" style={{ height: '100%' }}>\r\n {/* Content - Flexible center area */}\r\n <div className=\"px-6 text-center flex-1 flex flex-col justify-center\">\r\n {/* Logo */}\r\n <div className=\"mb-8 flex justify-center\">\r\n <div className=\"w-20 h-20 flex items-center justify-center\">\r\n <img \r\n className=\"Sirv w-full h-full object-contain\" \r\n data-src=\"https://anushkasirv.sirv.com/OnairosBlack.png\" \r\n alt=\"Onairos Logo\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Welcome Text */}\r\n <p className=\"text-gray-500 text-sm mb-2\">Welcome to</p>\r\n\r\n {/* Main Title */}\r\n <h1 className=\"text-4xl font-bold text-gray-900 mb-6 text-balance\">Onairos</h1>\r\n\r\n {/* Description */}\r\n <p className=\"text-gray-600 text-base leading-relaxed mb-12 text-pretty px-2\">\r\n OnairOS personalizes your digital experience on every app so you can just enjoy being you!\r\n </p>\r\n </div>\r\n\r\n {/* Get Started Button - Fixed at bottom */}\r\n <div className=\"px-6 pb-8 flex-shrink-0\">\r\n <button\r\n className=\"w-full bg-gray-900 hover:bg-gray-800 text-white rounded-full py-4 text-base font-medium flex items-center justify-center gap-2 transition-colors\"\r\n onClick={onContinue}\r\n >\r\n Get Started\r\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// Theme colors for Onairos SDK - derived from mobile design\r\nexport const COLORS = {\r\n // Button gradient colors\r\n btnGradStart: '#1A1A1A',\r\n btnGradEnd: '#000000',\r\n \r\n // Button text and icon colors\r\n btnLabel: '#FFFFFF',\r\n btnBorder: 'rgba(0, 0, 0, 0.2)',\r\n \r\n // Icon circle gradient colors\r\n iconCircleGradientStart: '#333333',\r\n iconCircleGradientEnd: '#1A1A1A',\r\n \r\n // Background colors\r\n background: '#FFFFFF',\r\n backgroundSecondary: '#F8F9FA',\r\n \r\n // Text colors\r\n textPrimary: '#1A1A1A',\r\n textSecondary: '#6B7280',\r\n textMuted: '#9CA3AF',\r\n \r\n // Border colors\r\n border: '#E5E7EB',\r\n borderLight: '#F3F4F6',\r\n \r\n // Status colors\r\n success: '#10B981',\r\n error: '#EF4444',\r\n warning: '#F59E0B',\r\n info: '#3B82F6',\r\n \r\n // Interactive states\r\n hover: 'rgba(0, 0, 0, 0.05)',\r\n pressed: 'rgba(0, 0, 0, 0.1)',\r\n focus: 'rgba(59, 130, 246, 0.1)',\r\n};\r\n\r\nexport default COLORS; ","import React, { useState } from 'react';\r\nimport { COLORS } from '../../theme/colors.js';\r\n\r\n// Icon Circle component matching the React Native version\r\nconst IconCircle = ({ \r\n size = 40, \r\n children,\r\n className = ''\r\n}) => {\r\n return (\r\n <div \r\n className={`relative flex items-center justify-center border border-black border-opacity-25 ${className}`}\r\n style={{\r\n width: size,\r\n height: size,\r\n borderRadius: size / 2,\r\n background: `linear-gradient(to bottom, ${COLORS.iconCircleGradientStart}, ${COLORS.iconCircleGradientEnd})`\r\n }}\r\n >\r\n {children || (\r\n <span \r\n className=\"font-semibold opacity-95\"\r\n style={{\r\n fontSize: '20px',\r\n color: COLORS.btnLabel,\r\n backgroundColor: 'transparent'\r\n }}\r\n >\r\n →\r\n </span>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\n// Primary Button component matching the React Native design\r\nconst PrimaryButton = ({\r\n label = \"Get Started\",\r\n onClick,\r\n iconRight,\r\n loading = false,\r\n disabled = false,\r\n testId,\r\n className = '',\r\n style = {},\r\n textStyle = {},\r\n centered = false,\r\n ...props\r\n}) => {\r\n const [pressed, setPressed] = useState(false);\r\n\r\n const handleMouseDown = () => setPressed(true);\r\n const handleMouseUp = () => setPressed(false);\r\n const handleMouseLeave = () => setPressed(false);\r\n\r\n const buttonStyle = {\r\n height: '48px',\r\n borderRadius: '100px',\r\n border: `1px solid ${COLORS.btnBorder}`,\r\n background: `linear-gradient(to bottom, ${COLORS.btnGradStart}, ${COLORS.btnGradEnd})`,\r\n position: 'relative',\r\n overflow: 'hidden',\r\n width: centered ? 'auto' : '100%',\r\n minWidth: centered ? '250px' : 'auto',\r\n maxWidth: centered ? '350px' : 'none',\r\n margin: centered ? '0 auto' : '0',\r\n cursor: disabled ? 'not-allowed' : 'pointer',\r\n opacity: disabled ? 0.65 : 1,\r\n boxShadow: disabled ? 'none' : '20px 30px 40px rgba(0,0,0,0.10)',\r\n transition: 'all 0.2s ease',\r\n ...style\r\n };\r\n\r\n const pressedOverlayStyle = {\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n backgroundColor: 'rgba(0,0,0,0.1)',\r\n borderRadius: '100px',\r\n opacity: pressed ? 1 : 0,\r\n transition: 'opacity 0.1s ease'\r\n };\r\n\r\n const textContainerStyle = {\r\n position: 'absolute',\r\n left: 0,\r\n right: 0,\r\n top: 0,\r\n bottom: 0,\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n backgroundColor: 'transparent'\r\n };\r\n\r\n const iconPositionStyle = {\r\n position: 'absolute',\r\n right: '4px',\r\n top: '4px',\r\n bottom: '4px',\r\n width: '40px',\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n backgroundColor: 'transparent'\r\n };\r\n\r\n const labelStyle = {\r\n fontFamily: 'Inter, system-ui, sans-serif',\r\n fontWeight: '600',\r\n fontSize: '16px',\r\n color: COLORS.btnLabel,\r\n textAlign: 'center',\r\n backgroundColor: 'transparent',\r\n ...textStyle\r\n };\r\n\r\n return (\r\n <button\r\n className={`relative ${className}`}\r\n style={buttonStyle}\r\n onClick={onClick}\r\n onMouseDown={handleMouseDown}\r\n onMouseUp={handleMouseUp}\r\n onMouseLeave={handleMouseLeave}\r\n disabled={disabled || loading}\r\n data-testid={testId}\r\n aria-label={label}\r\n {...props}\r\n >\r\n {/* Pressed state overlay */}\r\n <div style={pressedOverlayStyle} />\r\n\r\n {/* Centered text container */}\r\n <div style={textContainerStyle}>\r\n {loading ? (\r\n <div \r\n className=\"animate-spin rounded-full border-2 border-white border-t-transparent\"\r\n style={{ width: '20px', height: '20px' }}\r\n />\r\n ) : (\r\n <span style={labelStyle}>{label}</span>\r\n )}\r\n </div>\r\n\r\n {/* Icon in fixed position on right */}\r\n <div style={iconPositionStyle}>\r\n {!loading && (iconRight || <IconCircle />)}\r\n </div>\r\n </button>\r\n );\r\n};\r\n\r\nexport { IconCircle };\r\nexport default PrimaryButton; ","/**\r\n * API Configuration for Onairos\r\n * Centralized configuration for API endpoints\r\n */\r\n\r\n// Environment detection\r\nconst isDevelopment = window.location.hostname === 'localhost' || \r\n window.location.hostname === '127.0.0.1' ||\r\n window.location.port === '3000' ||\r\n window.location.port === '8080';\r\n\r\n// API Configuration\r\nexport const API_CONFIG = {\r\n // Base URLs\r\n DEVELOPMENT_URL: 'http://localhost:8080',\r\n PRODUCTION_URL: 'https://api2.onairos.uk',\r\n \r\n // Current environment\r\n IS_DEVELOPMENT: isDevelopment,\r\n \r\n // Get base URL based on environment\r\n getBaseUrl() {\r\n return this.IS_DEVELOPMENT ? this.DEVELOPMENT_URL : this.PRODUCTION_URL;\r\n },\r\n \r\n // Email verification endpoints\r\n EMAIL_VERIFY: '/email/verify',\r\n EMAIL_VERIFY_CONFIRM: '/email/verify/confirm',\r\n \r\n // Get full URLs\r\n getEmailVerifyUrl() {\r\n return `${this.getBaseUrl()}${this.EMAIL_VERIFY}`;\r\n },\r\n \r\n getEmailVerifyConfirmUrl() {\r\n return `${this.getBaseUrl()}${this.EMAIL_VERIFY_CONFIRM}`;\r\n },\r\n \r\n // Debug info\r\n getDebugInfo() {\r\n return {\r\n environment: this.IS_DEVELOPMENT ? 'development' : 'production',\r\n baseUrl: this.getBaseUrl(),\r\n hostname: window.location.hostname,\r\n port: window.location.port,\r\n emailVerifyUrl: this.getEmailVerifyUrl(),\r\n emailVerifyConfirmUrl: this.getEmailVerifyConfirmUrl()\r\n };\r\n }\r\n};\r\n\r\n// Log configuration on load\r\nconsole.log('🔧 API Configuration loaded:', API_CONFIG.getDebugInfo());\r\n\r\nexport default API_CONFIG;\r\n","import React, { useState, useEffect } from 'react';\r\nimport { Mail, ArrowRight, Check } from 'lucide-react';\r\nimport PrimaryButton from './ui/PrimaryButton.jsx';\r\nimport { COLORS } from '../theme/colors.js';\r\nimport { API_CONFIG } from '../config/api-config.js';\r\n\r\nexport default function EmailAuth({ onSuccess, testMode = false }) {\r\n // Component identification\r\n console.log('📧 EmailAuth (onairos/src/components) initialized');\r\n console.log('🔧 API Config:', API_CONFIG.getDebugInfo());\r\n console.log('🧪 Test Mode:', testMode);\r\n \r\n const [email, setEmail] = useState('');\r\n const [code, setCode] = useState('');\r\n const [step, setStep] = useState('email'); // 'email' | 'code' | 'success'\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState('');\r\n\r\n // Auto-focus first PIN input when code step loads\r\n useEffect(() => {\r\n if (step === 'code') {\r\n // Small delay to ensure DOM is ready\r\n setTimeout(() => {\r\n const firstInput = document.querySelector('input[maxLength=\"1\"]');\r\n if (firstInput) {\r\n firstInput.focus();\r\n }\r\n }, 100);\r\n }\r\n }, [step]);\r\n\r\n const validateEmail = (email) => {\r\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n return emailRegex.test(email);\r\n };\r\n\r\n const handleEmailSubmit = async (e) => {\r\n e.preventDefault();\r\n setError('');\r\n\r\n if (!validateEmail(email)) {\r\n setError('Please enter a valid email address');\r\n return;\r\n }\r\n\r\n setIsLoading(true);\r\n\r\n try {\r\n const doFetchWithRetry = async (url, options, attempts = 3) => {\r\n let lastErr;\r\n for (let i = 0; i < attempts; i++) {\r\n try {\r\n const res = await fetch(url, options);\r\n if (!res.ok) {\r\n // Capture response body for better diagnostics\r\n try {\r\n const body = await res.json();\r\n lastErr = new Error(body?.error || `HTTP ${res.status}`);\r\n } catch {\r\n lastErr = new Error(`HTTP ${res.status}`);\r\n }\r\n } else {\r\n return res;\r\n }\r\n } catch (err) {\r\n lastErr = err;\r\n }\r\n // backoff: 400ms, 800ms\r\n await new Promise(r => setTimeout(r, 400 * (i + 1)));\r\n }\r\n throw lastErr || new Error('Network error');\r\n };\r\n\r\n if (testMode) {\r\n // Test mode: Skip API call completely, simulate instant success\r\n console.log('🧪 Test mode: Simulating email verification request for:', email);\r\n setTimeout(() => {\r\n setStep('code');\r\n setIsLoading(false);\r\n console.log('🧪 Test mode: Email verification simulated successfully');\r\n }, 800); // Shorter delay for faster testing\r\n } else {\r\n // Production mode: Use proper email verification API from schema\r\n const apiKey = window.onairosApiKey || 'test-key';\r\n const apiUrl = API_CONFIG.getEmailVerifyUrl();\r\n \r\n console.log('🚀 LIVE API CALL - Email Request');\r\n console.log('📋 API Key:', apiKey ? `${apiKey.substring(0, 8)}...` : 'NOT SET');\r\n console.log('🌐 URL:', apiUrl);\r\n console.log('📧 Email:', email);\r\n \r\n const headers = {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': apiKey,\r\n // Keep Authorization for backwards compatibility\r\n 'Authorization': `Bearer ${apiKey}`\r\n };\r\n\r\n \r\n const response = await doFetchWithRetry(apiUrl, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify({ \r\n email: (email || '').trim().toLowerCase()\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error('Failed to send verification code');\r\n }\r\n\r\n const data = await response.json();\r\n if (!data.success) {\r\n throw new Error(data.error || 'Failed to send verification code');\r\n }\r\n\r\n console.log('📧 Email request response:', data);\r\n\r\n setStep('code');\r\n setIsLoading(false);\r\n }\r\n } catch (error) {\r\n console.error('Email request error:', error);\r\n setError('Couldn’t send code. Please try again.');\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n const handleGoogleAuth = async () => {\r\n try {\r\n // Use the same Google OAuth logic as UniversalOnboarding\r\n const sdkConfig = {\r\n baseUrl: 'https://api2.onairos.uk',\r\n apiKey: window.onairosApiKey || 'test-key',\r\n enableHealthMonitoring: true,\r\n enableAutoRefresh: true,\r\n enableConnectionValidation: true\r\n };\r\n\r\n const username = localStorage.getItem('username') || localStorage.getItem('onairosUser')?.email || 'user@example.com';\r\n \r\n const authorizeUrl = `${sdkConfig.baseUrl}/gmail/authorize`;\r\n const params = new URLSearchParams({\r\n username: username,\r\n sdk_type: 'web',\r\n return_url: window.location.origin + '/oauth-callback.html'\r\n });\r\n\r\n const fullUrl = `${authorizeUrl}?${params.toString()}`;\r\n console.log('🔗 Starting Google OAuth from email flow...');\r\n console.log('📋 Google OAuth URL:', fullUrl);\r\n\r\n // Open popup for OAuth\r\n const popup = window.open(\r\n fullUrl,\r\n 'google_oauth',\r\n 'width=500,height=600,scrollbars=yes,resizable=yes'\r\n );\r\n\r\n if (!popup) {\r\n throw new Error('Popup blocked. Please allow popups for this site.');\r\n }\r\n\r\n // Monitor popup for completion\r\n const checkInterval = setInterval(() => {\r\n if (popup.closed) {\r\n clearInterval(checkInterval);\r\n console.log('✅ Google OAuth popup closed');\r\n // Simulate successful OAuth for now\r\n onSuccess({ \r\n email: 'user@gmail.com', \r\n method: 'google',\r\n connectedAccounts: { Google: true }\r\n });\r\n }\r\n }, 1000);\r\n\r\n } catch (error) {\r\n console.error('❌ Google OAuth failed:', error);\r\n setError('Google authentication failed. Please try again.');\r\n }\r\n };\r\n\r\n const handleCodeSubmit = async (e) => {\r\n e.preventDefault();\r\n setError('');\r\n setIsLoading(true);\r\n\r\n try {\r\n const doFetchWithRetry = async (url, options, attempts = 3) => {\r\n let lastErr;\r\n for (let i = 0; i < attempts; i++) {\r\n try {\r\n const res = await fetch(url, options);\r\n if (!res.ok) {\r\n try {\r\n const body = await res.json();\r\n lastErr = new Error(body?.error || `HTTP ${res.status}`);\r\n } catch {\r\n lastErr = new Error(`HTTP ${res.status}`);\r\n }\r\n } else {\r\n return res;\r\n }\r\n } catch (err) {\r\n lastErr = err;\r\n }\r\n await new Promise(r => setTimeout(r, 400 * (i + 1)));\r\n }\r\n throw lastErr || new Error('Network error');\r\n };\r\n\r\n if (testMode) {\r\n // Test mode: Skip API call completely, simulate verification\r\n console.log('🧪 Test mode: Simulating code verification for:', email, 'with code:', code);\r\n \r\n if (code === '123456' || code.length === 6) {\r\n setStep('success');\r\n setTimeout(() => {\r\n // Simulate new user for design testing using new response format\r\n const simulatedResponse = { \r\n email, \r\n verified: true, \r\n token: 'test-token-' + Date.now(),\r\n userName: email.split('@')[0],\r\n // New response format\r\n isNewUser: true,\r\n userState: 'new',\r\n flowType: 'onboarding',\r\n user: {\r\n userName: email.split('@')[0],\r\n email: email,\r\n verified: true,\r\n creationDate: new Date().toISOString(),\r\n lastLogin: new Date().toISOString()\r\n },\r\n enochInstructions: {\r\n recommendedFlow: 'onboarding',\r\n nextActionTitle: 'Get Started'\r\n },\r\n // Legacy fields for backward compatibility\r\n existingUser: false,\r\n accountInfo: null,\r\n adminMode: false,\r\n userCreated: true,\r\n accountDetails: {\r\n email: email,\r\n createdAt: new Date().toISOString(),\r\n testAccount: true\r\n }\r\n };\r\n console.log('🧪 Test mode: Simulated verification successful, user data:', simulatedResponse);\r\n onSuccess(simulatedResponse);\r\n }, 600); // Faster for design testing\r\n } else {\r\n setError('Invalid code. Use any 6-digit code (e.g., 123456) for testing.');\r\n setIsLoading(false);\r\n }\r\n } else {\r\n // Production mode: Use real email verification API from schema\r\n const apiKey = window.onairosApiKey || 'test-key';\r\n const apiUrl = API_CONFIG.getEmailVerifyConfirmUrl();\r\n \r\n console.log('🚀 LIVE API CALL - Code Verification');\r\n console.log('📋 API Key:', apiKey ? `${apiKey.substring(0, 8)}...` : 'NOT SET');\r\n console.log('🌐 URL:', apiUrl);\r\n console.log('📧 Email:', email);\r\n console.log('🔢 Code:', code);\r\n \r\n const headers = {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': apiKey,\r\n 'Authorization': `Bearer ${apiKey}`\r\n };\r\n \r\n const response = await doFetchWithRetry(apiUrl, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify({ \r\n email: (email || '').trim().toLowerCase(), \r\n code \r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error('Invalid verification code');\r\n }\r\n\r\n const data = await response.json();\r\n \r\n if (!data.success) {\r\n // Handle error with attempts remaining if available\r\n const errorMessage = data.error || 'Verification failed';\r\n if (data.attemptsRemaining !== undefined) {\r\n throw new Error(`${errorMessage} (${data.attemptsRemaining} attempts remaining)`);\r\n } else {\r\n throw new Error(errorMessage);\r\n }\r\n }\r\n\r\n console.log('📧 Email verification response:', data);\r\n\r\n setStep('success');\r\n setTimeout(() => {\r\n // Pass complete API response using new format\r\n onSuccess({ \r\n email, \r\n verified: true, \r\n token: data.token,\r\n userName: data.userName || data.user?.userName,\r\n // New response format fields\r\n isNewUser: data.isNewUser,\r\n userState: data.userState,\r\n flowType: data.flowType,\r\n user: data.user,\r\n existingUserData: data.existingUserData,\r\n enochInstructions: data.enochInstructions,\r\n // Legacy fields for backward compatibility\r\n existingUser: !data.isNewUser,\r\n accountInfo: data.existingUserData,\r\n adminMode: data.adminMode,\r\n userCreated: data.userCreated,\r\n accountDetails: data.accountDetails || data.user\r\n });\r\n }, 1000);\r\n }\r\n } catch (error) {\r\n console.error('Email verification error:', error);\r\n setError('Invalid code. Please try again.');\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n const renderEmailStep = () => (\r\n <div className=\"w-full flex flex-col\" style={{ height: '100%' }}>\r\n {/* Content - Flexible center area */}\r\n <div className=\"px-12 pt-16 pb-8 text-center flex-1 flex flex-col\">\r\n <div className=\"mb-8\">\r\n <h1 className=\"text-2xl font-bold text-gray-900 mb-2 text-balance leading-tight\">\r\n Use pre-existing Persona or create a new one in seconds\r\n </h1>\r\n <p className=\"text-gray-600 text-base\">Sign in or create an account</p>\r\n </div>\r\n\r\n <div className=\"mb-6\">\r\n <input\r\n type=\"email\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n placeholder=\"Enter your email\"\r\n className=\"w-full max-w-sm mx-auto px-4 py-4 text-base bg-gray-50 border-0 rounded-xl placeholder:text-gray-400 focus:bg-white focus:ring-2 focus:ring-gray-200 outline-none transition-all duration-200\"\r\n style={{ \r\n fontFamily: 'Inter, system-ui, sans-serif'\r\n }}\r\n required\r\n />\r\n </div>\r\n\r\n <div className=\"mb-6 text-center\">\r\n <span className=\"text-gray-500 text-sm\">Or</span>\r\n </div>\r\n\r\n <div className=\"mb-8\">\r\n <button\r\n type=\"button\"\r\n className=\"w-full max-w-sm mx-auto py-4 text-base font-medium rounded-xl border border-gray-200 hover:bg-gray-50 flex items-center justify-center gap-3 bg-transparent transition-colors\"\r\n style={{ \r\n fontFamily: 'Inter, system-ui, sans-serif'\r\n }}\r\n onClick={handleGoogleAuth}\r\n >\r\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\">\r\n <path\r\n fill=\"#4285F4\"\r\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\r\n />\r\n <path\r\n fill=\"#34A853\"\r\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\r\n />\r\n <path\r\n fill=\"#FBBC05\"\r\n d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\r\n />\r\n <path\r\n fill=\"#EA4335\"\r\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\r\n />\r\n </svg>\r\n Continue with Google\r\n </button>\r\n </div>\r\n\r\n {/* Error Display */}\r\n {error && (\r\n <div className=\"mb-6\">\r\n <p className=\"text-sm text-center\" style={{ color: COLORS.error }}>{error}</p>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Continue Button - Fixed at bottom */}\r\n <div className=\"px-12 pb-8 flex-shrink-0\">\r\n <button\r\n className=\"w-full max-w-sm mx-auto bg-gray-900 hover:bg-gray-800 text-white rounded-full py-4 text-base font-medium flex items-center justify-center gap-2 transition-colors disabled:opacity-50\"\r\n onClick={handleEmailSubmit}\r\n disabled={isLoading || !email.trim()}\r\n style={{ \r\n fontFamily: 'Inter, system-ui, sans-serif'\r\n }}\r\n >\r\n {isLoading ? 'Loading...' : 'Continue'}\r\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n\r\n const renderCodeStep = () => (\r\n <div className=\"w-full flex flex-col\" style={{ height: '100%' }}>\r\n {/* Heading - matching VerificationStep.tsx */}\r\n <div className=\"w-full pt-16 px-12 mb-10 text-center\">\r\n <h1 \r\n className=\"font-bold mb-2\"\r\n style={{ \r\n fontFamily: 'IBM Plex Sans, system-ui, sans-serif',\r\n fontWeight: '700',\r\n fontSize: '24px',\r\n lineHeight: '32px',\r\n color: COLORS.textPrimary\r\n }}\r\n >\r\n Enter verification code\r\n </h1>\r\n <p \r\n className=\"mb-2\"\r\n style={{ \r\n fontFamily: 'Inter, system-ui, sans-serif',\r\n fontWeight: '400',\r\n fontSize: '16px',\r\n lineHeight: '24px',\r\n color: COLORS.textSecondary\r\n }}\r\n >\r\n We've sent a 6-digit code to {email}\r\n </p>\r\n </div>\r\n\r\n\r\n {/* Code Input - matching VerificationStep design with individual digit boxes */}\r\n <div className=\"px-12 mb-6\">\r\n <div className=\"flex justify-center space-x-3\">\r\n {Array.from({ length: 6 }, (_, index) => (\r\n <input\r\n key={index}\r\n type=\"text\"\r\n maxLength=\"1\"\r\n value={code[index] || ''}\r\n onChange={(e) => {\r\n const newCode = code.split('');\r\n newCode[index] = e.target.value;\r\n setCode(newCode.join(''));\r\n \r\n // Auto-focus next input\r\n if (e.target.value && index < 5) {\r\n const nextInput = e.target.parentElement?.children[index + 1];\r\n if (nextInput) nextInput.focus();\r\n }\r\n }}\r\n onKeyDown={(e) => {\r\n // Handle backspace to focus previous input\r\n if (e.key === 'Backspace' && !code[index] && index > 0) {\r\n const prevInput = e.target.parentElement?.children[index - 1];\r\n if (prevInput) prevInput.focus();\r\n }\r\n }}\r\n className=\"w-12 h-12 border rounded-lg text-center text-lg font-medium focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none\"\r\n style={{ \r\n borderColor: COLORS.border,\r\n backgroundColor: COLORS.background,\r\n fontFamily: 'Inter, system-ui, sans-serif'\r\n }}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n\r\n {/* Error Display */}\r\n {error && (\r\n <div className=\"px-12 mb-6\">\r\n <p className=\"text-sm text-center\" style={{ color: COLORS.error }}>{error}</p>\r\n </div>\r\n )}\r\n\r\n {/* Continue Button - positioned right below code inputs */}\r\n <div className=\"px-12 mb-6\">\r\n <div className=\"max-w-sm mx-auto\">\r\n <PrimaryButton\r\n label=\"Continue\"\r\n onClick={handleCodeSubmit}\r\n loading={isLoading}\r\n disabled={isLoading || code.length !== 6}\r\n testId=\"verify-code-button\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Spacer */}\r\n <div style={{ flex: 1, minHeight: '20px' }} />\r\n\r\n {/* Back to email option */}\r\n <div className=\"px-12 w-full\">\r\n <div className=\"max-w-sm mx-auto\">\r\n <button\r\n type=\"button\"\r\n onClick={() => setStep('email')}\r\n className=\"w-full py-2 px-4 font-medium transition-colors text-sm\"\r\n style={{ color: COLORS.textSecondary }}\r\n >\r\n Use a different email\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n\r\n const renderSuccessStep = () => (\r\n <div className=\"w-full flex flex-col items-center space-y-6 pt-16 px-12\">\r\n <div \r\n className=\"flex items-center justify-center w-16 h-16 rounded-full\"\r\n style={{ backgroundColor: '#D1FAE5' }}\r\n >\r\n <Check className=\"w-8 h-8\" style={{ color: COLORS.success }} />\r\n </div>\r\n \r\n <div className=\"text-center space-y-2\">\r\n <h2 \r\n className=\"text-xl font-semibold\"\r\n style={{ color: COLORS.textPrimary }}\r\n >\r\n Email verified!\r\n </h2>\r\n <p style={{ color: COLORS.textSecondary }}>Setting up your account...</p>\r\n </div>\r\n\r\n <div className=\"w-8 h-8\">\r\n <div className=\"animate-spin h-8 w-8 border-2 border-blue-600 rounded-full border-t-transparent\"></div>\r\n </div>\r\n </div>\r\n );\r\n\r\n return (\r\n <div className=\"w-full\">\r\n {step === 'email' && renderEmailStep()}\r\n {step === 'code' && renderCodeStep()}\r\n {step === 'success' && renderSuccessStep()}\r\n </div>\r\n );\r\n} \r\n","/**\r\n * Onairos Browser Extension Detection Utility\r\n * \r\n * This utility detects if the Onairos browser extension is installed\r\n * by checking for the global window.onairos object that the extension injects.\r\n * \r\n * Based on the extension's inject-script.js implementation:\r\n * - window.onairos.isOnairos = true\r\n * - window.onairos.version = '1.0.0'\r\n * - 'onairosReady' event is dispatched when extension loads\r\n */\r\n\r\n/**\r\n * Chrome Web Store URL for the Onairos browser extension\r\n */\r\nexport const ONAIROS_EXTENSION_STORE_URL = 'https://chromewebstore.google.com/detail/onairos/apkfageplidiblifhnadehmplfccapkf?hl=en';\r\n\r\n/**\r\n * Timeout for extension detection (in milliseconds)\r\n */\r\nconst DETECTION_TIMEOUT = 2000;\r\n\r\n/**\r\n * Detect if the Onairos browser extension is installed\r\n * @returns {Promise<boolean>} True if extension is installed and active\r\n */\r\nexport const detectOnairosExtension = () => {\r\n return new Promise((resolve) => {\r\n // Method 1: Direct detection - check if already loaded\r\n if (window.onairos && window.onairos.isOnairos) {\r\n console.log('✅ OnairosTerminal extension detected (already loaded)');\r\n resolve(true);\r\n return;\r\n }\r\n\r\n // Method 2: Event-based detection - wait for extension to load\r\n let resolved = false;\r\n \r\n const handleOnairosReady = () => {\r\n if (!resolved) {\r\n resolved = true;\r\n console.log('✅ OnairosTerminal extension detected (via event)');\r\n resolve(true);\r\n }\r\n };\r\n\r\n // Listen for the onairosReady event\r\n window.addEventListener('onairosReady', handleOnairosReady, { once: true });\r\n\r\n // Set timeout to avoid waiting indefinitely\r\n setTimeout(() => {\r\n if (!resolved) {\r\n resolved = true;\r\n window.removeEventListener('onairosReady', handleOnairosReady);\r\n console.log('❌ OnairosTerminal extension not detected (timeout)');\r\n resolve(false);\r\n }\r\n }, DETECTION_TIMEOUT);\r\n });\r\n};\r\n\r\n/**\r\n * Get extension information if available\r\n * @returns {Object|null} Extension info or null if not available\r\n */\r\nexport const getExtensionInfo = () => {\r\n if (window.onairos && window.onairos.getInfo) {\r\n return window.onairos.getInfo();\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Check if extension is available synchronously (for already loaded extensions)\r\n * @returns {boolean} True if extension is immediately available\r\n */\r\nexport const isExtensionAvailableSync = () => {\r\n return !!(window.onairos && window.onairos.isOnairos);\r\n};\r\n\r\n/**\r\n * Open Chrome Web Store to install the extension\r\n * @param {string} source - Source identifier for analytics (e.g., 'chatgpt', 'claude')\r\n */\r\nexport const openExtensionInstallPage = (source = 'unknown') => {\r\n console.log(`🔗 Opening Chrome Web Store for extension installation (source: ${source})`);\r\n \r\n // For now, use a placeholder URL - replace with actual extension ID when available\r\n const storeUrl = ONAIROS_EXTENSION_STORE_URL;\r\n \r\n // Try to open in new tab\r\n const installWindow = window.open(storeUrl, '_blank');\r\n \r\n if (!installWindow) {\r\n // Fallback if popup is blocked\r\n console.warn('⚠️ Popup blocked, redirecting to extension store');\r\n window.location.href = storeUrl;\r\n }\r\n};\r\n\r\n/**\r\n * LLM Platform URLs\r\n */\r\nexport const LLM_URLS = {\r\n chatgpt: 'https://chatgpt.com',\r\n claude: 'https://claude.ai',\r\n gemini: 'https://gemini.google.com',\r\n grok: 'https://grok.x.ai'\r\n};\r\n\r\n/**\r\n * Open LLM platform if extension is installed, otherwise prompt for extension installation\r\n * @param {string} platform - LLM platform name ('chatgpt', 'claude', 'gemini', 'grok')\r\n * @param {Function} onExtensionMissing - Callback when extension is not installed\r\n * @param {Object} userInfo - User information to pass to the LLM platform\r\n * @param {string} userInfo.username - User's username/email\r\n * @param {string} userInfo.userId - User's unique identifier\r\n * @param {string} userInfo.sessionToken - Optional session token\r\n * @returns {Promise<boolean>} True if LLM was opened, false if extension missing\r\n */\r\nexport const openLLMWithExtensionCheck = async (platform, onExtensionMissing = null, userInfo = {}) => {\r\n console.log(`🤖 Attempting to open ${platform} with extension check...`);\r\n \r\n // Check if extension is installed\r\n const hasExtension = await detectOnairosExtension();\r\n \r\n if (hasExtension) {\r\n // Extension is installed - open the LLM platform with user info\r\n const baseUrl = LLM_URLS[platform];\r\n if (baseUrl) {\r\n // Build URL with user parameters for the browser extension to detect\r\n const url = new URL(baseUrl);\r\n \r\n // Add Onairos-specific parameters that the extension can read\r\n if (userInfo.username) {\r\n url.searchParams.set('onairos_user', encodeURIComponent(userInfo.username));\r\n }\r\n if (userInfo.userId) {\r\n url.searchParams.set('onairos_id', encodeURIComponent(userInfo.userId));\r\n }\r\n if (userInfo.sessionToken) {\r\n url.searchParams.set('onairos_session', encodeURIComponent(userInfo.sessionToken));\r\n }\r\n \r\n // Add platform identifier for the extension\r\n url.searchParams.set('onairos_platform', platform);\r\n url.searchParams.set('onairos_source', 'npm_connector');\r\n url.searchParams.set('onairos_timestamp', Date.now().toString());\r\n \r\n const finalUrl = url.toString();\r\n console.log(`✅ Extension detected, opening ${platform} at ${finalUrl}`);\r\n console.log(`👤 User info: ${JSON.stringify(userInfo)}`);\r\n \r\n const llmWindow = window.open(finalUrl, '_blank');\r\n \r\n if (!llmWindow) {\r\n console.warn(`⚠️ Popup blocked for ${platform}`);\r\n return false;\r\n }\r\n return true;\r\n } else {\r\n console.error(`❌ Unknown LLM platform: ${platform}`);\r\n return false;\r\n }\r\n } else {\r\n // Extension is not installed - handle missing extension\r\n console.log(`❌ Extension not detected for ${platform}, prompting installation`);\r\n \r\n if (onExtensionMissing) {\r\n onExtensionMissing(platform);\r\n } else {\r\n // Default behavior: open extension store\r\n openExtensionInstallPage(platform);\r\n }\r\n \r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Enhanced extension detection with retry mechanism\r\n * @param {number} maxRetries - Maximum number of detection attempts\r\n * @param {number} retryDelay - Delay between retries in milliseconds\r\n * @returns {Promise<boolean>} True if extension is detected\r\n */\r\nexport const detectExtensionWithRetry = async (maxRetries = 3, retryDelay = 500) => {\r\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\r\n console.log(`🔍 Extension detection attempt ${attempt}/${maxRetries}`);\r\n \r\n const detected = await detectOnairosExtension();\r\n if (detected) {\r\n return true;\r\n }\r\n \r\n if (attempt < maxRetries) {\r\n await new Promise(resolve => setTimeout(resolve, retryDelay));\r\n }\r\n }\r\n \r\n console.log(`❌ Extension not detected after ${maxRetries} attempts`);\r\n return false;\r\n};\r\n\r\n/**\r\n * Extract Onairos user information from URL parameters\r\n * This function is intended to be used by the browser extension to read user info\r\n * @param {string} url - URL to parse (defaults to current page URL)\r\n * @returns {Object|null} User information object or null if no Onairos params found\r\n */\r\nexport const extractUserInfoFromURL = (url = window.location.href) => {\r\n try {\r\n const urlObj = new URL(url);\r\n const params = urlObj.searchParams;\r\n \r\n // Check if this URL has Onairos parameters\r\n if (!params.has('onairos_user') && !params.has('onairos_id')) {\r\n return null;\r\n }\r\n \r\n const userInfo = {\r\n username: params.get('onairos_user') ? decodeURIComponent(params.get('onairos_user')) : null,\r\n userId: params.get('onairos_id') ? decodeURIComponent(params.get('onairos_id')) : null,\r\n sessionToken: params.get('onairos_session') ? decodeURIComponent(params.get('onairos_session')) : null,\r\n platform: params.get('onairos_platform') || null,\r\n source: params.get('onairos_source') || null,\r\n timestamp: params.get('onairos_timestamp') || null\r\n };\r\n \r\n // Only return if we have at least username or userId\r\n if (userInfo.username || userInfo.userId) {\r\n console.log('📋 Extracted Onairos user info from URL:', userInfo);\r\n return userInfo;\r\n }\r\n \r\n return null;\r\n } catch (error) {\r\n console.error('❌ Error extracting user info from URL:', error);\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Send user information to the browser extension\r\n * This function communicates with the extension to provide user context\r\n * @param {Object} userInfo - User information to send\r\n * @returns {Promise<boolean>} True if successfully sent to extension\r\n */\r\nexport const sendUserInfoToExtension = async (userInfo) => {\r\n try {\r\n if (!window.onairos || !window.onairos.isOnairos) {\r\n console.warn('⚠️ Onairos extension not detected, cannot send user info');\r\n return false;\r\n }\r\n \r\n // Send user info via postMessage to the extension\r\n window.postMessage({\r\n source: 'onairos_npm_connector',\r\n type: 'USER_INFO',\r\n data: {\r\n ...userInfo,\r\n timestamp: new Date().toISOString(),\r\n connectorVersion: '3.4.2'\r\n }\r\n }, '*');\r\n \r\n console.log('📤 Sent user info to Onairos extension:', userInfo);\r\n return true;\r\n } catch (error) {\r\n console.error('❌ Error sending user info to extension:', error);\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Send LLM conversation data to backend (for browser extension)\r\n * This function formats and sends encrypted conversation data to the new /llm-data/store endpoint\r\n * @param {Object} conversationData - Raw conversation data\r\n * @param {Object} userInfo - User authentication info\r\n * @param {string} platform - LLM platform (chatgpt, claude, gemini, grok)\r\n * @returns {Promise<boolean>} True if successfully stored\r\n */\r\nexport const storeLLMConversationData = async (conversationData, userInfo, platform) => {\r\n try {\r\n // Format data according to new backend API schema\r\n const payload = {\r\n encryptedData: btoa(JSON.stringify(conversationData)), // Base64 encode for now\r\n encryptionMetadata: {\r\n algorithm: \"AES-GCM\",\r\n keyDerivation: \"PBKDF2\",\r\n iterations: 100000\r\n },\r\n authentication: {\r\n username: userInfo.username || userInfo.email,\r\n timestamp: Date.now()\r\n },\r\n integrity: {\r\n hash: await generateDataHash(conversationData),\r\n algorithm: \"SHA-256\"\r\n },\r\n platform: platform,\r\n source: 'browser_extension'\r\n };\r\n\r\n const response = await fetch('https://api2.onairos.uk/llm-data/store', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${userInfo.sessionToken || userInfo.jwtToken}`,\r\n 'X-Onairos-User': userInfo.userId || userInfo.username\r\n },\r\n body: JSON.stringify(payload)\r\n });\r\n\r\n if (response.ok) {\r\n console.log('✅ LLM conversation data stored successfully');\r\n return true;\r\n } else {\r\n console.error('❌ Failed to store LLM data:', response.status);\r\n return false;\r\n }\r\n } catch (error) {\r\n console.error('❌ Error storing LLM conversation data:', error);\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Generate SHA-256 hash of data for integrity verification\r\n * @param {Object} data - Data to hash\r\n * @returns {Promise<string>} SHA-256 hash\r\n */\r\nasync function generateDataHash(data) {\r\n try {\r\n const encoder = new TextEncoder();\r\n const dataString = JSON.stringify(data);\r\n const dataBuffer = encoder.encode(dataString);\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n return `sha256-${hashHex}`;\r\n } catch (error) {\r\n console.error('Error generating hash:', error);\r\n return `sha256-${Date.now()}`; // Fallback\r\n }\r\n}\r\n\r\n/**\r\n * Get user information from standard Onairos localStorage keys\r\n * @returns {Object} User information from localStorage\r\n */\r\nexport const getUserInfoFromStorage = () => {\r\n try {\r\n // Primary storage locations used by Onairos\r\n const userDataStr = localStorage.getItem('onairosUser'); // Main user data object\r\n const jwtToken = localStorage.getItem('onairos_jwt_token'); // JWT token from email verification\r\n const legacyToken = localStorage.getItem('onairosToken'); // Legacy token from login\r\n const username = localStorage.getItem('username'); // Username from login\r\n const userDataSDK = localStorage.getItem('onairos_user_data'); // SDK user data\r\n \r\n let userData = null;\r\n \r\n // Try to parse main user data\r\n if (userDataStr) {\r\n try {\r\n userData = JSON.parse(userDataStr);\r\n } catch (error) {\r\n console.warn('⚠️ Failed to parse onairosUser from localStorage');\r\n }\r\n }\r\n \r\n // Try to parse SDK user data as fallback\r\n if (!userData && userDataSDK) {\r\n try {\r\n userData = JSON.parse(userDataSDK);\r\n } catch (error) {\r\n console.warn('⚠️ Failed to parse onairos_user_data from localStorage');\r\n }\r\n }\r\n \r\n // Build comprehensive user info object\r\n const userInfo = {\r\n // User identification\r\n username: userData?.email || userData?.username || username || null,\r\n userId: userData?.userId || userData?.email || username || null,\r\n email: userData?.email || null,\r\n \r\n // Authentication tokens\r\n sessionToken: jwtToken || userData?.token || legacyToken || null,\r\n jwtToken: jwtToken || userData?.token || null,\r\n \r\n // User metadata\r\n isNewUser: userData?.isNewUser || false,\r\n verified: userData?.verified || false,\r\n onboardingComplete: userData?.onboardingComplete || false,\r\n pinCreated: userData?.pinCreated || false,\r\n \r\n // Account details\r\n accountInfo: userData?.accountInfo || null,\r\n connectedAccounts: userData?.connectedAccounts || [],\r\n \r\n // Timestamps\r\n lastLogin: userData?.lastLogin || null,\r\n createdAt: userData?.createdAt || null,\r\n \r\n // Source tracking\r\n source: 'localStorage_extraction',\r\n extractedAt: new Date().toISOString()\r\n };\r\n \r\n console.log('📋 Extracted user info from localStorage:', userInfo);\r\n return userInfo;\r\n } catch (error) {\r\n console.error('❌ Error extracting user info from localStorage:', error);\r\n return {\r\n username: null,\r\n userId: null,\r\n sessionToken: null,\r\n source: 'extraction_failed',\r\n error: error.message\r\n };\r\n }\r\n};\r\n\r\n/**\r\n * Initialize user context for the current page\r\n * This should be called when the page loads to set up user context for the extension\r\n * @param {Object} userInfo - User information to initialize (optional, will auto-extract if not provided)\r\n */\r\nexport const initializeUserContext = async (userInfo = null) => {\r\n console.log('🚀 Initializing Onairos user context...');\r\n \r\n // If no user info provided, extract from localStorage\r\n if (!userInfo) {\r\n userInfo = getUserInfoFromStorage();\r\n }\r\n \r\n // First try to extract user info from URL (in case we're on an LLM platform)\r\n const urlUserInfo = extractUserInfoFromURL();\r\n \r\n // Merge URL info with provided/extracted info (URL takes precedence)\r\n const finalUserInfo = {\r\n ...userInfo,\r\n ...urlUserInfo\r\n };\r\n \r\n if (finalUserInfo.username || finalUserInfo.userId) {\r\n // Try to send to extension\r\n const sent = await sendUserInfoToExtension(finalUserInfo);\r\n \r\n if (sent) {\r\n console.log('✅ User context initialized successfully');\r\n } else {\r\n console.log('⚠️ Extension not available, user context stored locally');\r\n // Store in localStorage as fallback\r\n localStorage.setItem('onairos_user_context', JSON.stringify(finalUserInfo));\r\n }\r\n \r\n return finalUserInfo;\r\n } else {\r\n console.log('⚠️ No user information available to initialize');\r\n return null;\r\n }\r\n};\r\n","import React from 'react';\r\nimport { openExtensionInstallPage, LLM_URLS } from '../utils/extensionDetection';\r\n\r\n/**\r\n * Extension Installation Prompt Component\r\n * \r\n * Displays when a user tries to connect to an LLM but doesn't have \r\n * the Onairos browser extension installed.\r\n */\r\nconst ExtensionInstallPrompt = ({ \r\n open = false, \r\n onClose, \r\n platform = 'chatgpt',\r\n onInstallClick = null \r\n}) => {\r\n if (!open) return null;\r\n\r\n const platformNames = {\r\n chatgpt: 'ChatGPT',\r\n claude: 'Claude',\r\n gemini: 'Gemini',\r\n grok: 'Grok'\r\n };\r\n\r\n const platformName = platformNames[platform] || 'LLM';\r\n const platformUrl = LLM_URLS[platform] || '#';\r\n\r\n const handleInstallClick = () => {\r\n if (onInstallClick) {\r\n onInstallClick(platform);\r\n } else {\r\n openExtensionInstallPage(platform);\r\n }\r\n };\r\n\r\n const handleDirectVisit = () => {\r\n window.open(platformUrl, '_blank');\r\n if (onClose) onClose();\r\n };\r\n\r\n return (\r\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\r\n <div className=\"bg-white rounded-lg shadow-xl max-w-md w-full mx-4 max-h-[90vh] overflow-hidden\">\r\n <div className=\"p-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center mb-4\">\r\n <div className=\"w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center mr-3\">\r\n <svg className=\"w-6 h-6 text-blue-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 6v6m0 0v6m0-6h6m-6 0H6\" />\r\n </svg>\r\n </div>\r\n <h2 className=\"text-xl font-bold text-gray-900\">\r\n Install Onairos Extension\r\n </h2>\r\n </div>\r\n \r\n {/* Content */}\r\n <div className=\"space-y-4 text-gray-700\">\r\n <p>\r\n To connect with <strong>{platformName}</strong> and enable personalized AI interactions, \r\n you need the Onairos browser extension installed.\r\n </p>\r\n \r\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4\">\r\n <h3 className=\"font-semibold text-blue-900 mb-2\">🚀 What the extension does:</h3>\r\n <ul className=\"list-disc ml-4 space-y-1 text-blue-800 text-sm\">\r\n <li>Detects when you're on {platformName} and other LLM sites</li>\r\n <li>Enables secure data sharing with your consent</li>\r\n <li>Personalizes AI responses based on your preferences</li>\r\n <li>Works seamlessly in the background</li>\r\n </ul>\r\n </div>\r\n\r\n <div className=\"bg-amber-50 border border-amber-200 rounded-lg p-4\">\r\n <h3 className=\"font-semibold text-amber-900 mb-2\">⚡ Quick Setup:</h3>\r\n <ol className=\"list-decimal ml-4 space-y-1 text-amber-800 text-sm\">\r\n <li>Click \"Install Extension\" below</li>\r\n <li>Add the extension from Chrome Web Store</li>\r\n <li>Return here and try connecting again</li>\r\n </ol>\r\n </div>\r\n \r\n <p className=\"text-sm text-gray-600\">\r\n Don't want to install the extension? You can still visit{' '}\r\n <a \r\n href={platformUrl} \r\n className=\"text-blue-600 hover:underline\" \r\n target=\"_blank\" \r\n rel=\"noopener noreferrer\"\r\n >\r\n {platformUrl}\r\n </a>\r\n {' '}directly, but you won't get personalized AI features.\r\n </p>\r\n </div>\r\n \r\n {/* Actions */}\r\n <div className=\"flex flex-col space-y-3 mt-6\">\r\n <button\r\n onClick={handleInstallClick}\r\n className=\"w-full px-4 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium flex items-center justify-center\"\r\n >\r\n <svg className=\"w-5 h-5 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\r\n </svg>\r\n Install Onairos Extension\r\n </button>\r\n \r\n <div className=\"flex space-x-3\">\r\n <button\r\n onClick={handleDirectVisit}\r\n className=\"flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 text-sm\"\r\n >\r\n Visit {platformName} Anyway\r\n </button>\r\n <button\r\n onClick={onClose}\r\n className=\"flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 text-sm\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Footer */}\r\n <div className=\"mt-4 pt-4 border-t border-gray-200\">\r\n <p className=\"text-xs text-gray-500 text-center\">\r\n The Onairos extension is free, secure, and respects your privacy. \r\n <br />\r\n <a href=\"https://onairos.uk/privacy\" className=\"text-blue-600 hover:underline\">\r\n Learn more about our privacy policy\r\n </a>\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ExtensionInstallPrompt;\r\n","import React, { useState, useCallback } from 'react';\r\nimport { openLLMWithExtensionCheck, detectOnairosExtension, getUserInfoFromStorage } from '../utils/extensionDetection';\r\nimport ExtensionInstallPrompt from './ExtensionInstallPrompt';\r\n\r\n/**\r\n * LLM Connector Manager Component\r\n * \r\n * Manages the connection flow for LLM platforms (ChatGPT, Claude, Gemini, Grok).\r\n * Handles extension detection and shows appropriate prompts.\r\n */\r\nconst LLMConnectorManager = ({ \r\n children,\r\n onConnectionChange = null,\r\n username = null \r\n}) => {\r\n const [showInstallPrompt, setShowInstallPrompt] = useState(false);\r\n const [currentPlatform, setCurrentPlatform] = useState(null);\r\n const [isConnecting, setIsConnecting] = useState(false);\r\n\r\n /**\r\n * Handle LLM connection attempt\r\n * @param {string} platform - LLM platform name\r\n * @param {Function} onSuccess - Callback for successful connection\r\n * @param {Function} onError - Callback for connection error\r\n */\r\n const handleLLMConnect = useCallback(async (platform, onSuccess = null, onError = null) => {\r\n if (isConnecting) {\r\n console.log('⚠️ Already connecting, ignoring request');\r\n return;\r\n }\r\n\r\n setIsConnecting(true);\r\n setCurrentPlatform(platform);\r\n\r\n try {\r\n console.log(`🤖 Attempting to connect to ${platform}...`);\r\n\r\n // Prepare user information for the browser extension\r\n // First try to get comprehensive user info from localStorage\r\n const storedUserInfo = getUserInfoFromStorage();\r\n \r\n const userInfo = {\r\n // Use stored info as primary source, fallback to props\r\n username: storedUserInfo.username || username,\r\n userId: storedUserInfo.userId || storedUserInfo.username || username,\r\n email: storedUserInfo.email,\r\n sessionToken: storedUserInfo.sessionToken,\r\n jwtToken: storedUserInfo.jwtToken,\r\n \r\n // User metadata\r\n isNewUser: storedUserInfo.isNewUser,\r\n verified: storedUserInfo.verified,\r\n onboardingComplete: storedUserInfo.onboardingComplete,\r\n pinCreated: storedUserInfo.pinCreated,\r\n \r\n // Account details\r\n accountInfo: storedUserInfo.accountInfo,\r\n connectedAccounts: storedUserInfo.connectedAccounts,\r\n \r\n // Add additional context\r\n source: 'onairos_npm_connector',\r\n connectorVersion: '3.4.2', // Updated version from package.json\r\n timestamp: new Date().toISOString(),\r\n platform: platform\r\n };\r\n\r\n // Use the extension detection utility with user info\r\n const success = await openLLMWithExtensionCheck(\r\n platform,\r\n (missingPlatform) => {\r\n // Extension is missing - show install prompt\r\n console.log(`❌ Extension missing for ${missingPlatform}, showing install prompt`);\r\n setCurrentPlatform(missingPlatform);\r\n setShowInstallPrompt(true);\r\n },\r\n userInfo\r\n );\r\n\r\n if (success) {\r\n // LLM was opened successfully\r\n console.log(`✅ ${platform} opened successfully`);\r\n \r\n // Simulate connection after a short delay (like the original ChatGPT connector)\r\n setTimeout(() => {\r\n if (onConnectionChange) {\r\n onConnectionChange(platform, true);\r\n }\r\n if (onSuccess) {\r\n onSuccess(platform);\r\n }\r\n setIsConnecting(false);\r\n }, 1000);\r\n } else {\r\n // Failed to open (popup blocked or other error)\r\n console.log(`❌ Failed to open ${platform}`);\r\n setIsConnecting(false);\r\n \r\n if (onError) {\r\n onError(platform, 'Failed to open LLM platform');\r\n }\r\n }\r\n } catch (error) {\r\n console.error(`❌ Error connecting to ${platform}:`, error);\r\n setIsConnecting(false);\r\n \r\n if (onError) {\r\n onError(platform, error.message);\r\n }\r\n }\r\n }, [isConnecting, onConnectionChange]);\r\n\r\n /**\r\n * Handle disconnection from LLM platform\r\n * @param {string} platform - LLM platform name\r\n */\r\n const handleLLMDisconnect = useCallback((platform) => {\r\n console.log(`🔌 Disconnecting from ${platform}`);\r\n \r\n if (onConnectionChange) {\r\n onConnectionChange(platform, false);\r\n }\r\n }, [onConnectionChange]);\r\n\r\n /**\r\n * Close the extension install prompt\r\n */\r\n const handleCloseInstallPrompt = useCallback(() => {\r\n setShowInstallPrompt(false);\r\n setCurrentPlatform(null);\r\n setIsConnecting(false);\r\n }, []);\r\n\r\n /**\r\n * Handle extension installation click\r\n */\r\n const handleExtensionInstall = useCallback((platform) => {\r\n console.log(`🔗 User clicked to install extension for ${platform}`);\r\n // The ExtensionInstallPrompt component will handle opening the store\r\n // We'll close the prompt after a delay to let the user install\r\n setTimeout(() => {\r\n setShowInstallPrompt(false);\r\n setCurrentPlatform(null);\r\n setIsConnecting(false);\r\n }, 1000);\r\n }, []);\r\n\r\n /**\r\n * Check extension status\r\n * @returns {Promise<boolean>} True if extension is available\r\n */\r\n const checkExtensionStatus = useCallback(async () => {\r\n return await detectOnairosExtension();\r\n }, []);\r\n\r\n // Provide context to children components\r\n const contextValue = {\r\n // Connection methods\r\n connectToLLM: handleLLMConnect,\r\n disconnectFromLLM: handleLLMDisconnect,\r\n \r\n // State\r\n isConnecting,\r\n currentPlatform,\r\n \r\n // Utilities\r\n checkExtensionStatus,\r\n \r\n // User info\r\n username\r\n };\r\n\r\n return (\r\n <div data-llm-manager=\"true\">\r\n {/* Render children with context */}\r\n {React.Children.map(children, child => {\r\n if (React.isValidElement(child)) {\r\n return React.cloneElement(child, {\r\n ...child.props,\r\n llmConnectorManager: contextValue\r\n });\r\n }\r\n return child;\r\n })}\r\n\r\n {/* Extension Install Prompt */}\r\n <ExtensionInstallPrompt\r\n open={showInstallPrompt}\r\n platform={currentPlatform}\r\n onClose={handleCloseInstallPrompt}\r\n onInstallClick={handleExtensionInstall}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\n/**\r\n * Hook for using LLM Connector Manager context\r\n * @param {Object} props - Component props that might contain llmConnectorManager\r\n * @returns {Object} LLM connector manager context\r\n */\r\nexport const useLLMConnectorManager = (props) => {\r\n return props.llmConnectorManager || {\r\n connectToLLM: () => console.warn('LLM Connector Manager not available'),\r\n disconnectFromLLM: () => console.warn('LLM Connector Manager not available'),\r\n isConnecting: false,\r\n currentPlatform: null,\r\n checkExtensionStatus: () => Promise.resolve(false),\r\n username: null\r\n };\r\n};\r\n\r\nexport default LLMConnectorManager;\r\n","import React, { useEffect, useId, useState, useRef } from 'react';\r\nimport Lottie from 'lottie-react';\r\nimport personaAnim from '../../public/persona-anim.json';\r\nimport LLMConnectorManager from './LLMConnectorManager';\r\nconst chatgptIcon = 'https://anushkasirv.sirv.com/openai.png';\r\nconst claudeIcon = 'https://anushkasirv.sirv.com/claude-color.png';\r\nconst geminiIcon = 'https://anushkasirv.sirv.com/gemini-color.png';\r\nconst grokIcon = 'https://anushkasirv.sirv.com/grok.png';\r\n\r\nconst sdkConfig = {\r\n apiKey: process.env.REACT_APP_ONAIROS_API_KEY || 'onairos_web_sdk_live_key_2024',\r\n baseUrl: process.env.REACT_APP_ONAIROS_BASE_URL || 'https://api2.onairos.uk',\r\n sdkType: 'web',\r\n enableHealthMonitoring: true,\r\n enableAutoRefresh: true,\r\n enableConnectionValidation: true,\r\n};\r\n\r\nconst fadeSlideInKeyframes = `\r\n@keyframes fadeSlideIn {\r\n from { opacity: 0; transform: translateX(var(--slide-x)); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n`;\r\n\r\nexport default function UniversalOnboarding({ onComplete, llmConnectorManager }) {\r\n const lottieRef = useRef(null);\r\n const lastFrameRef = useRef(0);\r\n const rafRef = useRef(null);\r\n\r\n const [connectedAccounts, setConnectedAccounts] = useState({});\r\n const [isConnecting, setIsConnecting] = useState(false);\r\n const [connectingPlatform, setConnectingPlatform] = useState(null);\r\n const [selected, setSelected] = useState('Instagram');\r\n const [currentPage, setCurrentPage] = useState(1);\r\n\r\n // swipe state\r\n const touchStartX = useRef(0);\r\n const touchDeltaX = useRef(0);\r\n\r\n const [vh, setVh] = useState(() => (typeof window !== 'undefined' ? window.innerHeight : 800));\r\n useEffect(() => {\r\n const onResize = () => setVh(window.innerHeight);\r\n window.addEventListener('resize', onResize);\r\n return () => window.removeEventListener('resize', onResize);\r\n }, []);\r\n\r\n // Reset flow on every page load/refresh\r\n useEffect(() => {\r\n // Clear any persisted OAuth state on mount\r\n localStorage.removeItem('onairos_oauth_platform');\r\n localStorage.removeItem('onairos_oauth_return');\r\n }, []);\r\n\r\n const FOOTER_H = 88;\r\n\r\n // persona stays as requested (background, unchanged placement)\r\n const personaSide = Math.min(vh * 0.52, 500);\r\n const PERSONA_TOP = 96;\r\n\r\n // icon layout (restore tighter spacing on page 1; place the band lower)\r\n const SLOT = Math.max(56, Math.min(64, Math.floor(vh * 0.07)));\r\n const CIRCLE = 42;\r\n const GAP_PAGE1 = 12;\r\n const GAP_PAGE2 = 20;\r\n const ACTIVE_SCALE = vh < 760 ? 1.12 : 1.22;\r\n\r\n const ICONS_H = 84;\r\n\r\n const igGradId = useId();\r\n\r\n // ---- official brand SVGs (compact, consistent viewboxes) ----\r\n const Brand = {\r\n ChatGPT: <img src={chatgptIcon} alt=\"ChatGPT\" style={{ width: 22, height: 22, objectFit: 'contain' }} />,\r\n Claude: <img src={claudeIcon} alt=\"Claude\" style={{ width: 22, height: 22, objectFit: 'contain' }} />,\r\n Gemini: <img src={geminiIcon} alt=\"Gemini\" style={{ width: 22, height: 22, objectFit: 'contain' }} />,\r\n Grok: <img src={grokIcon} alt=\"Grok\" style={{ width: 22, height: 22, objectFit: 'contain' }} />,\r\n Instagram: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <defs>\r\n <radialGradient id={igGradId} cx=\"0.5\" cy=\"1\" r=\"1\">\r\n <stop offset=\"0%\" stopColor=\"#FDBB4B\"/>\r\n <stop offset=\"40%\" stopColor=\"#E95950\"/>\r\n <stop offset=\"70%\" stopColor=\"#BC2A8D\"/>\r\n <stop offset=\"100%\" stopColor=\"#4C68D7\"/>\r\n </radialGradient>\r\n </defs>\r\n <path fill={`url(#${igGradId})`} d=\"M7 2h10a5 5 0 0 1 5 5v10a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5V7a5 5 0 0 1 5-5zm5 5.5A4.5 4.5 0 1 0 16.5 12 4.5 4.5 0 0 0 12 7.5zm0 7.4A2.9 2.9 0 1 1 14.9 12 2.9 2.9 0 0 1 12 14.9Zm5.35-8.25a1.15 1.15 0 1 0 1.15 1.15 1.15 1.15 0 0 0-1.15-1.15Z\"/>\r\n </svg>\r\n ),\r\n YouTube: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <path fill=\"#FF0000\" d=\"M22.54 6.42a3 3 0 0 0-2.11-2.12C18.49 3.75 12 3.75 12 3.75s-6.49 0-8.43.55A3 3 0 0 0 1.46 6.42 31.63 31.63 0 0 0 1 12a31.63 31.63 0 0 0 .46 5.58 3 3 0 0 0 2.11 2.12C5.51 20.25 12 20.25 12 20.25s6.49 0 8.43-.55a3 3 0 0 0 2.11-2.12A31.63 31.63 0 0 0 23 12a31.63 31.63 0 0 0-.46-5.58z\"/>\r\n <path fill=\"#FFF\" d=\"M10 8.75v6.5l6-3.25-6-3.25z\"/>\r\n </svg>\r\n ),\r\n Reddit: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#FF4500\"/>\r\n <circle cx=\"8.75\" cy=\"12.5\" r=\"1.25\" fill=\"#FFF\"/>\r\n <circle cx=\"15.25\" cy=\"12.5\" r=\"1.25\" fill=\"#FFF\"/>\r\n <path fill=\"#FFF\" d=\"M7.9 15c.8.8 2.3 1.05 4.1 1.05S15.3 15.8 16.1 15c.2-.2.2-.5 0-.7-.2-.2-.5-.2-.7 0-.6.6-1.9.85-3.4.85S9.3 14.9 8.7 14.3c-.2-.2-.5-.2-.7 0-.2.2-.2.5 0 .7z\"/>\r\n </svg>\r\n ),\r\n LinkedIn: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"3\" fill=\"#0A66C2\"/>\r\n <rect x=\"5\" y=\"9\" width=\"3\" height=\"10\" fill=\"#FFF\"/>\r\n <circle cx=\"6.5\" cy=\"6.5\" r=\"1.5\" fill=\"#FFF\"/>\r\n <path fill=\"#FFF\" d=\"M16.8 19H13.9v-5c0-1.2-.5-1.8-1.4-1.8-.9 0-1.6.6-1.6 1.8V19H8V9h2.8v1.3c.5-.8 1.4-1.5 2.7-1.5 2 0 3.3 1.3 3.3 3.7V19z\"/>\r\n </svg>\r\n ),\r\n Twitter: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <path fill=\"#1DA1F2\" d=\"M23.643 4.937c-.835.37-1.732.62-2.675.733.962-.576 1.7-1.49 2.048-2.578-.9.534-1.897.922-2.958 1.13-.85-.904-2.06-1.47-3.4-1.47-2.572 0-4.658 2.086-4.658 4.66 0 .364.042.718.12 1.06-3.873-.195-7.304-2.05-9.602-4.868-.4.69-.63 1.49-.63 2.342 0 1.616.823 3.043 2.072 3.878-.764-.025-1.482-.234-2.11-.583v.06c0 2.257 1.605 4.14 3.737 4.568-.392.106-.803.162-1.227.162-.3 0-.593-.028-.877-.082.593 1.85 2.313 3.198 4.352 3.234-1.595 1.25-3.604 1.995-5.786 1.995-.376 0-.747-.022-1.112-.065 2.062 1.323 4.51 2.093 7.14 2.093 8.57 0 13.255-7.098 13.255-13.254 0-.2-.005-.402-.014-.602.91-.658 1.7-1.477 2.323-2.41z\"/>\r\n </svg>\r\n ),\r\n };\r\n\r\n const aiLinks = {\r\n ChatGPT: 'https://chat.openai.com',\r\n Claude: 'https://claude.ai',\r\n Gemini: 'https://gemini.google.com',\r\n Grok: 'https://grok.x.ai',\r\n };\r\n\r\n const descriptions = {\r\n ChatGPT: <>We analyze your <strong className=\"font-semibold\">prompt style</strong> and <strong className=\"font-semibold\">chat history</strong> to match your writing and thinking patterns.</>,\r\n Claude: <>We learn your <strong className=\"font-semibold\">document workflow</strong> and <strong className=\"font-semibold\">reasoning preferences</strong> to tune output format and detail.</>,\r\n Gemini: <>We study your <strong className=\"font-semibold\">search patterns</strong> and <strong className=\"font-semibold\">multimodal usage</strong> to improve response accuracy.</>,\r\n Grok: <>We adapt to your <strong className=\"font-semibold\">X posting style</strong> and <strong className=\"font-semibold\">meme literacy</strong> to match your tone.</>,\r\n Twitter: <>We analyze your <strong className=\"font-semibold\">tweets</strong> and <strong className=\"font-semibold\">interests</strong> to understand your preferences.</>,\r\n YouTube: <>We study your <strong className=\"font-semibold\">watch history</strong> and <strong className=\"font-semibold\">interactions</strong> to learn your interests.</>,\r\n Reddit: <>We examine your <strong className=\"font-semibold\">search history</strong> and <strong className=\"font-semibold\">discussions</strong> to understand your interests.</>,\r\n Instagram: <>We analyze your <strong className=\"font-semibold\">photos</strong> and <strong className=\"font-semibold\">interactions</strong> to learn visual preferences.</>,\r\n LinkedIn: <>We study your <strong className=\"font-semibold\">professional graph</strong> and <strong className=\"font-semibold\">content</strong> to understand career interests.</>,\r\n };\r\n\r\n const allPlatforms = [\r\n // Page 1\r\n { name: 'Instagram', connector: 'instagram', icon: Brand.Instagram },\r\n { name: 'YouTube', connector: 'youtube', icon: Brand.YouTube },\r\n { name: 'ChatGPT', connector: 'chatgpt', icon: Brand.ChatGPT, directLink: aiLinks.ChatGPT },\r\n // Page 2\r\n { name: 'Claude', connector: 'claude', icon: Brand.Claude, directLink: aiLinks.Claude },\r\n { name: 'Gemini', connector: 'gemini', icon: Brand.Gemini, directLink: aiLinks.Gemini },\r\n { name: 'Twitter', connector: 'twitter', icon: Brand.Twitter },\r\n // Page 3\r\n { name: 'LinkedIn', connector: 'linkedin', icon: Brand.LinkedIn },\r\n { name: 'Reddit', connector: 'reddit', icon: Brand.Reddit },\r\n { name: 'Grok', connector: 'grok', icon: Brand.Grok, directLink: aiLinks.Grok },\r\n ];\r\n\r\n const getPlatformsForPage = (page) => {\r\n if (page === 1) return allPlatforms.slice(0, 3);\r\n if (page === 2) return allPlatforms.slice(3, 6);\r\n return allPlatforms.slice(6);\r\n };\r\n\r\n const platforms = getPlatformsForPage(currentPage);\r\n\r\n useEffect(() => {\r\n const p = localStorage.getItem('onairos_oauth_platform');\r\n if (p) {\r\n localStorage.removeItem('onairos_oauth_platform');\r\n localStorage.removeItem('onairos_oauth_return');\r\n setConnectedAccounts((s) => ({ ...s, [p]: true }));\r\n }\r\n }, []);\r\n\r\n async function connectToPlatform(name) {\r\n const plat = allPlatforms.find((p) => p.name === name);\r\n if (!plat) return false;\r\n try {\r\n // For direct-link platforms (no OAuth), mark connected immediately and return\r\n if (plat.directLink) {\r\n setConnectedAccounts((s) => ({ ...s, [name]: true }));\r\n setIsConnecting(false);\r\n setConnectingPlatform(null);\r\n return true;\r\n }\r\n\r\n // Immediately reflect selection in UI without spinner while starting OAuth\r\n setConnectedAccounts((s) => ({ ...s, [name]: true }));\r\n setIsConnecting(true);\r\n setConnectingPlatform(name);\r\n const username = localStorage.getItem('username') || (JSON.parse(localStorage.getItem('onairosUser') || '{}')?.email) || 'user@example.com';\r\n\r\n const res = await fetch(`${sdkConfig.baseUrl}/${plat.connector}/authorize`, {\r\n method: 'POST', headers: { 'x-api-key': sdkConfig.apiKey, 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ session: { username } }),\r\n });\r\n if (!res.ok) throw new Error('auth failed');\r\n const data = await res.json();\r\n\r\n const candidates = (\r\n {\r\n youtube: ['youtubeURL','youtubeUrl','youtube_url'],\r\n linkedin: ['linkedinURL','linkedinUrl','linkedin_url'],\r\n reddit: ['redditURL','redditUrl','reddit_url'],\r\n pinterest: ['pinterestURL','pinterestUrl','pinterest_url'],\r\n instagram: ['instagramURL','instagramUrl','instagram_url'],\r\n github: ['githubURL','githubUrl','github_url'],\r\n facebook: ['facebookURL','facebookUrl','facebook_url'],\r\n gmail: ['gmailURL','gmailUrl','gmail_url'],\r\n }[plat.connector]\r\n ) || [`${plat.connector}URL`, `${plat.connector}Url`, `${plat.connector}_url`, 'platformURL', 'authUrl', 'url'];\r\n\r\n let oauthUrl = null; for (const k of candidates) if (data[k]) { oauthUrl = data[k]; break; }\r\n if (!oauthUrl) throw new Error('no url');\r\n\r\n const popup = window.open(oauthUrl, `${plat.connector}_oauth`, 'width=500,height=600,scrollbars=yes,resizable=yes,status=no,location=no,toolbar=no,menubar=no');\r\n if (!popup) throw new Error('popup blocked');\r\n\r\n let touched = false; const it = setInterval(() => {\r\n try { if (popup.location && popup.location.hostname === 'onairos.uk') { touched = true; popup.close(); } } catch { if (!touched) touched = true; }\r\n try { if (popup.closed) { clearInterval(it); setIsConnecting(false); setConnectingPlatform(null); } } catch {}\r\n }, 800);\r\n\r\n setTimeout(() => { try { if (!popup.closed && touched) popup.close(); } catch {} }, 10000);\r\n setTimeout(() => { if (!popup.closed) { popup.close(); clearInterval(it); setIsConnecting(false); setConnectingPlatform(null); } }, 300000);\r\n return true;\r\n } catch {\r\n // On failure, revert the optimistic toggle\r\n setConnectedAccounts((s) => ({ ...s, [name]: false }));\r\n setIsConnecting(false); setConnectingPlatform(null); return false;\r\n }\r\n }\r\n\r\n const handleSwitch = async (name, llmConnectorManager = null) => {\r\n // Don't allow toggling other platforms while one is connecting\r\n if (isConnecting && connectingPlatform !== name) return;\r\n \r\n const on = !!connectedAccounts[name];\r\n \r\n if (on) {\r\n // Disconnect - always allow immediate toggle off\r\n console.log(`🔄 Disconnecting ${name}`);\r\n setConnectedAccounts((s) => ({ ...s, [name]: false }));\r\n setIsConnecting(false);\r\n setConnectingPlatform(null);\r\n } else {\r\n // Connect\r\n console.log(`🔄 Connecting ${name}`);\r\n const platform = allPlatforms.find(p => p.name === name);\r\n \r\n // Check if this is an LLM platform that should use extension detection\r\n if (platform && platform.directLink) {\r\n // For AI platforms: open their website and auto-toggle\r\n window.open(platform.directLink, '_blank');\r\n setConnectedAccounts((s) => ({ ...s, [name]: true }));\r\n \r\n // Also try LLM Connector Manager if available\r\n if (llmConnectorManager) {\r\n const platformKey = platform.connector;\r\n llmConnectorManager.connectToLLM(\r\n platformKey,\r\n (connectedPlatform) => {\r\n console.log(`✅ ${connectedPlatform} connected via extension`);\r\n },\r\n (errorPlatform, error) => {\r\n console.error(`❌ ${errorPlatform} connection error:`, error);\r\n }\r\n );\r\n }\r\n } else {\r\n // Use traditional OAuth flow for social media platforms\r\n await connectToPlatform(name);\r\n }\r\n }\r\n };\r\n\r\n const connectedCount = Object.values(connectedAccounts).filter(Boolean).length;\r\n\r\n useEffect(() => {\r\n if (!lottieRef.current) return;\r\n const totalFrames = (personaAnim.op || 0) - (personaAnim.ip || 0);\r\n const TOTAL_PLATFORMS = 9; // Total number of platforms across all pages\r\n const progress = connectedCount / TOTAL_PLATFORMS;\r\n const target = Math.max(0, Math.floor(progress * totalFrames));\r\n const start = lastFrameRef.current || 0;\r\n const duration = 420; const startTs = performance.now();\r\n const step = (now) => {\r\n const t = Math.min(1, (now - startTs) / duration);\r\n const eased = t < 0.5 ? 2*t*t : -1 + (4 - 2*t)*t;\r\n const frame = Math.floor(start + (target - start) * eased);\r\n lottieRef.current.goToAndStop(frame, true);\r\n if (t < 1) rafRef.current = requestAnimationFrame(step); else lastFrameRef.current = target;\r\n };\r\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\r\n rafRef.current = requestAnimationFrame(step);\r\n return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); };\r\n }, [connectedCount]);\r\n\r\n // swipe handlers for smooth paging\r\n const onTouchStart = (e) => { touchStartX.current = e.touches[0].clientX; touchDeltaX.current = 0; };\r\n const onTouchMove = (e) => { touchDeltaX.current = e.touches[0].clientX - touchStartX.current; };\r\n const onTouchEnd = () => {\r\n const dx = touchDeltaX.current; const THRESH = 40;\r\n if (dx < -THRESH && currentPage < 3) setCurrentPage(currentPage + 1);\r\n else if (dx > THRESH && currentPage > 1) setCurrentPage(currentPage - 1);\r\n };\r\n\r\n return (\r\n <LLMConnectorManager\r\n onConnectionChange={(platform, connected) => {\r\n const platformName = platform.charAt(0).toUpperCase() + platform.slice(1);\r\n const displayName = platformName === 'Chatgpt' ? 'ChatGPT' : platformName;\r\n setConnectedAccounts((s) => ({ ...s, [displayName]: connected }));\r\n }}\r\n username={localStorage.getItem('username') || (JSON.parse(localStorage.getItem('onairosUser') || '{}')?.email) || 'user@example.com'}\r\n >\r\n <style dangerouslySetInnerHTML={{ __html: fadeSlideInKeyframes }} />\r\n <div\r\n className=\"relative w-full h-full grid overflow-hidden\"\r\n style={{\r\n height: Math.min('90vh', Math.max(600, Math.min(720, vh * 0.9))),\r\n minHeight: 580,\r\n maxHeight: 720,\r\n gridTemplateRows: 'auto 1fr auto',\r\n }}\r\n >\r\n {/* persona bg */}\r\n <div\r\n aria-hidden\r\n style={{\r\n position: 'absolute',\r\n left: '50%',\r\n top: PERSONA_TOP,\r\n transform: 'translateX(-50%)',\r\n width: personaSide,\r\n height: personaSide,\r\n zIndex: 0,\r\n pointerEvents: 'none',\r\n opacity: 0.95,\r\n }}\r\n >\r\n <div className=\"overflow-hidden rounded-[28px] w-full h-full\">\r\n <Lottie\r\n lottieRef={lottieRef}\r\n animationData={personaAnim}\r\n autoplay={false}\r\n loop={false}\r\n style={{ width: '100%', height: '100%' }}\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* header */}\r\n <div className=\"px-6 pt-16 pb-4 text-center z-10\">\r\n <h1 className=\"text-2xl font-bold text-gray-900 mb-2 leading-tight\">Connect App Data</h1>\r\n <p className=\"text-gray-600 text-base\">More Connections, Better Personalization.</p>\r\n </div>\r\n\r\n {/* middle scrollable */}\r\n <div className=\"min-h-0 overflow-y-auto px-6 flex flex-col\" style={{ zIndex: 10, position: 'relative' }}>\r\n <div className=\"flex-1\" />\r\n {/* icons */}\r\n <div className=\"w-full mb-3\" style={{ zIndex: 15, position: 'relative' }}>\r\n <div className=\"grid w-full\" onTouchStart={onTouchStart} onTouchMove={onTouchMove} onTouchEnd={onTouchEnd} style={{ height: ICONS_H, gridAutoFlow: 'column', gridTemplateColumns: `repeat(${platforms.length}, minmax(0,1fr))`, columnGap: currentPage === 1 ? GAP_PAGE1 : GAP_PAGE2, alignItems: 'center', justifyItems: 'center', paddingInline: 8 }}>\r\n {platforms.map((p, idx) => {\r\n const on = !!connectedAccounts[p.name];\r\n const isSel = selected === p.name;\r\n const shift = (currentPage === 1 ? idx : idx - 2) * 14;\r\n return (\r\n <div key={p.name} style={{ opacity: 0, transform: `translateX(${shift}px)`, animation: 'fadeSlideIn 0.28s forwards', ['--slide-x']: `${shift}px` }}>\r\n <button type=\"button\" onClick={() => { setSelected(p.name); handleSwitch(p.name, llmConnectorManager); }} className=\"grid place-items-center outline-none\" style={{ width: SLOT, height: SLOT }} title={p.name}>\r\n <div className={`rounded-full border-3 flex items-center justify-center shadow transition-all ${on ? 'border-blue-600 shadow-blue-500/50' : 'border-gray-300 hover:border-gray-400'} bg-white`} style={{ width: CIRCLE, height: CIRCLE, transform: `scale(${isSel ? ACTIVE_SCALE : 1})` }}>\r\n {p.icon}\r\n </div>\r\n </button>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n {/* dots */}\r\n <div className=\"flex justify-center gap-4 mb-3\">\r\n {[1, 2, 3].map((n) => (\r\n <button key={n} onClick={() => setCurrentPage(n)} style={{ width: 12, height: 12 }}>\r\n <span className={`block rounded-full ${currentPage === n ? 'bg-blue-600 scale-110' : 'bg-gray-300'} transition-transform`} style={{ width: 12, height: 12 }} />\r\n </button>\r\n ))}\r\n </div>\r\n {/* card */}\r\n <div className=\"rounded-2xl bg-white shadow-sm border border-gray-200 px-4 py-2.5 mx-auto mb-2\" style={{ width: 'min(420px,90%)' }}>\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"text-gray-900 font-medium text-sm\">{selected}</div>\r\n <button type=\"button\" role=\"switch\" aria-checked={!!connectedAccounts[selected]} onClick={() => handleSwitch(selected, llmConnectorManager)} disabled={isConnecting && connectingPlatform !== selected} className={`relative inline-flex items-center transition-colors ${connectedAccounts[selected] ? 'bg-black' : 'bg-gray-200'} rounded-full`} style={{ width: 44, height: 26 }}>\r\n <span className=\"absolute bg-white rounded-full shadow\" style={{ width: 18, height: 18, transform: connectedAccounts[selected] ? 'translateX(20px)' : 'translateX(5px)', transition: 'transform 160ms ease' }} />\r\n </button>\r\n </div>\r\n <div className=\"mt-1.5 text-xs text-gray-700 leading-4 bg-gray-50 rounded-xl px-3 py-2\">\r\n {descriptions[selected] || null}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* footer anchored */}\r\n <div className=\"px-6 pb-4 pt-3 bg-gradient-to-t from-white via-white/90 to-transparent z-20\">\r\n <div className=\"w-full bg-gray-900 hover:bg-gray-800 text-white rounded-full py-4 text-base font-medium flex items-center justify-center gap-2 cursor-pointer transition-colors\" onClick={() => { const connected = Object.entries(connectedAccounts).filter(([, v]) => v).map(([k]) => k); onComplete?.({ connectedAccounts: connected, totalConnections: connected.length }); }}>\r\n Update\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" /></svg>\r\n </div>\r\n <div onClick={() => onComplete?.({ connectedAccounts: [], totalConnections: 0 })} className=\"w-full text-gray-600 text-base font-medium py-2 text-center cursor-pointer hover:text-gray-800 transition-colors\">Skip</div>\r\n </div>\r\n </div>\r\n </LLMConnectorManager>\r\n );\r\n}","import React, { useState, useEffect } from 'react';\r\n\r\nexport default function PinSetup({ onComplete, onBack, userEmail }) {\r\n const [pin, setPin] = useState('');\r\n const [pinRequirements, setPinRequirements] = useState({\r\n length: false,\r\n uppercase: false,\r\n number: false,\r\n });\r\n\r\n // Check PIN requirements\r\n useEffect(() => {\r\n setPinRequirements({\r\n length: pin.length >= 6,\r\n uppercase: /[A-Z]/.test(pin),\r\n number: /\\d/.test(pin),\r\n });\r\n }, [pin]);\r\n\r\n const allRequirementsMet = pinRequirements.length && pinRequirements.uppercase && pinRequirements.number;\r\n\r\n const handleSubmit = () => {\r\n if (allRequirementsMet) {\r\n onComplete({\r\n pin: pin, // This should be hashed in production\r\n pinCreated: true,\r\n timestamp: new Date().toISOString()\r\n });\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"w-full h-full flex flex-col\" style={{ height: '100%', minHeight: 0 }}>\r\n {/* Content - Flexible center area */}\r\n <div className=\"px-6 pt-16 flex-1 flex flex-col\" style={{ minHeight: 0, overflow: 'hidden' }}>\r\n <div className=\"mb-6 flex-shrink-0\">\r\n <h1 className=\"text-2xl font-bold text-gray-900 mb-2\">Create a PIN</h1>\r\n <p className=\"text-gray-600 text-base\">A PIN so only you have the access to your data</p>\r\n </div>\r\n\r\n <div className=\"mb-6 flex-shrink-0\">\r\n <input\r\n type=\"password\"\r\n value={pin}\r\n onChange={(e) => setPin(e.target.value)}\r\n className=\"w-full px-4 py-4 border-2 border-gray-300 rounded-xl text-center text-lg font-medium focus:border-gray-900 focus:outline-none bg-gray-50\"\r\n placeholder=\"Enter your PIN\"\r\n maxLength={20}\r\n />\r\n </div>\r\n\r\n {/* Scrollable requirements list */}\r\n <div className=\"flex-1 overflow-y-auto\" style={{ minHeight: 0 }}>\r\n <div className=\"space-y-3 pb-4\">\r\n <p className=\"text-gray-900 font-medium mb-4\">Your PIN must:</p>\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div\r\n className={`w-5 h-5 rounded-full border-2 ${pinRequirements.length ? \"border-green-500 bg-green-500\" : \"border-gray-300 bg-white\"}`}\r\n >\r\n {pinRequirements.length && (\r\n <svg className=\"w-3 h-3 text-white m-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\r\n </svg>\r\n )}\r\n </div>\r\n <span className=\"text-gray-700\">Be at least 6 characters in length.</span>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <div\r\n className={`w-5 h-5 rounded-full border-2 ${pinRequirements.uppercase ? \"border-green-500 bg-green-500\" : \"border-gray-300 bg-white\"}`}\r\n >\r\n {pinRequirements.uppercase && (\r\n <svg className=\"w-3 h-3 text-white m-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\r\n </svg>\r\n )}\r\n </div>\r\n <span className=\"text-gray-700\">Contain an uppercase letter.</span>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <div\r\n className={`w-5 h-5 rounded-full border-2 ${pinRequirements.number ? \"border-green-500 bg-green-500\" : \"border-gray-300 bg-white\"}`}\r\n >\r\n {pinRequirements.number && (\r\n <svg className=\"w-3 h-3 text-white m-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\r\n </svg>\r\n )}\r\n </div>\r\n <span className=\"text-gray-700\">Contain a number.</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Buttons - Fixed at bottom */}\r\n <div className=\"px-6 pb-6 pt-4 flex-shrink-0 space-y-3\" style={{ minHeight: 'auto' }}>\r\n <div\r\n className={`w-full rounded-full py-4 text-base font-medium flex items-center justify-center gap-2 transition-colors ${\r\n allRequirementsMet \r\n ? \"bg-gray-900 hover:bg-gray-800 text-white cursor-pointer\" \r\n : \"bg-gray-300 text-gray-500 cursor-not-allowed\"\r\n }`}\r\n onClick={allRequirementsMet ? handleSubmit : undefined}\r\n >\r\n Continue\r\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n} ","import React, { useState, useEffect } from 'react';\nimport PrimaryButton from './ui/PrimaryButton.jsx';\nimport { COLORS } from '../theme/colors.js';\n\nconst dataTypes = [\n { \n id: 'basic', \n name: 'Basic Profile', \n description: 'Essential profile information, account details, and basic demographics', \n icon: 'User',\n required: true,\n tooltip: 'Includes name, email, basic profile information. This data is essential for personalization and is always included.',\n privacyLink: 'https://onairos.uk/privacy#basic-info'\n },\n { \n id: 'preferences', \n name: 'User Preferences', \n description: 'User preferences, interests, settings and personal choices', \n icon: 'Grid3X3',\n required: false,\n tooltip: 'Your stated preferences and interests from connected platforms. Helps customize your experience.',\n privacyLink: 'https://onairos.uk/privacy#preferences-data'\n },\n { \n id: 'personality', \n name: 'Personality Traits', \n description: 'Personality traits, behavioral patterns and psychological insights', \n icon: 'Brain',\n required: false,\n tooltip: 'AI-analyzed personality traits based on your social media activity and interactions. Used to improve content recommendations.',\n privacyLink: 'https://onairos.uk/privacy#personality-data'\n }\n];\n\n// Data Type Toggle Component with compact checkbox design\nconst DataTypeToggle = ({ dataType, isEnabled, onToggle, isLast }) => {\n const handleToggle = () => {\n if (dataType.required) return; // Don't allow toggling required items\n onToggle(dataType.id, !isEnabled);\n };\n\n const getIconComponent = (iconName) => {\n const iconProps = { className: \"w-4 h-4 text-gray-600\" };\n \n switch (iconName) {\n case 'User':\n return (\n <svg {...iconProps} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\" />\n </svg>\n );\n case 'Grid3X3':\n return (\n <svg {...iconProps} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z\" />\n </svg>\n );\n case 'Brain':\n return (\n <svg {...iconProps} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z\" />\n </svg>\n );\n default:\n return <span className=\"text-lg\">{iconName}</span>;\n }\n };\n\n return (\n <div className=\"flex items-center justify-between p-3 rounded-lg bg-gray-50\">\n <div className=\"flex items-center gap-4\">\n <div className=\"w-8 h-8 bg-gray-200 rounded-full flex items-center justify-center flex-shrink-0\">\n {getIconComponent(dataType.icon)}\n </div>\n <div className=\"min-w-0 flex-1\">\n <span className=\"font-medium text-gray-900 text-sm\">{dataType.name}</span>\n </div>\n </div>\n <div\n onClick={handleToggle}\n className={`w-5 h-5 rounded border-2 flex items-center justify-center cursor-pointer transition-colors flex-shrink-0 ${\n isEnabled ? \"bg-gray-900 border-gray-900\" : \"bg-white border-gray-300\"\n }`}\n >\n {isEnabled && (\n <svg className=\"w-3 h-3 text-white\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )}\n </div>\n </div>\n );\n};\n\nconst DataRequest = ({ \n userEmail = 'user@example.com', \n testMode = false, \n onComplete, \n autoFetch = true,\n appName = 'Test App',\n formatResponse = false,\n responseFormat = 'simple'\n}) => {\n const [selectedData, setSelectedData] = useState({\n basic: true, // Always true for required data\n personality: false,\n preferences: false\n });\n const [isLoadingApi, setIsLoadingApi] = useState(false);\n const [apiError, setApiError] = useState(null);\n\n const handleDataToggle = (dataId, enabled) => {\n const dataType = dataTypes.find(dt => dt.id === dataId);\n if (dataType?.required) return; // Don't allow toggling required items\n\n setSelectedData(prev => ({\n ...prev,\n [dataId]: enabled\n }));\n };\n\n const generateUserHash = (email) => {\n let hash = 0;\n const str = email + Date.now().toString();\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return `user_${Math.abs(hash).toString(36)}`;\n };\n\n const fetchUserData = async () => {\n console.log('🔥 DataRequest: fetchUserData called');\n console.log('🔥 DataRequest: onComplete function:', typeof onComplete);\n console.log('🔥 DataRequest: selectedData:', selectedData);\n console.log('🔥 DataRequest: selectedCount:', selectedCount);\n \n setIsLoadingApi(true);\n setApiError(null);\n \n try {\n const userHash = generateUserHash(userEmail);\n \n // Get selected data types\n const approvedData = Object.entries(selectedData)\n .filter(([key, value]) => value)\n .map(([key]) => key);\n\n const mapDataTypesToConfirmations = (approvedData) => {\n const confirmations = [];\n const currentDate = new Date().toISOString();\n \n const dataTypeMapping = {\n 'basic': 'Medium',\n 'personality': 'Large', \n 'preferences': 'Traits'\n };\n \n approvedData.forEach(dataType => {\n if (dataTypeMapping[dataType]) {\n confirmations.push({\n data: dataTypeMapping[dataType],\n date: currentDate\n });\n }\n });\n \n return confirmations;\n };\n\n const apiEndpoint = testMode \n ? 'https://api2.onairos.uk/inferenceTest'\n : 'https://api2.onairos.uk/getAPIurlMobile';\n \n const baseResult = {\n userHash,\n appName,\n approvedData,\n apiUrl: apiEndpoint,\n testMode,\n timestamp: new Date().toISOString()\n };\n\n if (autoFetch) {\n if (testMode) {\n // Test mode: Skip API call completely, simulate response\n console.log('🧪 Test mode: Simulating data request API call for:', approvedData);\n \n setTimeout(() => {\n const simulatedApiData = {\n success: true,\n message: \"Data request simulated successfully\",\n data: {\n personalityScores: {\n openness: 0.75,\n conscientiousness: 0.68,\n extraversion: 0.82,\n agreeableness: 0.71,\n neuroticism: 0.43\n },\n insights: [\n \"You show high creativity and openness to new experiences\",\n \"Strong social tendencies with good interpersonal skills\",\n \"Well-organized approach to tasks and goals\"\n ],\n dataProcessed: approvedData,\n timestamp: new Date().toISOString(),\n testMode: true\n }\n };\n\n const result = {\n ...baseResult,\n apiResponse: simulatedApiData,\n success: true,\n simulated: true\n };\n\n setIsLoadingApi(false);\n console.log('🧪 Test mode: Simulated data request completed:', result);\n console.log('🔥 DataRequest: onComplete function type:', typeof onComplete);\n if (onComplete && typeof onComplete === 'function') {\n onComplete(result);\n console.log('🔥 DataRequest: onComplete called successfully (test mode)');\n } else {\n console.error('🔥 DataRequest: onComplete is not a function or is undefined (test mode)');\n }\n }, 1200); // Simulate realistic processing time\n } else {\n // Production mode: Make real API call\n try {\n const confirmations = mapDataTypesToConfirmations(approvedData);\n \n const requestBody = {\n approvedData,\n userEmail,\n appName,\n confirmations\n };\n\n console.log('🔥 DataRequest: Making API call to:', apiEndpoint);\n console.log('🔥 Request body:', requestBody);\n\n const apiResponse = await fetch(apiEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody)\n });\n\n if (!apiResponse.ok) {\n throw new Error(`API request failed with status ${apiResponse.status}`);\n }\n\n const apiData = await apiResponse.json();\n console.log('🔥 API Response:', apiData);\n\n const result = {\n ...baseResult,\n apiResponse: apiData,\n success: true\n };\n\n setIsLoadingApi(false);\n console.log('🔥 DataRequest: Calling onComplete with result:', result);\n console.log('🔥 DataRequest: onComplete function type:', typeof onComplete);\n if (onComplete && typeof onComplete === 'function') {\n onComplete(result);\n console.log('🔥 DataRequest: onComplete called successfully');\n } else {\n console.error('🔥 DataRequest: onComplete is not a function or is undefined');\n }\n\n } catch (apiError) {\n console.error('🔥 API Error:', apiError);\n setApiError(apiError.message);\n setIsLoadingApi(false);\n \n const errorResult = {\n ...baseResult,\n apiResponse: null,\n error: apiError.message,\n success: false\n };\n \n onComplete(errorResult);\n }\n }\n } else {\n setIsLoadingApi(false);\n console.log('🔥 DataRequest: Auto-fetch disabled, calling onComplete with base result');\n console.log('🔥 DataRequest: onComplete function type:', typeof onComplete);\n if (onComplete && typeof onComplete === 'function') {\n onComplete(baseResult);\n console.log('🔥 DataRequest: onComplete called successfully (auto-fetch disabled)');\n } else {\n console.error('🔥 DataRequest: onComplete is not a function or is undefined (auto-fetch disabled)');\n }\n }\n } catch (error) {\n console.error('🔥 DataRequest Error:', error);\n setApiError(error.message);\n setIsLoadingApi(false);\n \n if (onComplete) {\n onComplete({\n error: error.message,\n success: false,\n userEmail,\n appName,\n testMode\n });\n }\n }\n };\n\n // Count selected data types\n const selectedCount = Object.values(selectedData).filter(Boolean).length;\n\n return (\n <div className=\"w-full h-full flex flex-col min-h-0\">\n {/* Content - Flexible center area with proper constraints */}\n <div className=\"px-6 pt-16 flex-1 flex flex-col min-h-0\" style={{ minHeight: 'calc(100vh - 200px)' }}>\n {/* Icon Flow */}\n <div className=\"mb-4 flex justify-center items-center gap-4 flex-shrink-0\">\n <div className=\"w-12 h-12 bg-white rounded-xl shadow-lg flex items-center justify-center border border-gray-100\">\n <svg className=\"w-6 h-6\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M12 2C13.1 2 14 2.9 14 4C14 5.1 13.1 6 12 6C10.9 6 10 5.1 10 4C10 2.9 10.9 2 12 2Z\"\n fill=\"black\"\n />\n <path\n d=\"M21 9V7L15 6.5V9C15 10.66 13.66 12 12 12C10.34 12 9 10.66 9 9V6.5L3 7V9C3 12.87 6.13 16 10 16V22H14V16C17.87 16 21 12.87 21 9Z\"\n fill=\"black\"\n />\n </svg>\n </div>\n <svg className=\"w-4 h-4 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n <div className=\"w-12 h-12 bg-white rounded-xl shadow-lg flex items-center justify-center border border-gray-100\">\n <span className=\"text-xl font-serif font-bold text-black\">E</span>\n </div>\n </div>\n\n {/* Title Section */}\n <div className=\"mb-4 flex-shrink-0\">\n <h1 className=\"text-xl font-bold text-gray-900 mb-2 text-balance leading-tight\">\n Enoch wants to personalize your experience\n </h1>\n <p className=\"text-gray-600 text-sm\">Choose what to share:</p>\n </div>\n\n {/* Consent Options - Scrollable area */}\n <div className=\"flex-1 overflow-y-auto min-h-0\">\n <div className=\"space-y-4 pb-4\">\n {dataTypes.map((dataType, index) => (\n <DataTypeToggle\n key={dataType.id}\n dataType={dataType}\n isEnabled={selectedData[dataType.id]}\n onToggle={handleDataToggle}\n isLast={index === dataTypes.length - 1}\n />\n ))}\n </div>\n </div>\n </div>\n\n {/* Buttons - Fixed at bottom with guaranteed visibility */}\n <div className=\"px-6 pb-6 pt-3 flex-shrink-0 space-y-2 bg-white border-t border-gray-100\">\n <div\n className=\"w-full bg-gray-900 hover:bg-gray-800 text-white rounded-full py-3 text-sm font-medium flex items-center justify-center gap-2 cursor-pointer transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n onClick={fetchUserData}\n disabled={isLoadingApi || selectedCount === 0}\n >\n {isLoadingApi ? \"Processing...\" : \"Accept & Continue\"}\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </div>\n <div\n onClick={() => onComplete({ cancelled: true })}\n className=\"w-full bg-gray-200 hover:bg-gray-300 text-gray-700 rounded-full py-3 text-sm font-medium text-center cursor-pointer transition-colors\"\n >\n Decline\n </div>\n\n {/* Error display */}\n {apiError && (\n <div className=\"mt-3 p-3 rounded-lg text-center bg-red-50 border border-red-200 text-red-600\">\n <p className=\"text-xs\">{apiError}</p>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default DataRequest; ","import React, { useState, useEffect } from 'react';\nimport { COLORS } from '../theme/colors.js';\n\nexport default function TrainingComponent({ onComplete, userEmail, appName = 'App', testMode = false }) {\n const [currentStep, setCurrentStep] = useState(0);\n const [progress, setProgress] = useState(0);\n const [isComplete, setIsComplete] = useState(false);\n\n const steps = [\n {\n title: 'Setting up your personal AI',\n description: 'Initializing your secure data model',\n icon: '🤖',\n duration: testMode ? 800 : 2000 // Much faster in test mode\n },\n {\n title: 'Processing your connections',\n description: 'Analyzing your social media patterns',\n icon: '🔗',\n duration: testMode ? 600 : 2500\n },\n {\n title: 'Training your model',\n description: 'Building your personalized insights',\n icon: '🧠',\n duration: testMode ? 700 : 3000\n },\n {\n title: 'Finalizing setup',\n description: 'Preparing your Onairos experience',\n icon: '✨',\n duration: testMode ? 500 : 2000\n }\n ];\n\n useEffect(() => {\n let interval;\n let stepTimeout;\n\n if (currentStep < steps.length) {\n const stepDuration = steps[currentStep].duration;\n const stepProgress = 100 / steps.length;\n\n // Update progress gradually\n interval = setInterval(() => {\n setProgress(prev => {\n const newProgress = prev + (stepProgress / (stepDuration / 100));\n return Math.min(newProgress, (currentStep + 1) * stepProgress);\n });\n }, 100);\n\n // Move to next step after duration\n stepTimeout = setTimeout(() => {\n if (currentStep < steps.length - 1) {\n setCurrentStep(prev => prev + 1);\n } else {\n setIsComplete(true);\n const completionDelay = testMode ? 400 : 1000; // Faster completion in test mode\n \n if (testMode) {\n console.log('🧪 Test mode: Training simulation completed');\n }\n \n setTimeout(() => {\n onComplete({\n trainingComplete: true,\n timestamp: new Date().toISOString(),\n userEmail: userEmail,\n appName: appName,\n testMode: testMode,\n simulatedTraining: testMode\n });\n }, completionDelay);\n }\n }, stepDuration);\n }\n\n return () => {\n if (interval) clearInterval(interval);\n if (stepTimeout) clearTimeout(stepTimeout);\n };\n }, [currentStep, onComplete, userEmail, appName]);\n\n return (\n <div className=\"w-full flex flex-col items-center space-y-8\">\n <div className=\"text-center\">\n <div \n className=\"w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4\"\n style={{\n background: `linear-gradient(135deg, ${COLORS.info}, #8B5CF6)`\n }}\n >\n <div className=\"text-3xl\">\n {isComplete ? '🎉' : steps[currentStep]?.icon}\n </div>\n </div>\n <h2 \n className=\"text-2xl font-bold mb-2\"\n style={{ color: COLORS.textPrimary }}\n >\n {isComplete ? 'All set!' : steps[currentStep]?.title}\n </h2>\n <p style={{ color: COLORS.textSecondary }}>\n {isComplete \n ? 'Your personal AI is ready to use' \n : steps[currentStep]?.description\n }\n </p>\n </div>\n\n {/* Progress Bar */}\n <div className=\"w-full\">\n <div \n className=\"flex justify-between text-sm mb-2\"\n style={{ color: COLORS.textSecondary }}\n >\n <span>Progress</span>\n <span>{Math.round(progress)}%</span>\n </div>\n <div \n className=\"w-full rounded-full h-2\"\n style={{ backgroundColor: COLORS.borderLight }}\n >\n <div \n className=\"h-2 rounded-full transition-all duration-300 ease-out\"\n style={{ \n width: `${progress}%`,\n background: `linear-gradient(90deg, ${COLORS.info}, #8B5CF6)`\n }}\n />\n </div>\n </div>\n\n {/* Steps Indicator */}\n <div className=\"flex justify-center space-x-2\">\n {steps.map((_, index) => (\n <div\n key={index}\n className=\"w-3 h-3 rounded-full transition-all duration-300\"\n style={{\n backgroundColor: index <= currentStep ? COLORS.info : COLORS.border\n }}\n />\n ))}\n </div>\n\n {/* Current Step Details */}\n <div \n className=\"p-4 rounded-lg w-full\"\n style={{ backgroundColor: COLORS.backgroundSecondary }}\n >\n <div className=\"flex items-center space-x-3\">\n <div \n className=\"w-8 h-8 rounded-full flex items-center justify-center\"\n style={{ backgroundColor: '#DBEAFE' }}\n >\n <div className=\"text-sm\">\n {isComplete ? '✅' : steps[currentStep]?.icon}\n </div>\n </div>\n <div>\n <h3 \n className=\"font-medium\"\n style={{ color: COLORS.textPrimary }}\n >\n {isComplete ? 'Training Complete' : `Step ${currentStep + 1} of ${steps.length}`}\n </h3>\n <p \n className=\"text-sm\"\n style={{ color: COLORS.textSecondary }}\n >\n {isComplete \n ? 'Your Onairos experience is ready' \n : steps[currentStep]?.description\n }\n </p>\n </div>\n </div>\n </div>\n\n {/* App Info */}\n <div className=\"text-center\">\n <p \n className=\"text-sm\"\n style={{ color: COLORS.textSecondary }}\n >\n Setting up for <span className=\"font-medium\">{appName}</span>\n </p>\n {userEmail && (\n <p \n className=\"text-xs mt-1\"\n style={{ color: COLORS.textMuted }}\n >\n {userEmail}\n </p>\n )}\n </div>\n </div>\n );\n} ","import React, { useState, useEffect } from \"react\";\r\nimport Lottie from 'lottie-react';\r\nimport rainAnim from '../../public/rain-anim.json';\r\n\r\nexport default function LoadingScreen({ onComplete }) {\r\n const [currentStep, setCurrentStep] = useState(0);\r\n const [dotCount, setDotCount] = useState(0);\r\n\r\n const loadingStates = [\r\n { message: \"Validating PIN and continuing training\", progress: 20 },\r\n { message: \"Uploading model to secure storage\", progress: 40 },\r\n { message: \"Running test inference\", progress: 60 },\r\n { message: \"Storing results in databases\", progress: 80 },\r\n { message: \"Complete!\", progress: 100 },\r\n ];\r\n\r\n useEffect(() => {\r\n const stateInterval = setInterval(() => {\r\n setCurrentStep((prev) => {\r\n const nextStep = prev + 1;\r\n if (nextStep >= loadingStates.length) {\r\n // Loading complete, call onComplete after a short delay\r\n setTimeout(() => {\r\n onComplete();\r\n }, 1000);\r\n return prev; // Keep at last step\r\n }\r\n return nextStep;\r\n });\r\n }, 3000); // Change state every 3 seconds\r\n\r\n return () => clearInterval(stateInterval);\r\n }, [loadingStates.length, onComplete]);\r\n\r\n useEffect(() => {\r\n const dotInterval = setInterval(() => {\r\n setDotCount((prev) => (prev + 1) % 4); // 0, 1, 2, 3 dots\r\n }, 500); // Change dots every 500ms\r\n\r\n return () => clearInterval(dotInterval);\r\n }, []);\r\n\r\n const currentState = loadingStates[currentStep];\r\n\r\n return (\r\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647, pointerEvents: 'auto' }}>\r\n {/* Modal - Full height from bottom */}\r\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\r\n {/* Header */}\r\n <div className=\"px-6 pt-6 pb-4 flex-shrink-0\">\r\n </div>\r\n\r\n {/* Content - Rain animation and loading state */}\r\n <div className=\"flex-1 flex flex-col px-6\">\r\n {/* Rain Animation */}\r\n <div className=\"flex-1 flex items-center justify-center\">\r\n <div style={{ width: '100%', maxWidth: '400px', aspectRatio: '1' }}>\r\n <Lottie\r\n animationData={rainAnim}\r\n loop={true}\r\n autoplay={true}\r\n style={{ width: '100%', height: '100%' }}\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Loading State - Positioned at bottom */}\r\n <div className=\"flex-shrink-0 pb-12\">\r\n <div className=\"text-center\">\r\n <h1 className=\"font-bold text-gray-900 leading-tight mb-6\" style={{ fontSize: 'clamp(16px, 4vw, 20px)' }}>\r\n {currentState.message}\r\n {currentState.message !== \"Complete!\" && (\r\n <span className=\"inline-block w-8 text-left\">{\".\".repeat(dotCount)}</span>\r\n )}\r\n </h1>\r\n\r\n <div className=\"mx-auto\" style={{ width: 'clamp(200px, 50vw, 300px)' }}>\r\n <div className=\"w-full h-2 bg-gray-200 rounded-full\">\r\n <div\r\n className=\"h-2 bg-gray-900 rounded-full transition-all duration-1000 ease-out\"\r\n style={{ width: `${currentState.progress}%` }}\r\n ></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Bottom spacing */}\r\n <div className=\"h-20 flex-shrink-0\"></div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","/**\r\n * Response formatter utility for Onairos SDK\r\n * Converts array-based responses to dictionary format for better developer experience\r\n */\r\n\r\n// Standard 16 personality types in order that the API returns them\r\nexport const PERSONALITY_TYPES = [\r\n 'Analyst',\r\n 'Diplomat', \r\n 'Sentinel',\r\n 'Explorer',\r\n 'Architect',\r\n 'Logician',\r\n 'Commander',\r\n 'Debater',\r\n 'Advocate',\r\n 'Mediator',\r\n 'Protagonist',\r\n 'Campaigner',\r\n 'Logistician',\r\n 'Defender',\r\n 'Executive',\r\n 'Consul'\r\n];\r\n\r\n// Standard trait categories that might be returned\r\nexport const TRAIT_CATEGORIES = [\r\n 'Openness',\r\n 'Conscientiousness',\r\n 'Extraversion',\r\n 'Agreeableness',\r\n 'Neuroticism'\r\n];\r\n\r\n/**\r\n * Formats API response to include both array and dictionary formats\r\n * @param {Object} apiResponse - Raw API response from Onairos\r\n * @param {Object} options - Formatting options\r\n * @param {boolean} options.includeDictionary - Whether to include dictionary format (default: true)\r\n * @param {boolean} options.includeArray - Whether to include original array format (default: true)\r\n * @returns {Object} Formatted response with both formats\r\n */\r\nexport function formatOnairosResponse(apiResponse, options = {}) {\r\n const { includeDictionary = true, includeArray = true } = options;\r\n \r\n if (!apiResponse) {\r\n return apiResponse;\r\n }\r\n\r\n const formatted = { ...apiResponse };\r\n\r\n // Handle personality scores if present\r\n if (apiResponse.InferenceResult?.traits || apiResponse.traits || apiResponse.scores) {\r\n const scores = apiResponse.InferenceResult?.traits || apiResponse.traits || apiResponse.scores;\r\n \r\n if (Array.isArray(scores) && scores.length >= 16) {\r\n if (includeDictionary) {\r\n // Create personality dictionary\r\n const personalityDict = {};\r\n PERSONALITY_TYPES.forEach((type, index) => {\r\n personalityDict[type] = scores[index];\r\n });\r\n \r\n // Add to formatted response\r\n if (formatted.InferenceResult) {\r\n formatted.InferenceResult.personalityDict = personalityDict;\r\n } else {\r\n formatted.personalityDict = personalityDict;\r\n }\r\n }\r\n \r\n if (!includeArray) {\r\n // Remove array format if not requested\r\n if (formatted.InferenceResult?.traits) {\r\n delete formatted.InferenceResult.traits;\r\n }\r\n if (formatted.traits) {\r\n delete formatted.traits;\r\n }\r\n if (formatted.scores) {\r\n delete formatted.scores;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Handle trait data if present (for preferences/traits)\r\n if (apiResponse.traitResult || apiResponse.traits) {\r\n const traits = apiResponse.traitResult || apiResponse.traits;\r\n \r\n if (Array.isArray(traits) && includeDictionary) {\r\n const traitDict = {};\r\n TRAIT_CATEGORIES.forEach((category, index) => {\r\n if (traits[index] !== undefined) {\r\n traitDict[category] = traits[index];\r\n }\r\n });\r\n \r\n formatted.traitDict = traitDict;\r\n }\r\n }\r\n\r\n return formatted;\r\n}\r\n\r\n/**\r\n * Legacy formatter for backward compatibility\r\n * Converts scores array to personality dictionary only\r\n * @param {Array} scores - Array of personality scores\r\n * @returns {Object} Dictionary with personality type names as keys\r\n */\r\nexport function formatPersonalityScores(scores) {\r\n if (!Array.isArray(scores) || scores.length < 16) {\r\n console.warn('Invalid scores array provided to formatPersonalityScores');\r\n return {};\r\n }\r\n\r\n const personalityDict = {};\r\n PERSONALITY_TYPES.forEach((type, index) => {\r\n personalityDict[type] = scores[index];\r\n });\r\n \r\n return personalityDict;\r\n}\r\n\r\n/**\r\n * Get personality type names in order\r\n * @returns {Array} Array of personality type names\r\n */\r\nexport function getPersonalityTypes() {\r\n return [...PERSONALITY_TYPES];\r\n}\r\n\r\n/**\r\n * Get trait category names in order \r\n * @returns {Array} Array of trait category names\r\n */\r\nexport function getTraitCategories() {\r\n return [...TRAIT_CATEGORIES];\r\n} ","import React from 'react';\r\nimport { COLORS } from '../../theme/colors.js';\r\n\r\n// Standardized page layout component with white background\r\nconst PageLayout = ({\r\n children,\r\n title,\r\n subtitle,\r\n icon,\r\n showHeader = true,\r\n showCloseButton = false,\r\n onClose,\r\n onBack,\r\n showBackButton = false,\r\n className = '',\r\n contentClassName = '',\r\n centerContent = true,\r\n style = {},\r\n ...props\r\n}) => {\r\n const layoutStyle = {\r\n backgroundColor: COLORS.background,\r\n minHeight: '100%',\r\n width: '100%',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n ...style\r\n };\r\n\r\n const headerStyle = {\r\n position: 'sticky',\r\n top: 0,\r\n backgroundColor: COLORS.background,\r\n zIndex: 10,\r\n padding: 'clamp(8px, 2vw, 16px) clamp(16px, 4vw, 32px) clamp(6px, 1.5vw, 12px)'\r\n };\r\n\r\n const contentStyle = {\r\n flex: 1,\r\n padding: 'clamp(16px, 4vw, 32px)',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n overflow: 'auto',\r\n minHeight: 0, // Allow flex item to shrink below content size\r\n ...(centerContent && {\r\n alignItems: 'center',\r\n justifyContent: 'flex-start'\r\n })\r\n };\r\n\r\n const titleStyle = {\r\n fontFamily: 'Inter, system-ui, sans-serif',\r\n fontSize: 'clamp(20px, 5vw, 28px)',\r\n fontWeight: '700',\r\n color: COLORS.textPrimary,\r\n margin: '0 0 clamp(6px, 1.5vw, 12px) 0',\r\n textAlign: centerContent ? 'center' : 'left',\r\n lineHeight: '1.2'\r\n };\r\n\r\n const subtitleStyle = {\r\n fontFamily: 'Inter, system-ui, sans-serif',\r\n fontSize: 'clamp(14px, 3.5vw, 18px)',\r\n fontWeight: '400',\r\n color: COLORS.textSecondary,\r\n margin: '0 0 clamp(20px, 5vw, 40px) 0',\r\n textAlign: centerContent ? 'center' : 'left',\r\n lineHeight: '1.5'\r\n };\r\n\r\n const iconStyle = {\r\n width: 'clamp(40px, 8vw, 56px)',\r\n height: 'clamp(40px, 8vw, 56px)',\r\n margin: '0 auto clamp(16px, 4vw, 32px)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n fontSize: 'clamp(20px, 5vw, 28px)'\r\n };\r\n\r\n return (\r\n <div \r\n className={`onairos-page-layout ${className}`}\r\n style={layoutStyle}\r\n {...props}\r\n >\r\n {/* Header with navigation */}\r\n {showHeader && (\r\n <div style={headerStyle}>\r\n <div className=\"flex items-center justify-between\">\r\n {/* Back button */}\r\n {showBackButton && onBack && (\r\n <button\r\n onClick={onBack}\r\n className=\"flex items-center justify-center w-8 h-8 rounded-full hover:bg-gray-100 transition-colors\"\r\n aria-label=\"Go back\"\r\n >\r\n <span style={{ fontSize: '16px', color: COLORS.textPrimary }}>←</span>\r\n </button>\r\n )}\r\n\r\n\r\n {/* Close button */}\r\n {showCloseButton && onClose && (\r\n <button\r\n onClick={onClose}\r\n className=\"flex items-center justify-center w-8 h-8 rounded-full hover:bg-gray-100 transition-colors\"\r\n aria-label=\"Close\"\r\n >\r\n <span style={{ fontSize: '16px', color: COLORS.textPrimary }}>×</span>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Main content area */}\r\n <div \r\n className={`onairos-page-content ${contentClassName}`}\r\n style={contentStyle}\r\n >\r\n {/* Icon */}\r\n {icon && (\r\n <div style={iconStyle}>\r\n {typeof icon === 'string' ? <span>{icon}</span> : icon}\r\n </div>\r\n )}\r\n\r\n {/* Title */}\r\n {title && (\r\n <h1 style={titleStyle}>\r\n {title}\r\n </h1>\r\n )}\r\n\r\n {/* Subtitle */}\r\n {subtitle && (\r\n <p style={subtitleStyle}>\r\n {subtitle}\r\n </p>\r\n )}\r\n\r\n {/* Page content */}\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n// Modal wrapper component for overlay-style pages\r\nconst ModalPageLayout = ({\r\n children,\r\n visible = true,\r\n onClose,\r\n onBackdropClick,\r\n backdropStyle = {},\r\n modalStyle = {},\r\n ...pageLayoutProps\r\n}) => {\r\n if (!visible) return null;\r\n\r\n const backdropStyles = {\r\n position: 'fixed',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\r\n zIndex: 2147483647,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'opacity 200ms ease',\r\n willChange: 'opacity',\r\n ...backdropStyle\r\n };\r\n\r\n const modalStyles = {\r\n backgroundColor: COLORS.background,\r\n borderTopLeftRadius: '24px',\r\n borderTopRightRadius: '24px',\r\n borderBottomLeftRadius: '24px',\r\n borderBottomRightRadius: '24px',\r\n height: '90vh',\r\n width: '100%',\r\n maxWidth: '500px',\r\n boxShadow: '0 -10px 40px rgba(0, 0, 0, 0.3)',\r\n overflow: 'hidden',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n transform: 'translateY(0)',\r\n transition: 'transform 220ms ease, opacity 220ms ease',\r\n willChange: 'transform, opacity',\r\n ...modalStyle\r\n };\r\n\r\n const handleBackdropClick = (e) => {\r\n if (e.target === e.currentTarget) {\r\n if (onBackdropClick) {\r\n onBackdropClick();\r\n } else if (onClose) {\r\n onClose();\r\n }\r\n }\r\n };\r\n\r\n return (\r\n <div style={backdropStyles} onClick={handleBackdropClick}>\r\n <div style={modalStyles}>\r\n <PageLayout\r\n showHeader={true}\r\n showCloseButton={true}\r\n onClose={onClose}\r\n {...pageLayoutProps}\r\n >\r\n {children}\r\n </PageLayout>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport { ModalPageLayout };\r\nexport default PageLayout; ","import React, { useEffect, useState } from 'react';\nimport WelcomeScreen from './components/WelcomeScreen.jsx';\nimport EmailAuth from './components/EmailAuth.js';\nimport UniversalOnboarding from './components/UniversalOnboarding.jsx';\nimport PinSetup from './components/PinSetup.js';\nimport DataRequest from './components/DataRequest.js';\nimport TrainingComponent from './components/TrainingComponent.jsx';\nimport LoadingScreen from './components/LoadingScreen.jsx';\nimport { formatOnairosResponse } from './utils/responseFormatter.js';\nimport { ModalPageLayout } from './components/ui/PageLayout.jsx';\n\nexport function OnairosButton({\n requestData, \n webpageName, \n inferenceData = null, \n onComplete = null, \n autoFetch = true, // Auto-enabled for seamless testing experience\n testMode = false, // Production mode by default - set to true for testing\n proofMode = false, \n textLayout = 'below', \n textColor = 'white',\n login = false,\n buttonType = 'pill',\n loginReturn = null,\n loginType = 'signIn',\n visualType = 'full',\n appIcon = null,\n enableTraining = true,\n formatResponse = true,\n responseFormat = { includeDictionary: true, includeArray: true },\n priorityPlatform = null // Platform to prioritize (e.g., 'gmail', 'pinterest', 'linkedin')\n}) {\n\n const [showOverlay, setShowOverlay] = useState(false);\n const [currentFlow, setCurrentFlow] = useState('welcome'); // 'welcome' | 'email' | 'onboarding' | 'pin' | 'dataRequest' (training is within onboarding)\n const [userData, setUserData] = useState(null);\n const [error, setError] = useState(null);\n\n // Check for existing user session\n useEffect(() => {\n const checkExistingSession = () => {\n // In test mode, always start fresh to see the full flow\n if (testMode) {\n console.log('🧪 Test mode: Starting fresh flow, clearing any cached user data');\n localStorage.removeItem('onairosUser');\n setCurrentFlow('welcome');\n return;\n }\n \n const savedUser = localStorage.getItem('onairosUser');\n if (savedUser) {\n try {\n const user = JSON.parse(savedUser);\n setUserData(user);\n // If user has completed onboarding and PIN setup, go directly to data request\n if (user.onboardingComplete && user.pinCreated) {\n setCurrentFlow('dataRequest');\n } else if (user.verified && !user.onboardingComplete) {\n setCurrentFlow('onboarding');\n } else if (user.onboardingComplete && !user.pinCreated) {\n setCurrentFlow('pin');\n }\n } catch (error) {\n console.error('Error parsing saved user data:', error);\n localStorage.removeItem('onairosUser');\n }\n }\n };\n\n checkExistingSession();\n }, [testMode]);\n\n const openTerminal = async () => {\n try {\n console.log('🔥 openTerminal called - resetting flow');\n // ALWAYS reset flow on open to start fresh every time\n setCurrentFlow('welcome');\n setUserData(null);\n try { localStorage.removeItem('onairosUser'); } catch {}\n setShowOverlay(true);\n } catch (error) {\n console.error('Error in openTerminal:', error);\n }\n };\n\n const handleCloseOverlay = () => {\n setShowOverlay(false);\n setError(null);\n // Reset flow and session so next open starts fresh\n setCurrentFlow('welcome');\n try { localStorage.removeItem('onairosUser'); } catch {}\n setUserData(null);\n };\n\n // Handle clicks on the backdrop to close modal\n const handleBackdropClick = (e) => {\n if (e.target === e.currentTarget) {\n handleCloseOverlay();\n }\n };\n\n const handleWelcomeContinue = () => {\n console.log('🔥 Welcome screen continue clicked');\n setCurrentFlow('email');\n };\n\n const handleEmailAuthSuccess = (authData) => {\n console.log('🔥 Email auth successful:', authData);\n console.log('🔧 User State:', {\n isNewUser: authData.isNewUser,\n userState: authData.userState,\n flowType: authData.flowType,\n existingUser: authData.existingUser,\n hasAccountInfo: !!authData.accountInfo\n });\n \n // Determine flow based on API response - more explicit checking\n const isNewUser = authData.isNewUser === true || \n authData.existingUser === false || \n authData.flowType === 'onboarding' || \n authData.userState === 'new' ||\n !authData.accountInfo; // No account info means new user\n \n console.log('🔍 Flow determination:', {\n finalDecision: isNewUser ? 'NEW USER → onboarding (data connectors)' : 'EXISTING USER → dataRequest (data permissions)',\n reasoning: {\n isNewUser: authData.isNewUser,\n existingUserFalse: authData.existingUser === false,\n flowTypeOnboarding: authData.flowType === 'onboarding',\n noAccountInfo: !authData.accountInfo\n }\n });\n \n const newUserData = {\n ...authData,\n verified: true,\n onboardingComplete: !isNewUser, // New users need onboarding, returning users have completed it\n pinCreated: !isNewUser // Assume returning users have PIN, new users need to create it\n };\n \n setUserData(newUserData);\n localStorage.setItem('onairosUser', JSON.stringify(newUserData));\n \n // Flow decision logic - prioritize new user detection\n if (isNewUser) {\n console.log('🚀 NEW USER detected → Starting onboarding flow (data connectors page)');\n setCurrentFlow('onboarding');\n } else {\n console.log('👋 EXISTING USER detected → Going directly to data request (data permissions page)');\n setCurrentFlow('dataRequest');\n }\n };\n\n const handleOnboardingComplete = (onboardingData) => {\n console.log('Onboarding completed:', onboardingData);\n const updatedUserData = {\n ...userData,\n onboardingComplete: true,\n connectedAccounts: onboardingData.connectedAccounts || []\n };\n setUserData(updatedUserData);\n localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));\n setCurrentFlow('pin');\n };\n\n const handlePinSetupComplete = (pinData) => {\n console.log('PIN setup completed:', pinData);\n const updatedUserData = {\n ...userData,\n ...pinData,\n pinCreated: true\n };\n setUserData(updatedUserData);\n localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));\n \n // Move to loading flow\n setCurrentFlow('loading');\n };\n\n const handleLoadingComplete = () => {\n setCurrentFlow('dataRequest');\n };\n\n const handleTrainingComplete = (trainingResult) => {\n console.log('🎓 Training completed:', trainingResult);\n const updatedUserData = {\n ...userData,\n trainingCompleted: true,\n ...trainingResult\n };\n setUserData(updatedUserData);\n localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));\n \n // Move to data request after training\n setCurrentFlow('dataRequest');\n };\n\n const handleDataRequestComplete = (requestResult) => {\n console.log('🔥 OnairosButton: Data request completed:', requestResult);\n \n // Update user data with request result\n const updatedUserData = {\n ...userData,\n lastDataRequest: requestResult\n };\n setUserData(updatedUserData);\n localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));\n\n // Close overlay immediately\n console.log('🔥 Closing overlay after data request completion');\n // Use centralized close to also reset flow and session\n handleCloseOverlay();\n\n // Format response if requested and API response is present\n let formattedResult = requestResult;\n if (formatResponse && requestResult?.apiResponse) {\n try {\n formattedResult = {\n ...requestResult,\n apiResponse: formatOnairosResponse(requestResult.apiResponse, responseFormat)\n };\n console.log('🔥 Response formatted with dictionary:', formattedResult.apiResponse?.personalityDict || 'No personality data');\n } catch (error) {\n console.warn('🔥 Error formatting response:', error);\n // Continue with original result if formatting fails\n }\n }\n\n // Enhanced user data formatting for better display\n const { logFormattedUserData } = require('./utils/userDataFormatter');\n \n // Add user data to the result for comprehensive formatting\n const completeResult = {\n ...formattedResult,\n userData: updatedUserData\n };\n\n // Log formatted user data for better readability\n const enhancedResult = logFormattedUserData(completeResult);\n\n // Call onComplete callback if provided\n console.log('🔥 Calling onComplete callback with enhanced result');\n if (onComplete) {\n try {\n onComplete(enhancedResult);\n console.log('🔥 onComplete callback executed successfully with enhanced formatting');\n } catch (error) {\n console.error('🔥 Error in onComplete callback:', error);\n }\n } else {\n console.log('🔥 No onComplete callback provided');\n }\n };\n\n const getFlowTitle = () => {\n switch (currentFlow) {\n case 'welcome':\n return ''; // WelcomeScreen handles its own titles\n case 'email':\n return ''; // EmailAuth handles its own titles\n case 'onboarding':\n return 'Connect Your Data';\n case 'pin':\n return 'Secure Your Account';\n case 'training':\n return 'Training Your Model';\n case 'dataRequest':\n return 'Data Request';\n default:\n return '';\n }\n };\n\n const getFlowSubtitle = () => {\n switch (currentFlow) {\n case 'welcome':\n return ''; // WelcomeScreen handles its own subtitles\n case 'email':\n return ''; // EmailAuth handles its own subtitles\n case 'onboarding':\n return 'Choose which accounts to connect for a personalized experience';\n case 'pin':\n return 'Create a secure PIN to protect your data';\n case 'training':\n return 'Building your personalized insights';\n case 'dataRequest':\n return `Select the data you want to share with ${webpageName}`;\n default:\n return '';\n }\n };\n\n const getFlowIcon = () => {\n switch (currentFlow) {\n case 'welcome':\n return ''; // WelcomeScreen handles its own layout\n case 'email':\n return ''; // EmailAuth handles its own layout\n case 'onboarding':\n return '🔗';\n case 'pin':\n return '🔒';\n case 'training':\n return '⚡';\n case 'dataRequest':\n return '📊';\n default:\n return '';\n }\n };\n\n const renderCurrentFlow = () => {\n switch (currentFlow) {\n case 'welcome':\n return (\n <WelcomeScreen \n onContinue={handleWelcomeContinue}\n onClose={handleCloseOverlay}\n webpageName={webpageName}\n appIcon={appIcon}\n testMode={testMode}\n />\n );\n case 'email':\n return (\n <div className=\"h-[min(85vh,700px)]\">\n <EmailAuth \n onSuccess={handleEmailAuthSuccess}\n testMode={testMode} // Use the testMode prop from initialization\n />\n </div>\n );\n \n case 'onboarding':\n return (\n <UniversalOnboarding \n onComplete={handleOnboardingComplete}\n onBack={() => setCurrentFlow('email')}\n appIcon={appIcon || \"https://onairos.sirv.com/Images/OnairosBlack.png\"}\n appName={webpageName}\n username={userData?.email || userData?.username}\n testMode={testMode}\n priorityPlatform={priorityPlatform}\n />\n );\n \n case 'pin':\n return (\n <PinSetup \n onComplete={handlePinSetupComplete}\n userEmail={userData?.email}\n />\n );\n \n case 'training':\n return (\n <TrainingComponent \n onComplete={handleTrainingComplete}\n userEmail={userData?.email}\n appName={webpageName}\n connectedAccounts={userData?.connectedAccounts || []}\n testMode={testMode}\n />\n );\n \n case 'dataRequest':\n return (\n <DataRequest \n onComplete={handleDataRequestComplete}\n userEmail={userData?.email}\n requestData={requestData}\n appName={webpageName}\n autoFetch={autoFetch}\n testMode={testMode}\n appIcon={appIcon}\n connectedAccounts={userData?.connectedAccounts || {}}\n />\n );\n \n default:\n return (\n <div className=\"flex flex-col items-center space-y-4 p-6\">\n <div className=\"animate-spin h-8 w-8 border-2 border-blue-600 rounded-full border-t-transparent\"></div>\n <p className=\"text-gray-600\">Loading...</p>\n </div>\n );\n }\n };\n\n // Styling and button class based on visual type\n const buttonClass = \n `flex items-center justify-center font-bold rounded cursor-pointer ${\n buttonType === 'pill' ? 'px-4 py-2' : 'w-12 h-12'\n } bg-transparent OnairosConnect`;\n\n const buttonStyle = {\n flexDirection: textLayout === 'below' ? 'column' : 'row',\n backgroundColor: 'transparent',\n color: textColor,\n border: '1px solid transparent',\n };\n\n // Icon and text style based on the visualType\n const logoStyle = {\n width: '20px',\n height: '20px',\n marginRight: visualType === 'full' ? '12px' : '0',\n };\n\n const getText = () => {\n switch (loginType) {\n case 'signUp':\n return 'Sign Up with Onairos';\n case 'signOut':\n return 'Sign Out of Onairos';\n default:\n return 'Sign In with Onairos';\n }\n };\n\n return (\n <>\n <button\n className={buttonClass}\n onClick={openTerminal}\n style={buttonStyle}\n >\n {(visualType === 'full' || visualType === 'icon') && (\n <img\n src={login ? \"https://onairos.sirv.com/Images/OnairosWhite.png\" : \"https://onairos.sirv.com/Images/OnairosBlack.png\"}\n alt=\"Onairos Logo\"\n style={logoStyle}\n />\n )}\n {visualType !== 'icon' && (\n <span className={`${textColor === 'black' ? 'text-black' : 'text-white'} ${visualType === 'icon' ? 'sr-only' : ''} ${textLayout === 'right' ? 'ml-2' : textLayout === 'left' ? 'mr-2' : ''}`}>\n {getText()}\n </span>\n )}\n </button>\n\n {/* Modal with New Design */}\n {showOverlay && (\n <>\n {currentFlow === 'email' ? (\n // Special case for email - render directly without PageLayout wrapper\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647 }}>\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\n {/* Header */}\n <div className=\"relative px-6 pt-6 pb-4 flex-shrink-0\">\n <button\n onClick={handleCloseOverlay}\n className=\"absolute left-4 top-4 p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n <svg className=\"w-5 h-5 text-gray-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Email Content */}\n <div className=\"h-[min(85vh,700px)]\">\n <EmailAuth \n onSuccess={handleEmailAuthSuccess}\n testMode={testMode}\n />\n </div>\n </div>\n </div>\n ) : currentFlow === 'onboarding' ? (\n // Special case for onboarding - render directly without PageLayout wrapper\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647 }}>\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\n {/* Header */}\n <div className=\"relative px-6 pt-6 pb-4 flex-shrink-0\">\n <button\n onClick={() => setCurrentFlow('email')}\n className=\"absolute left-4 top-4 p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n <svg className=\"w-5 h-5 text-gray-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n </div>\n\n {/* Onboarding Content */}\n <UniversalOnboarding \n onComplete={handleOnboardingComplete}\n onBack={() => setCurrentFlow('email')}\n appIcon={appIcon || \"https://onairos.sirv.com/Images/OnairosBlack.png\"}\n appName={webpageName}\n username={userData?.email || userData?.username}\n testMode={testMode}\n priorityPlatform={priorityPlatform}\n />\n </div>\n </div>\n ) : currentFlow === 'dataRequest' ? (\n // Special case for dataRequest - render directly without PageLayout wrapper\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647 }}>\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\n {/* Header */}\n <div className=\"relative px-6 pt-6 pb-4 flex-shrink-0\">\n <button\n onClick={() => setCurrentFlow('loading')}\n className=\"absolute left-4 top-4 p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n <svg className=\"w-5 h-5 text-gray-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n </div>\n\n {/* DataRequest Content */}\n <DataRequest \n onComplete={handleDataRequestComplete}\n userEmail={userData?.email}\n requestData={requestData}\n appName={webpageName}\n autoFetch={autoFetch}\n testMode={testMode}\n appIcon={appIcon}\n connectedAccounts={userData?.connectedAccounts || {}}\n />\n </div>\n </div>\n ) : currentFlow === 'pin' ? (\n // Special case for pin - render directly without PageLayout wrapper\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647 }}>\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\n {/* Header */}\n <div className=\"relative px-6 pt-6 pb-4 flex-shrink-0\">\n <button\n onClick={() => setCurrentFlow('onboarding')}\n className=\"absolute left-4 top-4 p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n <svg className=\"w-5 h-5 text-gray-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n </div>\n\n {/* PinSetup Content - Must take remaining height */}\n <div className=\"flex-1 min-h-0\">\n <PinSetup \n onComplete={handlePinSetupComplete}\n onBack={() => setCurrentFlow('onboarding')}\n userEmail={userData?.email}\n />\n </div>\n </div>\n </div>\n ) : currentFlow === 'loading' ? (\n // Loading screen\n <LoadingScreen onComplete={handleLoadingComplete} />\n ) : (\n // All other flows use PageLayout wrapper\n <ModalPageLayout\n visible={showOverlay}\n onClose={handleCloseOverlay}\n showBackButton={currentFlow === 'training'}\n onBack={() => {\n if (currentFlow === 'email') setCurrentFlow('welcome');\n if (currentFlow === 'onboarding') setCurrentFlow('email');\n if (currentFlow === 'pin') setCurrentFlow('onboarding'); \n if (currentFlow === 'training') setCurrentFlow('pin');\n }}\n title={getFlowTitle()}\n subtitle={getFlowSubtitle()}\n icon={getFlowIcon()}\n centerContent={true}\n >\n {renderCurrentFlow()}\n </ModalPageLayout>\n )}\n </>\n )}\n </>\n );\n}\n\nexport default OnairosButton;","/**\r\n * Enhanced User Data Formatter for onComplete Callback\r\n * Provides structured, readable formatting of Onairos user data\r\n */\r\n\r\n/**\r\n * Formats user data for better readability in onComplete callback\r\n * @param {Object} result - The complete result object from data request\r\n * @returns {Object} Enhanced result with formatted user data display\r\n */\r\nexport function formatUserDataForDisplay(result) {\r\n if (!result) return result;\r\n\r\n const formatted = { ...result };\r\n \r\n // Create a structured summary of the user data\r\n const userDataSummary = {\r\n // Basic request information\r\n requestInfo: {\r\n timestamp: result.timestamp || new Date().toISOString(),\r\n appName: result.appName || 'Unknown App',\r\n userHash: result.userHash || 'Unknown User',\r\n testMode: result.testMode || false,\r\n dataTypesRequested: result.approvedData || []\r\n },\r\n \r\n // User authentication and profile data\r\n userProfile: {\r\n email: result.userData?.email || 'Not provided',\r\n userType: result.userData?.userType || 'Unknown',\r\n onboardingComplete: result.userData?.onboardingComplete || false,\r\n pinCreated: result.userData?.pinCreated || false,\r\n trainingComplete: result.userData?.trainingComplete || false,\r\n modelReady: result.userData?.modelReady || false\r\n },\r\n \r\n // Connected platforms/accounts\r\n connectedAccounts: formatConnectedAccounts(result.userData?.connectedAccounts || []),\r\n \r\n // API response data (personality, preferences, etc.)\r\n aiData: formatAIResponseData(result.apiResponse),\r\n \r\n // Success status and any errors\r\n status: {\r\n success: result.success || false,\r\n hasApiResponse: !!result.apiResponse,\r\n hasErrors: !!result.error || !!result.apiError\r\n }\r\n };\r\n\r\n // Add the formatted summary to the result\r\n formatted.userDataSummary = userDataSummary;\r\n \r\n // Create a pretty-printed version for console logging\r\n formatted.prettyPrint = createPrettyPrintVersion(userDataSummary);\r\n \r\n return formatted;\r\n}\r\n\r\n/**\r\n * Formats connected accounts data\r\n * @param {Array} accounts - Array of connected account objects\r\n * @returns {Object} Formatted accounts summary\r\n */\r\nfunction formatConnectedAccounts(accounts) {\r\n if (!Array.isArray(accounts) || accounts.length === 0) {\r\n return {\r\n count: 0,\r\n platforms: [],\r\n summary: 'No connected accounts'\r\n };\r\n }\r\n\r\n return {\r\n count: accounts.length,\r\n platforms: accounts.map(account => ({\r\n name: account.platform || account.name || 'Unknown Platform',\r\n status: account.status || 'Unknown',\r\n connectedAt: account.connectedAt || 'Unknown date',\r\n hasData: account.hasData || false\r\n })),\r\n summary: `${accounts.length} platform(s) connected: ${accounts.map(a => a.platform || a.name).join(', ')}`\r\n };\r\n}\r\n\r\n/**\r\n * Formats AI response data (personality scores, traits, etc.)\r\n * @param {Object} apiResponse - The API response containing AI data\r\n * @returns {Object} Formatted AI data summary\r\n */\r\nfunction formatAIResponseData(apiResponse) {\r\n if (!apiResponse) {\r\n return {\r\n available: false,\r\n summary: 'No AI data available'\r\n };\r\n }\r\n\r\n const aiData = {\r\n available: true,\r\n dataTypes: []\r\n };\r\n\r\n // Check for personality data\r\n if (apiResponse.InferenceResult?.traits || apiResponse.personalityDict || apiResponse.traits) {\r\n const personalityData = {\r\n type: 'personality',\r\n available: true\r\n };\r\n\r\n // If we have dictionary format, use it for better readability\r\n if (apiResponse.personalityDict) {\r\n personalityData.data = apiResponse.personalityDict;\r\n personalityData.summary = `Personality analysis with ${Object.keys(apiResponse.personalityDict).length} traits`;\r\n } else if (apiResponse.InferenceResult?.traits) {\r\n personalityData.data = apiResponse.InferenceResult.traits;\r\n personalityData.summary = `Personality scores array with ${apiResponse.InferenceResult.traits.length} values`;\r\n } else if (apiResponse.traits) {\r\n personalityData.data = apiResponse.traits;\r\n personalityData.summary = `Personality traits with ${Array.isArray(apiResponse.traits) ? apiResponse.traits.length : Object.keys(apiResponse.traits).length} items`;\r\n }\r\n\r\n aiData.dataTypes.push(personalityData);\r\n }\r\n\r\n // Check for preferences/traits data\r\n if (apiResponse.traitResult || apiResponse.traitDict) {\r\n const preferencesData = {\r\n type: 'preferences',\r\n available: true\r\n };\r\n\r\n if (apiResponse.traitDict) {\r\n preferencesData.data = apiResponse.traitDict;\r\n preferencesData.summary = `Preferences analysis with ${Object.keys(apiResponse.traitDict).length} categories`;\r\n } else if (apiResponse.traitResult) {\r\n preferencesData.data = apiResponse.traitResult;\r\n preferencesData.summary = `Trait results with ${Array.isArray(apiResponse.traitResult) ? apiResponse.traitResult.length : Object.keys(apiResponse.traitResult).length} items`;\r\n }\r\n\r\n aiData.dataTypes.push(preferencesData);\r\n }\r\n\r\n // Check for basic info/output\r\n if (apiResponse.InferenceResult?.output || apiResponse.output) {\r\n aiData.dataTypes.push({\r\n type: 'basic_info',\r\n available: true,\r\n data: apiResponse.InferenceResult?.output || apiResponse.output,\r\n summary: 'Basic user information and insights'\r\n });\r\n }\r\n\r\n // Create overall summary\r\n aiData.summary = aiData.dataTypes.length > 0 \r\n ? `AI analysis complete with ${aiData.dataTypes.length} data type(s): ${aiData.dataTypes.map(d => d.type).join(', ')}`\r\n : 'AI data structure present but no recognized data types found';\r\n\r\n return aiData;\r\n}\r\n\r\n/**\r\n * Creates a pretty-printed version for console logging\r\n * @param {Object} userDataSummary - The formatted user data summary\r\n * @returns {string} Pretty-printed string for console output\r\n */\r\nfunction createPrettyPrintVersion(userDataSummary) {\r\n const lines = [];\r\n \r\n lines.push('🎉 ONAIROS USER DATA SUMMARY');\r\n lines.push('=' .repeat(50));\r\n \r\n // Request Info\r\n lines.push('\\n📋 REQUEST INFORMATION:');\r\n lines.push(` App: ${userDataSummary.requestInfo.appName}`);\r\n lines.push(` User: ${userDataSummary.requestInfo.userHash}`);\r\n lines.push(` Mode: ${userDataSummary.requestInfo.testMode ? 'Test' : 'Production'}`);\r\n lines.push(` Data Types: ${userDataSummary.requestInfo.dataTypesRequested.join(', ') || 'None'}`);\r\n lines.push(` Timestamp: ${new Date(userDataSummary.requestInfo.timestamp).toLocaleString()}`);\r\n \r\n // User Profile\r\n lines.push('\\n👤 USER PROFILE:');\r\n lines.push(` Email: ${userDataSummary.userProfile.email}`);\r\n lines.push(` Type: ${userDataSummary.userProfile.userType}`);\r\n lines.push(` Onboarding: ${userDataSummary.userProfile.onboardingComplete ? '✅' : '❌'}`);\r\n lines.push(` PIN Setup: ${userDataSummary.userProfile.pinCreated ? '✅' : '❌'}`);\r\n lines.push(` Training: ${userDataSummary.userProfile.trainingComplete ? '✅' : '❌'}`);\r\n lines.push(` Model Ready: ${userDataSummary.userProfile.modelReady ? '✅' : '❌'}`);\r\n \r\n // Connected Accounts\r\n lines.push('\\n🔗 CONNECTED ACCOUNTS:');\r\n lines.push(` ${userDataSummary.connectedAccounts.summary}`);\r\n if (userDataSummary.connectedAccounts.platforms.length > 0) {\r\n userDataSummary.connectedAccounts.platforms.forEach(platform => {\r\n lines.push(` • ${platform.name}: ${platform.status} ${platform.hasData ? '(has data)' : '(no data)'}`);\r\n });\r\n }\r\n \r\n // AI Data\r\n lines.push('\\n🤖 AI ANALYSIS DATA:');\r\n lines.push(` ${userDataSummary.aiData.summary}`);\r\n if (userDataSummary.aiData.dataTypes.length > 0) {\r\n userDataSummary.aiData.dataTypes.forEach(dataType => {\r\n lines.push(` • ${dataType.type.toUpperCase()}: ${dataType.summary}`);\r\n });\r\n }\r\n \r\n // Status\r\n lines.push('\\n✅ STATUS:');\r\n lines.push(` Success: ${userDataSummary.status.success ? '✅' : '❌'}`);\r\n lines.push(` API Response: ${userDataSummary.status.hasApiResponse ? '✅' : '❌'}`);\r\n lines.push(` Errors: ${userDataSummary.status.hasErrors ? '❌ Yes' : '✅ None'}`);\r\n \r\n lines.push('\\n' + '=' .repeat(50));\r\n \r\n return lines.join('\\n');\r\n}\r\n\r\n/**\r\n * Console logging helper that prints formatted user data\r\n * @param {Object} result - The result object from onComplete\r\n */\r\nexport function logFormattedUserData(result) {\r\n const formatted = formatUserDataForDisplay(result);\r\n \r\n console.log('\\n' + formatted.prettyPrint + '\\n');\r\n \r\n // Also log the structured data for programmatic access\r\n console.log('📊 Structured User Data Summary:', formatted.userDataSummary);\r\n \r\n return formatted;\r\n}\r\n\r\nexport default {\r\n formatUserDataForDisplay,\r\n logFormattedUserData\r\n};\r\n"],"names":["WelcomeScreen","_ref","onContinue","onClose","useEffect","script","document","createElement","src","async","head","appendChild","existingScript","querySelector","removeChild","React","className","style","height","alt","onClick","fill","stroke","viewBox","strokeLinecap","strokeLinejoin","strokeWidth","d","COLORS","btnGradStart","btnGradEnd","btnLabel","btnBorder","iconCircleGradientStart","iconCircleGradientEnd","background","backgroundSecondary","textPrimary","textSecondary","textMuted","border","borderLight","success","error","warning","info","hover","pressed","focus","IconCircle","size","children","concat","width","borderRadius","fontSize","color","backgroundColor","_ref2","label","iconRight","loading","disabled","testId","textStyle","centered","props","_objectWithoutProperties","_excluded","setPressed","useState","buttonStyle","_objectSpread","position","overflow","minWidth","maxWidth","margin","cursor","opacity","boxShadow","transition","pressedOverlayStyle","top","left","right","bottom","labelStyle","fontFamily","fontWeight","textAlign","_extends","onMouseDown","handleMouseDown","onMouseUp","handleMouseUp","onMouseLeave","handleMouseLeave","display","justifyContent","alignItems","API_CONFIG","DEVELOPMENT_URL","PRODUCTION_URL","IS_DEVELOPMENT","window","location","hostname","port","getBaseUrl","this","EMAIL_VERIFY","EMAIL_VERIFY_CONFIRM","getEmailVerifyUrl","getEmailVerifyConfirmUrl","getDebugInfo","environment","baseUrl","emailVerifyUrl","emailVerifyConfirmUrl","console","log","EmailAuth","onSuccess","testMode","email","setEmail","code","setCode","step","setStep","isLoading","setIsLoading","setError","setTimeout","firstInput","handleEmailSubmit","e","preventDefault","test","validateEmail","doFetchWithRetry","url","options","lastErr","attempts","arguments","length","undefined","i","res","fetch","ok","body","json","Error","status","_unused","err","Promise","r","apiKey","onairosApiKey","apiUrl","substring","headers","response","method","JSON","stringify","trim","toLowerCase","data","handleGoogleAuth","_localStorage$getItem","sdkConfig","enableHealthMonitoring","enableAutoRefresh","enableConnectionValidation","username","localStorage","getItem","authorizeUrl","params","URLSearchParams","sdk_type","return_url","origin","fullUrl","toString","popup","open","checkInterval","setInterval","closed","clearInterval","connectedAccounts","Google","handleCodeSubmit","_unused2","simulatedResponse","verified","token","Date","now","userName","split","isNewUser","userState","flowType","user","creationDate","toISOString","lastLogin","enochInstructions","recommendedFlow","nextActionTitle","existingUser","accountInfo","adminMode","userCreated","accountDetails","createdAt","testAccount","errorMessage","attemptsRemaining","_data$user","existingUserData","type","value","onChange","target","placeholder","required","lineHeight","Array","from","_","index","key","maxLength","newCode","join","_e$target$parentEleme","nextInput","parentElement","onKeyDown","_e$target$parentEleme2","prevInput","borderColor","PrimaryButton","flex","minHeight","Check","detectOnairosExtension","resolve","onairos","isOnairos","resolved","handleOnairosReady","addEventListener","once","removeEventListener","openExtensionInstallPage","source","storeUrl","warn","href","LLM_URLS","chatgpt","claude","gemini","grok","getUserInfoFromStorage","_userData","_userData2","_userData3","_userData4","_userData5","_userData6","_userData7","_userData8","_userData9","_userData0","_userData1","_userData10","_userData11","_userData12","_userData13","userDataStr","jwtToken","legacyToken","userDataSDK","userData","parse","userInfo","userId","sessionToken","onboardingComplete","pinCreated","extractedAt","message","platform","onInstallClick","platformName","platformUrl","rel","handleInstallClick","handleDirectVisit","onConnectionChange","showInstallPrompt","setShowInstallPrompt","currentPlatform","setCurrentPlatform","isConnecting","setIsConnecting","handleLLMConnect","useCallback","onError","storedUserInfo","connectorVersion","timestamp","onExtensionMissing","URL","searchParams","set","encodeURIComponent","finalUrl","openLLMWithExtensionCheck","missingPlatform","handleLLMDisconnect","handleCloseInstallPrompt","handleExtensionInstall","checkExtensionStatus","contextValue","connectToLLM","disconnectFromLLM","map","child","llmConnectorManager","ExtensionInstallPrompt","chatgptIcon","claudeIcon","geminiIcon","grokIcon","process","env","REACT_APP_ONAIROS_API_KEY","REACT_APP_ONAIROS_BASE_URL","sdkType","fadeSlideInKeyframes","UniversalOnboarding","_JSON$parse2","onComplete","lottieRef","useRef","lastFrameRef","rafRef","setConnectedAccounts","connectingPlatform","setConnectingPlatform","selected","setSelected","currentPage","setCurrentPage","touchStartX","touchDeltaX","vh","setVh","innerHeight","onResize","removeItem","personaSide","Math","min","SLOT","max","floor","ACTIVE_SCALE","igGradId","useId","Brand","ChatGPT","objectFit","Claude","Gemini","Grok","Instagram","id","cx","cy","offset","stopColor","YouTube","Reddit","LinkedIn","x","y","rx","Twitter","aiLinks","descriptions","allPlatforms","name","connector","icon","directLink","platforms","page","slice","p","s","handleSwitch","find","platformKey","connectedPlatform","errorPlatform","plat","_JSON$parse","session","candidates","youtube","linkedin","reddit","pinterest","instagram","github","facebook","gmail","oauthUrl","k","touched","it","close","_unused3","_unused4","connectToPlatform","connectedCount","Object","values","filter","Boolean","current","totalFrames","personaAnim","progress","start","startTs","performance","t","eased","frame","goToAndStop","requestAnimationFrame","cancelAnimationFrame","LLMConnectorManager","connected","charAt","toUpperCase","displayName","dangerouslySetInnerHTML","__html","maxHeight","gridTemplateRows","transform","zIndex","pointerEvents","Lottie","animationData","autoplay","loop","onTouchStart","touches","clientX","onTouchMove","onTouchEnd","dx","gridAutoFlow","gridTemplateColumns","columnGap","justifyItems","paddingInline","idx","on","isSel","shift","animation","title","n","role","entries","v","_ref3","totalConnections","xmlns","PinSetup","onBack","userEmail","pin","setPin","pinRequirements","setPinRequirements","uppercase","number","allRequirementsMet","handleSubmit","dataTypes","description","tooltip","privacyLink","DataTypeToggle","dataType","isEnabled","onToggle","isLast","iconName","iconProps","getIconComponent","handleToggle","fillRule","clipRule","autoFetch","appName","formatResponse","responseFormat","selectedData","setSelectedData","basic","personality","preferences","isLoadingApi","setIsLoadingApi","apiError","setApiError","handleDataToggle","dataId","enabled","dt","prev","selectedCount","userHash","hash","str","charCodeAt","abs","generateUserHash","approvedData","_ref4","mapDataTypesToConfirmations","confirmations","currentDate","dataTypeMapping","forEach","push","date","apiEndpoint","baseResult","simulatedApiData","personalityScores","openness","conscientiousness","extraversion","agreeableness","neuroticism","insights","dataProcessed","result","apiResponse","simulated","requestBody","apiData","errorResult","cancelled","TrainingComponent","_steps$currentStep","_steps$currentStep2","_steps$currentStep3","_steps$currentStep4","_steps$currentStep5","currentStep","setCurrentStep","setProgress","isComplete","setIsComplete","steps","duration","interval","stepTimeout","stepDuration","stepProgress","newProgress","completionDelay","trainingComplete","simulatedTraining","clearTimeout","round","LoadingScreen","dotCount","setDotCount","loadingStates","stateInterval","nextStep","dotInterval","currentState","aspectRatio","rainAnim","repeat","PERSONALITY_TYPES","TRAIT_CATEGORIES","formatOnairosResponse","_apiResponse$Inferenc","includeDictionary","includeArray","formatted","InferenceResult","traits","scores","_apiResponse$Inferenc2","isArray","personalityDict","_formatted$InferenceR","traitResult","traitDict","category","PageLayout","subtitle","showHeader","showCloseButton","showBackButton","contentClassName","centerContent","layoutStyle","flexDirection","headerStyle","padding","contentStyle","titleStyle","subtitleStyle","ModalPageLayout","visible","onBackdropClick","backdropStyle","modalStyle","pageLayoutProps","_excluded2","backdropStyles","willChange","modalStyles","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius","currentTarget","OnairosButton","requestData","webpageName","inferenceData","proofMode","textLayout","textColor","login","buttonType","loginReturn","loginType","visualType","appIcon","enableTraining","priorityPlatform","showOverlay","setShowOverlay","currentFlow","setCurrentFlow","setUserData","checkExistingSession","savedUser","handleCloseOverlay","handleWelcomeContinue","handleEmailAuthSuccess","authData","hasAccountInfo","finalDecision","reasoning","existingUserFalse","flowTypeOnboarding","noAccountInfo","newUserData","setItem","handleOnboardingComplete","onboardingData","updatedUserData","handlePinSetupComplete","pinData","handleTrainingComplete","trainingResult","trainingCompleted","handleDataRequestComplete","requestResult","lastDataRequest","formattedResult","_formattedResult$apiR","logFormattedUserData","require","enhancedResult","buttonClass","logoStyle","marginRight","getText","DataRequest","handleLoadingComplete","getFlowTitle","getFlowSubtitle","getFlowIcon","renderCurrentFlow","formatUserDataForDisplay","_result$userData","_result$userData2","_result$userData3","_result$userData4","_result$userData5","_result$userData6","_result$userData7","userDataSummary","requestInfo","dataTypesRequested","userProfile","userType","modelReady","formatConnectedAccounts","aiData","formatAIResponseData","hasApiResponse","hasErrors","prettyPrint","lines","toLocaleString","summary","hasData","createPrettyPrintVersion","accounts","count","account","connectedAt","a","_apiResponse$Inferenc3","available","personalityData","keys","preferencesData","_apiResponse$Inferenc4","output"],"sourceRoot":""}
1
+ {"version":3,"file":"575.js","mappings":"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","sources":["webpack://OnairosLaravel/./src/components/WelcomeScreen.jsx","webpack://OnairosLaravel/./src/theme/colors.js","webpack://OnairosLaravel/./src/components/ui/PrimaryButton.jsx","webpack://OnairosLaravel/./src/config/api-config.js","webpack://OnairosLaravel/./src/components/EmailAuth.js","webpack://OnairosLaravel/./src/utils/extensionDetection.js","webpack://OnairosLaravel/./src/components/ExtensionInstallPrompt.jsx","webpack://OnairosLaravel/./src/components/LLMConnectorManager.jsx","webpack://OnairosLaravel/./src/components/UniversalOnboarding.jsx","webpack://OnairosLaravel/./src/components/PinSetup.js","webpack://OnairosLaravel/./src/components/DataRequest.js","webpack://OnairosLaravel/./src/components/TrainingComponent.jsx","webpack://OnairosLaravel/./src/components/LoadingScreen.jsx","webpack://OnairosLaravel/./src/utils/responseFormatter.js","webpack://OnairosLaravel/./src/components/ui/PageLayout.jsx","webpack://OnairosLaravel/./src/onairosButton.jsx","webpack://OnairosLaravel/./src/utils/userDataFormatter.js"],"sourcesContent":["import React, { useEffect } from 'react';\r\nimport { COLORS } from '../theme/colors.js';\r\n\r\nexport default function WelcomeScreen({ onContinue, onClose }) {\r\n // Load Sirv script for responsive images\r\n useEffect(() => {\r\n const script = document.createElement('script');\r\n script.src = 'https://scripts.sirv.com/sirvjs/v3/sirv.js';\r\n script.async = true;\r\n document.head.appendChild(script);\r\n \r\n return () => {\r\n const existingScript = document.querySelector('script[src=\"https://scripts.sirv.com/sirvjs/v3/sirv.js\"]');\r\n if (existingScript) {\r\n document.head.removeChild(existingScript);\r\n }\r\n };\r\n }, []);\r\n\r\n return (\r\n <div className=\"w-full flex flex-col\" style={{ height: '100%' }}>\r\n {/* Content - Flexible center area */}\r\n <div className=\"px-6 text-center flex-1 flex flex-col justify-center\">\r\n {/* Logo */}\r\n <div className=\"mb-8 flex justify-center\">\r\n <div className=\"w-20 h-20 flex items-center justify-center\">\r\n <img \r\n className=\"Sirv w-full h-full object-contain\" \r\n data-src=\"https://anushkasirv.sirv.com/OnairosBlack.png\" \r\n alt=\"Onairos Logo\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Welcome Text */}\r\n <p className=\"text-gray-500 text-sm mb-2\">Welcome to</p>\r\n\r\n {/* Main Title */}\r\n <h1 className=\"text-4xl font-bold text-gray-900 mb-6 text-balance\">Onairos</h1>\r\n\r\n {/* Description */}\r\n <p className=\"text-gray-600 text-base leading-relaxed mb-12 text-pretty px-2\">\r\n OnairOS personalizes your digital experience on every app so you can just enjoy being you!\r\n </p>\r\n </div>\r\n\r\n {/* Get Started Button - Fixed at bottom */}\r\n <div className=\"px-6 pb-8 flex-shrink-0\">\r\n <button\r\n className=\"w-full bg-gray-900 hover:bg-gray-800 text-white rounded-full py-4 text-base font-medium flex items-center justify-center gap-2 transition-colors\"\r\n onClick={onContinue}\r\n >\r\n Get Started\r\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","// Theme colors for Onairos SDK - derived from mobile design\r\nexport const COLORS = {\r\n // Button gradient colors\r\n btnGradStart: '#1A1A1A',\r\n btnGradEnd: '#000000',\r\n \r\n // Button text and icon colors\r\n btnLabel: '#FFFFFF',\r\n btnBorder: 'rgba(0, 0, 0, 0.2)',\r\n \r\n // Icon circle gradient colors\r\n iconCircleGradientStart: '#333333',\r\n iconCircleGradientEnd: '#1A1A1A',\r\n \r\n // Background colors\r\n background: '#FFFFFF',\r\n backgroundSecondary: '#F8F9FA',\r\n \r\n // Text colors\r\n textPrimary: '#1A1A1A',\r\n textSecondary: '#6B7280',\r\n textMuted: '#9CA3AF',\r\n \r\n // Border colors\r\n border: '#E5E7EB',\r\n borderLight: '#F3F4F6',\r\n \r\n // Status colors\r\n success: '#10B981',\r\n error: '#EF4444',\r\n warning: '#F59E0B',\r\n info: '#3B82F6',\r\n \r\n // Interactive states\r\n hover: 'rgba(0, 0, 0, 0.05)',\r\n pressed: 'rgba(0, 0, 0, 0.1)',\r\n focus: 'rgba(59, 130, 246, 0.1)',\r\n};\r\n\r\nexport default COLORS; ","import React, { useState } from 'react';\r\nimport { COLORS } from '../../theme/colors.js';\r\n\r\n// Icon Circle component matching the React Native version\r\nconst IconCircle = ({ \r\n size = 40, \r\n children,\r\n className = ''\r\n}) => {\r\n return (\r\n <div \r\n className={`relative flex items-center justify-center border border-black border-opacity-25 ${className}`}\r\n style={{\r\n width: size,\r\n height: size,\r\n borderRadius: size / 2,\r\n background: `linear-gradient(to bottom, ${COLORS.iconCircleGradientStart}, ${COLORS.iconCircleGradientEnd})`\r\n }}\r\n >\r\n {children || (\r\n <span \r\n className=\"font-semibold opacity-95\"\r\n style={{\r\n fontSize: '20px',\r\n color: COLORS.btnLabel,\r\n backgroundColor: 'transparent'\r\n }}\r\n >\r\n →\r\n </span>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\n// Primary Button component matching the React Native design\r\nconst PrimaryButton = ({\r\n label = \"Get Started\",\r\n onClick,\r\n iconRight,\r\n loading = false,\r\n disabled = false,\r\n testId,\r\n className = '',\r\n style = {},\r\n textStyle = {},\r\n centered = false,\r\n ...props\r\n}) => {\r\n const [pressed, setPressed] = useState(false);\r\n\r\n const handleMouseDown = () => setPressed(true);\r\n const handleMouseUp = () => setPressed(false);\r\n const handleMouseLeave = () => setPressed(false);\r\n\r\n const buttonStyle = {\r\n height: '48px',\r\n borderRadius: '100px',\r\n border: `1px solid ${COLORS.btnBorder}`,\r\n background: `linear-gradient(to bottom, ${COLORS.btnGradStart}, ${COLORS.btnGradEnd})`,\r\n position: 'relative',\r\n overflow: 'hidden',\r\n width: centered ? 'auto' : '100%',\r\n minWidth: centered ? '250px' : 'auto',\r\n maxWidth: centered ? '350px' : 'none',\r\n margin: centered ? '0 auto' : '0',\r\n cursor: disabled ? 'not-allowed' : 'pointer',\r\n opacity: disabled ? 0.65 : 1,\r\n boxShadow: disabled ? 'none' : '20px 30px 40px rgba(0,0,0,0.10)',\r\n transition: 'all 0.2s ease',\r\n ...style\r\n };\r\n\r\n const pressedOverlayStyle = {\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n backgroundColor: 'rgba(0,0,0,0.1)',\r\n borderRadius: '100px',\r\n opacity: pressed ? 1 : 0,\r\n transition: 'opacity 0.1s ease'\r\n };\r\n\r\n const textContainerStyle = {\r\n position: 'absolute',\r\n left: 0,\r\n right: 0,\r\n top: 0,\r\n bottom: 0,\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n backgroundColor: 'transparent'\r\n };\r\n\r\n const iconPositionStyle = {\r\n position: 'absolute',\r\n right: '4px',\r\n top: '4px',\r\n bottom: '4px',\r\n width: '40px',\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center',\r\n backgroundColor: 'transparent'\r\n };\r\n\r\n const labelStyle = {\r\n fontFamily: 'Inter, system-ui, sans-serif',\r\n fontWeight: '600',\r\n fontSize: '16px',\r\n color: COLORS.btnLabel,\r\n textAlign: 'center',\r\n backgroundColor: 'transparent',\r\n ...textStyle\r\n };\r\n\r\n return (\r\n <button\r\n className={`relative ${className}`}\r\n style={buttonStyle}\r\n onClick={onClick}\r\n onMouseDown={handleMouseDown}\r\n onMouseUp={handleMouseUp}\r\n onMouseLeave={handleMouseLeave}\r\n disabled={disabled || loading}\r\n data-testid={testId}\r\n aria-label={label}\r\n {...props}\r\n >\r\n {/* Pressed state overlay */}\r\n <div style={pressedOverlayStyle} />\r\n\r\n {/* Centered text container */}\r\n <div style={textContainerStyle}>\r\n {loading ? (\r\n <div \r\n className=\"animate-spin rounded-full border-2 border-white border-t-transparent\"\r\n style={{ width: '20px', height: '20px' }}\r\n />\r\n ) : (\r\n <span style={labelStyle}>{label}</span>\r\n )}\r\n </div>\r\n\r\n {/* Icon in fixed position on right */}\r\n <div style={iconPositionStyle}>\r\n {!loading && (iconRight || <IconCircle />)}\r\n </div>\r\n </button>\r\n );\r\n};\r\n\r\nexport { IconCircle };\r\nexport default PrimaryButton; ","/**\r\n * API Configuration for Onairos\r\n * Centralized configuration for API endpoints\r\n */\r\n\r\n// Environment detection\r\nconst isDevelopment = window.location.hostname === 'localhost' || \r\n window.location.hostname === '127.0.0.1' ||\r\n window.location.port === '3000' ||\r\n window.location.port === '8080';\r\n\r\n// API Configuration\r\nexport const API_CONFIG = {\r\n // Base URLs\r\n DEVELOPMENT_URL: 'http://localhost:8080',\r\n PRODUCTION_URL: 'https://api2.onairos.uk',\r\n \r\n // Current environment\r\n IS_DEVELOPMENT: isDevelopment,\r\n \r\n // Get base URL based on environment\r\n getBaseUrl() {\r\n return this.IS_DEVELOPMENT ? this.DEVELOPMENT_URL : this.PRODUCTION_URL;\r\n },\r\n \r\n // Email verification endpoints\r\n EMAIL_VERIFY: '/email/verify',\r\n EMAIL_VERIFY_CONFIRM: '/email/verify/confirm',\r\n \r\n // Get full URLs\r\n getEmailVerifyUrl() {\r\n return `${this.getBaseUrl()}${this.EMAIL_VERIFY}`;\r\n },\r\n \r\n getEmailVerifyConfirmUrl() {\r\n return `${this.getBaseUrl()}${this.EMAIL_VERIFY_CONFIRM}`;\r\n },\r\n \r\n // Debug info\r\n getDebugInfo() {\r\n return {\r\n environment: this.IS_DEVELOPMENT ? 'development' : 'production',\r\n baseUrl: this.getBaseUrl(),\r\n hostname: window.location.hostname,\r\n port: window.location.port,\r\n emailVerifyUrl: this.getEmailVerifyUrl(),\r\n emailVerifyConfirmUrl: this.getEmailVerifyConfirmUrl()\r\n };\r\n }\r\n};\r\n\r\n// Log configuration on load\r\nconsole.log('🔧 API Configuration loaded:', API_CONFIG.getDebugInfo());\r\n\r\nexport default API_CONFIG;\r\n\r\n","import React, { useState, useEffect } from 'react';\nimport { Mail, ArrowRight, Check } from 'lucide-react';\nimport PrimaryButton from './ui/PrimaryButton.jsx';\nimport { COLORS } from '../theme/colors.js';\nimport { API_CONFIG } from '../config/api-config.js';\n\nexport default function EmailAuth({ onSuccess, testMode = false }) {\n // Component identification\n console.log('📧 EmailAuth (onairos/src/components) initialized');\n console.log('🔧 API Config:', API_CONFIG.getDebugInfo());\n console.log('🧪 Test Mode:', testMode);\n \n const [email, setEmail] = useState('');\n const [code, setCode] = useState('');\n const [step, setStep] = useState('email'); // 'email' | 'code' | 'success'\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState('');\n\n // Auto-focus first PIN input when code step loads\n useEffect(() => {\n if (step === 'code') {\n // Small delay to ensure DOM is ready\n setTimeout(() => {\n const firstInput = document.querySelector('input[maxLength=\"1\"]');\n if (firstInput) {\n firstInput.focus();\n }\n }, 100);\n }\n }, [step]);\n\n const validateEmail = (email) => {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n };\n\n const handleEmailSubmit = async (e) => {\n e.preventDefault();\n setError('');\n\n if (!validateEmail(email)) {\n setError('Please enter a valid email address');\n return;\n }\n\n setIsLoading(true);\n\n try {\n const doFetchWithRetry = async (url, options, attempts = 3) => {\n let lastErr;\n for (let i = 0; i < attempts; i++) {\n try {\n const res = await fetch(url, options);\n if (!res.ok) {\n // Capture response body for better diagnostics\n try {\n const body = await res.json();\n lastErr = new Error(body?.error || `HTTP ${res.status}`);\n } catch {\n lastErr = new Error(`HTTP ${res.status}`);\n }\n } else {\n return res;\n }\n } catch (err) {\n lastErr = err;\n }\n // backoff: 400ms, 800ms\n await new Promise(r => setTimeout(r, 400 * (i + 1)));\n }\n throw lastErr || new Error('Network error');\n };\n\n if (testMode) {\n // Test mode: Skip API call completely, simulate instant success\n console.log('🧪 Test mode: Simulating email verification request for:', email);\n setTimeout(() => {\n setStep('code');\n setIsLoading(false);\n console.log('🧪 Test mode: Email verification simulated successfully');\n }, 800); // Shorter delay for faster testing\n } else {\n // Production mode: Use proper email verification API from schema\n const apiKey = window.onairosApiKey || 'test-key';\n const apiUrl = API_CONFIG.getEmailVerifyUrl();\n \n console.log('🚀 LIVE API CALL - Email Request');\n console.log('📋 API Key:', apiKey ? `${apiKey.substring(0, 8)}...` : 'NOT SET');\n console.log('🌐 URL:', apiUrl);\n console.log('📧 Email:', email);\n \n const headers = {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n // Keep Authorization for backwards compatibility\n 'Authorization': `Bearer ${apiKey}`\n };\n\n \n const response = await doFetchWithRetry(apiUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({ \n email: (email || '').trim().toLowerCase()\n }),\n });\n\n if (!response.ok) {\n throw new Error('Failed to send verification code');\n }\n\n const data = await response.json();\n if (!data.success) {\n throw new Error(data.error || 'Failed to send verification code');\n }\n\n console.log('📧 Email request response:', data);\n\n setStep('code');\n setIsLoading(false);\n }\n } catch (error) {\n console.error('Email request error:', error);\n setError('Couldn’t send code. Please try again.');\n setIsLoading(false);\n }\n };\n\n const handleGoogleAuth = async () => {\n try {\n // Use the same Google OAuth logic as UniversalOnboarding\n const sdkConfig = {\n baseUrl: 'https://api2.onairos.uk',\n apiKey: window.onairosApiKey || 'test-key',\n enableHealthMonitoring: true,\n enableAutoRefresh: true,\n enableConnectionValidation: true\n };\n\n const username = localStorage.getItem('username') || localStorage.getItem('onairosUser')?.email || 'user@example.com';\n \n const authorizeUrl = `${sdkConfig.baseUrl}/gmail/authorize`;\n const params = new URLSearchParams({\n username: username,\n sdk_type: 'web',\n return_url: window.location.origin + '/oauth-callback.html'\n });\n\n const fullUrl = `${authorizeUrl}?${params.toString()}`;\n console.log('🔗 Starting Google OAuth from email flow...');\n console.log('📋 Google OAuth URL:', fullUrl);\n\n // Open popup for OAuth\n const popup = window.open(\n fullUrl,\n 'google_oauth',\n 'width=500,height=600,scrollbars=yes,resizable=yes'\n );\n\n if (!popup) {\n throw new Error('Popup blocked. Please allow popups for this site.');\n }\n\n // Monitor popup for completion\n const checkInterval = setInterval(() => {\n if (popup.closed) {\n clearInterval(checkInterval);\n console.log('✅ Google OAuth popup closed');\n // Simulate successful OAuth for now\n onSuccess({ \n email: 'user@gmail.com', \n method: 'google',\n connectedAccounts: { Google: true }\n });\n }\n }, 1000);\n\n } catch (error) {\n console.error('❌ Google OAuth failed:', error);\n setError('Google authentication failed. Please try again.');\n }\n };\n\n const handleCodeSubmit = async (e) => {\n e.preventDefault();\n setError('');\n setIsLoading(true);\n\n try {\n const doFetchWithRetry = async (url, options, attempts = 3) => {\n let lastErr;\n for (let i = 0; i < attempts; i++) {\n try {\n const res = await fetch(url, options);\n if (!res.ok) {\n try {\n const body = await res.json();\n lastErr = new Error(body?.error || `HTTP ${res.status}`);\n } catch {\n lastErr = new Error(`HTTP ${res.status}`);\n }\n } else {\n return res;\n }\n } catch (err) {\n lastErr = err;\n }\n await new Promise(r => setTimeout(r, 400 * (i + 1)));\n }\n throw lastErr || new Error('Network error');\n };\n\n if (testMode) {\n // Test mode: Skip API call completely, simulate verification\n console.log('🧪 Test mode: Simulating code verification for:', email, 'with code:', code);\n \n if (code === '123456' || code.length === 6) {\n setStep('success');\n setTimeout(() => {\n // Simulate new user for design testing using new response format\n const simulatedResponse = { \n email, \n verified: true, \n token: 'test-token-' + Date.now(),\n userName: email.split('@')[0],\n // New response format\n isNewUser: true,\n userState: 'new',\n flowType: 'onboarding',\n user: {\n userName: email.split('@')[0],\n email: email,\n verified: true,\n creationDate: new Date().toISOString(),\n lastLogin: new Date().toISOString()\n },\n enochInstructions: {\n recommendedFlow: 'onboarding',\n nextActionTitle: 'Get Started'\n },\n // Legacy fields for backward compatibility\n existingUser: false,\n accountInfo: null,\n adminMode: false,\n userCreated: true,\n accountDetails: {\n email: email,\n createdAt: new Date().toISOString(),\n testAccount: true\n }\n };\n console.log('🧪 Test mode: Simulated verification successful, user data:', simulatedResponse);\n onSuccess(simulatedResponse);\n }, 600); // Faster for design testing\n } else {\n setError('Invalid code. Use any 6-digit code (e.g., 123456) for testing.');\n setIsLoading(false);\n }\n } else {\n // Production mode: Use real email verification API from schema\n const apiKey = window.onairosApiKey || 'test-key';\n const apiUrl = API_CONFIG.getEmailVerifyConfirmUrl();\n \n console.log('🚀 LIVE API CALL - Code Verification');\n console.log('📋 API Key:', apiKey ? `${apiKey.substring(0, 8)}...` : 'NOT SET');\n console.log('🌐 URL:', apiUrl);\n console.log('📧 Email:', email);\n console.log('🔢 Code:', code);\n \n const headers = {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'Authorization': `Bearer ${apiKey}`\n };\n \n const response = await doFetchWithRetry(apiUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({ \n email: (email || '').trim().toLowerCase(), \n code \n }),\n });\n\n if (!response.ok) {\n throw new Error('Invalid verification code');\n }\n\n const data = await response.json();\n \n if (!data.success) {\n // Handle error with attempts remaining if available\n const errorMessage = data.error || 'Verification failed';\n if (data.attemptsRemaining !== undefined) {\n throw new Error(`${errorMessage} (${data.attemptsRemaining} attempts remaining)`);\n } else {\n throw new Error(errorMessage);\n }\n }\n\n console.log('📧 Email verification response:', data);\n\n setStep('success');\n setTimeout(() => {\n // Pass complete API response using new format\n onSuccess({ \n email, \n verified: true, \n token: data.token,\n userName: data.userName || data.user?.userName,\n // New response format fields\n isNewUser: data.isNewUser,\n userState: data.userState,\n flowType: data.flowType,\n user: data.user,\n existingUserData: data.existingUserData,\n enochInstructions: data.enochInstructions,\n // Legacy fields for backward compatibility\n existingUser: !data.isNewUser,\n accountInfo: data.existingUserData,\n adminMode: data.adminMode,\n userCreated: data.userCreated,\n accountDetails: data.accountDetails || data.user\n });\n }, 1000);\n }\n } catch (error) {\n console.error('Email verification error:', error);\n setError('Invalid code. Please try again.');\n setIsLoading(false);\n }\n };\n\n const renderEmailStep = () => (\n <div className=\"w-full flex flex-col\" style={{ height: '100%' }}>\n {/* Content - Flexible center area */}\n <div className=\"px-12 pt-16 pb-8 text-center flex-1 flex flex-col\">\n <div className=\"mb-8\">\n <h1 className=\"text-2xl font-bold text-gray-900 mb-2 text-balance leading-tight\">\n Use pre-existing Persona or create a new one in seconds\n </h1>\n <p className=\"text-gray-600 text-base\">Sign in or create an account</p>\n </div>\n\n <div className=\"mb-6\">\n <input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Enter your email\"\n className=\"w-full max-w-sm mx-auto px-4 py-4 text-base bg-gray-50 border-0 rounded-xl placeholder:text-gray-400 focus:bg-white focus:ring-2 focus:ring-gray-200 outline-none transition-all duration-200\"\n style={{ \n fontFamily: 'Inter, system-ui, sans-serif'\n }}\n required\n />\n </div>\n\n <div className=\"mb-6 text-center\">\n <span className=\"text-gray-500 text-sm\">Or</span>\n </div>\n\n <div className=\"mb-8\">\n <button\n type=\"button\"\n className=\"w-full max-w-sm mx-auto py-4 text-base font-medium rounded-xl border border-gray-200 hover:bg-gray-50 flex items-center justify-center gap-3 bg-transparent transition-colors\"\n style={{ \n fontFamily: 'Inter, system-ui, sans-serif'\n }}\n onClick={handleGoogleAuth}\n >\n <svg className=\"w-5 h-5\" viewBox=\"0 0 24 24\">\n <path\n fill=\"#4285F4\"\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n />\n <path\n fill=\"#34A853\"\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n />\n <path\n fill=\"#FBBC05\"\n d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n />\n <path\n fill=\"#EA4335\"\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n />\n </svg>\n Continue with Google\n </button>\n </div>\n\n {/* Error Display */}\n {error && (\n <div className=\"mb-6\">\n <p className=\"text-sm text-center\" style={{ color: COLORS.error }}>{error}</p>\n </div>\n )}\n </div>\n\n {/* Continue Button - Fixed at bottom */}\n <div className=\"px-12 pb-8 flex-shrink-0\">\n <button\n className=\"w-full max-w-sm mx-auto bg-gray-900 hover:bg-gray-800 text-white rounded-full py-4 text-base font-medium flex items-center justify-center gap-2 transition-colors disabled:opacity-50\"\n onClick={handleEmailSubmit}\n disabled={isLoading || !email.trim()}\n style={{ \n fontFamily: 'Inter, system-ui, sans-serif'\n }}\n >\n {isLoading ? 'Loading...' : 'Continue'}\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n </div>\n </div>\n );\n\n const renderCodeStep = () => (\n <div className=\"w-full flex flex-col\" style={{ height: '100%' }}>\n {/* Heading - matching VerificationStep.tsx */}\n <div className=\"w-full pt-16 px-12 mb-10 text-center\">\n <h1 \n className=\"font-bold mb-2\"\n style={{ \n fontFamily: 'IBM Plex Sans, system-ui, sans-serif',\n fontWeight: '700',\n fontSize: '24px',\n lineHeight: '32px',\n color: COLORS.textPrimary\n }}\n >\n Enter verification code\n </h1>\n <p \n className=\"mb-2\"\n style={{ \n fontFamily: 'Inter, system-ui, sans-serif',\n fontWeight: '400',\n fontSize: '16px',\n lineHeight: '24px',\n color: COLORS.textSecondary\n }}\n >\n We've sent a 6-digit code to {email}\n </p>\n </div>\n\n\n {/* Code Input - matching VerificationStep design with individual digit boxes */}\n <div className=\"px-12 mb-6\">\n <div className=\"flex justify-center space-x-3\">\n {Array.from({ length: 6 }, (_, index) => (\n <input\n key={index}\n type=\"text\"\n maxLength=\"1\"\n value={code[index] || ''}\n onChange={(e) => {\n const newCode = code.split('');\n newCode[index] = e.target.value;\n setCode(newCode.join(''));\n \n // Auto-focus next input\n if (e.target.value && index < 5) {\n const nextInput = e.target.parentElement?.children[index + 1];\n if (nextInput) nextInput.focus();\n }\n }}\n onKeyDown={(e) => {\n // Handle backspace to focus previous input\n if (e.key === 'Backspace' && !code[index] && index > 0) {\n const prevInput = e.target.parentElement?.children[index - 1];\n if (prevInput) prevInput.focus();\n }\n }}\n className=\"w-12 h-12 border rounded-lg text-center text-lg font-medium focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none\"\n style={{ \n borderColor: COLORS.border,\n backgroundColor: COLORS.background,\n fontFamily: 'Inter, system-ui, sans-serif'\n }}\n />\n ))}\n </div>\n </div>\n\n {/* Error Display */}\n {error && (\n <div className=\"px-12 mb-6\">\n <p className=\"text-sm text-center\" style={{ color: COLORS.error }}>{error}</p>\n </div>\n )}\n\n {/* Continue Button - positioned right below code inputs */}\n <div className=\"px-12 mb-6\">\n <div className=\"max-w-sm mx-auto\">\n <PrimaryButton\n label=\"Continue\"\n onClick={handleCodeSubmit}\n loading={isLoading}\n disabled={isLoading || code.length !== 6}\n testId=\"verify-code-button\"\n />\n </div>\n </div>\n\n {/* Spacer */}\n <div style={{ flex: 1, minHeight: '20px' }} />\n\n {/* Back to email option */}\n <div className=\"px-12 w-full\">\n <div className=\"max-w-sm mx-auto\">\n <button\n type=\"button\"\n onClick={() => setStep('email')}\n className=\"w-full py-2 px-4 font-medium transition-colors text-sm\"\n style={{ color: COLORS.textSecondary }}\n >\n Use a different email\n </button>\n </div>\n </div>\n </div>\n );\n\n const renderSuccessStep = () => (\n <div className=\"w-full flex flex-col items-center space-y-6 pt-16 px-12\">\n <div \n className=\"flex items-center justify-center w-16 h-16 rounded-full\"\n style={{ backgroundColor: '#D1FAE5' }}\n >\n <Check className=\"w-8 h-8\" style={{ color: COLORS.success }} />\n </div>\n \n <div className=\"text-center space-y-2\">\n <h2 \n className=\"text-xl font-semibold\"\n style={{ color: COLORS.textPrimary }}\n >\n Email verified!\n </h2>\n <p style={{ color: COLORS.textSecondary }}>Setting up your account...</p>\n </div>\n\n <div className=\"w-8 h-8\">\n <div className=\"animate-spin h-8 w-8 border-2 border-blue-600 rounded-full border-t-transparent\"></div>\n </div>\n </div>\n );\n\n return (\n <div className=\"w-full\">\n {step === 'email' && renderEmailStep()}\n {step === 'code' && renderCodeStep()}\n {step === 'success' && renderSuccessStep()}\n </div>\n );\n} \n","/**\r\n * Onairos Browser Extension Detection Utility\r\n * \r\n * This utility detects if the Onairos browser extension is installed\r\n * by checking for the global window.onairos object that the extension injects.\r\n * \r\n * Based on the extension's inject-script.js implementation:\r\n * - window.onairos.isOnairos = true\r\n * - window.onairos.version = '1.0.0'\r\n * - 'onairosReady' event is dispatched when extension loads\r\n */\r\n\r\n/**\r\n * Chrome Web Store URL for the Onairos browser extension\r\n */\r\nexport const ONAIROS_EXTENSION_STORE_URL = 'https://chromewebstore.google.com/detail/onairos/apkfageplidiblifhnadehmplfccapkf?hl=en';\r\n\r\n/**\r\n * Timeout for extension detection (in milliseconds)\r\n */\r\nconst DETECTION_TIMEOUT = 2000;\r\n\r\n/**\r\n * Detect if the Onairos browser extension is installed\r\n * @returns {Promise<boolean>} True if extension is installed and active\r\n */\r\nexport const detectOnairosExtension = () => {\r\n return new Promise((resolve) => {\r\n // Method 1: Direct detection - check if already loaded\r\n if (window.onairos && window.onairos.isOnairos) {\r\n console.log('✅ OnairosTerminal extension detected (already loaded)');\r\n resolve(true);\r\n return;\r\n }\r\n\r\n // Method 2: Event-based detection - wait for extension to load\r\n let resolved = false;\r\n \r\n const handleOnairosReady = () => {\r\n if (!resolved) {\r\n resolved = true;\r\n console.log('✅ OnairosTerminal extension detected (via event)');\r\n resolve(true);\r\n }\r\n };\r\n\r\n // Listen for the onairosReady event\r\n window.addEventListener('onairosReady', handleOnairosReady, { once: true });\r\n\r\n // Set timeout to avoid waiting indefinitely\r\n setTimeout(() => {\r\n if (!resolved) {\r\n resolved = true;\r\n window.removeEventListener('onairosReady', handleOnairosReady);\r\n console.log('❌ OnairosTerminal extension not detected (timeout)');\r\n resolve(false);\r\n }\r\n }, DETECTION_TIMEOUT);\r\n });\r\n};\r\n\r\n/**\r\n * Get extension information if available\r\n * @returns {Object|null} Extension info or null if not available\r\n */\r\nexport const getExtensionInfo = () => {\r\n if (window.onairos && window.onairos.getInfo) {\r\n return window.onairos.getInfo();\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Check if extension is available synchronously (for already loaded extensions)\r\n * @returns {boolean} True if extension is immediately available\r\n */\r\nexport const isExtensionAvailableSync = () => {\r\n return !!(window.onairos && window.onairos.isOnairos);\r\n};\r\n\r\n/**\r\n * Open Chrome Web Store to install the extension\r\n * @param {string} source - Source identifier for analytics (e.g., 'chatgpt', 'claude')\r\n */\r\nexport const openExtensionInstallPage = (source = 'unknown') => {\r\n console.log(`🔗 Opening Chrome Web Store for extension installation (source: ${source})`);\r\n \r\n // For now, use a placeholder URL - replace with actual extension ID when available\r\n const storeUrl = ONAIROS_EXTENSION_STORE_URL;\r\n \r\n // Try to open in new tab\r\n const installWindow = window.open(storeUrl, '_blank');\r\n \r\n if (!installWindow) {\r\n // Fallback if popup is blocked\r\n console.warn('⚠️ Popup blocked, redirecting to extension store');\r\n window.location.href = storeUrl;\r\n }\r\n};\r\n\r\n/**\r\n * LLM Platform URLs\r\n */\r\nexport const LLM_URLS = {\r\n chatgpt: 'https://chatgpt.com',\r\n claude: 'https://claude.ai',\r\n gemini: 'https://gemini.google.com',\r\n grok: 'https://grok.x.ai'\r\n};\r\n\r\n/**\r\n * Open LLM platform if extension is installed, otherwise prompt for extension installation\r\n * @param {string} platform - LLM platform name ('chatgpt', 'claude', 'gemini', 'grok')\r\n * @param {Function} onExtensionMissing - Callback when extension is not installed\r\n * @param {Object} userInfo - User information to pass to the LLM platform\r\n * @param {string} userInfo.username - User's username/email\r\n * @param {string} userInfo.userId - User's unique identifier\r\n * @param {string} userInfo.sessionToken - Optional session token\r\n * @returns {Promise<boolean>} True if LLM was opened, false if extension missing\r\n */\r\nexport const openLLMWithExtensionCheck = async (platform, onExtensionMissing = null, userInfo = {}) => {\r\n console.log(`🤖 Attempting to open ${platform} with extension check...`);\r\n \r\n // Check if extension is installed\r\n const hasExtension = await detectOnairosExtension();\r\n \r\n if (hasExtension) {\r\n // Extension is installed - open the LLM platform with user info\r\n const baseUrl = LLM_URLS[platform];\r\n if (baseUrl) {\r\n // Build URL with user parameters for the browser extension to detect\r\n const url = new URL(baseUrl);\r\n \r\n // Add Onairos-specific parameters that the extension can read\r\n if (userInfo.username) {\r\n url.searchParams.set('onairos_user', encodeURIComponent(userInfo.username));\r\n }\r\n if (userInfo.userId) {\r\n url.searchParams.set('onairos_id', encodeURIComponent(userInfo.userId));\r\n }\r\n if (userInfo.sessionToken) {\r\n url.searchParams.set('onairos_session', encodeURIComponent(userInfo.sessionToken));\r\n }\r\n \r\n // Add platform identifier for the extension\r\n url.searchParams.set('onairos_platform', platform);\r\n url.searchParams.set('onairos_source', 'npm_connector');\r\n url.searchParams.set('onairos_timestamp', Date.now().toString());\r\n \r\n const finalUrl = url.toString();\r\n console.log(`✅ Extension detected, opening ${platform} at ${finalUrl}`);\r\n console.log(`👤 User info: ${JSON.stringify(userInfo)}`);\r\n \r\n const llmWindow = window.open(finalUrl, '_blank');\r\n \r\n if (!llmWindow) {\r\n console.warn(`⚠️ Popup blocked for ${platform}`);\r\n return false;\r\n }\r\n return true;\r\n } else {\r\n console.error(`❌ Unknown LLM platform: ${platform}`);\r\n return false;\r\n }\r\n } else {\r\n // Extension is not installed - handle missing extension\r\n console.log(`❌ Extension not detected for ${platform}, prompting installation`);\r\n \r\n if (onExtensionMissing) {\r\n onExtensionMissing(platform);\r\n } else {\r\n // Default behavior: open extension store\r\n openExtensionInstallPage(platform);\r\n }\r\n \r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Enhanced extension detection with retry mechanism\r\n * @param {number} maxRetries - Maximum number of detection attempts\r\n * @param {number} retryDelay - Delay between retries in milliseconds\r\n * @returns {Promise<boolean>} True if extension is detected\r\n */\r\nexport const detectExtensionWithRetry = async (maxRetries = 3, retryDelay = 500) => {\r\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\r\n console.log(`🔍 Extension detection attempt ${attempt}/${maxRetries}`);\r\n \r\n const detected = await detectOnairosExtension();\r\n if (detected) {\r\n return true;\r\n }\r\n \r\n if (attempt < maxRetries) {\r\n await new Promise(resolve => setTimeout(resolve, retryDelay));\r\n }\r\n }\r\n \r\n console.log(`❌ Extension not detected after ${maxRetries} attempts`);\r\n return false;\r\n};\r\n\r\n/**\r\n * Extract Onairos user information from URL parameters\r\n * This function is intended to be used by the browser extension to read user info\r\n * @param {string} url - URL to parse (defaults to current page URL)\r\n * @returns {Object|null} User information object or null if no Onairos params found\r\n */\r\nexport const extractUserInfoFromURL = (url = window.location.href) => {\r\n try {\r\n const urlObj = new URL(url);\r\n const params = urlObj.searchParams;\r\n \r\n // Check if this URL has Onairos parameters\r\n if (!params.has('onairos_user') && !params.has('onairos_id')) {\r\n return null;\r\n }\r\n \r\n const userInfo = {\r\n username: params.get('onairos_user') ? decodeURIComponent(params.get('onairos_user')) : null,\r\n userId: params.get('onairos_id') ? decodeURIComponent(params.get('onairos_id')) : null,\r\n sessionToken: params.get('onairos_session') ? decodeURIComponent(params.get('onairos_session')) : null,\r\n platform: params.get('onairos_platform') || null,\r\n source: params.get('onairos_source') || null,\r\n timestamp: params.get('onairos_timestamp') || null\r\n };\r\n \r\n // Only return if we have at least username or userId\r\n if (userInfo.username || userInfo.userId) {\r\n console.log('📋 Extracted Onairos user info from URL:', userInfo);\r\n return userInfo;\r\n }\r\n \r\n return null;\r\n } catch (error) {\r\n console.error('❌ Error extracting user info from URL:', error);\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Send user information to the browser extension\r\n * This function communicates with the extension to provide user context\r\n * @param {Object} userInfo - User information to send\r\n * @returns {Promise<boolean>} True if successfully sent to extension\r\n */\r\nexport const sendUserInfoToExtension = async (userInfo) => {\r\n try {\r\n if (!window.onairos || !window.onairos.isOnairos) {\r\n console.warn('⚠️ Onairos extension not detected, cannot send user info');\r\n return false;\r\n }\r\n \r\n // Send user info via postMessage to the extension\r\n window.postMessage({\r\n source: 'onairos_npm_connector',\r\n type: 'USER_INFO',\r\n data: {\r\n ...userInfo,\r\n timestamp: new Date().toISOString(),\r\n connectorVersion: '3.4.2'\r\n }\r\n }, '*');\r\n \r\n console.log('📤 Sent user info to Onairos extension:', userInfo);\r\n return true;\r\n } catch (error) {\r\n console.error('❌ Error sending user info to extension:', error);\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Send LLM conversation data to backend (for browser extension)\r\n * This function formats and sends encrypted conversation data to the new /llm-data/store endpoint\r\n * @param {Object} conversationData - Raw conversation data\r\n * @param {Object} userInfo - User authentication info\r\n * @param {string} platform - LLM platform (chatgpt, claude, gemini, grok)\r\n * @returns {Promise<boolean>} True if successfully stored\r\n */\r\nexport const storeLLMConversationData = async (conversationData, userInfo, platform) => {\r\n try {\r\n // Format data according to new backend API schema\r\n const payload = {\r\n encryptedData: btoa(JSON.stringify(conversationData)), // Base64 encode for now\r\n encryptionMetadata: {\r\n algorithm: \"AES-GCM\",\r\n keyDerivation: \"PBKDF2\",\r\n iterations: 100000\r\n },\r\n authentication: {\r\n username: userInfo.username || userInfo.email,\r\n timestamp: Date.now()\r\n },\r\n integrity: {\r\n hash: await generateDataHash(conversationData),\r\n algorithm: \"SHA-256\"\r\n },\r\n platform: platform,\r\n source: 'browser_extension'\r\n };\r\n\r\n const response = await fetch('https://api2.onairos.uk/llm-data/store', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${userInfo.sessionToken || userInfo.jwtToken}`,\r\n 'X-Onairos-User': userInfo.userId || userInfo.username\r\n },\r\n body: JSON.stringify(payload)\r\n });\r\n\r\n if (response.ok) {\r\n console.log('✅ LLM conversation data stored successfully');\r\n return true;\r\n } else {\r\n console.error('❌ Failed to store LLM data:', response.status);\r\n return false;\r\n }\r\n } catch (error) {\r\n console.error('❌ Error storing LLM conversation data:', error);\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Generate SHA-256 hash of data for integrity verification\r\n * @param {Object} data - Data to hash\r\n * @returns {Promise<string>} SHA-256 hash\r\n */\r\nasync function generateDataHash(data) {\r\n try {\r\n const encoder = new TextEncoder();\r\n const dataString = JSON.stringify(data);\r\n const dataBuffer = encoder.encode(dataString);\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n return `sha256-${hashHex}`;\r\n } catch (error) {\r\n console.error('Error generating hash:', error);\r\n return `sha256-${Date.now()}`; // Fallback\r\n }\r\n}\r\n\r\n/**\r\n * Get user information from standard Onairos localStorage keys\r\n * @returns {Object} User information from localStorage\r\n */\r\nexport const getUserInfoFromStorage = () => {\r\n try {\r\n // Primary storage locations used by Onairos\r\n const userDataStr = localStorage.getItem('onairosUser'); // Main user data object\r\n const jwtToken = localStorage.getItem('onairos_jwt_token'); // JWT token from email verification\r\n const legacyToken = localStorage.getItem('onairosToken'); // Legacy token from login\r\n const username = localStorage.getItem('username'); // Username from login\r\n const userDataSDK = localStorage.getItem('onairos_user_data'); // SDK user data\r\n \r\n let userData = null;\r\n \r\n // Try to parse main user data\r\n if (userDataStr) {\r\n try {\r\n userData = JSON.parse(userDataStr);\r\n } catch (error) {\r\n console.warn('⚠️ Failed to parse onairosUser from localStorage');\r\n }\r\n }\r\n \r\n // Try to parse SDK user data as fallback\r\n if (!userData && userDataSDK) {\r\n try {\r\n userData = JSON.parse(userDataSDK);\r\n } catch (error) {\r\n console.warn('⚠️ Failed to parse onairos_user_data from localStorage');\r\n }\r\n }\r\n \r\n // Build comprehensive user info object\r\n const userInfo = {\r\n // User identification\r\n username: userData?.email || userData?.username || username || null,\r\n userId: userData?.userId || userData?.email || username || null,\r\n email: userData?.email || null,\r\n \r\n // Authentication tokens\r\n sessionToken: jwtToken || userData?.token || legacyToken || null,\r\n jwtToken: jwtToken || userData?.token || null,\r\n \r\n // User metadata\r\n isNewUser: userData?.isNewUser || false,\r\n verified: userData?.verified || false,\r\n onboardingComplete: userData?.onboardingComplete || false,\r\n pinCreated: userData?.pinCreated || false,\r\n \r\n // Account details\r\n accountInfo: userData?.accountInfo || null,\r\n connectedAccounts: userData?.connectedAccounts || [],\r\n \r\n // Timestamps\r\n lastLogin: userData?.lastLogin || null,\r\n createdAt: userData?.createdAt || null,\r\n \r\n // Source tracking\r\n source: 'localStorage_extraction',\r\n extractedAt: new Date().toISOString()\r\n };\r\n \r\n console.log('📋 Extracted user info from localStorage:', userInfo);\r\n return userInfo;\r\n } catch (error) {\r\n console.error('❌ Error extracting user info from localStorage:', error);\r\n return {\r\n username: null,\r\n userId: null,\r\n sessionToken: null,\r\n source: 'extraction_failed',\r\n error: error.message\r\n };\r\n }\r\n};\r\n\r\n/**\r\n * Initialize user context for the current page\r\n * This should be called when the page loads to set up user context for the extension\r\n * @param {Object} userInfo - User information to initialize (optional, will auto-extract if not provided)\r\n */\r\nexport const initializeUserContext = async (userInfo = null) => {\r\n console.log('🚀 Initializing Onairos user context...');\r\n \r\n // If no user info provided, extract from localStorage\r\n if (!userInfo) {\r\n userInfo = getUserInfoFromStorage();\r\n }\r\n \r\n // First try to extract user info from URL (in case we're on an LLM platform)\r\n const urlUserInfo = extractUserInfoFromURL();\r\n \r\n // Merge URL info with provided/extracted info (URL takes precedence)\r\n const finalUserInfo = {\r\n ...userInfo,\r\n ...urlUserInfo\r\n };\r\n \r\n if (finalUserInfo.username || finalUserInfo.userId) {\r\n // Try to send to extension\r\n const sent = await sendUserInfoToExtension(finalUserInfo);\r\n \r\n if (sent) {\r\n console.log('✅ User context initialized successfully');\r\n } else {\r\n console.log('⚠️ Extension not available, user context stored locally');\r\n // Store in localStorage as fallback\r\n localStorage.setItem('onairos_user_context', JSON.stringify(finalUserInfo));\r\n }\r\n \r\n return finalUserInfo;\r\n } else {\r\n console.log('⚠️ No user information available to initialize');\r\n return null;\r\n }\r\n};\r\n","import React from 'react';\r\nimport { openExtensionInstallPage, LLM_URLS } from '../utils/extensionDetection';\r\n\r\n/**\r\n * Extension Installation Prompt Component\r\n * \r\n * Displays when a user tries to connect to an LLM but doesn't have \r\n * the Onairos browser extension installed.\r\n */\r\nconst ExtensionInstallPrompt = ({ \r\n open = false, \r\n onClose, \r\n platform = 'chatgpt',\r\n onInstallClick = null \r\n}) => {\r\n if (!open) return null;\r\n\r\n const platformNames = {\r\n chatgpt: 'ChatGPT',\r\n claude: 'Claude',\r\n gemini: 'Gemini',\r\n grok: 'Grok'\r\n };\r\n\r\n const platformName = platformNames[platform] || 'LLM';\r\n const platformUrl = LLM_URLS[platform] || '#';\r\n\r\n const handleInstallClick = () => {\r\n if (onInstallClick) {\r\n onInstallClick(platform);\r\n } else {\r\n openExtensionInstallPage(platform);\r\n }\r\n };\r\n\r\n const handleDirectVisit = () => {\r\n window.open(platformUrl, '_blank');\r\n if (onClose) onClose();\r\n };\r\n\r\n return (\r\n <div className=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\r\n <div className=\"bg-white rounded-lg shadow-xl max-w-md w-full mx-4 max-h-[90vh] overflow-hidden\">\r\n <div className=\"p-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center mb-4\">\r\n <div className=\"w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center mr-3\">\r\n <svg className=\"w-6 h-6 text-blue-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 6v6m0 0v6m0-6h6m-6 0H6\" />\r\n </svg>\r\n </div>\r\n <h2 className=\"text-xl font-bold text-gray-900\">\r\n Install Onairos Extension\r\n </h2>\r\n </div>\r\n \r\n {/* Content */}\r\n <div className=\"space-y-4 text-gray-700\">\r\n <p>\r\n To connect with <strong>{platformName}</strong> and enable personalized AI interactions, \r\n you need the Onairos browser extension installed.\r\n </p>\r\n \r\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4\">\r\n <h3 className=\"font-semibold text-blue-900 mb-2\">🚀 What the extension does:</h3>\r\n <ul className=\"list-disc ml-4 space-y-1 text-blue-800 text-sm\">\r\n <li>Detects when you're on {platformName} and other LLM sites</li>\r\n <li>Enables secure data sharing with your consent</li>\r\n <li>Personalizes AI responses based on your preferences</li>\r\n <li>Works seamlessly in the background</li>\r\n </ul>\r\n </div>\r\n\r\n <div className=\"bg-amber-50 border border-amber-200 rounded-lg p-4\">\r\n <h3 className=\"font-semibold text-amber-900 mb-2\">⚡ Quick Setup:</h3>\r\n <ol className=\"list-decimal ml-4 space-y-1 text-amber-800 text-sm\">\r\n <li>Click \"Install Extension\" below</li>\r\n <li>Add the extension from Chrome Web Store</li>\r\n <li>Return here and try connecting again</li>\r\n </ol>\r\n </div>\r\n \r\n <p className=\"text-sm text-gray-600\">\r\n Don't want to install the extension? You can still visit{' '}\r\n <a \r\n href={platformUrl} \r\n className=\"text-blue-600 hover:underline\" \r\n target=\"_blank\" \r\n rel=\"noopener noreferrer\"\r\n >\r\n {platformUrl}\r\n </a>\r\n {' '}directly, but you won't get personalized AI features.\r\n </p>\r\n </div>\r\n \r\n {/* Actions */}\r\n <div className=\"flex flex-col space-y-3 mt-6\">\r\n <button\r\n onClick={handleInstallClick}\r\n className=\"w-full px-4 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium flex items-center justify-center\"\r\n >\r\n <svg className=\"w-5 h-5 mr-2\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\r\n </svg>\r\n Install Onairos Extension\r\n </button>\r\n \r\n <div className=\"flex space-x-3\">\r\n <button\r\n onClick={handleDirectVisit}\r\n className=\"flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 text-sm\"\r\n >\r\n Visit {platformName} Anyway\r\n </button>\r\n <button\r\n onClick={onClose}\r\n className=\"flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 text-sm\"\r\n >\r\n Cancel\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Footer */}\r\n <div className=\"mt-4 pt-4 border-t border-gray-200\">\r\n <p className=\"text-xs text-gray-500 text-center\">\r\n The Onairos extension is free, secure, and respects your privacy. \r\n <br />\r\n <a href=\"https://onairos.uk/privacy\" className=\"text-blue-600 hover:underline\">\r\n Learn more about our privacy policy\r\n </a>\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport default ExtensionInstallPrompt;\r\n","import React, { useState, useCallback } from 'react';\r\nimport { openLLMWithExtensionCheck, detectOnairosExtension, getUserInfoFromStorage } from '../utils/extensionDetection';\r\nimport ExtensionInstallPrompt from './ExtensionInstallPrompt';\r\n\r\n/**\r\n * LLM Connector Manager Component\r\n * \r\n * Manages the connection flow for LLM platforms (ChatGPT, Claude, Gemini, Grok).\r\n * Handles extension detection and shows appropriate prompts.\r\n */\r\nconst LLMConnectorManager = ({ \r\n children,\r\n onConnectionChange = null,\r\n username = null \r\n}) => {\r\n const [showInstallPrompt, setShowInstallPrompt] = useState(false);\r\n const [currentPlatform, setCurrentPlatform] = useState(null);\r\n const [isConnecting, setIsConnecting] = useState(false);\r\n\r\n /**\r\n * Handle LLM connection attempt\r\n * @param {string} platform - LLM platform name\r\n * @param {Function} onSuccess - Callback for successful connection\r\n * @param {Function} onError - Callback for connection error\r\n */\r\n const handleLLMConnect = useCallback(async (platform, onSuccess = null, onError = null) => {\r\n if (isConnecting) {\r\n console.log('⚠️ Already connecting, ignoring request');\r\n return;\r\n }\r\n\r\n setIsConnecting(true);\r\n setCurrentPlatform(platform);\r\n\r\n try {\r\n console.log(`🤖 Attempting to connect to ${platform}...`);\r\n\r\n // Prepare user information for the browser extension\r\n // First try to get comprehensive user info from localStorage\r\n const storedUserInfo = getUserInfoFromStorage();\r\n \r\n const userInfo = {\r\n // Use stored info as primary source, fallback to props\r\n username: storedUserInfo.username || username,\r\n userId: storedUserInfo.userId || storedUserInfo.username || username,\r\n email: storedUserInfo.email,\r\n sessionToken: storedUserInfo.sessionToken,\r\n jwtToken: storedUserInfo.jwtToken,\r\n \r\n // User metadata\r\n isNewUser: storedUserInfo.isNewUser,\r\n verified: storedUserInfo.verified,\r\n onboardingComplete: storedUserInfo.onboardingComplete,\r\n pinCreated: storedUserInfo.pinCreated,\r\n \r\n // Account details\r\n accountInfo: storedUserInfo.accountInfo,\r\n connectedAccounts: storedUserInfo.connectedAccounts,\r\n \r\n // Add additional context\r\n source: 'onairos_npm_connector',\r\n connectorVersion: '3.4.2', // Updated version from package.json\r\n timestamp: new Date().toISOString(),\r\n platform: platform\r\n };\r\n\r\n // Use the extension detection utility with user info\r\n const success = await openLLMWithExtensionCheck(\r\n platform,\r\n (missingPlatform) => {\r\n // Extension is missing - show install prompt\r\n console.log(`❌ Extension missing for ${missingPlatform}, showing install prompt`);\r\n setCurrentPlatform(missingPlatform);\r\n setShowInstallPrompt(true);\r\n },\r\n userInfo\r\n );\r\n\r\n if (success) {\r\n // LLM was opened successfully\r\n console.log(`✅ ${platform} opened successfully`);\r\n \r\n // Simulate connection after a short delay (like the original ChatGPT connector)\r\n setTimeout(() => {\r\n if (onConnectionChange) {\r\n onConnectionChange(platform, true);\r\n }\r\n if (onSuccess) {\r\n onSuccess(platform);\r\n }\r\n setIsConnecting(false);\r\n }, 1000);\r\n } else {\r\n // Failed to open (popup blocked or other error)\r\n console.log(`❌ Failed to open ${platform}`);\r\n setIsConnecting(false);\r\n \r\n if (onError) {\r\n onError(platform, 'Failed to open LLM platform');\r\n }\r\n }\r\n } catch (error) {\r\n console.error(`❌ Error connecting to ${platform}:`, error);\r\n setIsConnecting(false);\r\n \r\n if (onError) {\r\n onError(platform, error.message);\r\n }\r\n }\r\n }, [isConnecting, onConnectionChange]);\r\n\r\n /**\r\n * Handle disconnection from LLM platform\r\n * @param {string} platform - LLM platform name\r\n */\r\n const handleLLMDisconnect = useCallback((platform) => {\r\n console.log(`🔌 Disconnecting from ${platform}`);\r\n \r\n if (onConnectionChange) {\r\n onConnectionChange(platform, false);\r\n }\r\n }, [onConnectionChange]);\r\n\r\n /**\r\n * Close the extension install prompt\r\n */\r\n const handleCloseInstallPrompt = useCallback(() => {\r\n setShowInstallPrompt(false);\r\n setCurrentPlatform(null);\r\n setIsConnecting(false);\r\n }, []);\r\n\r\n /**\r\n * Handle extension installation click\r\n */\r\n const handleExtensionInstall = useCallback((platform) => {\r\n console.log(`🔗 User clicked to install extension for ${platform}`);\r\n // The ExtensionInstallPrompt component will handle opening the store\r\n // We'll close the prompt after a delay to let the user install\r\n setTimeout(() => {\r\n setShowInstallPrompt(false);\r\n setCurrentPlatform(null);\r\n setIsConnecting(false);\r\n }, 1000);\r\n }, []);\r\n\r\n /**\r\n * Check extension status\r\n * @returns {Promise<boolean>} True if extension is available\r\n */\r\n const checkExtensionStatus = useCallback(async () => {\r\n return await detectOnairosExtension();\r\n }, []);\r\n\r\n // Provide context to children components\r\n const contextValue = {\r\n // Connection methods\r\n connectToLLM: handleLLMConnect,\r\n disconnectFromLLM: handleLLMDisconnect,\r\n \r\n // State\r\n isConnecting,\r\n currentPlatform,\r\n \r\n // Utilities\r\n checkExtensionStatus,\r\n \r\n // User info\r\n username\r\n };\r\n\r\n return (\r\n <div data-llm-manager=\"true\">\r\n {/* Render children with context */}\r\n {React.Children.map(children, child => {\r\n if (React.isValidElement(child)) {\r\n return React.cloneElement(child, {\r\n ...child.props,\r\n llmConnectorManager: contextValue\r\n });\r\n }\r\n return child;\r\n })}\r\n\r\n {/* Extension Install Prompt */}\r\n <ExtensionInstallPrompt\r\n open={showInstallPrompt}\r\n platform={currentPlatform}\r\n onClose={handleCloseInstallPrompt}\r\n onInstallClick={handleExtensionInstall}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\n/**\r\n * Hook for using LLM Connector Manager context\r\n * @param {Object} props - Component props that might contain llmConnectorManager\r\n * @returns {Object} LLM connector manager context\r\n */\r\nexport const useLLMConnectorManager = (props) => {\r\n return props.llmConnectorManager || {\r\n connectToLLM: () => console.warn('LLM Connector Manager not available'),\r\n disconnectFromLLM: () => console.warn('LLM Connector Manager not available'),\r\n isConnecting: false,\r\n currentPlatform: null,\r\n checkExtensionStatus: () => Promise.resolve(false),\r\n username: null\r\n };\r\n};\r\n\r\nexport default LLMConnectorManager;\r\n","import React, { useEffect, useId, useState, useRef } from 'react';\r\nimport Lottie from 'lottie-react';\r\nimport personaAnim from '../../public/persona-anim.json';\r\nimport LLMConnectorManager from './LLMConnectorManager';\r\nconst chatgptIcon = 'https://anushkasirv.sirv.com/openai.png';\r\nconst claudeIcon = 'https://anushkasirv.sirv.com/claude-color.png';\r\nconst geminiIcon = 'https://anushkasirv.sirv.com/gemini-color.png';\r\nconst grokIcon = 'https://anushkasirv.sirv.com/grok.png';\r\n\r\nconst sdkConfig = {\r\n apiKey: process.env.REACT_APP_ONAIROS_API_KEY || 'onairos_web_sdk_live_key_2024',\r\n baseUrl: process.env.REACT_APP_ONAIROS_BASE_URL || 'https://api2.onairos.uk',\r\n sdkType: 'web',\r\n enableHealthMonitoring: true,\r\n enableAutoRefresh: true,\r\n enableConnectionValidation: true,\r\n};\r\n\r\nconst fadeSlideInKeyframes = `\r\n@keyframes fadeSlideIn {\r\n from { opacity: 0; transform: translateX(var(--slide-x)); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n`;\r\n\r\nexport default function UniversalOnboarding({ onComplete, llmConnectorManager }) {\r\n const lottieRef = useRef(null);\r\n const lastFrameRef = useRef(0);\r\n const rafRef = useRef(null);\r\n\r\n const [connectedAccounts, setConnectedAccounts] = useState({});\r\n const [isConnecting, setIsConnecting] = useState(false);\r\n const [connectingPlatform, setConnectingPlatform] = useState(null);\r\n const [selected, setSelected] = useState('Instagram');\r\n const [currentPage, setCurrentPage] = useState(1);\r\n\r\n // swipe state\r\n const touchStartX = useRef(0);\r\n const touchDeltaX = useRef(0);\r\n\r\n const [vh, setVh] = useState(() => (typeof window !== 'undefined' ? window.innerHeight : 800));\r\n useEffect(() => {\r\n const onResize = () => setVh(window.innerHeight);\r\n window.addEventListener('resize', onResize);\r\n return () => window.removeEventListener('resize', onResize);\r\n }, []);\r\n\r\n // Reset flow on every page load/refresh\r\n useEffect(() => {\r\n // Clear any persisted OAuth state on mount\r\n localStorage.removeItem('onairos_oauth_platform');\r\n localStorage.removeItem('onairos_oauth_return');\r\n }, []);\r\n\r\n const FOOTER_H = 88;\r\n\r\n // persona stays as requested (background, unchanged placement)\r\n const personaSide = Math.min(vh * 0.52, 500);\r\n const PERSONA_TOP = 96;\r\n\r\n // icon layout (restore tighter spacing on page 1; place the band lower)\r\n const SLOT = Math.max(56, Math.min(64, Math.floor(vh * 0.07)));\r\n const CIRCLE = 42;\r\n const GAP_PAGE1 = 12;\r\n const GAP_PAGE2 = 20;\r\n const ACTIVE_SCALE = vh < 760 ? 1.12 : 1.22;\r\n\r\n const ICONS_H = 84;\r\n\r\n const igGradId = useId();\r\n\r\n // ---- official brand SVGs (compact, consistent viewboxes) ----\r\n const Brand = {\r\n ChatGPT: <img src={chatgptIcon} alt=\"ChatGPT\" style={{ width: 22, height: 22, objectFit: 'contain' }} />,\r\n Claude: <img src={claudeIcon} alt=\"Claude\" style={{ width: 22, height: 22, objectFit: 'contain' }} />,\r\n Gemini: <img src={geminiIcon} alt=\"Gemini\" style={{ width: 22, height: 22, objectFit: 'contain' }} />,\r\n Grok: <img src={grokIcon} alt=\"Grok\" style={{ width: 22, height: 22, objectFit: 'contain' }} />,\r\n Instagram: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <defs>\r\n <radialGradient id={igGradId} cx=\"0.5\" cy=\"1\" r=\"1\">\r\n <stop offset=\"0%\" stopColor=\"#FDBB4B\"/>\r\n <stop offset=\"40%\" stopColor=\"#E95950\"/>\r\n <stop offset=\"70%\" stopColor=\"#BC2A8D\"/>\r\n <stop offset=\"100%\" stopColor=\"#4C68D7\"/>\r\n </radialGradient>\r\n </defs>\r\n <path fill={`url(#${igGradId})`} d=\"M7 2h10a5 5 0 0 1 5 5v10a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5V7a5 5 0 0 1 5-5zm5 5.5A4.5 4.5 0 1 0 16.5 12 4.5 4.5 0 0 0 12 7.5zm0 7.4A2.9 2.9 0 1 1 14.9 12 2.9 2.9 0 0 1 12 14.9Zm5.35-8.25a1.15 1.15 0 1 0 1.15 1.15 1.15 1.15 0 0 0-1.15-1.15Z\"/>\r\n </svg>\r\n ),\r\n YouTube: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <path fill=\"#FF0000\" d=\"M22.54 6.42a3 3 0 0 0-2.11-2.12C18.49 3.75 12 3.75 12 3.75s-6.49 0-8.43.55A3 3 0 0 0 1.46 6.42 31.63 31.63 0 0 0 1 12a31.63 31.63 0 0 0 .46 5.58 3 3 0 0 0 2.11 2.12C5.51 20.25 12 20.25 12 20.25s6.49 0 8.43-.55a3 3 0 0 0 2.11-2.12A31.63 31.63 0 0 0 23 12a31.63 31.63 0 0 0-.46-5.58z\"/>\r\n <path fill=\"#FFF\" d=\"M10 8.75v6.5l6-3.25-6-3.25z\"/>\r\n </svg>\r\n ),\r\n Reddit: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#FF4500\"/>\r\n <circle cx=\"8.75\" cy=\"12.5\" r=\"1.25\" fill=\"#FFF\"/>\r\n <circle cx=\"15.25\" cy=\"12.5\" r=\"1.25\" fill=\"#FFF\"/>\r\n <path fill=\"#FFF\" d=\"M7.9 15c.8.8 2.3 1.05 4.1 1.05S15.3 15.8 16.1 15c.2-.2.2-.5 0-.7-.2-.2-.5-.2-.7 0-.6.6-1.9.85-3.4.85S9.3 14.9 8.7 14.3c-.2-.2-.5-.2-.7 0-.2.2-.2.5 0 .7z\"/>\r\n </svg>\r\n ),\r\n LinkedIn: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"3\" fill=\"#0A66C2\"/>\r\n <rect x=\"5\" y=\"9\" width=\"3\" height=\"10\" fill=\"#FFF\"/>\r\n <circle cx=\"6.5\" cy=\"6.5\" r=\"1.5\" fill=\"#FFF\"/>\r\n <path fill=\"#FFF\" d=\"M16.8 19H13.9v-5c0-1.2-.5-1.8-1.4-1.8-.9 0-1.6.6-1.6 1.8V19H8V9h2.8v1.3c.5-.8 1.4-1.5 2.7-1.5 2 0 3.3 1.3 3.3 3.7V19z\"/>\r\n </svg>\r\n ),\r\n Twitter: (\r\n <svg viewBox=\"0 0 24 24\" aria-hidden style={{ width: 22, height: 22 }}>\r\n <path fill=\"#1DA1F2\" d=\"M23.643 4.937c-.835.37-1.732.62-2.675.733.962-.576 1.7-1.49 2.048-2.578-.9.534-1.897.922-2.958 1.13-.85-.904-2.06-1.47-3.4-1.47-2.572 0-4.658 2.086-4.658 4.66 0 .364.042.718.12 1.06-3.873-.195-7.304-2.05-9.602-4.868-.4.69-.63 1.49-.63 2.342 0 1.616.823 3.043 2.072 3.878-.764-.025-1.482-.234-2.11-.583v.06c0 2.257 1.605 4.14 3.737 4.568-.392.106-.803.162-1.227.162-.3 0-.593-.028-.877-.082.593 1.85 2.313 3.198 4.352 3.234-1.595 1.25-3.604 1.995-5.786 1.995-.376 0-.747-.022-1.112-.065 2.062 1.323 4.51 2.093 7.14 2.093 8.57 0 13.255-7.098 13.255-13.254 0-.2-.005-.402-.014-.602.91-.658 1.7-1.477 2.323-2.41z\"/>\r\n </svg>\r\n ),\r\n };\r\n\r\n const aiLinks = {\r\n ChatGPT: 'https://chat.openai.com',\r\n Claude: 'https://claude.ai',\r\n Gemini: 'https://gemini.google.com',\r\n Grok: 'https://grok.x.ai',\r\n };\r\n\r\n const descriptions = {\r\n ChatGPT: <>We analyze your <strong className=\"font-semibold\">prompt style</strong> and <strong className=\"font-semibold\">chat history</strong> to match your writing and thinking patterns.</>,\r\n Claude: <>We learn your <strong className=\"font-semibold\">document workflow</strong> and <strong className=\"font-semibold\">reasoning preferences</strong> to tune output format and detail.</>,\r\n Gemini: <>We study your <strong className=\"font-semibold\">search patterns</strong> and <strong className=\"font-semibold\">multimodal usage</strong> to improve response accuracy.</>,\r\n Grok: <>We adapt to your <strong className=\"font-semibold\">X posting style</strong> and <strong className=\"font-semibold\">meme literacy</strong> to match your tone.</>,\r\n Twitter: <>We analyze your <strong className=\"font-semibold\">tweets</strong> and <strong className=\"font-semibold\">interests</strong> to understand your preferences.</>,\r\n YouTube: <>We study your <strong className=\"font-semibold\">watch history</strong> and <strong className=\"font-semibold\">interactions</strong> to learn your interests.</>,\r\n Reddit: <>We examine your <strong className=\"font-semibold\">search history</strong> and <strong className=\"font-semibold\">discussions</strong> to understand your interests.</>,\r\n Instagram: <>We analyze your <strong className=\"font-semibold\">photos</strong> and <strong className=\"font-semibold\">interactions</strong> to learn visual preferences.</>,\r\n LinkedIn: <>We study your <strong className=\"font-semibold\">professional graph</strong> and <strong className=\"font-semibold\">content</strong> to understand career interests.</>,\r\n };\r\n\r\n const allPlatforms = [\r\n // Page 1\r\n { name: 'Instagram', connector: 'instagram', icon: Brand.Instagram },\r\n { name: 'YouTube', connector: 'youtube', icon: Brand.YouTube },\r\n { name: 'ChatGPT', connector: 'chatgpt', icon: Brand.ChatGPT, directLink: aiLinks.ChatGPT },\r\n // Page 2\r\n { name: 'Claude', connector: 'claude', icon: Brand.Claude, directLink: aiLinks.Claude },\r\n { name: 'Gemini', connector: 'gemini', icon: Brand.Gemini, directLink: aiLinks.Gemini },\r\n { name: 'Twitter', connector: 'twitter', icon: Brand.Twitter },\r\n // Page 3\r\n { name: 'LinkedIn', connector: 'linkedin', icon: Brand.LinkedIn },\r\n { name: 'Reddit', connector: 'reddit', icon: Brand.Reddit },\r\n { name: 'Grok', connector: 'grok', icon: Brand.Grok, directLink: aiLinks.Grok },\r\n ];\r\n\r\n const getPlatformsForPage = (page) => {\r\n if (page === 1) return allPlatforms.slice(0, 3);\r\n if (page === 2) return allPlatforms.slice(3, 6);\r\n return allPlatforms.slice(6);\r\n };\r\n\r\n const platforms = getPlatformsForPage(currentPage);\r\n\r\n useEffect(() => {\r\n const p = localStorage.getItem('onairos_oauth_platform');\r\n if (p) {\r\n localStorage.removeItem('onairos_oauth_platform');\r\n localStorage.removeItem('onairos_oauth_return');\r\n setConnectedAccounts((s) => ({ ...s, [p]: true }));\r\n }\r\n }, []);\r\n\r\n async function connectToPlatform(name) {\r\n const plat = allPlatforms.find((p) => p.name === name);\r\n if (!plat) return false;\r\n try {\r\n // For direct-link platforms (no OAuth), mark connected immediately and return\r\n if (plat.directLink) {\r\n setConnectedAccounts((s) => ({ ...s, [name]: true }));\r\n setIsConnecting(false);\r\n setConnectingPlatform(null);\r\n return true;\r\n }\r\n\r\n // Immediately reflect selection in UI without spinner while starting OAuth\r\n setConnectedAccounts((s) => ({ ...s, [name]: true }));\r\n setIsConnecting(true);\r\n setConnectingPlatform(name);\r\n const username = localStorage.getItem('username') || (JSON.parse(localStorage.getItem('onairosUser') || '{}')?.email) || 'user@example.com';\r\n\r\n const res = await fetch(`${sdkConfig.baseUrl}/${plat.connector}/authorize`, {\r\n method: 'POST', headers: { 'x-api-key': sdkConfig.apiKey, 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ session: { username } }),\r\n });\r\n if (!res.ok) throw new Error('auth failed');\r\n const data = await res.json();\r\n\r\n const candidates = (\r\n {\r\n youtube: ['youtubeURL','youtubeUrl','youtube_url'],\r\n linkedin: ['linkedinURL','linkedinUrl','linkedin_url'],\r\n reddit: ['redditURL','redditUrl','reddit_url'],\r\n pinterest: ['pinterestURL','pinterestUrl','pinterest_url'],\r\n instagram: ['instagramURL','instagramUrl','instagram_url'],\r\n github: ['githubURL','githubUrl','github_url'],\r\n facebook: ['facebookURL','facebookUrl','facebook_url'],\r\n gmail: ['gmailURL','gmailUrl','gmail_url'],\r\n }[plat.connector]\r\n ) || [`${plat.connector}URL`, `${plat.connector}Url`, `${plat.connector}_url`, 'platformURL', 'authUrl', 'url'];\r\n\r\n let oauthUrl = null; for (const k of candidates) if (data[k]) { oauthUrl = data[k]; break; }\r\n if (!oauthUrl) throw new Error('no url');\r\n\r\n const popup = window.open(oauthUrl, `${plat.connector}_oauth`, 'width=500,height=600,scrollbars=yes,resizable=yes,status=no,location=no,toolbar=no,menubar=no');\r\n if (!popup) throw new Error('popup blocked');\r\n\r\n let touched = false; const it = setInterval(() => {\r\n try { if (popup.location && popup.location.hostname === 'onairos.uk') { touched = true; popup.close(); } } catch { if (!touched) touched = true; }\r\n try { if (popup.closed) { clearInterval(it); setIsConnecting(false); setConnectingPlatform(null); } } catch {}\r\n }, 800);\r\n\r\n setTimeout(() => { try { if (!popup.closed && touched) popup.close(); } catch {} }, 10000);\r\n setTimeout(() => { if (!popup.closed) { popup.close(); clearInterval(it); setIsConnecting(false); setConnectingPlatform(null); } }, 300000);\r\n return true;\r\n } catch {\r\n // On failure, revert the optimistic toggle\r\n setConnectedAccounts((s) => ({ ...s, [name]: false }));\r\n setIsConnecting(false); setConnectingPlatform(null); return false;\r\n }\r\n }\r\n\r\n const handleSwitch = async (name, llmConnectorManager = null) => {\r\n // Don't allow toggling other platforms while one is connecting\r\n if (isConnecting && connectingPlatform !== name) return;\r\n \r\n const on = !!connectedAccounts[name];\r\n \r\n if (on) {\r\n // Disconnect - always allow immediate toggle off\r\n console.log(`🔄 Disconnecting ${name}`);\r\n setConnectedAccounts((s) => ({ ...s, [name]: false }));\r\n setIsConnecting(false);\r\n setConnectingPlatform(null);\r\n } else {\r\n // Connect\r\n console.log(`🔄 Connecting ${name}`);\r\n const platform = allPlatforms.find(p => p.name === name);\r\n \r\n // Check if this is an LLM platform that should use extension detection\r\n if (platform && platform.directLink) {\r\n // For AI platforms: open their website and auto-toggle\r\n window.open(platform.directLink, '_blank');\r\n setConnectedAccounts((s) => ({ ...s, [name]: true }));\r\n \r\n // Also try LLM Connector Manager if available\r\n if (llmConnectorManager) {\r\n const platformKey = platform.connector;\r\n llmConnectorManager.connectToLLM(\r\n platformKey,\r\n (connectedPlatform) => {\r\n console.log(`✅ ${connectedPlatform} connected via extension`);\r\n },\r\n (errorPlatform, error) => {\r\n console.error(`❌ ${errorPlatform} connection error:`, error);\r\n }\r\n );\r\n }\r\n } else {\r\n // Use traditional OAuth flow for social media platforms\r\n await connectToPlatform(name);\r\n }\r\n }\r\n };\r\n\r\n const connectedCount = Object.values(connectedAccounts).filter(Boolean).length;\r\n\r\n useEffect(() => {\r\n if (!lottieRef.current) return;\r\n const totalFrames = (personaAnim.op || 0) - (personaAnim.ip || 0);\r\n const TOTAL_PLATFORMS = 9; // Total number of platforms across all pages\r\n const progress = connectedCount / TOTAL_PLATFORMS;\r\n const target = Math.max(0, Math.floor(progress * totalFrames));\r\n const start = lastFrameRef.current || 0;\r\n const duration = 420; const startTs = performance.now();\r\n const step = (now) => {\r\n const t = Math.min(1, (now - startTs) / duration);\r\n const eased = t < 0.5 ? 2*t*t : -1 + (4 - 2*t)*t;\r\n const frame = Math.floor(start + (target - start) * eased);\r\n lottieRef.current.goToAndStop(frame, true);\r\n if (t < 1) rafRef.current = requestAnimationFrame(step); else lastFrameRef.current = target;\r\n };\r\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\r\n rafRef.current = requestAnimationFrame(step);\r\n return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); };\r\n }, [connectedCount]);\r\n\r\n // swipe handlers for smooth paging\r\n const onTouchStart = (e) => { touchStartX.current = e.touches[0].clientX; touchDeltaX.current = 0; };\r\n const onTouchMove = (e) => { touchDeltaX.current = e.touches[0].clientX - touchStartX.current; };\r\n const onTouchEnd = () => {\r\n const dx = touchDeltaX.current; const THRESH = 40;\r\n if (dx < -THRESH && currentPage < 3) setCurrentPage(currentPage + 1);\r\n else if (dx > THRESH && currentPage > 1) setCurrentPage(currentPage - 1);\r\n };\r\n\r\n return (\r\n <LLMConnectorManager\r\n onConnectionChange={(platform, connected) => {\r\n const platformName = platform.charAt(0).toUpperCase() + platform.slice(1);\r\n const displayName = platformName === 'Chatgpt' ? 'ChatGPT' : platformName;\r\n setConnectedAccounts((s) => ({ ...s, [displayName]: connected }));\r\n }}\r\n username={localStorage.getItem('username') || (JSON.parse(localStorage.getItem('onairosUser') || '{}')?.email) || 'user@example.com'}\r\n >\r\n <style dangerouslySetInnerHTML={{ __html: fadeSlideInKeyframes }} />\r\n <div\r\n className=\"relative w-full h-full grid overflow-hidden\"\r\n style={{\r\n height: Math.min('90vh', Math.max(600, Math.min(720, vh * 0.9))),\r\n minHeight: 580,\r\n maxHeight: 720,\r\n gridTemplateRows: 'auto 1fr auto',\r\n }}\r\n >\r\n {/* persona bg */}\r\n <div\r\n aria-hidden\r\n style={{\r\n position: 'absolute',\r\n left: '50%',\r\n top: PERSONA_TOP,\r\n transform: 'translateX(-50%)',\r\n width: personaSide,\r\n height: personaSide,\r\n zIndex: 0,\r\n pointerEvents: 'none',\r\n opacity: 0.95,\r\n }}\r\n >\r\n <div className=\"overflow-hidden rounded-[28px] w-full h-full\">\r\n <Lottie\r\n lottieRef={lottieRef}\r\n animationData={personaAnim}\r\n autoplay={false}\r\n loop={false}\r\n style={{ width: '100%', height: '100%' }}\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* header */}\r\n <div className=\"px-6 pt-16 pb-4 text-center z-10\">\r\n <h1 className=\"text-2xl font-bold text-gray-900 mb-2 leading-tight\">Connect App Data</h1>\r\n <p className=\"text-gray-600 text-base\">More Connections, Better Personalization.</p>\r\n </div>\r\n\r\n {/* middle scrollable */}\r\n <div className=\"min-h-0 overflow-y-auto px-6 flex flex-col\" style={{ zIndex: 10, position: 'relative' }}>\r\n <div className=\"flex-1\" />\r\n {/* icons */}\r\n <div className=\"w-full mb-3\" style={{ zIndex: 15, position: 'relative' }}>\r\n <div className=\"grid w-full\" onTouchStart={onTouchStart} onTouchMove={onTouchMove} onTouchEnd={onTouchEnd} style={{ height: ICONS_H, gridAutoFlow: 'column', gridTemplateColumns: `repeat(${platforms.length}, minmax(0,1fr))`, columnGap: currentPage === 1 ? GAP_PAGE1 : GAP_PAGE2, alignItems: 'center', justifyItems: 'center', paddingInline: 8 }}>\r\n {platforms.map((p, idx) => {\r\n const on = !!connectedAccounts[p.name];\r\n const isSel = selected === p.name;\r\n const shift = (currentPage === 1 ? idx : idx - 2) * 14;\r\n return (\r\n <div key={p.name} style={{ opacity: 0, transform: `translateX(${shift}px)`, animation: 'fadeSlideIn 0.28s forwards', ['--slide-x']: `${shift}px` }}>\r\n <button type=\"button\" onClick={() => { setSelected(p.name); handleSwitch(p.name, llmConnectorManager); }} className=\"grid place-items-center outline-none\" style={{ width: SLOT, height: SLOT }} title={p.name}>\r\n <div className={`rounded-full border-3 flex items-center justify-center shadow transition-all ${on ? 'border-blue-600 shadow-blue-500/50' : 'border-gray-300 hover:border-gray-400'} bg-white`} style={{ width: CIRCLE, height: CIRCLE, transform: `scale(${isSel ? ACTIVE_SCALE : 1})` }}>\r\n {p.icon}\r\n </div>\r\n </button>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n {/* dots */}\r\n <div className=\"flex justify-center gap-4 mb-3\">\r\n {[1, 2, 3].map((n) => (\r\n <button key={n} onClick={() => setCurrentPage(n)} style={{ width: 12, height: 12 }}>\r\n <span className={`block rounded-full ${currentPage === n ? 'bg-blue-600 scale-110' : 'bg-gray-300'} transition-transform`} style={{ width: 12, height: 12 }} />\r\n </button>\r\n ))}\r\n </div>\r\n {/* card */}\r\n <div className=\"rounded-2xl bg-white shadow-sm border border-gray-200 px-4 py-2.5 mx-auto mb-2\" style={{ width: 'min(420px,90%)' }}>\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"text-gray-900 font-medium text-sm\">{selected}</div>\r\n <button type=\"button\" role=\"switch\" aria-checked={!!connectedAccounts[selected]} onClick={() => handleSwitch(selected, llmConnectorManager)} disabled={isConnecting && connectingPlatform !== selected} className={`relative inline-flex items-center transition-colors ${connectedAccounts[selected] ? 'bg-black' : 'bg-gray-200'} rounded-full`} style={{ width: 44, height: 26 }}>\r\n <span className=\"absolute bg-white rounded-full shadow\" style={{ width: 18, height: 18, transform: connectedAccounts[selected] ? 'translateX(20px)' : 'translateX(5px)', transition: 'transform 160ms ease' }} />\r\n </button>\r\n </div>\r\n <div className=\"mt-1.5 text-xs text-gray-700 leading-4 bg-gray-50 rounded-xl px-3 py-2\">\r\n {descriptions[selected] || null}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* footer anchored */}\r\n <div className=\"px-6 pb-4 pt-3 bg-gradient-to-t from-white via-white/90 to-transparent z-20\">\r\n <div className=\"w-full bg-gray-900 hover:bg-gray-800 text-white rounded-full py-4 text-base font-medium flex items-center justify-center gap-2 cursor-pointer transition-colors\" onClick={() => { const connected = Object.entries(connectedAccounts).filter(([, v]) => v).map(([k]) => k); onComplete?.({ connectedAccounts: connected, totalConnections: connected.length }); }}>\r\n Update\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" /></svg>\r\n </div>\r\n <div onClick={() => onComplete?.({ connectedAccounts: [], totalConnections: 0 })} className=\"w-full text-gray-600 text-base font-medium py-2 text-center cursor-pointer hover:text-gray-800 transition-colors\">Skip</div>\r\n </div>\r\n </div>\r\n </LLMConnectorManager>\r\n );\r\n}","import React, { useState, useEffect } from 'react';\r\n\r\nexport default function PinSetup({ onComplete, onBack, userEmail }) {\r\n const [pin, setPin] = useState('');\r\n const [pinRequirements, setPinRequirements] = useState({\r\n length: false,\r\n uppercase: false,\r\n number: false,\r\n });\r\n\r\n // Check PIN requirements\r\n useEffect(() => {\r\n setPinRequirements({\r\n length: pin.length >= 6,\r\n uppercase: /[A-Z]/.test(pin),\r\n number: /\\d/.test(pin),\r\n });\r\n }, [pin]);\r\n\r\n const allRequirementsMet = pinRequirements.length && pinRequirements.uppercase && pinRequirements.number;\r\n\r\n const handleSubmit = () => {\r\n if (allRequirementsMet) {\r\n onComplete({\r\n pin: pin, // This should be hashed in production\r\n pinCreated: true,\r\n timestamp: new Date().toISOString()\r\n });\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"w-full h-full flex flex-col\" style={{ height: '100%', minHeight: 0 }}>\r\n {/* Content - Flexible center area */}\r\n <div className=\"px-6 pt-16 flex-1 flex flex-col\" style={{ minHeight: 0, overflow: 'hidden' }}>\r\n <div className=\"mb-6 flex-shrink-0\">\r\n <h1 className=\"text-2xl font-bold text-gray-900 mb-2\">Create a PIN</h1>\r\n <p className=\"text-gray-600 text-base\">A PIN so only you have the access to your data</p>\r\n </div>\r\n\r\n <div className=\"mb-6 flex-shrink-0\">\r\n <input\r\n type=\"password\"\r\n value={pin}\r\n onChange={(e) => setPin(e.target.value)}\r\n className=\"w-full px-4 py-4 border-2 border-gray-300 rounded-xl text-center text-lg font-medium focus:border-gray-900 focus:outline-none bg-gray-50\"\r\n placeholder=\"Enter your PIN\"\r\n maxLength={20}\r\n />\r\n </div>\r\n\r\n {/* Scrollable requirements list */}\r\n <div className=\"flex-1 overflow-y-auto\" style={{ minHeight: 0 }}>\r\n <div className=\"space-y-3 pb-4\">\r\n <p className=\"text-gray-900 font-medium mb-4\">Your PIN must:</p>\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div\r\n className={`w-5 h-5 rounded-full border-2 ${pinRequirements.length ? \"border-green-500 bg-green-500\" : \"border-gray-300 bg-white\"}`}\r\n >\r\n {pinRequirements.length && (\r\n <svg className=\"w-3 h-3 text-white m-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\r\n </svg>\r\n )}\r\n </div>\r\n <span className=\"text-gray-700\">Be at least 6 characters in length.</span>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <div\r\n className={`w-5 h-5 rounded-full border-2 ${pinRequirements.uppercase ? \"border-green-500 bg-green-500\" : \"border-gray-300 bg-white\"}`}\r\n >\r\n {pinRequirements.uppercase && (\r\n <svg className=\"w-3 h-3 text-white m-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\r\n </svg>\r\n )}\r\n </div>\r\n <span className=\"text-gray-700\">Contain an uppercase letter.</span>\r\n </div>\r\n <div className=\"flex items-center gap-3\">\r\n <div\r\n className={`w-5 h-5 rounded-full border-2 ${pinRequirements.number ? \"border-green-500 bg-green-500\" : \"border-gray-300 bg-white\"}`}\r\n >\r\n {pinRequirements.number && (\r\n <svg className=\"w-3 h-3 text-white m-0.5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\r\n </svg>\r\n )}\r\n </div>\r\n <span className=\"text-gray-700\">Contain a number.</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Buttons - Fixed at bottom */}\r\n <div className=\"px-6 pb-6 pt-4 flex-shrink-0 space-y-3\" style={{ minHeight: 'auto' }}>\r\n <div\r\n className={`w-full rounded-full py-4 text-base font-medium flex items-center justify-center gap-2 transition-colors ${\r\n allRequirementsMet \r\n ? \"bg-gray-900 hover:bg-gray-800 text-white cursor-pointer\" \r\n : \"bg-gray-300 text-gray-500 cursor-not-allowed\"\r\n }`}\r\n onClick={allRequirementsMet ? handleSubmit : undefined}\r\n >\r\n Continue\r\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n} ","import React, { useState, useEffect } from 'react';\nimport PrimaryButton from './ui/PrimaryButton.jsx';\nimport { COLORS } from '../theme/colors.js';\n\nconst dataTypes = [\n { \n id: 'basic', \n name: 'Basic Profile', \n description: 'Essential profile information, account details, and basic demographics', \n icon: 'User',\n required: true,\n tooltip: 'Includes name, email, basic profile information. This data is essential for personalization and is always included.',\n privacyLink: 'https://onairos.uk/privacy#basic-info'\n },\n { \n id: 'preferences', \n name: 'User Preferences', \n description: 'User preferences, interests, settings and personal choices', \n icon: 'Grid3X3',\n required: false,\n tooltip: 'Your stated preferences and interests from connected platforms. Helps customize your experience.',\n privacyLink: 'https://onairos.uk/privacy#preferences-data'\n },\n { \n id: 'personality', \n name: 'Personality Traits', \n description: 'Personality traits, behavioral patterns and psychological insights', \n icon: 'Brain',\n required: false,\n tooltip: 'AI-analyzed personality traits based on your social media activity and interactions. Used to improve content recommendations.',\n privacyLink: 'https://onairos.uk/privacy#personality-data'\n }\n];\n\n// Data Type Toggle Component with compact checkbox design\nconst DataTypeToggle = ({ dataType, isEnabled, onToggle, isLast }) => {\n const handleToggle = () => {\n if (dataType.required) return; // Don't allow toggling required items\n onToggle(dataType.id, !isEnabled);\n };\n\n const getIconComponent = (iconName) => {\n const iconProps = { className: \"w-4 h-4 text-gray-600\" };\n \n switch (iconName) {\n case 'User':\n return (\n <svg {...iconProps} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\" />\n </svg>\n );\n case 'Grid3X3':\n return (\n <svg {...iconProps} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z\" />\n </svg>\n );\n case 'Brain':\n return (\n <svg {...iconProps} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z\" />\n </svg>\n );\n default:\n return <span className=\"text-lg\">{iconName}</span>;\n }\n };\n\n return (\n <div className=\"flex items-center justify-between p-3 rounded-lg bg-gray-50\">\n <div className=\"flex items-center gap-4\">\n <div className=\"w-8 h-8 bg-gray-200 rounded-full flex items-center justify-center flex-shrink-0\">\n {getIconComponent(dataType.icon)}\n </div>\n <div className=\"min-w-0 flex-1\">\n <span className=\"font-medium text-gray-900 text-sm\">{dataType.name}</span>\n </div>\n </div>\n <div\n onClick={handleToggle}\n className={`w-5 h-5 rounded border-2 flex items-center justify-center cursor-pointer transition-colors flex-shrink-0 ${\n isEnabled ? \"bg-gray-900 border-gray-900\" : \"bg-white border-gray-300\"\n }`}\n >\n {isEnabled && (\n <svg className=\"w-3 h-3 text-white\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )}\n </div>\n </div>\n );\n};\n\nconst DataRequest = ({ \n userEmail = 'user@example.com', \n testMode = false, \n onComplete, \n autoFetch = true,\n appName = 'Test App',\n formatResponse = false,\n responseFormat = 'simple'\n}) => {\n const [selectedData, setSelectedData] = useState({\n basic: true, // Always true for required data\n personality: false,\n preferences: false\n });\n const [isLoadingApi, setIsLoadingApi] = useState(false);\n const [apiError, setApiError] = useState(null);\n\n const handleDataToggle = (dataId, enabled) => {\n const dataType = dataTypes.find(dt => dt.id === dataId);\n if (dataType?.required) return; // Don't allow toggling required items\n\n setSelectedData(prev => ({\n ...prev,\n [dataId]: enabled\n }));\n };\n\n const generateUserHash = (email) => {\n let hash = 0;\n const str = email + Date.now().toString();\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return `user_${Math.abs(hash).toString(36)}`;\n };\n\n const fetchUserData = async () => {\n console.log('🔥 DataRequest: fetchUserData called');\n console.log('🔥 DataRequest: onComplete function:', typeof onComplete);\n console.log('🔥 DataRequest: selectedData:', selectedData);\n console.log('🔥 DataRequest: selectedCount:', selectedCount);\n \n setIsLoadingApi(true);\n setApiError(null);\n \n try {\n const userHash = generateUserHash(userEmail);\n \n // Get selected data types\n const approvedData = Object.entries(selectedData)\n .filter(([key, value]) => value)\n .map(([key]) => key);\n\n const mapDataTypesToConfirmations = (approvedData) => {\n const confirmations = [];\n const currentDate = new Date().toISOString();\n \n const dataTypeMapping = {\n 'basic': 'Medium',\n 'personality': 'Large', \n 'preferences': 'Traits'\n };\n \n approvedData.forEach(dataType => {\n if (dataTypeMapping[dataType]) {\n confirmations.push({\n data: dataTypeMapping[dataType],\n date: currentDate\n });\n }\n });\n \n return confirmations;\n };\n\n const apiEndpoint = testMode \n ? 'https://api2.onairos.uk/inferenceTest'\n : 'https://api2.onairos.uk/getAPIurlMobile';\n \n const baseResult = {\n userHash,\n appName,\n approvedData,\n apiUrl: apiEndpoint,\n testMode,\n timestamp: new Date().toISOString()\n };\n\n if (autoFetch) {\n if (testMode) {\n // Test mode: Skip API call completely, simulate response\n console.log('🧪 Test mode: Simulating data request API call for:', approvedData);\n \n setTimeout(() => {\n const simulatedApiData = {\n success: true,\n message: \"Data request simulated successfully\",\n data: {\n personalityScores: {\n openness: 0.75,\n conscientiousness: 0.68,\n extraversion: 0.82,\n agreeableness: 0.71,\n neuroticism: 0.43\n },\n insights: [\n \"You show high creativity and openness to new experiences\",\n \"Strong social tendencies with good interpersonal skills\",\n \"Well-organized approach to tasks and goals\"\n ],\n dataProcessed: approvedData,\n timestamp: new Date().toISOString(),\n testMode: true\n }\n };\n\n const result = {\n ...baseResult,\n apiResponse: simulatedApiData,\n success: true,\n simulated: true\n };\n\n setIsLoadingApi(false);\n console.log('🧪 Test mode: Simulated data request completed:', result);\n console.log('🔥 DataRequest: onComplete function type:', typeof onComplete);\n if (onComplete && typeof onComplete === 'function') {\n onComplete(result);\n console.log('🔥 DataRequest: onComplete called successfully (test mode)');\n } else {\n console.error('🔥 DataRequest: onComplete is not a function or is undefined (test mode)');\n }\n }, 1200); // Simulate realistic processing time\n } else {\n // Production mode: Make real API call\n try {\n const confirmations = mapDataTypesToConfirmations(approvedData);\n \n const requestBody = {\n approvedData,\n userEmail,\n appName,\n confirmations\n };\n\n console.log('🔥 DataRequest: Making API call to:', apiEndpoint);\n console.log('🔥 Request body:', requestBody);\n\n const apiResponse = await fetch(apiEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody)\n });\n\n if (!apiResponse.ok) {\n throw new Error(`API request failed with status ${apiResponse.status}`);\n }\n\n const apiData = await apiResponse.json();\n console.log('🔥 API Response:', apiData);\n\n const result = {\n ...baseResult,\n apiResponse: apiData,\n success: true\n };\n\n setIsLoadingApi(false);\n console.log('🔥 DataRequest: Calling onComplete with result:', result);\n console.log('🔥 DataRequest: onComplete function type:', typeof onComplete);\n if (onComplete && typeof onComplete === 'function') {\n onComplete(result);\n console.log('🔥 DataRequest: onComplete called successfully');\n } else {\n console.error('🔥 DataRequest: onComplete is not a function or is undefined');\n }\n\n } catch (apiError) {\n console.error('🔥 API Error:', apiError);\n setApiError(apiError.message);\n setIsLoadingApi(false);\n \n const errorResult = {\n ...baseResult,\n apiResponse: null,\n error: apiError.message,\n success: false\n };\n \n onComplete(errorResult);\n }\n }\n } else {\n setIsLoadingApi(false);\n console.log('🔥 DataRequest: Auto-fetch disabled, calling onComplete with base result');\n console.log('🔥 DataRequest: onComplete function type:', typeof onComplete);\n if (onComplete && typeof onComplete === 'function') {\n onComplete(baseResult);\n console.log('🔥 DataRequest: onComplete called successfully (auto-fetch disabled)');\n } else {\n console.error('🔥 DataRequest: onComplete is not a function or is undefined (auto-fetch disabled)');\n }\n }\n } catch (error) {\n console.error('🔥 DataRequest Error:', error);\n setApiError(error.message);\n setIsLoadingApi(false);\n \n if (onComplete) {\n onComplete({\n error: error.message,\n success: false,\n userEmail,\n appName,\n testMode\n });\n }\n }\n };\n\n // Count selected data types\n const selectedCount = Object.values(selectedData).filter(Boolean).length;\n\n return (\n <div className=\"w-full h-full flex flex-col min-h-0\">\n {/* Content - Flexible center area with proper constraints */}\n <div className=\"px-6 pt-16 flex-1 flex flex-col min-h-0\" style={{ minHeight: 'calc(100vh - 200px)' }}>\n {/* Icon Flow */}\n <div className=\"mb-4 flex justify-center items-center gap-4 flex-shrink-0\">\n <div className=\"w-12 h-12 bg-white rounded-xl shadow-lg flex items-center justify-center border border-gray-100\">\n <svg className=\"w-6 h-6\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M12 2C13.1 2 14 2.9 14 4C14 5.1 13.1 6 12 6C10.9 6 10 5.1 10 4C10 2.9 10.9 2 12 2Z\"\n fill=\"black\"\n />\n <path\n d=\"M21 9V7L15 6.5V9C15 10.66 13.66 12 12 12C10.34 12 9 10.66 9 9V6.5L3 7V9C3 12.87 6.13 16 10 16V22H14V16C17.87 16 21 12.87 21 9Z\"\n fill=\"black\"\n />\n </svg>\n </div>\n <svg className=\"w-4 h-4 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n <div className=\"w-12 h-12 bg-white rounded-xl shadow-lg flex items-center justify-center border border-gray-100\">\n <span className=\"text-xl font-serif font-bold text-black\">E</span>\n </div>\n </div>\n\n {/* Title Section */}\n <div className=\"mb-4 flex-shrink-0\">\n <h1 className=\"text-xl font-bold text-gray-900 mb-2 text-balance leading-tight\">\n Enoch wants to personalize your experience\n </h1>\n <p className=\"text-gray-600 text-sm\">Choose what to share:</p>\n </div>\n\n {/* Consent Options - Scrollable area */}\n <div className=\"flex-1 overflow-y-auto min-h-0\">\n <div className=\"space-y-4 pb-4\">\n {dataTypes.map((dataType, index) => (\n <DataTypeToggle\n key={dataType.id}\n dataType={dataType}\n isEnabled={selectedData[dataType.id]}\n onToggle={handleDataToggle}\n isLast={index === dataTypes.length - 1}\n />\n ))}\n </div>\n </div>\n </div>\n\n {/* Buttons - Fixed at bottom with guaranteed visibility */}\n <div className=\"px-6 pb-6 pt-3 flex-shrink-0 space-y-2 bg-white border-t border-gray-100\">\n <div\n className=\"w-full bg-gray-900 hover:bg-gray-800 text-white rounded-full py-3 text-sm font-medium flex items-center justify-center gap-2 cursor-pointer transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n onClick={fetchUserData}\n disabled={isLoadingApi || selectedCount === 0}\n >\n {isLoadingApi ? \"Processing...\" : \"Accept & Continue\"}\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </div>\n <div\n onClick={() => onComplete({ cancelled: true })}\n className=\"w-full bg-gray-200 hover:bg-gray-300 text-gray-700 rounded-full py-3 text-sm font-medium text-center cursor-pointer transition-colors\"\n >\n Decline\n </div>\n\n {/* Error display */}\n {apiError && (\n <div className=\"mt-3 p-3 rounded-lg text-center bg-red-50 border border-red-200 text-red-600\">\n <p className=\"text-xs\">{apiError}</p>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default DataRequest; ","import React, { useState, useEffect } from 'react';\nimport { COLORS } from '../theme/colors.js';\n\nexport default function TrainingComponent({ onComplete, userEmail, appName = 'App', testMode = false }) {\n const [currentStep, setCurrentStep] = useState(0);\n const [progress, setProgress] = useState(0);\n const [isComplete, setIsComplete] = useState(false);\n\n const steps = [\n {\n title: 'Setting up your personal AI',\n description: 'Initializing your secure data model',\n icon: '🤖',\n duration: testMode ? 800 : 2000 // Much faster in test mode\n },\n {\n title: 'Processing your connections',\n description: 'Analyzing your social media patterns',\n icon: '🔗',\n duration: testMode ? 600 : 2500\n },\n {\n title: 'Training your model',\n description: 'Building your personalized insights',\n icon: '🧠',\n duration: testMode ? 700 : 3000\n },\n {\n title: 'Finalizing setup',\n description: 'Preparing your Onairos experience',\n icon: '✨',\n duration: testMode ? 500 : 2000\n }\n ];\n\n useEffect(() => {\n let interval;\n let stepTimeout;\n\n if (currentStep < steps.length) {\n const stepDuration = steps[currentStep].duration;\n const stepProgress = 100 / steps.length;\n\n // Update progress gradually\n interval = setInterval(() => {\n setProgress(prev => {\n const newProgress = prev + (stepProgress / (stepDuration / 100));\n return Math.min(newProgress, (currentStep + 1) * stepProgress);\n });\n }, 100);\n\n // Move to next step after duration\n stepTimeout = setTimeout(() => {\n if (currentStep < steps.length - 1) {\n setCurrentStep(prev => prev + 1);\n } else {\n setIsComplete(true);\n const completionDelay = testMode ? 400 : 1000; // Faster completion in test mode\n \n if (testMode) {\n console.log('🧪 Test mode: Training simulation completed');\n }\n \n setTimeout(() => {\n onComplete({\n trainingComplete: true,\n timestamp: new Date().toISOString(),\n userEmail: userEmail,\n appName: appName,\n testMode: testMode,\n simulatedTraining: testMode\n });\n }, completionDelay);\n }\n }, stepDuration);\n }\n\n return () => {\n if (interval) clearInterval(interval);\n if (stepTimeout) clearTimeout(stepTimeout);\n };\n }, [currentStep, onComplete, userEmail, appName]);\n\n return (\n <div className=\"w-full flex flex-col items-center space-y-8\">\n <div className=\"text-center\">\n <div \n className=\"w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4\"\n style={{\n background: `linear-gradient(135deg, ${COLORS.info}, #8B5CF6)`\n }}\n >\n <div className=\"text-3xl\">\n {isComplete ? '🎉' : steps[currentStep]?.icon}\n </div>\n </div>\n <h2 \n className=\"text-2xl font-bold mb-2\"\n style={{ color: COLORS.textPrimary }}\n >\n {isComplete ? 'All set!' : steps[currentStep]?.title}\n </h2>\n <p style={{ color: COLORS.textSecondary }}>\n {isComplete \n ? 'Your personal AI is ready to use' \n : steps[currentStep]?.description\n }\n </p>\n </div>\n\n {/* Progress Bar */}\n <div className=\"w-full\">\n <div \n className=\"flex justify-between text-sm mb-2\"\n style={{ color: COLORS.textSecondary }}\n >\n <span>Progress</span>\n <span>{Math.round(progress)}%</span>\n </div>\n <div \n className=\"w-full rounded-full h-2\"\n style={{ backgroundColor: COLORS.borderLight }}\n >\n <div \n className=\"h-2 rounded-full transition-all duration-300 ease-out\"\n style={{ \n width: `${progress}%`,\n background: `linear-gradient(90deg, ${COLORS.info}, #8B5CF6)`\n }}\n />\n </div>\n </div>\n\n {/* Steps Indicator */}\n <div className=\"flex justify-center space-x-2\">\n {steps.map((_, index) => (\n <div\n key={index}\n className=\"w-3 h-3 rounded-full transition-all duration-300\"\n style={{\n backgroundColor: index <= currentStep ? COLORS.info : COLORS.border\n }}\n />\n ))}\n </div>\n\n {/* Current Step Details */}\n <div \n className=\"p-4 rounded-lg w-full\"\n style={{ backgroundColor: COLORS.backgroundSecondary }}\n >\n <div className=\"flex items-center space-x-3\">\n <div \n className=\"w-8 h-8 rounded-full flex items-center justify-center\"\n style={{ backgroundColor: '#DBEAFE' }}\n >\n <div className=\"text-sm\">\n {isComplete ? '✅' : steps[currentStep]?.icon}\n </div>\n </div>\n <div>\n <h3 \n className=\"font-medium\"\n style={{ color: COLORS.textPrimary }}\n >\n {isComplete ? 'Training Complete' : `Step ${currentStep + 1} of ${steps.length}`}\n </h3>\n <p \n className=\"text-sm\"\n style={{ color: COLORS.textSecondary }}\n >\n {isComplete \n ? 'Your Onairos experience is ready' \n : steps[currentStep]?.description\n }\n </p>\n </div>\n </div>\n </div>\n\n {/* App Info */}\n <div className=\"text-center\">\n <p \n className=\"text-sm\"\n style={{ color: COLORS.textSecondary }}\n >\n Setting up for <span className=\"font-medium\">{appName}</span>\n </p>\n {userEmail && (\n <p \n className=\"text-xs mt-1\"\n style={{ color: COLORS.textMuted }}\n >\n {userEmail}\n </p>\n )}\n </div>\n </div>\n );\n} ","import React, { useState, useEffect } from \"react\";\r\nimport Lottie from 'lottie-react';\r\nimport rainAnim from '../../public/rain-anim.json';\r\n\r\nexport default function LoadingScreen({ onComplete }) {\r\n const [currentStep, setCurrentStep] = useState(0);\r\n const [dotCount, setDotCount] = useState(0);\r\n\r\n const loadingStates = [\r\n { message: \"Validating PIN and continuing training\", progress: 20 },\r\n { message: \"Uploading model to secure storage\", progress: 40 },\r\n { message: \"Running test inference\", progress: 60 },\r\n { message: \"Storing results in databases\", progress: 80 },\r\n { message: \"Complete!\", progress: 100 },\r\n ];\r\n\r\n useEffect(() => {\r\n const stateInterval = setInterval(() => {\r\n setCurrentStep((prev) => {\r\n const nextStep = prev + 1;\r\n if (nextStep >= loadingStates.length) {\r\n // Loading complete, call onComplete after a short delay\r\n setTimeout(() => {\r\n onComplete();\r\n }, 1000);\r\n return prev; // Keep at last step\r\n }\r\n return nextStep;\r\n });\r\n }, 3000); // Change state every 3 seconds\r\n\r\n return () => clearInterval(stateInterval);\r\n }, [loadingStates.length, onComplete]);\r\n\r\n useEffect(() => {\r\n const dotInterval = setInterval(() => {\r\n setDotCount((prev) => (prev + 1) % 4); // 0, 1, 2, 3 dots\r\n }, 500); // Change dots every 500ms\r\n\r\n return () => clearInterval(dotInterval);\r\n }, []);\r\n\r\n const currentState = loadingStates[currentStep];\r\n\r\n return (\r\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647, pointerEvents: 'auto' }}>\r\n {/* Modal - Full height from bottom */}\r\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\r\n {/* Header */}\r\n <div className=\"px-6 pt-6 pb-4 flex-shrink-0\">\r\n </div>\r\n\r\n {/* Content - Rain animation and loading state */}\r\n <div className=\"flex-1 flex flex-col px-6\">\r\n {/* Rain Animation */}\r\n <div className=\"flex-1 flex items-center justify-center\">\r\n <div style={{ width: '100%', maxWidth: '400px', aspectRatio: '1' }}>\r\n <Lottie\r\n animationData={rainAnim}\r\n loop={true}\r\n autoplay={true}\r\n style={{ width: '100%', height: '100%' }}\r\n />\r\n </div>\r\n </div>\r\n\r\n {/* Loading State - Positioned at bottom */}\r\n <div className=\"flex-shrink-0 pb-12\">\r\n <div className=\"text-center\">\r\n <h1 className=\"font-bold text-gray-900 leading-tight mb-6\" style={{ fontSize: 'clamp(16px, 4vw, 20px)' }}>\r\n {currentState.message}\r\n {currentState.message !== \"Complete!\" && (\r\n <span className=\"inline-block w-8 text-left\">{\".\".repeat(dotCount)}</span>\r\n )}\r\n </h1>\r\n\r\n <div className=\"mx-auto\" style={{ width: 'clamp(200px, 50vw, 300px)' }}>\r\n <div className=\"w-full h-2 bg-gray-200 rounded-full\">\r\n <div\r\n className=\"h-2 bg-gray-900 rounded-full transition-all duration-1000 ease-out\"\r\n style={{ width: `${currentState.progress}%` }}\r\n ></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Bottom spacing */}\r\n <div className=\"h-20 flex-shrink-0\"></div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","/**\r\n * Response formatter utility for Onairos SDK\r\n * Converts array-based responses to dictionary format for better developer experience\r\n */\r\n\r\n// Standard 16 personality types in order that the API returns them\r\nexport const PERSONALITY_TYPES = [\r\n 'Analyst',\r\n 'Diplomat', \r\n 'Sentinel',\r\n 'Explorer',\r\n 'Architect',\r\n 'Logician',\r\n 'Commander',\r\n 'Debater',\r\n 'Advocate',\r\n 'Mediator',\r\n 'Protagonist',\r\n 'Campaigner',\r\n 'Logistician',\r\n 'Defender',\r\n 'Executive',\r\n 'Consul'\r\n];\r\n\r\n// Standard trait categories that might be returned\r\nexport const TRAIT_CATEGORIES = [\r\n 'Openness',\r\n 'Conscientiousness',\r\n 'Extraversion',\r\n 'Agreeableness',\r\n 'Neuroticism'\r\n];\r\n\r\n/**\r\n * Formats API response to include both array and dictionary formats\r\n * @param {Object} apiResponse - Raw API response from Onairos\r\n * @param {Object} options - Formatting options\r\n * @param {boolean} options.includeDictionary - Whether to include dictionary format (default: true)\r\n * @param {boolean} options.includeArray - Whether to include original array format (default: true)\r\n * @returns {Object} Formatted response with both formats\r\n */\r\nexport function formatOnairosResponse(apiResponse, options = {}) {\r\n const { includeDictionary = true, includeArray = true } = options;\r\n \r\n if (!apiResponse) {\r\n return apiResponse;\r\n }\r\n\r\n const formatted = { ...apiResponse };\r\n\r\n // Handle personality scores if present\r\n if (apiResponse.InferenceResult?.traits || apiResponse.traits || apiResponse.scores) {\r\n const scores = apiResponse.InferenceResult?.traits || apiResponse.traits || apiResponse.scores;\r\n \r\n if (Array.isArray(scores) && scores.length >= 16) {\r\n if (includeDictionary) {\r\n // Create personality dictionary\r\n const personalityDict = {};\r\n PERSONALITY_TYPES.forEach((type, index) => {\r\n personalityDict[type] = scores[index];\r\n });\r\n \r\n // Add to formatted response\r\n if (formatted.InferenceResult) {\r\n formatted.InferenceResult.personalityDict = personalityDict;\r\n } else {\r\n formatted.personalityDict = personalityDict;\r\n }\r\n }\r\n \r\n if (!includeArray) {\r\n // Remove array format if not requested\r\n if (formatted.InferenceResult?.traits) {\r\n delete formatted.InferenceResult.traits;\r\n }\r\n if (formatted.traits) {\r\n delete formatted.traits;\r\n }\r\n if (formatted.scores) {\r\n delete formatted.scores;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Handle trait data if present (for preferences/traits)\r\n if (apiResponse.traitResult || apiResponse.traits) {\r\n const traits = apiResponse.traitResult || apiResponse.traits;\r\n \r\n if (Array.isArray(traits) && includeDictionary) {\r\n const traitDict = {};\r\n TRAIT_CATEGORIES.forEach((category, index) => {\r\n if (traits[index] !== undefined) {\r\n traitDict[category] = traits[index];\r\n }\r\n });\r\n \r\n formatted.traitDict = traitDict;\r\n }\r\n }\r\n\r\n return formatted;\r\n}\r\n\r\n/**\r\n * Legacy formatter for backward compatibility\r\n * Converts scores array to personality dictionary only\r\n * @param {Array} scores - Array of personality scores\r\n * @returns {Object} Dictionary with personality type names as keys\r\n */\r\nexport function formatPersonalityScores(scores) {\r\n if (!Array.isArray(scores) || scores.length < 16) {\r\n console.warn('Invalid scores array provided to formatPersonalityScores');\r\n return {};\r\n }\r\n\r\n const personalityDict = {};\r\n PERSONALITY_TYPES.forEach((type, index) => {\r\n personalityDict[type] = scores[index];\r\n });\r\n \r\n return personalityDict;\r\n}\r\n\r\n/**\r\n * Get personality type names in order\r\n * @returns {Array} Array of personality type names\r\n */\r\nexport function getPersonalityTypes() {\r\n return [...PERSONALITY_TYPES];\r\n}\r\n\r\n/**\r\n * Get trait category names in order \r\n * @returns {Array} Array of trait category names\r\n */\r\nexport function getTraitCategories() {\r\n return [...TRAIT_CATEGORIES];\r\n} ","import React from 'react';\r\nimport { COLORS } from '../../theme/colors.js';\r\n\r\n// Standardized page layout component with white background\r\nconst PageLayout = ({\r\n children,\r\n title,\r\n subtitle,\r\n icon,\r\n showHeader = true,\r\n showCloseButton = false,\r\n onClose,\r\n onBack,\r\n showBackButton = false,\r\n className = '',\r\n contentClassName = '',\r\n centerContent = true,\r\n style = {},\r\n ...props\r\n}) => {\r\n const layoutStyle = {\r\n backgroundColor: COLORS.background,\r\n minHeight: '100%',\r\n width: '100%',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n ...style\r\n };\r\n\r\n const headerStyle = {\r\n position: 'sticky',\r\n top: 0,\r\n backgroundColor: COLORS.background,\r\n zIndex: 10,\r\n padding: 'clamp(8px, 2vw, 16px) clamp(16px, 4vw, 32px) clamp(6px, 1.5vw, 12px)'\r\n };\r\n\r\n const contentStyle = {\r\n flex: 1,\r\n padding: 'clamp(16px, 4vw, 32px)',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n overflow: 'auto',\r\n minHeight: 0, // Allow flex item to shrink below content size\r\n ...(centerContent && {\r\n alignItems: 'center',\r\n justifyContent: 'flex-start'\r\n })\r\n };\r\n\r\n const titleStyle = {\r\n fontFamily: 'Inter, system-ui, sans-serif',\r\n fontSize: 'clamp(20px, 5vw, 28px)',\r\n fontWeight: '700',\r\n color: COLORS.textPrimary,\r\n margin: '0 0 clamp(6px, 1.5vw, 12px) 0',\r\n textAlign: centerContent ? 'center' : 'left',\r\n lineHeight: '1.2'\r\n };\r\n\r\n const subtitleStyle = {\r\n fontFamily: 'Inter, system-ui, sans-serif',\r\n fontSize: 'clamp(14px, 3.5vw, 18px)',\r\n fontWeight: '400',\r\n color: COLORS.textSecondary,\r\n margin: '0 0 clamp(20px, 5vw, 40px) 0',\r\n textAlign: centerContent ? 'center' : 'left',\r\n lineHeight: '1.5'\r\n };\r\n\r\n const iconStyle = {\r\n width: 'clamp(40px, 8vw, 56px)',\r\n height: 'clamp(40px, 8vw, 56px)',\r\n margin: '0 auto clamp(16px, 4vw, 32px)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n fontSize: 'clamp(20px, 5vw, 28px)'\r\n };\r\n\r\n return (\r\n <div \r\n className={`onairos-page-layout ${className}`}\r\n style={layoutStyle}\r\n {...props}\r\n >\r\n {/* Header with navigation */}\r\n {showHeader && (\r\n <div style={headerStyle}>\r\n <div className=\"flex items-center justify-between\">\r\n {/* Back button */}\r\n {showBackButton && onBack && (\r\n <button\r\n onClick={onBack}\r\n className=\"flex items-center justify-center w-8 h-8 rounded-full hover:bg-gray-100 transition-colors\"\r\n aria-label=\"Go back\"\r\n >\r\n <span style={{ fontSize: '16px', color: COLORS.textPrimary }}>←</span>\r\n </button>\r\n )}\r\n\r\n\r\n {/* Close button */}\r\n {showCloseButton && onClose && (\r\n <button\r\n onClick={onClose}\r\n className=\"flex items-center justify-center w-8 h-8 rounded-full hover:bg-gray-100 transition-colors\"\r\n aria-label=\"Close\"\r\n >\r\n <span style={{ fontSize: '16px', color: COLORS.textPrimary }}>×</span>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Main content area */}\r\n <div \r\n className={`onairos-page-content ${contentClassName}`}\r\n style={contentStyle}\r\n >\r\n {/* Icon */}\r\n {icon && (\r\n <div style={iconStyle}>\r\n {typeof icon === 'string' ? <span>{icon}</span> : icon}\r\n </div>\r\n )}\r\n\r\n {/* Title */}\r\n {title && (\r\n <h1 style={titleStyle}>\r\n {title}\r\n </h1>\r\n )}\r\n\r\n {/* Subtitle */}\r\n {subtitle && (\r\n <p style={subtitleStyle}>\r\n {subtitle}\r\n </p>\r\n )}\r\n\r\n {/* Page content */}\r\n {children}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n// Modal wrapper component for overlay-style pages\r\nconst ModalPageLayout = ({\r\n children,\r\n visible = true,\r\n onClose,\r\n onBackdropClick,\r\n backdropStyle = {},\r\n modalStyle = {},\r\n ...pageLayoutProps\r\n}) => {\r\n if (!visible) return null;\r\n\r\n const backdropStyles = {\r\n position: 'fixed',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\r\n zIndex: 2147483647,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'opacity 200ms ease',\r\n willChange: 'opacity',\r\n ...backdropStyle\r\n };\r\n\r\n const modalStyles = {\r\n backgroundColor: COLORS.background,\r\n borderTopLeftRadius: '24px',\r\n borderTopRightRadius: '24px',\r\n borderBottomLeftRadius: '24px',\r\n borderBottomRightRadius: '24px',\r\n height: '90vh',\r\n width: '100%',\r\n maxWidth: '500px',\r\n boxShadow: '0 -10px 40px rgba(0, 0, 0, 0.3)',\r\n overflow: 'hidden',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n transform: 'translateY(0)',\r\n transition: 'transform 220ms ease, opacity 220ms ease',\r\n willChange: 'transform, opacity',\r\n ...modalStyle\r\n };\r\n\r\n const handleBackdropClick = (e) => {\r\n if (e.target === e.currentTarget) {\r\n if (onBackdropClick) {\r\n onBackdropClick();\r\n } else if (onClose) {\r\n onClose();\r\n }\r\n }\r\n };\r\n\r\n return (\r\n <div style={backdropStyles} onClick={handleBackdropClick}>\r\n <div style={modalStyles}>\r\n <PageLayout\r\n showHeader={true}\r\n showCloseButton={true}\r\n onClose={onClose}\r\n {...pageLayoutProps}\r\n >\r\n {children}\r\n </PageLayout>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport { ModalPageLayout };\r\nexport default PageLayout; ","import React, { useEffect, useState } from 'react';\nimport WelcomeScreen from './components/WelcomeScreen.jsx';\nimport EmailAuth from './components/EmailAuth.js';\nimport UniversalOnboarding from './components/UniversalOnboarding.jsx';\nimport PinSetup from './components/PinSetup.js';\nimport DataRequest from './components/DataRequest.js';\nimport TrainingComponent from './components/TrainingComponent.jsx';\nimport LoadingScreen from './components/LoadingScreen.jsx';\nimport { formatOnairosResponse } from './utils/responseFormatter.js';\nimport { ModalPageLayout } from './components/ui/PageLayout.jsx';\n\nexport function OnairosButton({\n requestData, \n webpageName, \n inferenceData = null, \n onComplete = null, \n autoFetch = true, // Auto-enabled for seamless testing experience\n testMode = false, // Production mode by default - set to true for testing\n proofMode = false, \n textLayout = 'below', \n textColor = 'white',\n login = false,\n buttonType = 'pill',\n loginReturn = null,\n loginType = 'signIn',\n visualType = 'full',\n appIcon = null,\n enableTraining = true,\n formatResponse = true,\n responseFormat = { includeDictionary: true, includeArray: true },\n priorityPlatform = null // Platform to prioritize (e.g., 'gmail', 'pinterest', 'linkedin')\n}) {\n\n const [showOverlay, setShowOverlay] = useState(false);\n const [currentFlow, setCurrentFlow] = useState('welcome'); // 'welcome' | 'email' | 'onboarding' | 'pin' | 'dataRequest' (training is within onboarding)\n const [userData, setUserData] = useState(null);\n const [error, setError] = useState(null);\n\n // Check for existing user session\n useEffect(() => {\n const checkExistingSession = () => {\n // In test mode, always start fresh to see the full flow\n if (testMode) {\n console.log('🧪 Test mode: Starting fresh flow, clearing any cached user data');\n localStorage.removeItem('onairosUser');\n setCurrentFlow('welcome');\n return;\n }\n \n const savedUser = localStorage.getItem('onairosUser');\n if (savedUser) {\n try {\n const user = JSON.parse(savedUser);\n setUserData(user);\n // If user has completed onboarding and PIN setup, go directly to data request\n if (user.onboardingComplete && user.pinCreated) {\n setCurrentFlow('dataRequest');\n } else if (user.verified && !user.onboardingComplete) {\n setCurrentFlow('onboarding');\n } else if (user.onboardingComplete && !user.pinCreated) {\n setCurrentFlow('pin');\n }\n } catch (error) {\n console.error('Error parsing saved user data:', error);\n localStorage.removeItem('onairosUser');\n }\n }\n };\n\n checkExistingSession();\n }, [testMode]);\n\n const openTerminal = async () => {\n try {\n console.log('🔥 openTerminal called - resetting flow');\n // ALWAYS reset flow on open to start fresh every time\n setCurrentFlow('welcome');\n setUserData(null);\n try { localStorage.removeItem('onairosUser'); } catch {}\n setShowOverlay(true);\n } catch (error) {\n console.error('Error in openTerminal:', error);\n }\n };\n\n const handleCloseOverlay = () => {\n setShowOverlay(false);\n setError(null);\n // Reset flow and session so next open starts fresh\n setCurrentFlow('welcome');\n try { localStorage.removeItem('onairosUser'); } catch {}\n setUserData(null);\n };\n\n // Handle clicks on the backdrop to close modal\n const handleBackdropClick = (e) => {\n if (e.target === e.currentTarget) {\n handleCloseOverlay();\n }\n };\n\n const handleWelcomeContinue = () => {\n console.log('🔥 Welcome screen continue clicked');\n setCurrentFlow('email');\n };\n\n const handleEmailAuthSuccess = (authData) => {\n console.log('🔥 Email auth successful:', authData);\n console.log('🔧 User State:', {\n isNewUser: authData.isNewUser,\n userState: authData.userState,\n flowType: authData.flowType,\n existingUser: authData.existingUser,\n hasAccountInfo: !!authData.accountInfo\n });\n \n // Determine flow based on API response - more explicit checking\n const isNewUser = authData.isNewUser === true || \n authData.existingUser === false || \n authData.flowType === 'onboarding' || \n authData.userState === 'new' ||\n !authData.accountInfo; // No account info means new user\n \n console.log('🔍 Flow determination:', {\n finalDecision: isNewUser ? 'NEW USER → onboarding (data connectors)' : 'EXISTING USER → dataRequest (data permissions)',\n reasoning: {\n isNewUser: authData.isNewUser,\n existingUserFalse: authData.existingUser === false,\n flowTypeOnboarding: authData.flowType === 'onboarding',\n noAccountInfo: !authData.accountInfo\n }\n });\n \n const newUserData = {\n ...authData,\n verified: true,\n onboardingComplete: !isNewUser, // New users need onboarding, returning users have completed it\n pinCreated: !isNewUser // Assume returning users have PIN, new users need to create it\n };\n \n setUserData(newUserData);\n localStorage.setItem('onairosUser', JSON.stringify(newUserData));\n \n // Flow decision logic - prioritize new user detection\n if (isNewUser) {\n console.log('🚀 NEW USER detected → Starting onboarding flow (data connectors page)');\n setCurrentFlow('onboarding');\n } else {\n console.log('👋 EXISTING USER detected → Going directly to data request (data permissions page)');\n setCurrentFlow('dataRequest');\n }\n };\n\n const handleOnboardingComplete = (onboardingData) => {\n console.log('Onboarding completed:', onboardingData);\n const updatedUserData = {\n ...userData,\n onboardingComplete: true,\n connectedAccounts: onboardingData.connectedAccounts || []\n };\n setUserData(updatedUserData);\n localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));\n setCurrentFlow('pin');\n };\n\n const handlePinSetupComplete = (pinData) => {\n console.log('PIN setup completed:', pinData);\n const updatedUserData = {\n ...userData,\n ...pinData,\n pinCreated: true\n };\n setUserData(updatedUserData);\n localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));\n \n // Move to loading flow\n setCurrentFlow('loading');\n };\n\n const handleLoadingComplete = () => {\n setCurrentFlow('dataRequest');\n };\n\n const handleTrainingComplete = (trainingResult) => {\n console.log('🎓 Training completed:', trainingResult);\n const updatedUserData = {\n ...userData,\n trainingCompleted: true,\n ...trainingResult\n };\n setUserData(updatedUserData);\n localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));\n \n // Move to data request after training\n setCurrentFlow('dataRequest');\n };\n\n const handleDataRequestComplete = (requestResult) => {\n console.log('🔥 OnairosButton: Data request completed:', requestResult);\n \n // Update user data with request result\n const updatedUserData = {\n ...userData,\n lastDataRequest: requestResult\n };\n setUserData(updatedUserData);\n localStorage.setItem('onairosUser', JSON.stringify(updatedUserData));\n\n // Close overlay immediately\n console.log('🔥 Closing overlay after data request completion');\n // Use centralized close to also reset flow and session\n handleCloseOverlay();\n\n // Format response if requested and API response is present\n let formattedResult = requestResult;\n if (formatResponse && requestResult?.apiResponse) {\n try {\n formattedResult = {\n ...requestResult,\n apiResponse: formatOnairosResponse(requestResult.apiResponse, responseFormat)\n };\n console.log('🔥 Response formatted with dictionary:', formattedResult.apiResponse?.personalityDict || 'No personality data');\n } catch (error) {\n console.warn('🔥 Error formatting response:', error);\n // Continue with original result if formatting fails\n }\n }\n\n // Enhanced user data formatting for better display\n const { logFormattedUserData } = require('./utils/userDataFormatter');\n \n // Add user data to the result for comprehensive formatting\n const completeResult = {\n ...formattedResult,\n userData: updatedUserData\n };\n\n // Log formatted user data for better readability\n const enhancedResult = logFormattedUserData(completeResult);\n\n // Call onComplete callback if provided\n console.log('🔥 Calling onComplete callback with enhanced result');\n if (onComplete) {\n try {\n onComplete(enhancedResult);\n console.log('🔥 onComplete callback executed successfully with enhanced formatting');\n } catch (error) {\n console.error('🔥 Error in onComplete callback:', error);\n }\n } else {\n console.log('🔥 No onComplete callback provided');\n }\n };\n\n const getFlowTitle = () => {\n switch (currentFlow) {\n case 'welcome':\n return ''; // WelcomeScreen handles its own titles\n case 'email':\n return ''; // EmailAuth handles its own titles\n case 'onboarding':\n return 'Connect Your Data';\n case 'pin':\n return 'Secure Your Account';\n case 'training':\n return 'Training Your Model';\n case 'dataRequest':\n return 'Data Request';\n default:\n return '';\n }\n };\n\n const getFlowSubtitle = () => {\n switch (currentFlow) {\n case 'welcome':\n return ''; // WelcomeScreen handles its own subtitles\n case 'email':\n return ''; // EmailAuth handles its own subtitles\n case 'onboarding':\n return 'Choose which accounts to connect for a personalized experience';\n case 'pin':\n return 'Create a secure PIN to protect your data';\n case 'training':\n return 'Building your personalized insights';\n case 'dataRequest':\n return `Select the data you want to share with ${webpageName}`;\n default:\n return '';\n }\n };\n\n const getFlowIcon = () => {\n switch (currentFlow) {\n case 'welcome':\n return ''; // WelcomeScreen handles its own layout\n case 'email':\n return ''; // EmailAuth handles its own layout\n case 'onboarding':\n return '🔗';\n case 'pin':\n return '🔒';\n case 'training':\n return '⚡';\n case 'dataRequest':\n return '📊';\n default:\n return '';\n }\n };\n\n const renderCurrentFlow = () => {\n switch (currentFlow) {\n case 'welcome':\n return (\n <WelcomeScreen \n onContinue={handleWelcomeContinue}\n onClose={handleCloseOverlay}\n webpageName={webpageName}\n appIcon={appIcon}\n testMode={testMode}\n />\n );\n case 'email':\n return (\n <div className=\"h-[min(85vh,700px)]\">\n <EmailAuth \n onSuccess={handleEmailAuthSuccess}\n testMode={testMode} // Use the testMode prop from initialization\n />\n </div>\n );\n \n case 'onboarding':\n return (\n <UniversalOnboarding \n onComplete={handleOnboardingComplete}\n onBack={() => setCurrentFlow('email')}\n appIcon={appIcon || \"https://onairos.sirv.com/Images/OnairosBlack.png\"}\n appName={webpageName}\n username={userData?.email || userData?.username}\n testMode={testMode}\n priorityPlatform={priorityPlatform}\n />\n );\n \n case 'pin':\n return (\n <PinSetup \n onComplete={handlePinSetupComplete}\n userEmail={userData?.email}\n />\n );\n \n case 'training':\n return (\n <TrainingComponent \n onComplete={handleTrainingComplete}\n userEmail={userData?.email}\n appName={webpageName}\n connectedAccounts={userData?.connectedAccounts || []}\n testMode={testMode}\n />\n );\n \n case 'dataRequest':\n return (\n <DataRequest \n onComplete={handleDataRequestComplete}\n userEmail={userData?.email}\n requestData={requestData}\n appName={webpageName}\n autoFetch={autoFetch}\n testMode={testMode}\n appIcon={appIcon}\n connectedAccounts={userData?.connectedAccounts || {}}\n />\n );\n \n default:\n return (\n <div className=\"flex flex-col items-center space-y-4 p-6\">\n <div className=\"animate-spin h-8 w-8 border-2 border-blue-600 rounded-full border-t-transparent\"></div>\n <p className=\"text-gray-600\">Loading...</p>\n </div>\n );\n }\n };\n\n // Styling and button class based on visual type\n const buttonClass = \n `flex items-center justify-center font-bold rounded cursor-pointer ${\n buttonType === 'pill' ? 'px-4 py-2' : 'w-12 h-12'\n } bg-transparent OnairosConnect`;\n\n const buttonStyle = {\n flexDirection: textLayout === 'below' ? 'column' : 'row',\n backgroundColor: 'transparent',\n color: textColor,\n border: '1px solid transparent',\n };\n\n // Icon and text style based on the visualType\n const logoStyle = {\n width: '20px',\n height: '20px',\n marginRight: visualType === 'full' ? '12px' : '0',\n };\n\n const getText = () => {\n switch (loginType) {\n case 'signUp':\n return 'Sign Up with Onairos';\n case 'signOut':\n return 'Sign Out of Onairos';\n default:\n return 'Sign In with Onairos';\n }\n };\n\n return (\n <>\n <button\n className={buttonClass}\n onClick={openTerminal}\n style={buttonStyle}\n >\n {(visualType === 'full' || visualType === 'icon') && (\n <img\n src={login ? \"https://onairos.sirv.com/Images/OnairosWhite.png\" : \"https://onairos.sirv.com/Images/OnairosBlack.png\"}\n alt=\"Onairos Logo\"\n style={logoStyle}\n />\n )}\n {visualType !== 'icon' && (\n <span className={`${textColor === 'black' ? 'text-black' : 'text-white'} ${visualType === 'icon' ? 'sr-only' : ''} ${textLayout === 'right' ? 'ml-2' : textLayout === 'left' ? 'mr-2' : ''}`}>\n {getText()}\n </span>\n )}\n </button>\n\n {/* Modal with New Design */}\n {showOverlay && (\n <>\n {currentFlow === 'email' ? (\n // Special case for email - render directly without PageLayout wrapper\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647 }}>\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\n {/* Header */}\n <div className=\"relative px-6 pt-6 pb-4 flex-shrink-0\">\n <button\n onClick={handleCloseOverlay}\n className=\"absolute left-4 top-4 p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n <svg className=\"w-5 h-5 text-gray-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Email Content */}\n <div className=\"h-[min(85vh,700px)]\">\n <EmailAuth \n onSuccess={handleEmailAuthSuccess}\n testMode={testMode}\n />\n </div>\n </div>\n </div>\n ) : currentFlow === 'onboarding' ? (\n // Special case for onboarding - render directly without PageLayout wrapper\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647 }}>\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\n {/* Header */}\n <div className=\"relative px-6 pt-6 pb-4 flex-shrink-0\">\n <button\n onClick={() => setCurrentFlow('email')}\n className=\"absolute left-4 top-4 p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n <svg className=\"w-5 h-5 text-gray-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n </div>\n\n {/* Onboarding Content */}\n <UniversalOnboarding \n onComplete={handleOnboardingComplete}\n onBack={() => setCurrentFlow('email')}\n appIcon={appIcon || \"https://onairos.sirv.com/Images/OnairosBlack.png\"}\n appName={webpageName}\n username={userData?.email || userData?.username}\n testMode={testMode}\n priorityPlatform={priorityPlatform}\n />\n </div>\n </div>\n ) : currentFlow === 'dataRequest' ? (\n // Special case for dataRequest - render directly without PageLayout wrapper\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647 }}>\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\n {/* Header */}\n <div className=\"relative px-6 pt-6 pb-4 flex-shrink-0\">\n <button\n onClick={() => setCurrentFlow('loading')}\n className=\"absolute left-4 top-4 p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n <svg className=\"w-5 h-5 text-gray-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n </div>\n\n {/* DataRequest Content */}\n <DataRequest \n onComplete={handleDataRequestComplete}\n userEmail={userData?.email}\n requestData={requestData}\n appName={webpageName}\n autoFetch={autoFetch}\n testMode={testMode}\n appIcon={appIcon}\n connectedAccounts={userData?.connectedAccounts || {}}\n />\n </div>\n </div>\n ) : currentFlow === 'pin' ? (\n // Special case for pin - render directly without PageLayout wrapper\n <div className=\"fixed inset-0 bg-gray-500 bg-opacity-50 flex items-center justify-center p-6\" style={{ zIndex: 2147483647 }}>\n <div className=\"bg-white rounded-3xl w-full max-w-lg mx-auto shadow-2xl overflow-hidden flex flex-col\" style={{ maxWidth: '500px', height: '90vh' }}>\n {/* Header */}\n <div className=\"relative px-6 pt-6 pb-4 flex-shrink-0\">\n <button\n onClick={() => setCurrentFlow('onboarding')}\n className=\"absolute left-4 top-4 p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n <svg className=\"w-5 h-5 text-gray-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n </div>\n\n {/* PinSetup Content - Must take remaining height */}\n <div className=\"flex-1 min-h-0\">\n <PinSetup \n onComplete={handlePinSetupComplete}\n onBack={() => setCurrentFlow('onboarding')}\n userEmail={userData?.email}\n />\n </div>\n </div>\n </div>\n ) : currentFlow === 'loading' ? (\n // Loading screen\n <LoadingScreen onComplete={handleLoadingComplete} />\n ) : (\n // All other flows use PageLayout wrapper\n <ModalPageLayout\n visible={showOverlay}\n onClose={handleCloseOverlay}\n showBackButton={currentFlow === 'training'}\n onBack={() => {\n if (currentFlow === 'email') setCurrentFlow('welcome');\n if (currentFlow === 'onboarding') setCurrentFlow('email');\n if (currentFlow === 'pin') setCurrentFlow('onboarding'); \n if (currentFlow === 'training') setCurrentFlow('pin');\n }}\n title={getFlowTitle()}\n subtitle={getFlowSubtitle()}\n icon={getFlowIcon()}\n centerContent={true}\n >\n {renderCurrentFlow()}\n </ModalPageLayout>\n )}\n </>\n )}\n </>\n );\n}\n\nexport default OnairosButton;","/**\r\n * Enhanced User Data Formatter for onComplete Callback\r\n * Provides structured, readable formatting of Onairos user data\r\n */\r\n\r\n/**\r\n * Formats user data for better readability in onComplete callback\r\n * @param {Object} result - The complete result object from data request\r\n * @returns {Object} Enhanced result with formatted user data display\r\n */\r\nexport function formatUserDataForDisplay(result) {\r\n if (!result) return result;\r\n\r\n const formatted = { ...result };\r\n \r\n // Create a structured summary of the user data\r\n const userDataSummary = {\r\n // Basic request information\r\n requestInfo: {\r\n timestamp: result.timestamp || new Date().toISOString(),\r\n appName: result.appName || 'Unknown App',\r\n userHash: result.userHash || 'Unknown User',\r\n testMode: result.testMode || false,\r\n dataTypesRequested: result.approvedData || []\r\n },\r\n \r\n // User authentication and profile data\r\n userProfile: {\r\n email: result.userData?.email || 'Not provided',\r\n userType: result.userData?.userType || 'Unknown',\r\n onboardingComplete: result.userData?.onboardingComplete || false,\r\n pinCreated: result.userData?.pinCreated || false,\r\n trainingComplete: result.userData?.trainingComplete || false,\r\n modelReady: result.userData?.modelReady || false\r\n },\r\n \r\n // Connected platforms/accounts\r\n connectedAccounts: formatConnectedAccounts(result.userData?.connectedAccounts || []),\r\n \r\n // API response data (personality, preferences, etc.)\r\n aiData: formatAIResponseData(result.apiResponse),\r\n \r\n // Success status and any errors\r\n status: {\r\n success: result.success || false,\r\n hasApiResponse: !!result.apiResponse,\r\n hasErrors: !!result.error || !!result.apiError\r\n }\r\n };\r\n\r\n // Add the formatted summary to the result\r\n formatted.userDataSummary = userDataSummary;\r\n \r\n // Create a pretty-printed version for console logging\r\n formatted.prettyPrint = createPrettyPrintVersion(userDataSummary);\r\n \r\n return formatted;\r\n}\r\n\r\n/**\r\n * Formats connected accounts data\r\n * @param {Array} accounts - Array of connected account objects\r\n * @returns {Object} Formatted accounts summary\r\n */\r\nfunction formatConnectedAccounts(accounts) {\r\n if (!Array.isArray(accounts) || accounts.length === 0) {\r\n return {\r\n count: 0,\r\n platforms: [],\r\n summary: 'No connected accounts'\r\n };\r\n }\r\n\r\n return {\r\n count: accounts.length,\r\n platforms: accounts.map(account => ({\r\n name: account.platform || account.name || 'Unknown Platform',\r\n status: account.status || 'Unknown',\r\n connectedAt: account.connectedAt || 'Unknown date',\r\n hasData: account.hasData || false\r\n })),\r\n summary: `${accounts.length} platform(s) connected: ${accounts.map(a => a.platform || a.name).join(', ')}`\r\n };\r\n}\r\n\r\n/**\r\n * Formats AI response data (personality scores, traits, etc.)\r\n * @param {Object} apiResponse - The API response containing AI data\r\n * @returns {Object} Formatted AI data summary\r\n */\r\nfunction formatAIResponseData(apiResponse) {\r\n if (!apiResponse) {\r\n return {\r\n available: false,\r\n summary: 'No AI data available'\r\n };\r\n }\r\n\r\n const aiData = {\r\n available: true,\r\n dataTypes: []\r\n };\r\n\r\n // Check for personality data\r\n if (apiResponse.InferenceResult?.traits || apiResponse.personalityDict || apiResponse.traits) {\r\n const personalityData = {\r\n type: 'personality',\r\n available: true\r\n };\r\n\r\n // If we have dictionary format, use it for better readability\r\n if (apiResponse.personalityDict) {\r\n personalityData.data = apiResponse.personalityDict;\r\n personalityData.summary = `Personality analysis with ${Object.keys(apiResponse.personalityDict).length} traits`;\r\n } else if (apiResponse.InferenceResult?.traits) {\r\n personalityData.data = apiResponse.InferenceResult.traits;\r\n personalityData.summary = `Personality scores array with ${apiResponse.InferenceResult.traits.length} values`;\r\n } else if (apiResponse.traits) {\r\n personalityData.data = apiResponse.traits;\r\n personalityData.summary = `Personality traits with ${Array.isArray(apiResponse.traits) ? apiResponse.traits.length : Object.keys(apiResponse.traits).length} items`;\r\n }\r\n\r\n aiData.dataTypes.push(personalityData);\r\n }\r\n\r\n // Check for preferences/traits data\r\n if (apiResponse.traitResult || apiResponse.traitDict) {\r\n const preferencesData = {\r\n type: 'preferences',\r\n available: true\r\n };\r\n\r\n if (apiResponse.traitDict) {\r\n preferencesData.data = apiResponse.traitDict;\r\n preferencesData.summary = `Preferences analysis with ${Object.keys(apiResponse.traitDict).length} categories`;\r\n } else if (apiResponse.traitResult) {\r\n preferencesData.data = apiResponse.traitResult;\r\n preferencesData.summary = `Trait results with ${Array.isArray(apiResponse.traitResult) ? apiResponse.traitResult.length : Object.keys(apiResponse.traitResult).length} items`;\r\n }\r\n\r\n aiData.dataTypes.push(preferencesData);\r\n }\r\n\r\n // Check for basic info/output\r\n if (apiResponse.InferenceResult?.output || apiResponse.output) {\r\n aiData.dataTypes.push({\r\n type: 'basic_info',\r\n available: true,\r\n data: apiResponse.InferenceResult?.output || apiResponse.output,\r\n summary: 'Basic user information and insights'\r\n });\r\n }\r\n\r\n // Create overall summary\r\n aiData.summary = aiData.dataTypes.length > 0 \r\n ? `AI analysis complete with ${aiData.dataTypes.length} data type(s): ${aiData.dataTypes.map(d => d.type).join(', ')}`\r\n : 'AI data structure present but no recognized data types found';\r\n\r\n return aiData;\r\n}\r\n\r\n/**\r\n * Creates a pretty-printed version for console logging\r\n * @param {Object} userDataSummary - The formatted user data summary\r\n * @returns {string} Pretty-printed string for console output\r\n */\r\nfunction createPrettyPrintVersion(userDataSummary) {\r\n const lines = [];\r\n \r\n lines.push('🎉 ONAIROS USER DATA SUMMARY');\r\n lines.push('=' .repeat(50));\r\n \r\n // Request Info\r\n lines.push('\\n📋 REQUEST INFORMATION:');\r\n lines.push(` App: ${userDataSummary.requestInfo.appName}`);\r\n lines.push(` User: ${userDataSummary.requestInfo.userHash}`);\r\n lines.push(` Mode: ${userDataSummary.requestInfo.testMode ? 'Test' : 'Production'}`);\r\n lines.push(` Data Types: ${userDataSummary.requestInfo.dataTypesRequested.join(', ') || 'None'}`);\r\n lines.push(` Timestamp: ${new Date(userDataSummary.requestInfo.timestamp).toLocaleString()}`);\r\n \r\n // User Profile\r\n lines.push('\\n👤 USER PROFILE:');\r\n lines.push(` Email: ${userDataSummary.userProfile.email}`);\r\n lines.push(` Type: ${userDataSummary.userProfile.userType}`);\r\n lines.push(` Onboarding: ${userDataSummary.userProfile.onboardingComplete ? '✅' : '❌'}`);\r\n lines.push(` PIN Setup: ${userDataSummary.userProfile.pinCreated ? '✅' : '❌'}`);\r\n lines.push(` Training: ${userDataSummary.userProfile.trainingComplete ? '✅' : '❌'}`);\r\n lines.push(` Model Ready: ${userDataSummary.userProfile.modelReady ? '✅' : '❌'}`);\r\n \r\n // Connected Accounts\r\n lines.push('\\n🔗 CONNECTED ACCOUNTS:');\r\n lines.push(` ${userDataSummary.connectedAccounts.summary}`);\r\n if (userDataSummary.connectedAccounts.platforms.length > 0) {\r\n userDataSummary.connectedAccounts.platforms.forEach(platform => {\r\n lines.push(` • ${platform.name}: ${platform.status} ${platform.hasData ? '(has data)' : '(no data)'}`);\r\n });\r\n }\r\n \r\n // AI Data\r\n lines.push('\\n🤖 AI ANALYSIS DATA:');\r\n lines.push(` ${userDataSummary.aiData.summary}`);\r\n if (userDataSummary.aiData.dataTypes.length > 0) {\r\n userDataSummary.aiData.dataTypes.forEach(dataType => {\r\n lines.push(` • ${dataType.type.toUpperCase()}: ${dataType.summary}`);\r\n });\r\n }\r\n \r\n // Status\r\n lines.push('\\n✅ STATUS:');\r\n lines.push(` Success: ${userDataSummary.status.success ? '✅' : '❌'}`);\r\n lines.push(` API Response: ${userDataSummary.status.hasApiResponse ? '✅' : '❌'}`);\r\n lines.push(` Errors: ${userDataSummary.status.hasErrors ? '❌ Yes' : '✅ None'}`);\r\n \r\n lines.push('\\n' + '=' .repeat(50));\r\n \r\n return lines.join('\\n');\r\n}\r\n\r\n/**\r\n * Console logging helper that prints formatted user data\r\n * @param {Object} result - The result object from onComplete\r\n */\r\nexport function logFormattedUserData(result) {\r\n const formatted = formatUserDataForDisplay(result);\r\n \r\n console.log('\\n' + formatted.prettyPrint + '\\n');\r\n \r\n // Also log the structured data for programmatic access\r\n console.log('📊 Structured User Data Summary:', formatted.userDataSummary);\r\n \r\n return formatted;\r\n}\r\n\r\nexport default {\r\n formatUserDataForDisplay,\r\n logFormattedUserData\r\n};\r\n"],"names":["WelcomeScreen","_ref","onContinue","onClose","useEffect","script","document","createElement","src","async","head","appendChild","existingScript","querySelector","removeChild","React","className","style","height","alt","onClick","fill","stroke","viewBox","strokeLinecap","strokeLinejoin","strokeWidth","d","COLORS","btnGradStart","btnGradEnd","btnLabel","btnBorder","iconCircleGradientStart","iconCircleGradientEnd","background","backgroundSecondary","textPrimary","textSecondary","textMuted","border","borderLight","success","error","warning","info","hover","pressed","focus","IconCircle","size","children","concat","width","borderRadius","fontSize","color","backgroundColor","_ref2","label","iconRight","loading","disabled","testId","textStyle","centered","props","_objectWithoutProperties","_excluded","setPressed","useState","buttonStyle","_objectSpread","position","overflow","minWidth","maxWidth","margin","cursor","opacity","boxShadow","transition","pressedOverlayStyle","top","left","right","bottom","labelStyle","fontFamily","fontWeight","textAlign","_extends","onMouseDown","handleMouseDown","onMouseUp","handleMouseUp","onMouseLeave","handleMouseLeave","display","justifyContent","alignItems","API_CONFIG","DEVELOPMENT_URL","PRODUCTION_URL","IS_DEVELOPMENT","window","location","hostname","port","getBaseUrl","this","EMAIL_VERIFY","EMAIL_VERIFY_CONFIRM","getEmailVerifyUrl","getEmailVerifyConfirmUrl","getDebugInfo","environment","baseUrl","emailVerifyUrl","emailVerifyConfirmUrl","console","log","EmailAuth","onSuccess","testMode","email","setEmail","code","setCode","step","setStep","isLoading","setIsLoading","setError","setTimeout","firstInput","handleEmailSubmit","e","preventDefault","test","validateEmail","doFetchWithRetry","url","options","lastErr","attempts","arguments","length","undefined","i","res","fetch","ok","body","json","Error","status","_unused","err","Promise","r","apiKey","onairosApiKey","apiUrl","substring","headers","response","method","JSON","stringify","trim","toLowerCase","data","handleGoogleAuth","_localStorage$getItem","sdkConfig","enableHealthMonitoring","enableAutoRefresh","enableConnectionValidation","username","localStorage","getItem","authorizeUrl","params","URLSearchParams","sdk_type","return_url","origin","fullUrl","toString","popup","open","checkInterval","setInterval","closed","clearInterval","connectedAccounts","Google","handleCodeSubmit","_unused2","simulatedResponse","verified","token","Date","now","userName","split","isNewUser","userState","flowType","user","creationDate","toISOString","lastLogin","enochInstructions","recommendedFlow","nextActionTitle","existingUser","accountInfo","adminMode","userCreated","accountDetails","createdAt","testAccount","errorMessage","attemptsRemaining","_data$user","existingUserData","type","value","onChange","target","placeholder","required","lineHeight","Array","from","_","index","key","maxLength","newCode","join","_e$target$parentEleme","nextInput","parentElement","onKeyDown","_e$target$parentEleme2","prevInput","borderColor","PrimaryButton","flex","minHeight","Check","detectOnairosExtension","resolve","onairos","isOnairos","resolved","handleOnairosReady","addEventListener","once","removeEventListener","openExtensionInstallPage","source","storeUrl","warn","href","LLM_URLS","chatgpt","claude","gemini","grok","getUserInfoFromStorage","_userData","_userData2","_userData3","_userData4","_userData5","_userData6","_userData7","_userData8","_userData9","_userData0","_userData1","_userData10","_userData11","_userData12","_userData13","userDataStr","jwtToken","legacyToken","userDataSDK","userData","parse","userInfo","userId","sessionToken","onboardingComplete","pinCreated","extractedAt","message","platform","onInstallClick","platformName","platformUrl","rel","handleInstallClick","handleDirectVisit","onConnectionChange","showInstallPrompt","setShowInstallPrompt","currentPlatform","setCurrentPlatform","isConnecting","setIsConnecting","handleLLMConnect","useCallback","onError","storedUserInfo","connectorVersion","timestamp","onExtensionMissing","URL","searchParams","set","encodeURIComponent","finalUrl","openLLMWithExtensionCheck","missingPlatform","handleLLMDisconnect","handleCloseInstallPrompt","handleExtensionInstall","checkExtensionStatus","contextValue","connectToLLM","disconnectFromLLM","map","child","llmConnectorManager","ExtensionInstallPrompt","chatgptIcon","claudeIcon","geminiIcon","grokIcon","process","env","REACT_APP_ONAIROS_API_KEY","REACT_APP_ONAIROS_BASE_URL","sdkType","fadeSlideInKeyframes","UniversalOnboarding","_JSON$parse2","onComplete","lottieRef","useRef","lastFrameRef","rafRef","setConnectedAccounts","connectingPlatform","setConnectingPlatform","selected","setSelected","currentPage","setCurrentPage","touchStartX","touchDeltaX","vh","setVh","innerHeight","onResize","removeItem","personaSide","Math","min","SLOT","max","floor","ACTIVE_SCALE","igGradId","useId","Brand","ChatGPT","objectFit","Claude","Gemini","Grok","Instagram","id","cx","cy","offset","stopColor","YouTube","Reddit","LinkedIn","x","y","rx","Twitter","aiLinks","descriptions","allPlatforms","name","connector","icon","directLink","platforms","page","slice","p","s","handleSwitch","find","platformKey","connectedPlatform","errorPlatform","plat","_JSON$parse","session","candidates","youtube","linkedin","reddit","pinterest","instagram","github","facebook","gmail","oauthUrl","k","touched","it","close","_unused3","_unused4","connectToPlatform","connectedCount","Object","values","filter","Boolean","current","totalFrames","personaAnim","progress","start","startTs","performance","t","eased","frame","goToAndStop","requestAnimationFrame","cancelAnimationFrame","LLMConnectorManager","connected","charAt","toUpperCase","displayName","dangerouslySetInnerHTML","__html","maxHeight","gridTemplateRows","transform","zIndex","pointerEvents","Lottie","animationData","autoplay","loop","onTouchStart","touches","clientX","onTouchMove","onTouchEnd","dx","gridAutoFlow","gridTemplateColumns","columnGap","justifyItems","paddingInline","idx","on","isSel","shift","animation","title","n","role","entries","v","_ref3","totalConnections","xmlns","PinSetup","onBack","userEmail","pin","setPin","pinRequirements","setPinRequirements","uppercase","number","allRequirementsMet","handleSubmit","dataTypes","description","tooltip","privacyLink","DataTypeToggle","dataType","isEnabled","onToggle","isLast","iconName","iconProps","getIconComponent","handleToggle","fillRule","clipRule","autoFetch","appName","formatResponse","responseFormat","selectedData","setSelectedData","basic","personality","preferences","isLoadingApi","setIsLoadingApi","apiError","setApiError","handleDataToggle","dataId","enabled","dt","prev","selectedCount","userHash","hash","str","charCodeAt","abs","generateUserHash","approvedData","_ref4","mapDataTypesToConfirmations","confirmations","currentDate","dataTypeMapping","forEach","push","date","apiEndpoint","baseResult","simulatedApiData","personalityScores","openness","conscientiousness","extraversion","agreeableness","neuroticism","insights","dataProcessed","result","apiResponse","simulated","requestBody","apiData","errorResult","cancelled","TrainingComponent","_steps$currentStep","_steps$currentStep2","_steps$currentStep3","_steps$currentStep4","_steps$currentStep5","currentStep","setCurrentStep","setProgress","isComplete","setIsComplete","steps","duration","interval","stepTimeout","stepDuration","stepProgress","newProgress","completionDelay","trainingComplete","simulatedTraining","clearTimeout","round","LoadingScreen","dotCount","setDotCount","loadingStates","stateInterval","nextStep","dotInterval","currentState","aspectRatio","rainAnim","repeat","PERSONALITY_TYPES","TRAIT_CATEGORIES","formatOnairosResponse","_apiResponse$Inferenc","includeDictionary","includeArray","formatted","InferenceResult","traits","scores","_apiResponse$Inferenc2","isArray","personalityDict","_formatted$InferenceR","traitResult","traitDict","category","PageLayout","subtitle","showHeader","showCloseButton","showBackButton","contentClassName","centerContent","layoutStyle","flexDirection","headerStyle","padding","contentStyle","titleStyle","subtitleStyle","ModalPageLayout","visible","onBackdropClick","backdropStyle","modalStyle","pageLayoutProps","_excluded2","backdropStyles","willChange","modalStyles","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius","currentTarget","OnairosButton","requestData","webpageName","inferenceData","proofMode","textLayout","textColor","login","buttonType","loginReturn","loginType","visualType","appIcon","enableTraining","priorityPlatform","showOverlay","setShowOverlay","currentFlow","setCurrentFlow","setUserData","checkExistingSession","savedUser","handleCloseOverlay","handleWelcomeContinue","handleEmailAuthSuccess","authData","hasAccountInfo","finalDecision","reasoning","existingUserFalse","flowTypeOnboarding","noAccountInfo","newUserData","setItem","handleOnboardingComplete","onboardingData","updatedUserData","handlePinSetupComplete","pinData","handleTrainingComplete","trainingResult","trainingCompleted","handleDataRequestComplete","requestResult","lastDataRequest","formattedResult","_formattedResult$apiR","logFormattedUserData","require","enhancedResult","buttonClass","logoStyle","marginRight","getText","DataRequest","handleLoadingComplete","getFlowTitle","getFlowSubtitle","getFlowIcon","renderCurrentFlow","formatUserDataForDisplay","_result$userData","_result$userData2","_result$userData3","_result$userData4","_result$userData5","_result$userData6","_result$userData7","userDataSummary","requestInfo","dataTypesRequested","userProfile","userType","modelReady","formatConnectedAccounts","aiData","formatAIResponseData","hasApiResponse","hasErrors","prettyPrint","lines","toLocaleString","summary","hasData","createPrettyPrintVersion","accounts","count","account","connectedAt","a","_apiResponse$Inferenc3","available","personalityData","keys","preferencesData","_apiResponse$Inferenc4","output"],"sourceRoot":""}