@onairos/react-native 3.4.1 → 3.6.0
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/README.md +423 -374
- package/lib/commonjs/api/index.js +9 -145
- package/lib/commonjs/assets/animations/loaderani.json +1 -0
- package/lib/commonjs/assets/animations/persona-animation.json +1 -0
- package/lib/commonjs/assets/fonts/EBGaramond-VariableFont_wght.ttf +0 -0
- package/lib/commonjs/assets/fonts/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
- package/lib/commonjs/assets/icons/Facebookicon.png +0 -0
- package/lib/commonjs/assets/icons/Gmail.png +0 -0
- package/lib/commonjs/assets/icons/Linkedinicon.png +0 -0
- package/lib/commonjs/assets/icons/Redditicon.png +0 -0
- package/lib/commonjs/assets/icons/YouTubeicon2.png +0 -0
- package/lib/commonjs/assets/icons/YouTubeicon3.png +0 -0
- package/lib/commonjs/assets/icons/chatgpt.png +0 -0
- package/lib/commonjs/assets/icons/claude.png +0 -0
- package/lib/commonjs/assets/icons/gemini.png +0 -0
- package/lib/commonjs/assets/icons/grok.png +0 -0
- package/lib/commonjs/assets/images/Checkbox.svg +3 -0
- package/lib/commonjs/assets/images/EnochE.svg +19 -0
- package/lib/commonjs/assets/images/Enochicon1.png +0 -0
- package/lib/commonjs/assets/images/Face_ID_logo.png +0 -0
- package/lib/commonjs/assets/images/Facebookicon.png +0 -0
- package/lib/commonjs/assets/images/Gmail.png +0 -0
- package/lib/commonjs/assets/images/Googlelogo.png +0 -0
- package/lib/commonjs/assets/images/Linkedinicon.png +0 -0
- package/lib/commonjs/assets/images/OnairosNewLogo.png +0 -0
- package/lib/commonjs/assets/images/Onairoslogo.png +0 -0
- package/lib/commonjs/assets/images/Personalityprofile.svg +3 -0
- package/lib/commonjs/assets/images/Personalitytraits.svg +3 -0
- package/lib/commonjs/assets/images/Redditicon.png +0 -0
- package/lib/commonjs/assets/images/Userpreferences.svg +3 -0
- package/lib/commonjs/assets/images/YouTubeicon3.png +0 -0
- package/lib/commonjs/assets/images/arrow.svg +20 -0
- package/lib/commonjs/assets/images/basicproficon.svg +43 -0
- package/lib/commonjs/assets/images/basicprofile.svg +3 -0
- package/lib/commonjs/assets/images/chatgpt.png +0 -0
- package/lib/commonjs/assets/images/checkmark.svg +4 -0
- package/lib/commonjs/assets/images/claude.png +0 -0
- package/lib/commonjs/assets/images/contentanalysis.svg +3 -0
- package/lib/commonjs/assets/images/contenticon.svg +23 -0
- package/lib/commonjs/assets/images/gemini.png +0 -0
- package/lib/commonjs/assets/images/grok.png +0 -0
- package/lib/commonjs/assets/images/persona1.png +0 -0
- package/lib/commonjs/assets/images/persona2.png +0 -0
- package/lib/commonjs/assets/images/persona3.png +0 -0
- package/lib/commonjs/assets/images/persona4.png +0 -0
- package/lib/commonjs/assets/images/persona5.png +0 -0
- package/lib/commonjs/assets/images/personalityicon.svg +18 -0
- package/lib/commonjs/assets/images/x-close.svg +3 -0
- package/lib/commonjs/components/BodyText.js +9 -0
- package/lib/commonjs/components/BrandMark.js +10 -0
- package/lib/commonjs/components/CodeInput.js +9 -0
- package/lib/commonjs/components/EmailInput.js +8 -0
- package/lib/commonjs/components/GoogleButton.js +9 -0
- package/lib/commonjs/components/HeadingGroup.js +9 -0
- package/lib/commonjs/components/LLMDataInputModal.js +14 -0
- package/lib/commonjs/components/ModalHeader.js +9 -0
- package/lib/commonjs/components/ModalSheet.js +9 -0
- package/lib/commonjs/components/Onairos.js +14 -374
- package/lib/commonjs/components/OnairosButton.js +13 -309
- package/lib/commonjs/components/OnairosSignInButton.js +12 -0
- package/lib/commonjs/components/Overlay.js +13 -483
- package/lib/commonjs/components/PersonaImage.js +10 -0
- package/lib/commonjs/components/PersonaLoadingScreen.js +12 -0
- package/lib/commonjs/components/PersonalizationConsentScreen.js +13 -0
- package/lib/commonjs/components/PinCreationScreen.js +12 -0
- package/lib/commonjs/components/PinInput.js +9 -302
- package/lib/commonjs/components/PlatformConnectorsStep.js +23 -0
- package/lib/commonjs/components/PlatformList.js +10 -137
- package/lib/commonjs/components/PlatformToggle.js +9 -0
- package/lib/commonjs/components/PrimaryButton.js +10 -0
- package/lib/commonjs/components/SignInMatchAnimation.js +9 -0
- package/lib/commonjs/components/SignInStep.js +12 -0
- package/lib/commonjs/components/UniversalOnboarding.js +30 -1702
- package/lib/commonjs/components/VerificationStep.js +11 -0
- package/lib/commonjs/components/WelcomeScreen.js +22 -0
- package/lib/commonjs/components/icons/Basicproficon.js +8 -0
- package/lib/commonjs/components/icons/Basicprofile.js +8 -0
- package/lib/commonjs/components/icons/Checkbox.js +8 -0
- package/lib/commonjs/components/icons/Checkmark.js +8 -0
- package/lib/commonjs/components/icons/Contentanalysis.js +8 -0
- package/lib/commonjs/components/icons/Contenticon.js +8 -0
- package/lib/commonjs/components/icons/EnochE.js +8 -0
- package/lib/commonjs/components/icons/Personalityicon.js +8 -0
- package/lib/commonjs/components/icons/Personalityprofile.js +8 -0
- package/lib/commonjs/components/icons/Personalitytraits.js +8 -0
- package/lib/commonjs/components/icons/Userpreferences.js +8 -0
- package/lib/commonjs/components/icons/index.js +17 -0
- package/lib/commonjs/components/onboarding/OAuthWebView.js +18 -827
- package/lib/commonjs/components/onboarding/OnboardingHeader.js +10 -74
- package/lib/commonjs/components/onboarding/PinInput.js +10 -283
- package/lib/commonjs/components/onboarding/PlatformConnector.js +11 -249
- package/lib/commonjs/config/api.js +7 -0
- package/lib/commonjs/constants/index.js +7 -83
- package/lib/commonjs/context/AuthContext.js +10 -0
- package/lib/commonjs/hooks/useConnectedAccounts.js +9 -0
- package/lib/commonjs/hooks/useConnections.js +8 -159
- package/lib/commonjs/hooks/useCredentials.js +10 -177
- package/lib/commonjs/hooks/useUserConnections.js +10 -0
- package/lib/commonjs/index.js +34 -106
- package/lib/commonjs/services/SDK_API_KEY_VALIDATION.md +421 -421
- package/lib/commonjs/services/apiClient.js +8 -0
- package/lib/commonjs/services/apiKeyService.js +9 -952
- package/lib/commonjs/services/authService.js +10 -0
- package/lib/commonjs/services/biometricPinService.js +8 -0
- package/lib/commonjs/services/chatGPTConversationExtractor.js +8 -0
- package/lib/commonjs/services/chatGPTConversationService.js +9 -0
- package/lib/commonjs/services/claudeConversationExtractor.js +8 -0
- package/lib/commonjs/services/claudeConversationService.js +9 -0
- package/lib/commonjs/services/connectedAccountsService.js +10 -0
- package/lib/commonjs/services/googleAuthService.js +11 -0
- package/lib/commonjs/services/hingeDataExtractor.js +8 -0
- package/lib/commonjs/services/hingeDataService.js +9 -0
- package/lib/commonjs/services/imageCompressionService.js +7 -0
- package/lib/commonjs/services/instagramDataExtractor.js +8 -0
- package/lib/commonjs/services/instagramDataService.js +9 -0
- package/lib/commonjs/services/jwtStorageService.js +7 -0
- package/lib/commonjs/services/linkedinDOMExtractor.js +7 -0
- package/lib/commonjs/services/linkedinProfileService.js +9 -0
- package/lib/commonjs/services/linkedinScrapingService.js +8 -0
- package/lib/commonjs/services/llmDataStorage.js +8 -0
- package/lib/commonjs/services/mobileTrainingService.js +8 -0
- package/lib/commonjs/services/oauthService.js +11 -390
- package/lib/commonjs/services/pinEncryptionService.js +8 -0
- package/lib/commonjs/services/pinStorageUtils.js +7 -0
- package/lib/commonjs/services/platformAuthService.js +12 -1067
- package/lib/commonjs/services/sephoraDataExtractor.js +8 -0
- package/lib/commonjs/services/sephoraDataService.js +9 -0
- package/lib/commonjs/services/storageService.js +8 -0
- package/lib/commonjs/services/telegramDataExtractor.js +8 -0
- package/lib/commonjs/services/telegramDataService.js +11 -0
- package/lib/commonjs/services/trainingApiHelpers.js +7 -0
- package/lib/commonjs/services/userConnectionsService.js +10 -0
- package/lib/commonjs/services/youtubeMigrationService.js +10 -0
- package/lib/commonjs/theme/index.js +7 -0
- package/lib/commonjs/types/ambient.d.js +1 -2
- package/lib/commonjs/types/declarations.d.js +1 -2
- package/lib/commonjs/types/index.js +1 -6
- package/lib/commonjs/types/node-fix.d.js +1 -2
- package/lib/commonjs/types/node-override.d.js +1 -2
- package/lib/commonjs/types/opacity.d.js +1 -2
- package/lib/commonjs/types.js +1 -14
- package/lib/commonjs/utils/Portal.js +8 -98
- package/lib/commonjs/utils/api.js +9 -129
- package/lib/commonjs/utils/assetRegistry.js +33 -0
- package/lib/commonjs/utils/auth.js +9 -111
- package/lib/commonjs/utils/connectorTests.js +29 -0
- package/lib/commonjs/utils/crypto.js +8 -62
- package/lib/commonjs/utils/debugHelper.js +1 -64
- package/lib/commonjs/utils/encryption.js +7 -76
- package/lib/commonjs/utils/eventUtils.js +1 -0
- package/lib/commonjs/utils/haptics.js +9 -0
- package/lib/commonjs/utils/imagePreloader.js +1 -0
- package/lib/commonjs/utils/networkDiagnostics.js +8 -0
- package/lib/commonjs/utils/onairosApi.js +9 -350
- package/lib/commonjs/utils/programmaticFlow.js +9 -117
- package/lib/commonjs/utils/retryHelper.js +1 -220
- package/lib/commonjs/utils/secureStorage.js +10 -349
- package/lib/commonjs/utils/webviewScripts/chatgpt.js +1 -0
- package/lib/commonjs/utils/webviewScripts/claude.js +1 -0
- package/lib/commonjs/utils/webviewScripts/hinge.js +1 -0
- package/lib/commonjs/utils/webviewScripts/index.js +13 -0
- package/lib/commonjs/utils/webviewScripts/instagram.js +1 -0
- package/lib/commonjs/utils/webviewScripts/linkedin.js +1 -0
- package/lib/commonjs/utils/webviewScripts/sephora.js +1 -0
- package/lib/commonjs/utils/webviewScripts/telegram.js +1 -0
- package/lib/module/api/index.js +1 -139
- package/lib/module/assets/animations/loaderani.json +1 -0
- package/lib/module/assets/animations/persona-animation.json +1 -0
- package/lib/module/assets/fonts/EBGaramond-VariableFont_wght.ttf +0 -0
- package/lib/module/assets/fonts/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
- package/lib/module/assets/icons/Facebookicon.png +0 -0
- package/lib/module/assets/icons/Gmail.png +0 -0
- package/lib/module/assets/icons/Linkedinicon.png +0 -0
- package/lib/module/assets/icons/Redditicon.png +0 -0
- package/lib/module/assets/icons/YouTubeicon2.png +0 -0
- package/lib/module/assets/icons/YouTubeicon3.png +0 -0
- package/lib/module/assets/icons/chatgpt.png +0 -0
- package/lib/module/assets/icons/claude.png +0 -0
- package/lib/module/assets/icons/farcaster.png +0 -0
- package/lib/module/assets/icons/gemini.png +0 -0
- package/lib/module/assets/icons/grok.png +0 -0
- package/lib/module/assets/icons/instagram.png +0 -0
- package/lib/module/assets/icons/pinterest.png +0 -0
- package/lib/module/assets/icons/swerv_logo.png +0 -0
- package/lib/module/assets/icons/twitter.jpg +0 -0
- package/lib/module/assets/images/Checkbox.svg +3 -0
- package/lib/module/assets/images/EnochE.svg +19 -0
- package/lib/module/assets/images/Enochicon1.png +0 -0
- package/lib/module/assets/images/Face_ID_logo.png +0 -0
- package/lib/module/assets/images/Facebookicon.png +0 -0
- package/lib/module/assets/images/Gmail.png +0 -0
- package/lib/module/assets/images/Googlelogo.png +0 -0
- package/lib/module/assets/images/Linkedinicon.png +0 -0
- package/lib/module/assets/images/OnairosNewLogo.png +0 -0
- package/lib/module/assets/images/Onairoslogo.png +0 -0
- package/lib/module/assets/images/Personalityprofile.svg +3 -0
- package/lib/module/assets/images/Personalitytraits.svg +3 -0
- package/lib/module/assets/images/Redditicon.png +0 -0
- package/lib/module/assets/images/Userpreferences.svg +3 -0
- package/lib/module/assets/images/YouTubeicon3.png +0 -0
- package/lib/module/assets/images/arrow.svg +20 -0
- package/lib/module/assets/images/basicproficon.svg +43 -0
- package/lib/module/assets/images/basicprofile.svg +3 -0
- package/lib/module/assets/images/chatgpt.png +0 -0
- package/lib/module/assets/images/checkmark.svg +4 -0
- package/lib/module/assets/images/claude.png +0 -0
- package/lib/module/assets/images/contentanalysis.svg +3 -0
- package/lib/module/assets/images/contenticon.svg +23 -0
- package/lib/module/assets/images/gemini.png +0 -0
- package/lib/module/assets/images/grok.png +0 -0
- package/lib/module/assets/images/persona1.png +0 -0
- package/lib/module/assets/images/persona2.png +0 -0
- package/lib/module/assets/images/persona3.png +0 -0
- package/lib/module/assets/images/persona4.png +0 -0
- package/lib/module/assets/images/persona5.png +0 -0
- package/lib/module/assets/images/personalityicon.svg +18 -0
- package/lib/module/assets/images/x-close.svg +3 -0
- package/lib/module/components/BodyText.js +1 -0
- package/lib/module/components/BrandMark.js +1 -0
- package/lib/module/components/CodeInput.js +1 -0
- package/lib/module/components/EmailInput.js +1 -0
- package/lib/module/components/GoogleButton.js +1 -0
- package/lib/module/components/HeadingGroup.js +1 -0
- package/lib/module/components/LLMDataInputModal.js +8 -0
- package/lib/module/components/ModalHeader.js +1 -0
- package/lib/module/components/ModalSheet.js +1 -0
- package/lib/module/components/Onairos.js +1 -367
- package/lib/module/components/OnairosButton.js +1 -302
- package/lib/module/components/OnairosSignInButton.js +1 -0
- package/lib/module/components/Overlay.js +1 -474
- package/lib/module/components/PersonaImage.js +1 -0
- package/lib/module/components/PersonaLoadingScreen.js +1 -0
- package/lib/module/components/PersonalizationConsentScreen.js +1 -0
- package/lib/module/components/PinCreationScreen.js +1 -0
- package/lib/module/components/PinInput.js +1 -293
- package/lib/module/components/PlatformConnectorsStep.js +7 -0
- package/lib/module/components/PlatformList.js +1 -129
- package/lib/module/components/PlatformToggle.js +1 -0
- package/lib/module/components/PrimaryButton.js +1 -0
- package/lib/module/components/SignInMatchAnimation.js +1 -0
- package/lib/module/components/SignInStep.js +1 -0
- package/lib/module/components/UniversalOnboarding.js +1 -1693
- package/lib/module/components/VerificationStep.js +1 -0
- package/lib/module/components/WelcomeScreen.js +1 -0
- package/lib/module/components/icons/Basicproficon.js +1 -0
- package/lib/module/components/icons/Basicprofile.js +1 -0
- package/lib/module/components/icons/Checkbox.js +1 -0
- package/lib/module/components/icons/Checkmark.js +1 -0
- package/lib/module/components/icons/Contentanalysis.js +1 -0
- package/lib/module/components/icons/Contenticon.js +1 -0
- package/lib/module/components/icons/EnochE.js +1 -0
- package/lib/module/components/icons/Personalityicon.js +1 -0
- package/lib/module/components/icons/Personalityprofile.js +1 -0
- package/lib/module/components/icons/Personalitytraits.js +1 -0
- package/lib/module/components/icons/Userpreferences.js +1 -0
- package/lib/module/components/icons/index.js +1 -0
- package/lib/module/components/onboarding/OAuthWebView.js +1 -818
- package/lib/module/components/onboarding/OnboardingHeader.js +1 -66
- package/lib/module/components/onboarding/PinInput.js +1 -274
- package/lib/module/components/onboarding/PlatformConnector.js +1 -240
- package/lib/module/config/api.js +1 -0
- package/lib/module/constants/index.js +1 -77
- package/lib/module/context/AuthContext.js +1 -0
- package/lib/module/hooks/useConnectedAccounts.js +1 -0
- package/lib/module/hooks/useConnections.js +1 -152
- package/lib/module/hooks/useCredentials.js +6 -169
- package/lib/module/hooks/useUserConnections.js +1 -0
- package/lib/module/index.js +1 -32
- package/lib/module/services/SDK_API_KEY_VALIDATION.md +421 -421
- package/lib/module/services/apiClient.js +1 -0
- package/lib/module/services/apiKeyService.js +1 -925
- package/lib/module/services/authService.js +1 -0
- package/lib/module/services/biometricPinService.js +1 -0
- package/lib/module/services/chatGPTConversationExtractor.js +1 -0
- package/lib/module/services/chatGPTConversationService.js +1 -0
- package/lib/module/services/claudeConversationExtractor.js +1 -0
- package/lib/module/services/claudeConversationService.js +1 -0
- package/lib/module/services/connectedAccountsService.js +1 -0
- package/lib/module/services/googleAuthService.js +1 -0
- package/lib/module/services/hingeDataExtractor.js +1 -0
- package/lib/module/services/hingeDataService.js +1 -0
- package/lib/module/services/imageCompressionService.js +1 -0
- package/lib/module/services/instagramDataExtractor.js +1 -0
- package/lib/module/services/instagramDataService.js +1 -0
- package/lib/module/services/jwtStorageService.js +1 -0
- package/lib/module/services/linkedinDOMExtractor.js +1 -0
- package/lib/module/services/linkedinProfileService.js +1 -0
- package/lib/module/services/linkedinScrapingService.js +1 -0
- package/lib/module/services/llmDataStorage.js +1 -0
- package/lib/module/services/mobileTrainingService.js +1 -0
- package/lib/module/services/oauthService.js +1 -380
- package/lib/module/services/pinEncryptionService.js +7 -0
- package/lib/module/services/pinStorageUtils.js +1 -0
- package/lib/module/services/platformAuthService.js +1 -1041
- package/lib/module/services/sephoraDataExtractor.js +1 -0
- package/lib/module/services/sephoraDataService.js +1 -0
- package/lib/module/services/storageService.js +1 -0
- package/lib/module/services/telegramDataExtractor.js +1 -0
- package/lib/module/services/telegramDataService.js +8 -0
- package/lib/module/services/trainingApiHelpers.js +1 -0
- package/lib/module/services/userConnectionsService.js +1 -0
- package/lib/module/services/youtubeMigrationService.js +1 -0
- package/lib/module/theme/index.js +1 -0
- package/lib/module/types.js +1 -10
- package/lib/module/utils/Portal.js +1 -90
- package/lib/module/utils/api.js +1 -117
- package/lib/module/utils/assetRegistry.js +33 -0
- package/lib/module/utils/auth.js +1 -99
- package/lib/module/utils/connectorTests.js +28 -0
- package/lib/module/utils/crypto.js +1 -54
- package/lib/module/utils/debugHelper.js +1 -54
- package/lib/module/utils/encryption.js +1 -67
- package/lib/module/utils/eventUtils.js +1 -0
- package/lib/module/utils/haptics.js +8 -0
- package/lib/module/utils/imagePreloader.js +1 -0
- package/lib/module/utils/networkDiagnostics.js +1 -0
- package/lib/module/utils/onairosApi.js +1 -333
- package/lib/module/utils/programmaticFlow.js +1 -111
- package/lib/module/utils/retryHelper.js +1 -211
- package/lib/module/utils/secureStorage.js +6 -330
- package/lib/module/utils/webviewScripts/chatgpt.js +1 -0
- package/lib/module/utils/webviewScripts/claude.js +1 -0
- package/lib/module/utils/webviewScripts/hinge.js +1 -0
- package/lib/module/utils/webviewScripts/index.js +1 -0
- package/lib/module/utils/webviewScripts/instagram.js +1 -0
- package/lib/module/utils/webviewScripts/linkedin.js +1 -0
- package/lib/module/utils/webviewScripts/sephora.js +1 -0
- package/lib/module/utils/webviewScripts/telegram.js +1 -0
- package/package.json +62 -39
- package/lib/commonjs/api/index.js.map +0 -1
- package/lib/commonjs/assets/images/email.png +0 -0
- package/lib/commonjs/assets/images/linkedin.png +0 -0
- package/lib/commonjs/assets/images/reddit.png +0 -0
- package/lib/commonjs/assets/images/youtube.png +0 -0
- package/lib/commonjs/components/DataRequestModal.js +0 -228
- package/lib/commonjs/components/DataRequestModal.js.map +0 -1
- package/lib/commonjs/components/DataRequestScreen.js +0 -329
- package/lib/commonjs/components/DataRequestScreen.js.map +0 -1
- package/lib/commonjs/components/EmailVerificationModal.js +0 -320
- package/lib/commonjs/components/EmailVerificationModal.js.map +0 -1
- package/lib/commonjs/components/Onairos.js.map +0 -1
- package/lib/commonjs/components/OnairosButton.js.map +0 -1
- package/lib/commonjs/components/Overlay.js.map +0 -1
- package/lib/commonjs/components/PinInput.js.map +0 -1
- package/lib/commonjs/components/PlatformList.js.map +0 -1
- package/lib/commonjs/components/TrainingModal.js +0 -717
- package/lib/commonjs/components/TrainingModal.js.map +0 -1
- package/lib/commonjs/components/UniversalOnboarding.js.map +0 -1
- package/lib/commonjs/components/UniversalOnboarding.tsx.new +0 -455
- package/lib/commonjs/components/onboarding/OAuthWebView.js.map +0 -1
- package/lib/commonjs/components/onboarding/OnboardingHeader.js.map +0 -1
- package/lib/commonjs/components/onboarding/PinInput.js.map +0 -1
- package/lib/commonjs/components/onboarding/PlatformConnector.js.map +0 -1
- package/lib/commonjs/components/screens/ConnectorScreen.js +0 -146
- package/lib/commonjs/components/screens/ConnectorScreen.js.map +0 -1
- package/lib/commonjs/components/screens/LoadingScreen.js +0 -91
- package/lib/commonjs/components/screens/LoadingScreen.js.map +0 -1
- package/lib/commonjs/components/screens/PinCreationScreen.js +0 -61
- package/lib/commonjs/components/screens/PinCreationScreen.js.map +0 -1
- package/lib/commonjs/constants/index.js.map +0 -1
- package/lib/commonjs/hooks/useConnections.js.map +0 -1
- package/lib/commonjs/hooks/useCredentials.js.map +0 -1
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/services/apiKeyService.js.map +0 -1
- package/lib/commonjs/services/oauthService.js.map +0 -1
- package/lib/commonjs/services/platformAuthService.js.map +0 -1
- package/lib/commonjs/types/ambient.d.js.map +0 -1
- package/lib/commonjs/types/declarations.d.js.map +0 -1
- package/lib/commonjs/types/index.d.js.map +0 -1
- package/lib/commonjs/types/index.js.map +0 -1
- package/lib/commonjs/types/node-fix.d.js.map +0 -1
- package/lib/commonjs/types/node-override.d.js.map +0 -1
- package/lib/commonjs/types/opacity.d.js.map +0 -1
- package/lib/commonjs/types/types.d.js.map +0 -1
- package/lib/commonjs/types.js.map +0 -1
- package/lib/commonjs/utils/Portal.js.map +0 -1
- package/lib/commonjs/utils/api.js.map +0 -1
- package/lib/commonjs/utils/auth.js.map +0 -1
- package/lib/commonjs/utils/crypto.js.map +0 -1
- package/lib/commonjs/utils/debugHelper.js.map +0 -1
- package/lib/commonjs/utils/encryption.js.map +0 -1
- package/lib/commonjs/utils/onairosApi.js.map +0 -1
- package/lib/commonjs/utils/programmaticFlow.js.map +0 -1
- package/lib/commonjs/utils/retryHelper.js.map +0 -1
- package/lib/commonjs/utils/secureStorage.js.map +0 -1
- package/lib/module/api/index.js.map +0 -1
- package/lib/module/assets/images/email.png +0 -0
- package/lib/module/assets/images/linkedin.png +0 -0
- package/lib/module/assets/images/reddit.png +0 -0
- package/lib/module/assets/images/youtube.png +0 -0
- package/lib/module/components/DataRequestModal.js +0 -220
- package/lib/module/components/DataRequestModal.js.map +0 -1
- package/lib/module/components/DataRequestScreen.js +0 -321
- package/lib/module/components/DataRequestScreen.js.map +0 -1
- package/lib/module/components/EmailVerificationModal.js +0 -311
- package/lib/module/components/EmailVerificationModal.js.map +0 -1
- package/lib/module/components/Onairos.js.map +0 -1
- package/lib/module/components/OnairosButton.js.map +0 -1
- package/lib/module/components/Overlay.js.map +0 -1
- package/lib/module/components/PinInput.js.map +0 -1
- package/lib/module/components/PlatformList.js.map +0 -1
- package/lib/module/components/TrainingModal.js +0 -708
- package/lib/module/components/TrainingModal.js.map +0 -1
- package/lib/module/components/UniversalOnboarding.js.map +0 -1
- package/lib/module/components/UniversalOnboarding.tsx.new +0 -455
- package/lib/module/components/onboarding/OAuthWebView.js.map +0 -1
- package/lib/module/components/onboarding/OnboardingHeader.js.map +0 -1
- package/lib/module/components/onboarding/PinInput.js.map +0 -1
- package/lib/module/components/onboarding/PlatformConnector.js.map +0 -1
- package/lib/module/components/screens/ConnectorScreen.js +0 -138
- package/lib/module/components/screens/ConnectorScreen.js.map +0 -1
- package/lib/module/components/screens/LoadingScreen.js +0 -83
- package/lib/module/components/screens/LoadingScreen.js.map +0 -1
- package/lib/module/components/screens/PinCreationScreen.js +0 -53
- package/lib/module/components/screens/PinCreationScreen.js.map +0 -1
- package/lib/module/constants/index.js.map +0 -1
- package/lib/module/hooks/useConnections.js.map +0 -1
- package/lib/module/hooks/useCredentials.js.map +0 -1
- package/lib/module/index.js.map +0 -1
- package/lib/module/services/apiKeyService.js.map +0 -1
- package/lib/module/services/oauthService.js.map +0 -1
- package/lib/module/services/platformAuthService.js.map +0 -1
- package/lib/module/types/ambient.d.js.map +0 -1
- package/lib/module/types/declarations.d.js.map +0 -1
- package/lib/module/types/index.d.js.map +0 -1
- package/lib/module/types/index.js.map +0 -1
- package/lib/module/types/node-fix.d.js.map +0 -1
- package/lib/module/types/node-override.d.js.map +0 -1
- package/lib/module/types/opacity.d.js.map +0 -1
- package/lib/module/types/types.d.js.map +0 -1
- package/lib/module/types.js.map +0 -1
- package/lib/module/utils/Portal.js.map +0 -1
- package/lib/module/utils/api.js.map +0 -1
- package/lib/module/utils/auth.js.map +0 -1
- package/lib/module/utils/crypto.js.map +0 -1
- package/lib/module/utils/debugHelper.js.map +0 -1
- package/lib/module/utils/encryption.js.map +0 -1
- package/lib/module/utils/onairosApi.js.map +0 -1
- package/lib/module/utils/programmaticFlow.js.map +0 -1
- package/lib/module/utils/retryHelper.js.map +0 -1
- package/lib/module/utils/secureStorage.js.map +0 -1
- package/lib/typescript/api/index.d.ts +0 -8
- package/lib/typescript/api/index.d.ts.map +0 -1
- package/lib/typescript/components/DataRequestModal.d.ts +0 -11
- package/lib/typescript/components/DataRequestModal.d.ts.map +0 -1
- package/lib/typescript/components/DataRequestScreen.d.ts +0 -11
- package/lib/typescript/components/DataRequestScreen.d.ts.map +0 -1
- package/lib/typescript/components/EmailVerificationModal.d.ts +0 -11
- package/lib/typescript/components/EmailVerificationModal.d.ts.map +0 -1
- package/lib/typescript/components/Onairos.d.ts +0 -4
- package/lib/typescript/components/Onairos.d.ts.map +0 -1
- package/lib/typescript/components/OnairosButton.d.ts +0 -12
- package/lib/typescript/components/OnairosButton.d.ts.map +0 -1
- package/lib/typescript/components/Overlay.d.ts +0 -4
- package/lib/typescript/components/Overlay.d.ts.map +0 -1
- package/lib/typescript/components/PinInput.d.ts +0 -4
- package/lib/typescript/components/PinInput.d.ts.map +0 -1
- package/lib/typescript/components/PlatformList.d.ts +0 -4
- package/lib/typescript/components/PlatformList.d.ts.map +0 -1
- package/lib/typescript/components/TrainingModal.d.ts +0 -4
- package/lib/typescript/components/TrainingModal.d.ts.map +0 -1
- package/lib/typescript/components/UniversalOnboarding.d.ts +0 -4
- package/lib/typescript/components/UniversalOnboarding.d.ts.map +0 -1
- package/lib/typescript/components/onboarding/OAuthWebView.d.ts +0 -10
- package/lib/typescript/components/onboarding/OAuthWebView.d.ts.map +0 -1
- package/lib/typescript/components/onboarding/OnboardingHeader.d.ts +0 -11
- package/lib/typescript/components/onboarding/OnboardingHeader.d.ts.map +0 -1
- package/lib/typescript/components/onboarding/PinInput.d.ts +0 -4
- package/lib/typescript/components/onboarding/PinInput.d.ts.map +0 -1
- package/lib/typescript/components/onboarding/PlatformConnector.d.ts +0 -13
- package/lib/typescript/components/onboarding/PlatformConnector.d.ts.map +0 -1
- package/lib/typescript/components/screens/ConnectorScreen.d.ts +0 -9
- package/lib/typescript/components/screens/ConnectorScreen.d.ts.map +0 -1
- package/lib/typescript/components/screens/LoadingScreen.d.ts +0 -9
- package/lib/typescript/components/screens/LoadingScreen.d.ts.map +0 -1
- package/lib/typescript/components/screens/PinCreationScreen.d.ts +0 -10
- package/lib/typescript/components/screens/PinCreationScreen.d.ts.map +0 -1
- package/lib/typescript/constants/index.d.ts +0 -53
- package/lib/typescript/constants/index.d.ts.map +0 -1
- package/lib/typescript/hooks/useConnections.d.ts +0 -9
- package/lib/typescript/hooks/useConnections.d.ts.map +0 -1
- package/lib/typescript/hooks/useCredentials.d.ts +0 -9
- package/lib/typescript/hooks/useCredentials.d.ts.map +0 -1
- package/lib/typescript/index.d.ts +0 -18
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/services/apiKeyService.d.ts +0 -132
- package/lib/typescript/services/apiKeyService.d.ts.map +0 -1
- package/lib/typescript/services/oauthService.d.ts +0 -50
- package/lib/typescript/services/oauthService.d.ts.map +0 -1
- package/lib/typescript/services/platformAuthService.d.ts +0 -144
- package/lib/typescript/services/platformAuthService.d.ts.map +0 -1
- package/lib/typescript/types/index.d.ts +0 -231
- package/lib/typescript/types/index.d.ts.map +0 -1
- package/lib/typescript/types.d.ts +0 -270
- package/lib/typescript/types.d.ts.map +0 -1
- package/lib/typescript/utils/Portal.d.ts +0 -14
- package/lib/typescript/utils/Portal.d.ts.map +0 -1
- package/lib/typescript/utils/api.d.ts +0 -6
- package/lib/typescript/utils/api.d.ts.map +0 -1
- package/lib/typescript/utils/auth.d.ts +0 -6
- package/lib/typescript/utils/auth.d.ts.map +0 -1
- package/lib/typescript/utils/crypto.d.ts +0 -4
- package/lib/typescript/utils/crypto.d.ts.map +0 -1
- package/lib/typescript/utils/debugHelper.d.ts +0 -29
- package/lib/typescript/utils/debugHelper.d.ts.map +0 -1
- package/lib/typescript/utils/encryption.d.ts +0 -19
- package/lib/typescript/utils/encryption.d.ts.map +0 -1
- package/lib/typescript/utils/onairosApi.d.ts +0 -87
- package/lib/typescript/utils/onairosApi.d.ts.map +0 -1
- package/lib/typescript/utils/programmaticFlow.d.ts +0 -23
- package/lib/typescript/utils/programmaticFlow.d.ts.map +0 -1
- package/lib/typescript/utils/retryHelper.d.ts +0 -69
- package/lib/typescript/utils/retryHelper.d.ts.map +0 -1
- package/lib/typescript/utils/secureStorage.d.ts +0 -94
- package/lib/typescript/utils/secureStorage.d.ts.map +0 -1
- package/src/api/index.ts +0 -111
- package/src/assets/images/email.png +0 -0
- package/src/assets/images/linkedin.png +0 -0
- package/src/assets/images/onairos_logo.png +0 -0
- package/src/assets/images/reddit.png +0 -0
- package/src/assets/images/youtube.png +0 -0
- package/src/components/DataRequestModal.tsx +0 -227
- package/src/components/DataRequestScreen.tsx +0 -356
- package/src/components/EmailVerificationModal.tsx +0 -364
- package/src/components/Onairos.tsx +0 -425
- package/src/components/OnairosButton.tsx +0 -359
- package/src/components/Overlay.tsx +0 -506
- package/src/components/PinInput.tsx +0 -343
- package/src/components/PlatformList.tsx +0 -145
- package/src/components/TrainingModal.tsx +0 -737
- package/src/components/UniversalOnboarding.tsx +0 -1839
- package/src/components/UniversalOnboarding.tsx.new +0 -455
- package/src/components/onboarding/OAuthWebView.tsx +0 -838
- package/src/components/onboarding/OnboardingHeader.tsx +0 -70
- package/src/components/onboarding/PinInput.tsx +0 -356
- package/src/components/onboarding/PlatformConnector.tsx +0 -302
- package/src/components/screens/ConnectorScreen.tsx +0 -153
- package/src/components/screens/LoadingScreen.tsx +0 -100
- package/src/components/screens/PinCreationScreen.tsx +0 -67
- package/src/constants/index.ts +0 -83
- package/src/hooks/useConnections.ts +0 -163
- package/src/hooks/useCredentials.ts +0 -175
- package/src/index.js +0 -14
- package/src/index.ts +0 -50
- package/src/services/SDK_API_KEY_VALIDATION.md +0 -421
- package/src/services/apiKeyService.ts +0 -984
- package/src/services/oauthService.ts +0 -412
- package/src/services/platformAuthService.ts +0 -1113
- package/src/types/ambient.d.ts +0 -29
- package/src/types/declarations.d.ts +0 -26
- package/src/types/index.d.ts +0 -274
- package/src/types/index.ts +0 -244
- package/src/types/node-fix.d.ts +0 -19
- package/src/types/node-override.d.ts +0 -24
- package/src/types/opacity.d.ts +0 -16
- package/src/types/types.d.ts +0 -18
- package/src/types.ts +0 -298
- package/src/utils/Portal.tsx +0 -83
- package/src/utils/api.js +0 -112
- package/src/utils/auth.js +0 -104
- package/src/utils/crypto.js +0 -60
- package/src/utils/debugHelper.ts +0 -53
- package/src/utils/encryption.ts +0 -69
- package/src/utils/onairosApi.ts +0 -391
- package/src/utils/programmaticFlow.ts +0 -113
- package/src/utils/retryHelper.ts +0 -275
- package/src/utils/secureStorage.ts +0 -361
- package/types/index.d.ts +0 -218
- package/types/node-env.d.ts +0 -15
- /package/{src/assets/images → lib/commonjs/assets/icons}/farcaster.png +0 -0
- /package/{src/assets/images → lib/commonjs/assets/icons}/instagram.png +0 -0
- /package/{src/assets/images → lib/commonjs/assets/icons}/pinterest.png +0 -0
- /package/{src/assets/images → lib/commonjs/assets/icons}/swerv_logo.png +0 -0
- /package/{src/assets/images → lib/commonjs/assets/icons}/twitter.jpg +0 -0
|
@@ -1,1839 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useState, useRef } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
Text,
|
|
5
|
-
StyleSheet,
|
|
6
|
-
TouchableOpacity,
|
|
7
|
-
ActivityIndicator,
|
|
8
|
-
Dimensions,
|
|
9
|
-
Platform,
|
|
10
|
-
Modal,
|
|
11
|
-
Animated,
|
|
12
|
-
SafeAreaView,
|
|
13
|
-
TouchableWithoutFeedback,
|
|
14
|
-
ScrollView,
|
|
15
|
-
Image,
|
|
16
|
-
Switch,
|
|
17
|
-
Linking,
|
|
18
|
-
Alert,
|
|
19
|
-
TextInput,
|
|
20
|
-
} from 'react-native';
|
|
21
|
-
import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
22
|
-
import { PlatformList } from './PlatformList';
|
|
23
|
-
import { PinInput } from './PinInput';
|
|
24
|
-
import { TrainingModal } from './TrainingModal';
|
|
25
|
-
import { DataRequestScreen } from './DataRequestScreen';
|
|
26
|
-
import { OAuthWebView } from './onboarding/OAuthWebView';
|
|
27
|
-
import { useConnections } from '../hooks/useConnections';
|
|
28
|
-
import { COLORS, DEEP_LINK_CONFIG } from '../constants';
|
|
29
|
-
import { initiateOAuth, initiateNativeAuth, hasNativeSDK, isOAuthCallback, testApiConnectivity, handleOAuthCallbackUrl, refreshYouTubeTokens, requestEmailVerification, verifyEmailCode, checkEmailVerificationStatus, disconnectPlatform } from '../services/platformAuthService';
|
|
30
|
-
import type { UniversalOnboardingProps, ConnectionStatus, TestModeOptions } from '../types';
|
|
31
|
-
|
|
32
|
-
// Optional Opacity SDK imports with error handling
|
|
33
|
-
let opacityInit: any = null;
|
|
34
|
-
let OpacityEnvironment: any = null;
|
|
35
|
-
let opacityGet: any = null;
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
const opacitySDK = require('@opacity-labs/react-native-opacity');
|
|
39
|
-
opacityInit = opacitySDK.init;
|
|
40
|
-
OpacityEnvironment = opacitySDK.OpacityEnvironment;
|
|
41
|
-
opacityGet = opacitySDK.get;
|
|
42
|
-
} catch (error) {
|
|
43
|
-
console.warn('Opacity SDK not available:', error);
|
|
44
|
-
// Opacity SDK will be disabled if not available
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const { height, width } = Dimensions.get('window');
|
|
48
|
-
|
|
49
|
-
export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
50
|
-
visible,
|
|
51
|
-
onClose,
|
|
52
|
-
AppName,
|
|
53
|
-
appIcon,
|
|
54
|
-
requestData,
|
|
55
|
-
returnLink,
|
|
56
|
-
onComplete,
|
|
57
|
-
embedd = false,
|
|
58
|
-
debug = false,
|
|
59
|
-
testMode = false,
|
|
60
|
-
preferredPlatform,
|
|
61
|
-
inferenceData,
|
|
62
|
-
auto = false,
|
|
63
|
-
partner,
|
|
64
|
-
}) => {
|
|
65
|
-
const [step, setStep] = useState<'email' | 'verify' | 'dataRequest' | 'connect' | 'pin' | 'training' | 'oauth' | 'success'>('email');
|
|
66
|
-
const [connections, setConnections] = useState<ConnectionStatus>({});
|
|
67
|
-
const [pin, setPin] = useState<string>('');
|
|
68
|
-
const [selectedTier, setSelectedTier] = useState<'Small' | 'Medium' | 'Large'>('Medium');
|
|
69
|
-
const [training, setTraining] = useState<{
|
|
70
|
-
progress: number;
|
|
71
|
-
eta: string;
|
|
72
|
-
}>({ progress: 0, eta: '' });
|
|
73
|
-
const [slideAnim] = useState(new Animated.Value(height));
|
|
74
|
-
const [platformToggles, setPlatformToggles] = useState<{[key: string]: boolean}>({});
|
|
75
|
-
const [oauthUrl, setOauthUrl] = useState<string>('');
|
|
76
|
-
const [currentPlatform, setCurrentPlatform] = useState<string>('');
|
|
77
|
-
const [username, setUsername] = useState<string>('Avatar');
|
|
78
|
-
const [isConnectingPlatform, setIsConnectingPlatform] = useState<boolean>(false);
|
|
79
|
-
const [showLoginWebView, setShowLoginWebView] = useState<boolean>(false);
|
|
80
|
-
const [email, setEmail] = useState<string>('');
|
|
81
|
-
const [verificationCode, setVerificationCode] = useState<string>('');
|
|
82
|
-
const [isVerifyingCode, setIsVerifyingCode] = useState<boolean>(false);
|
|
83
|
-
|
|
84
|
-
const [isExistingUser, setIsExistingUser] = useState<boolean>(false);
|
|
85
|
-
|
|
86
|
-
// Add refs for cleanup and code inputs
|
|
87
|
-
const successTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
88
|
-
const isMountedRef = useRef<boolean>(true);
|
|
89
|
-
const codeInputRefs = useRef<Array<TextInput | null>>([]);
|
|
90
|
-
|
|
91
|
-
// Add state for showing additional platforms
|
|
92
|
-
const [showAllPlatforms, setShowAllPlatforms] = useState<boolean>(false);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
// Parse test mode options
|
|
96
|
-
const testModeOptions = typeof testMode === 'object' ? testMode : {} as any;
|
|
97
|
-
const isTestMode = testMode === true || (typeof testMode === 'object' && testMode !== null);
|
|
98
|
-
const showTestControls = (debug || isTestMode) && requestData;
|
|
99
|
-
|
|
100
|
-
// Simple 2-flow system
|
|
101
|
-
const isExistingUserFlow = testModeOptions.existingUser || false;
|
|
102
|
-
const isNewUserFlow = testModeOptions.newUser || false;
|
|
103
|
-
|
|
104
|
-
const platforms = [
|
|
105
|
-
{ id: 'instagram', name: 'Instagram', icon: require('../assets/images/instagram.png') },
|
|
106
|
-
{ id: 'youtube', name: 'YouTube', icon: require('../assets/images/youtube.png') },
|
|
107
|
-
{ id: 'email', name: 'Gmail', icon: require('../assets/images/email.png') },
|
|
108
|
-
{ id: 'reddit', name: 'Reddit', icon: require('../assets/images/reddit.png') },
|
|
109
|
-
{ id: 'pinterest', name: 'Pinterest', icon: require('../assets/images/pinterest.png') },
|
|
110
|
-
];
|
|
111
|
-
|
|
112
|
-
// Handle preferredPlatform to show ONLY preferred platforms (up to 2)
|
|
113
|
-
const getDisplayPlatforms = () => {
|
|
114
|
-
if (!preferredPlatform) {
|
|
115
|
-
// Default behavior: show first 3 platforms initially
|
|
116
|
-
return showAllPlatforms ? platforms : platforms.slice(0, 3);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const preferredArray = Array.isArray(preferredPlatform) ? preferredPlatform : [preferredPlatform];
|
|
120
|
-
const maxPreferred = Math.min(preferredArray.length, 2); // Limit to 2 preferred platforms max
|
|
121
|
-
|
|
122
|
-
// Show ONLY the preferred platforms (in specified order)
|
|
123
|
-
return preferredArray.slice(0, maxPreferred)
|
|
124
|
-
.map(id => platforms.find(p => p.id === id))
|
|
125
|
-
.filter(Boolean) as typeof platforms;
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
const platformsToDisplay = getDisplayPlatforms();
|
|
129
|
-
|
|
130
|
-
// Calculate additional platforms for "Show More" button
|
|
131
|
-
const additionalPlatforms = preferredPlatform ? [] : platforms.slice(3);
|
|
132
|
-
|
|
133
|
-
const {
|
|
134
|
-
connectPlatform,
|
|
135
|
-
disconnectPlatform,
|
|
136
|
-
getConnectionStatus,
|
|
137
|
-
isConnecting,
|
|
138
|
-
} = useConnections();
|
|
139
|
-
|
|
140
|
-
useEffect(() => {
|
|
141
|
-
// Set mounted flag
|
|
142
|
-
isMountedRef.current = true;
|
|
143
|
-
|
|
144
|
-
if (visible) {
|
|
145
|
-
loadInitialStatus();
|
|
146
|
-
// Animate in
|
|
147
|
-
Animated.spring(slideAnim, {
|
|
148
|
-
toValue: 0,
|
|
149
|
-
useNativeDriver: true,
|
|
150
|
-
bounciness: 0,
|
|
151
|
-
}).start();
|
|
152
|
-
|
|
153
|
-
// Set up deep link listener for OAuth callbacks
|
|
154
|
-
// Using the subscription pattern for React Native's Linking API
|
|
155
|
-
const subscription = Linking.addListener('url', ({ url }) => {
|
|
156
|
-
if (isOAuthCallback(url)) {
|
|
157
|
-
handleOAuthCallback(url);
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// Check for initial URL (app was opened via deep link)
|
|
162
|
-
Linking.getInitialURL().then(initialUrl => {
|
|
163
|
-
if (initialUrl && isOAuthCallback(initialUrl)) {
|
|
164
|
-
handleOAuthCallback(initialUrl);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// Initialize platform toggles
|
|
169
|
-
const initialToggles: { [key: string]: boolean } = {};
|
|
170
|
-
platforms.forEach((platform) => {
|
|
171
|
-
initialToggles[platform.id] = false;
|
|
172
|
-
});
|
|
173
|
-
setPlatformToggles(initialToggles);
|
|
174
|
-
|
|
175
|
-
// Debug mode for Expo Go
|
|
176
|
-
if (debug || Platform.OS === 'web') {
|
|
177
|
-
console.log('Debug mode enabled - Using mock data for onboarding');
|
|
178
|
-
console.log('Configuration:', {
|
|
179
|
-
auto,
|
|
180
|
-
partner,
|
|
181
|
-
hasInferenceData: !!inferenceData,
|
|
182
|
-
inferenceDataType: typeof inferenceData,
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
// Pre-populate with mock connections in debug mode
|
|
186
|
-
if (testMode || Platform.OS === 'web') {
|
|
187
|
-
setConnections({
|
|
188
|
-
instagram: { userName: 'instagram_user', connected: true },
|
|
189
|
-
youtube: { userName: 'youtube_user', connected: true },
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// If there's a preferred platform, pre-connect
|
|
195
|
-
if (preferredPlatform && debug) {
|
|
196
|
-
const preferredArray = Array.isArray(preferredPlatform) ? preferredPlatform : [preferredPlatform];
|
|
197
|
-
const newConnections: any = {};
|
|
198
|
-
preferredArray.slice(0, 2).forEach(platform => {
|
|
199
|
-
newConnections[platform] = { userName: `${platform}_user`, connected: true };
|
|
200
|
-
});
|
|
201
|
-
setConnections(prev => ({
|
|
202
|
-
...prev,
|
|
203
|
-
...newConnections
|
|
204
|
-
}));
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Return cleanup function
|
|
208
|
-
return () => {
|
|
209
|
-
// Remove event listener using the subscription
|
|
210
|
-
subscription.remove();
|
|
211
|
-
};
|
|
212
|
-
} else {
|
|
213
|
-
// Animate out
|
|
214
|
-
Animated.timing(slideAnim, {
|
|
215
|
-
toValue: height,
|
|
216
|
-
duration: 250,
|
|
217
|
-
useNativeDriver: true,
|
|
218
|
-
}).start(() => {
|
|
219
|
-
// Reset state if needed
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
}, [visible, preferredPlatform]);
|
|
223
|
-
|
|
224
|
-
// Cleanup effect for unmounting
|
|
225
|
-
useEffect(() => {
|
|
226
|
-
return () => {
|
|
227
|
-
// Set mounted flag to false
|
|
228
|
-
isMountedRef.current = false;
|
|
229
|
-
|
|
230
|
-
// Clear any pending timeouts
|
|
231
|
-
if (successTimeoutRef.current) {
|
|
232
|
-
clearTimeout(successTimeoutRef.current);
|
|
233
|
-
successTimeoutRef.current = null;
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
}, []);
|
|
237
|
-
|
|
238
|
-
const handleClose = () => {
|
|
239
|
-
// Clear any pending timeouts before closing
|
|
240
|
-
if (successTimeoutRef.current) {
|
|
241
|
-
clearTimeout(successTimeoutRef.current);
|
|
242
|
-
successTimeoutRef.current = null;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Set mounted flag to false
|
|
246
|
-
isMountedRef.current = false;
|
|
247
|
-
|
|
248
|
-
// Animate out and then call onClose
|
|
249
|
-
Animated.timing(slideAnim, {
|
|
250
|
-
toValue: height,
|
|
251
|
-
duration: 250,
|
|
252
|
-
useNativeDriver: true,
|
|
253
|
-
}).start(() => {
|
|
254
|
-
// Only call onClose if component is still meant to be mounted
|
|
255
|
-
// This prevents the "User closed onboarding" error
|
|
256
|
-
onClose();
|
|
257
|
-
});
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
const loadInitialStatus = useCallback(async () => {
|
|
261
|
-
try {
|
|
262
|
-
console.log('🔄 Loading initial connection status...');
|
|
263
|
-
const status = await getConnectionStatus();
|
|
264
|
-
console.log('✅ Connection status loaded:', status);
|
|
265
|
-
setConnections(status || {});
|
|
266
|
-
} catch (error) {
|
|
267
|
-
console.error('❌ Failed to load connection status:', error);
|
|
268
|
-
// Set empty connections to prevent crashes
|
|
269
|
-
setConnections({});
|
|
270
|
-
}
|
|
271
|
-
}, [getConnectionStatus]);
|
|
272
|
-
|
|
273
|
-
const togglePlatform = useCallback(async (platformId: string) => {
|
|
274
|
-
if (!platformToggles[platformId]) {
|
|
275
|
-
// Attempt to connect platform
|
|
276
|
-
try {
|
|
277
|
-
setIsConnectingPlatform(true);
|
|
278
|
-
console.log(`🔌 Initiating connection for ${platformId}`);
|
|
279
|
-
|
|
280
|
-
// Test API connectivity first
|
|
281
|
-
console.log('🔍 Testing API connectivity...');
|
|
282
|
-
const connectivityTest = await testApiConnectivity();
|
|
283
|
-
|
|
284
|
-
if (!connectivityTest.success) {
|
|
285
|
-
console.error('❌ API connectivity test failed:', connectivityTest.error);
|
|
286
|
-
Alert.alert('Network Error', `${connectivityTest.error}\n\nPlease check your internet connection and try again.`);
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
console.log('✅ API connectivity confirmed');
|
|
291
|
-
|
|
292
|
-
// Instagram: Use Opacity SDK exclusively
|
|
293
|
-
if (platformId === 'instagram') {
|
|
294
|
-
// Check if Opacity SDK is available
|
|
295
|
-
if (!opacityInit || !OpacityEnvironment || !opacityGet) {
|
|
296
|
-
console.error('❌ Opacity SDK not available for Instagram');
|
|
297
|
-
throw new Error('Instagram connection requires the Opacity SDK. Please ensure @opacity-labs/react-native-opacity is properly installed and configured.');
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
console.log('🔌 Initializing Opacity SDK for Instagram...');
|
|
301
|
-
|
|
302
|
-
// Initialize Opacity SDK with your API key
|
|
303
|
-
const apiKey = 'OsamaTest-7bde2407-7360-462a-86b4-b26d7f890cbb';
|
|
304
|
-
|
|
305
|
-
await opacityInit({
|
|
306
|
-
apiKey,
|
|
307
|
-
environment: OpacityEnvironment.Production,
|
|
308
|
-
shouldShowErrorsInWebView: true,
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
console.log('✅ Opacity SDK initialized successfully');
|
|
312
|
-
console.log('📱 Fetching Instagram profile...');
|
|
313
|
-
|
|
314
|
-
// Fetch Instagram profile using Opacity SDK
|
|
315
|
-
const profile = await opacityGet('flow:instagram:profile');
|
|
316
|
-
|
|
317
|
-
if (profile && typeof profile === 'object') {
|
|
318
|
-
console.log('✅ Instagram profile retrieved:', profile);
|
|
319
|
-
|
|
320
|
-
// Extract username from profile or use fallback
|
|
321
|
-
const instagramUsername = profile.username || profile.name || username;
|
|
322
|
-
|
|
323
|
-
// Update platform toggle state
|
|
324
|
-
setPlatformToggles(prev => ({
|
|
325
|
-
...prev,
|
|
326
|
-
[platformId]: true
|
|
327
|
-
}));
|
|
328
|
-
|
|
329
|
-
// Update connections state with Instagram data
|
|
330
|
-
setConnections(prev => ({
|
|
331
|
-
...prev,
|
|
332
|
-
[platformId]: {
|
|
333
|
-
userName: instagramUsername,
|
|
334
|
-
connected: true,
|
|
335
|
-
profileData: profile // Store additional profile data
|
|
336
|
-
}
|
|
337
|
-
}));
|
|
338
|
-
|
|
339
|
-
console.log(`✅ Instagram successfully connected for user: ${instagramUsername}`);
|
|
340
|
-
|
|
341
|
-
} else {
|
|
342
|
-
throw new Error('Invalid or empty Instagram profile data returned from Opacity SDK');
|
|
343
|
-
}
|
|
344
|
-
} else {
|
|
345
|
-
// For all other platforms (non-Instagram), check if they have native SDK
|
|
346
|
-
if (hasNativeSDK(platformId)) {
|
|
347
|
-
console.log(`📱 Using native SDK for ${platformId}`);
|
|
348
|
-
// Use native SDK for authentication
|
|
349
|
-
const success = await initiateNativeAuth(platformId, username);
|
|
350
|
-
if (success) {
|
|
351
|
-
console.log(`✅ Native authentication successful for ${platformId}`);
|
|
352
|
-
// Update platform toggle state
|
|
353
|
-
setPlatformToggles(prev => ({
|
|
354
|
-
...prev,
|
|
355
|
-
[platformId]: true
|
|
356
|
-
}));
|
|
357
|
-
|
|
358
|
-
// Update connections state
|
|
359
|
-
setConnections(prev => ({
|
|
360
|
-
...prev,
|
|
361
|
-
[platformId]: { userName: username, connected: true }
|
|
362
|
-
}));
|
|
363
|
-
} else {
|
|
364
|
-
throw new Error(`Native authentication failed for ${platformId}`);
|
|
365
|
-
}
|
|
366
|
-
} else {
|
|
367
|
-
// Use OAuth WebView flow
|
|
368
|
-
console.log(`🌐 Initiating OAuth flow for ${platformId}`);
|
|
369
|
-
|
|
370
|
-
const oauthUrl = await initiateOAuth(platformId, username, AppName);
|
|
371
|
-
|
|
372
|
-
if (oauthUrl) {
|
|
373
|
-
console.log(`✅ Received OAuth URL for ${platformId}:`, oauthUrl);
|
|
374
|
-
setCurrentPlatform(platformId);
|
|
375
|
-
setOauthUrl(oauthUrl);
|
|
376
|
-
setStep('oauth');
|
|
377
|
-
} else {
|
|
378
|
-
console.error(`❌ No OAuth URL returned for ${platformId}`);
|
|
379
|
-
throw new Error(`Failed to get authorization URL for ${platformId}. Please try again.`);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
} catch (error) {
|
|
384
|
-
console.error(`❌ Error connecting ${platformId}:`, error);
|
|
385
|
-
|
|
386
|
-
// Provide user-friendly error messages based on platform
|
|
387
|
-
let errorMessage = 'Unknown error occurred';
|
|
388
|
-
if (error instanceof Error) {
|
|
389
|
-
if (platformId === 'instagram') {
|
|
390
|
-
if (error.message.includes('Initialize')) {
|
|
391
|
-
errorMessage = 'Failed to initialize Instagram connection. Please check your internet connection.';
|
|
392
|
-
} else if (error.message.includes('profile')) {
|
|
393
|
-
errorMessage = 'Unable to retrieve Instagram profile. Please try again or check your Instagram account permissions.';
|
|
394
|
-
} else {
|
|
395
|
-
errorMessage = error.message;
|
|
396
|
-
}
|
|
397
|
-
} else {
|
|
398
|
-
errorMessage = error.message;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
Alert.alert(
|
|
403
|
-
`${platformId.charAt(0).toUpperCase() + platformId.slice(1)} Connection Failed`,
|
|
404
|
-
errorMessage,
|
|
405
|
-
[{ text: 'OK', style: 'default' }]
|
|
406
|
-
);
|
|
407
|
-
} finally {
|
|
408
|
-
setIsConnectingPlatform(false);
|
|
409
|
-
}
|
|
410
|
-
} else {
|
|
411
|
-
// Disconnect platform
|
|
412
|
-
console.log(`🔌 Disconnecting ${platformId}`);
|
|
413
|
-
setPlatformToggles(prev => ({
|
|
414
|
-
...prev,
|
|
415
|
-
[platformId]: false
|
|
416
|
-
}));
|
|
417
|
-
|
|
418
|
-
// Update connections state
|
|
419
|
-
setConnections(prev => {
|
|
420
|
-
const newConnections = { ...prev };
|
|
421
|
-
delete newConnections[platformId];
|
|
422
|
-
return newConnections;
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
}, [platformToggles, username, AppName]);
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* Handles OAuth callback URLs
|
|
429
|
-
*/
|
|
430
|
-
const handleOAuthCallback = useCallback((url: string) => {
|
|
431
|
-
console.log('🔗 OAuth callback received:', url);
|
|
432
|
-
|
|
433
|
-
const result = handleOAuthCallbackUrl(url);
|
|
434
|
-
|
|
435
|
-
if (result.success && result.platform && result.code) {
|
|
436
|
-
console.log(`✅ OAuth successful for ${result.platform}`);
|
|
437
|
-
|
|
438
|
-
// Update connections state
|
|
439
|
-
setConnections(prev => ({
|
|
440
|
-
...prev,
|
|
441
|
-
[result.platform!]: { userName: username, connected: true }
|
|
442
|
-
}));
|
|
443
|
-
|
|
444
|
-
// Update platform toggles
|
|
445
|
-
setPlatformToggles(prev => ({
|
|
446
|
-
...prev,
|
|
447
|
-
[result.platform!]: true
|
|
448
|
-
}));
|
|
449
|
-
|
|
450
|
-
// Close OAuth window and return to connect step
|
|
451
|
-
setOauthUrl('');
|
|
452
|
-
setCurrentPlatform('');
|
|
453
|
-
setStep('connect');
|
|
454
|
-
|
|
455
|
-
console.log(`🎉 ${result.platform} successfully connected via OAuth`);
|
|
456
|
-
} else {
|
|
457
|
-
console.error('❌ OAuth callback failed or incomplete');
|
|
458
|
-
}
|
|
459
|
-
}, [username]);
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* Handles completion of the OAuth flow
|
|
463
|
-
*/
|
|
464
|
-
const handleOAuthSuccess = useCallback((code: string) => {
|
|
465
|
-
console.log(`OAuth success for ${currentPlatform} with code: ${code}`);
|
|
466
|
-
|
|
467
|
-
// Update connections for the current platform
|
|
468
|
-
if (currentPlatform) {
|
|
469
|
-
// Update connections state
|
|
470
|
-
setConnections(prev => ({
|
|
471
|
-
...prev,
|
|
472
|
-
[currentPlatform]: { userName: username, connected: true }
|
|
473
|
-
}));
|
|
474
|
-
|
|
475
|
-
// Update platform toggles
|
|
476
|
-
setPlatformToggles(prev => ({
|
|
477
|
-
...prev,
|
|
478
|
-
[currentPlatform]: true
|
|
479
|
-
}));
|
|
480
|
-
|
|
481
|
-
console.log(`Successfully connected ${currentPlatform} for user ${username}`);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// Close OAuth window and return to connect step
|
|
485
|
-
setOauthUrl('');
|
|
486
|
-
setCurrentPlatform('');
|
|
487
|
-
setStep('connect');
|
|
488
|
-
}, [currentPlatform, username]);
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
// Function to check for existing account (spoofed for now)
|
|
493
|
-
const checkExistingAccount = useCallback(async () => {
|
|
494
|
-
console.log('Checking for existing account...');
|
|
495
|
-
// TODO: Implement actual logic to check cookies/storage for existing account
|
|
496
|
-
// For now, this is spoofed and doesn't do anything
|
|
497
|
-
return false;
|
|
498
|
-
}, []);
|
|
499
|
-
|
|
500
|
-
// Function to handle email submission
|
|
501
|
-
const handleEmailSubmit = useCallback(async () => {
|
|
502
|
-
console.log('🚀 handleEmailSubmit called with email:', email);
|
|
503
|
-
console.log('🧪 testMode value:', testMode);
|
|
504
|
-
console.log('🧪 isTestMode computed:', isTestMode);
|
|
505
|
-
|
|
506
|
-
try {
|
|
507
|
-
if (!email || !email.trim()) {
|
|
508
|
-
console.log('❌ No email provided');
|
|
509
|
-
Alert.alert('Error', 'Please enter your email address');
|
|
510
|
-
return;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// Basic email validation
|
|
514
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
515
|
-
if (!emailRegex.test(email.trim())) {
|
|
516
|
-
console.log('❌ Invalid email format');
|
|
517
|
-
Alert.alert('Error', 'Please enter a valid email address');
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
console.log('📧 Email validation passed, proceeding...');
|
|
522
|
-
|
|
523
|
-
// Check if we should skip API calls entirely (only for specific test scenarios)
|
|
524
|
-
const shouldSkipApiCalls = (typeof testMode === 'object' && testMode !== null && testMode.skipApiCalls === true);
|
|
525
|
-
|
|
526
|
-
if (shouldSkipApiCalls) {
|
|
527
|
-
console.log('🧪 Test mode with skipApiCalls: true - Skipping API call, proceeding to verification');
|
|
528
|
-
setStep('verify');
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
// Add loading state to prevent multiple submissions
|
|
533
|
-
if (isVerifyingCode) {
|
|
534
|
-
console.log('⚠️ Email verification already in progress');
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
setIsVerifyingCode(true);
|
|
539
|
-
console.log('🔄 Starting email verification process...');
|
|
540
|
-
console.log('📡 Will make API call with testMode flag:', isTestMode);
|
|
541
|
-
|
|
542
|
-
// Wrap the entire API call in a timeout to prevent hanging
|
|
543
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
544
|
-
setTimeout(() => reject(new Error('Request timeout')), 10000); // 10 second timeout
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
try {
|
|
548
|
-
// Safety check for function availability with detailed debugging
|
|
549
|
-
console.log('🔍 Checking requestEmailVerification function availability...');
|
|
550
|
-
console.log('🔍 Type of requestEmailVerification:', typeof requestEmailVerification);
|
|
551
|
-
console.log('🔍 requestEmailVerification function:', requestEmailVerification);
|
|
552
|
-
|
|
553
|
-
if (typeof requestEmailVerification !== 'function') {
|
|
554
|
-
console.error('❌ requestEmailVerification function not available');
|
|
555
|
-
console.error('❌ Available functions from platformAuthService:', {
|
|
556
|
-
requestEmailVerification: typeof requestEmailVerification,
|
|
557
|
-
verifyEmailCode: typeof verifyEmailCode,
|
|
558
|
-
checkEmailVerificationStatus: typeof checkEmailVerificationStatus,
|
|
559
|
-
});
|
|
560
|
-
// In development, just proceed anyway
|
|
561
|
-
console.log('🧪 Proceeding without API call in development mode');
|
|
562
|
-
setStep('verify');
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
console.log('✅ requestEmailVerification function is available');
|
|
567
|
-
console.log('🔄 Making API call to requestEmailVerification...');
|
|
568
|
-
|
|
569
|
-
// Race between API call and timeout
|
|
570
|
-
const result = await Promise.race([
|
|
571
|
-
requestEmailVerification(email.trim(), isTestMode),
|
|
572
|
-
timeoutPromise
|
|
573
|
-
]) as any;
|
|
574
|
-
|
|
575
|
-
console.log('📡 Email verification API result:', result);
|
|
576
|
-
|
|
577
|
-
if (result && result.success) {
|
|
578
|
-
console.log('✅ Verification code requested successfully');
|
|
579
|
-
setStep('verify');
|
|
580
|
-
} else {
|
|
581
|
-
console.warn('⚠️ Email verification request failed, but proceeding anyway:', result);
|
|
582
|
-
// In development mode, proceed even if API fails
|
|
583
|
-
setStep('verify');
|
|
584
|
-
}
|
|
585
|
-
} catch (verificationError) {
|
|
586
|
-
console.error('❌ Error in email verification API call:', verificationError);
|
|
587
|
-
// In development mode, proceed even if API fails
|
|
588
|
-
console.log('🧪 API failed but proceeding to verification step in development mode');
|
|
589
|
-
setStep('verify');
|
|
590
|
-
} finally {
|
|
591
|
-
setIsVerifyingCode(false);
|
|
592
|
-
}
|
|
593
|
-
} catch (error) {
|
|
594
|
-
console.error('❌ Unexpected error in email submission:', error);
|
|
595
|
-
setIsVerifyingCode(false);
|
|
596
|
-
|
|
597
|
-
// In development mode, still try to proceed
|
|
598
|
-
console.log('🧪 Error occurred but attempting to proceed to verification step');
|
|
599
|
-
try {
|
|
600
|
-
setStep('verify');
|
|
601
|
-
} catch (stepError) {
|
|
602
|
-
console.error('❌ Failed to set step to verify:', stepError);
|
|
603
|
-
Alert.alert('Error', 'An unexpected error occurred. Please try again.');
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
}, [email, isVerifyingCode, debug, testMode, isTestMode]);
|
|
607
|
-
|
|
608
|
-
// Function to handle verification code submission
|
|
609
|
-
const handleVerificationSubmit = useCallback(async () => {
|
|
610
|
-
if (!verificationCode.trim() || verificationCode.trim().length !== 6) {
|
|
611
|
-
Alert.alert('Error', 'Please enter a 6-digit verification code');
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
setIsVerifyingCode(true);
|
|
616
|
-
|
|
617
|
-
try {
|
|
618
|
-
// Safety check for function availability
|
|
619
|
-
if (typeof verifyEmailCode !== 'function') {
|
|
620
|
-
throw new Error('Email verification service not available');
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
// Test Mode: Use specific flows
|
|
624
|
-
if (isTestMode) {
|
|
625
|
-
console.log('🧪 Test mode verification - simulating success');
|
|
626
|
-
|
|
627
|
-
if (isExistingUserFlow) {
|
|
628
|
-
// Flow 1: Existing User → Data Request → Close (return API URL)
|
|
629
|
-
console.log('🧪 Test Flow 1: Existing User → Show Data Request');
|
|
630
|
-
setIsExistingUser(true);
|
|
631
|
-
setStep('dataRequest');
|
|
632
|
-
return;
|
|
633
|
-
} else if (isNewUserFlow) {
|
|
634
|
-
// Flow 2: New User → Platform Connect → PIN → Training
|
|
635
|
-
console.log('🧪 Test Flow 2: New User → Platform Connect');
|
|
636
|
-
const emailPrefix = email.trim().split('@')[0] || 'TestUser';
|
|
637
|
-
setUsername(emailPrefix);
|
|
638
|
-
setStep('connect');
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
// Real API call (production) or test mode
|
|
644
|
-
const result = await verifyEmailCode(email.trim(), verificationCode.trim(), isTestMode);
|
|
645
|
-
|
|
646
|
-
if (result.success) {
|
|
647
|
-
console.log('✅ Email verification successful');
|
|
648
|
-
|
|
649
|
-
// Check if user exists in backend (properly typed now)
|
|
650
|
-
const existingUser = result.existingUser || false;
|
|
651
|
-
setIsExistingUser(existingUser);
|
|
652
|
-
|
|
653
|
-
if (existingUser) {
|
|
654
|
-
console.log('👤 Existing user detected, showing data request screen');
|
|
655
|
-
setStep('dataRequest');
|
|
656
|
-
} else {
|
|
657
|
-
console.log('🆕 New user, proceeding to platform connection');
|
|
658
|
-
// Safely set username from email prefix
|
|
659
|
-
try {
|
|
660
|
-
const emailPrefix = email.trim().split('@')[0];
|
|
661
|
-
if (emailPrefix && emailPrefix.length > 0) {
|
|
662
|
-
setUsername(emailPrefix);
|
|
663
|
-
} else {
|
|
664
|
-
setUsername('User'); // Fallback username
|
|
665
|
-
}
|
|
666
|
-
} catch (usernameError) {
|
|
667
|
-
console.warn('Failed to extract username from email, using fallback:', usernameError);
|
|
668
|
-
setUsername('User');
|
|
669
|
-
}
|
|
670
|
-
setStep('connect');
|
|
671
|
-
}
|
|
672
|
-
} else {
|
|
673
|
-
Alert.alert('Verification Failed', result.error || 'Invalid verification code');
|
|
674
|
-
}
|
|
675
|
-
} catch (error) {
|
|
676
|
-
console.error('❌ Error verifying code:', error);
|
|
677
|
-
Alert.alert('Error', 'Failed to verify code');
|
|
678
|
-
} finally {
|
|
679
|
-
setIsVerifyingCode(false);
|
|
680
|
-
}
|
|
681
|
-
}, [email, verificationCode]);
|
|
682
|
-
|
|
683
|
-
const handlePinSubmit = useCallback(async (userPin: string) => {
|
|
684
|
-
setPin(userPin);
|
|
685
|
-
setStep('training');
|
|
686
|
-
|
|
687
|
-
// Save session data for "Never Connect Again" functionality
|
|
688
|
-
try {
|
|
689
|
-
const sessionData = {
|
|
690
|
-
pin: userPin,
|
|
691
|
-
connections,
|
|
692
|
-
platformToggles,
|
|
693
|
-
selectedTier,
|
|
694
|
-
username,
|
|
695
|
-
timestamp: Date.now(),
|
|
696
|
-
appName: AppName,
|
|
697
|
-
inferenceData: auto ? inferenceData : undefined,
|
|
698
|
-
partner,
|
|
699
|
-
};
|
|
700
|
-
|
|
701
|
-
// Store session data in secure storage for future use
|
|
702
|
-
console.log('Saving session data for future "Never Connect Again" functionality:', sessionData);
|
|
703
|
-
|
|
704
|
-
// TODO: Implement actual secure storage of session data
|
|
705
|
-
// This would typically involve:
|
|
706
|
-
// 1. Storing encrypted session data locally
|
|
707
|
-
// 2. Setting cookies in WebView for onairos.uk domain
|
|
708
|
-
// 3. Storing authentication tokens securely
|
|
709
|
-
|
|
710
|
-
// For now, we'll simulate this with console logging
|
|
711
|
-
console.log('Session data saved - future apps will detect existing account');
|
|
712
|
-
|
|
713
|
-
} catch (error) {
|
|
714
|
-
console.error('Failed to save session data:', error);
|
|
715
|
-
}
|
|
716
|
-
}, [connections, selectedTier, platformToggles, username, AppName, auto, inferenceData, partner]);
|
|
717
|
-
|
|
718
|
-
const handleTrainingComplete = useCallback(async () => {
|
|
719
|
-
console.log('🎉 Training completed successfully');
|
|
720
|
-
console.log('🔍 Auto mode enabled:', auto);
|
|
721
|
-
console.log('🔍 Inference data available:', !!inferenceData);
|
|
722
|
-
|
|
723
|
-
try {
|
|
724
|
-
if (auto && inferenceData) {
|
|
725
|
-
console.log('🤖 Auto mode: Making API request to get URL and perform inference');
|
|
726
|
-
|
|
727
|
-
// First, get the API URL from backend
|
|
728
|
-
const apiUrlResponse = await fetch('https://api2.onairos.uk/', {
|
|
729
|
-
method: 'POST',
|
|
730
|
-
headers: {
|
|
731
|
-
'Content-Type': 'application/json',
|
|
732
|
-
},
|
|
733
|
-
body: JSON.stringify({
|
|
734
|
-
Info: {
|
|
735
|
-
storage: 'secure',
|
|
736
|
-
appId: AppName,
|
|
737
|
-
confirmations: Object.keys(requestData || {}),
|
|
738
|
-
EncryptedUserPin: pin, // Use the actual PIN from user
|
|
739
|
-
account: email.trim(),
|
|
740
|
-
proofMode: false,
|
|
741
|
-
}
|
|
742
|
-
})
|
|
743
|
-
});
|
|
744
|
-
|
|
745
|
-
if (!apiUrlResponse.ok) {
|
|
746
|
-
throw new Error(`Failed to get API URL: ${apiUrlResponse.status}`);
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
const { apiUrl, token } = await apiUrlResponse.json();
|
|
750
|
-
console.log('✅ Received API URL:', apiUrl);
|
|
751
|
-
console.log('✅ Received token:', token?.substring(0, 20) + '...');
|
|
752
|
-
|
|
753
|
-
// Now make the inference call with the provided data
|
|
754
|
-
const inferenceResponse = await fetch(apiUrl, {
|
|
755
|
-
method: 'POST',
|
|
756
|
-
headers: {
|
|
757
|
-
'Content-Type': 'application/json',
|
|
758
|
-
'Authorization': `Bearer ${token}`,
|
|
759
|
-
},
|
|
760
|
-
body: JSON.stringify({
|
|
761
|
-
...inferenceData,
|
|
762
|
-
userEmail: email.trim(),
|
|
763
|
-
appName: AppName,
|
|
764
|
-
timestamp: new Date().toISOString(),
|
|
765
|
-
})
|
|
766
|
-
});
|
|
767
|
-
|
|
768
|
-
if (!inferenceResponse.ok) {
|
|
769
|
-
throw new Error(`Inference API failed: ${inferenceResponse.status}`);
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
const inferenceResults = await inferenceResponse.json();
|
|
773
|
-
console.log('✅ Auto mode inference results:', inferenceResults);
|
|
774
|
-
|
|
775
|
-
// Close the modal first
|
|
776
|
-
handleClose();
|
|
777
|
-
|
|
778
|
-
// Complete onboarding with inference results
|
|
779
|
-
setTimeout(() => {
|
|
780
|
-
onComplete(apiUrl, token, {
|
|
781
|
-
pin,
|
|
782
|
-
connections,
|
|
783
|
-
platformToggles,
|
|
784
|
-
selectedTier,
|
|
785
|
-
tierData: requestData?.[selectedTier],
|
|
786
|
-
sessionSaved: true,
|
|
787
|
-
// Add inference data if auto mode is enabled
|
|
788
|
-
...(auto && inferenceData && { inferenceData }),
|
|
789
|
-
// Add partner info for special partners
|
|
790
|
-
...(partner && { partner: partner === 'couplebible' ? 'CoupleBible' : partner }),
|
|
791
|
-
autoMode: true,
|
|
792
|
-
inferenceResults,
|
|
793
|
-
apiUrl,
|
|
794
|
-
token,
|
|
795
|
-
});
|
|
796
|
-
}, 100);
|
|
797
|
-
|
|
798
|
-
} else {
|
|
799
|
-
console.log('📋 Standard mode: Returning API URL for manual use');
|
|
800
|
-
|
|
801
|
-
// Prepare completion data
|
|
802
|
-
const completionData = {
|
|
803
|
-
pin,
|
|
804
|
-
connections,
|
|
805
|
-
platformToggles,
|
|
806
|
-
selectedTier,
|
|
807
|
-
tierData: requestData?.[selectedTier],
|
|
808
|
-
sessionSaved: true,
|
|
809
|
-
// Add inference data if auto mode is enabled
|
|
810
|
-
...(auto && inferenceData && { inferenceData }),
|
|
811
|
-
// Add partner info for special partners
|
|
812
|
-
...(partner && { partner: partner === 'couplebible' ? 'CoupleBible' : partner }),
|
|
813
|
-
autoMode: false,
|
|
814
|
-
};
|
|
815
|
-
|
|
816
|
-
console.log('Completion data prepared:', completionData);
|
|
817
|
-
|
|
818
|
-
// Close the modal first
|
|
819
|
-
handleClose();
|
|
820
|
-
|
|
821
|
-
// Then call the completion callback
|
|
822
|
-
setTimeout(() => {
|
|
823
|
-
onComplete('https://api2.onairos.uk', 'dummy-token', completionData);
|
|
824
|
-
}, 100);
|
|
825
|
-
}
|
|
826
|
-
} catch (error) {
|
|
827
|
-
console.error('❌ Error in training complete:', error);
|
|
828
|
-
|
|
829
|
-
// Fallback to standard mode
|
|
830
|
-
const completionData = {
|
|
831
|
-
pin,
|
|
832
|
-
connections,
|
|
833
|
-
platformToggles,
|
|
834
|
-
selectedTier,
|
|
835
|
-
tierData: requestData?.[selectedTier],
|
|
836
|
-
sessionSaved: true,
|
|
837
|
-
// Add inference data if auto mode is enabled
|
|
838
|
-
...(auto && inferenceData && { inferenceData }),
|
|
839
|
-
// Add partner info for special partners
|
|
840
|
-
...(partner && { partner: partner === 'couplebible' ? 'CoupleBible' : partner }),
|
|
841
|
-
autoMode: false,
|
|
842
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
843
|
-
};
|
|
844
|
-
|
|
845
|
-
console.log('Fallback completion data:', completionData);
|
|
846
|
-
|
|
847
|
-
// Close the modal first
|
|
848
|
-
handleClose();
|
|
849
|
-
|
|
850
|
-
// Then call the completion callback
|
|
851
|
-
setTimeout(() => {
|
|
852
|
-
onComplete('https://api2.onairos.uk', 'dummy-token', completionData);
|
|
853
|
-
}, 100);
|
|
854
|
-
}
|
|
855
|
-
}, [pin, connections, platformToggles, selectedTier, requestData, auto, inferenceData, partner, handleClose, onComplete, AppName, email]);
|
|
856
|
-
|
|
857
|
-
const handleDataRequestAccept = useCallback(async () => {
|
|
858
|
-
console.log('Data request accepted for existing user');
|
|
859
|
-
console.log('🔍 Auto mode enabled:', auto);
|
|
860
|
-
console.log('🔍 Inference data available:', !!inferenceData);
|
|
861
|
-
|
|
862
|
-
try {
|
|
863
|
-
if (auto && inferenceData) {
|
|
864
|
-
console.log('🤖 Auto mode: Making API request to get URL and perform inference');
|
|
865
|
-
|
|
866
|
-
// First, get the API URL from backend
|
|
867
|
-
const apiUrlResponse = await fetch('https://api2.onairos.uk/', {
|
|
868
|
-
method: 'POST',
|
|
869
|
-
headers: {
|
|
870
|
-
'Content-Type': 'application/json',
|
|
871
|
-
},
|
|
872
|
-
body: JSON.stringify({
|
|
873
|
-
Info: {
|
|
874
|
-
storage: 'secure', // or whatever storage type
|
|
875
|
-
appId: AppName,
|
|
876
|
-
confirmations: Object.keys(requestData || {}),
|
|
877
|
-
EncryptedUserPin: 'temp-pin', // This would come from user PIN in real flow
|
|
878
|
-
account: email.trim(),
|
|
879
|
-
proofMode: false,
|
|
880
|
-
}
|
|
881
|
-
})
|
|
882
|
-
});
|
|
883
|
-
|
|
884
|
-
if (!apiUrlResponse.ok) {
|
|
885
|
-
throw new Error(`Failed to get API URL: ${apiUrlResponse.status}`);
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
const { apiUrl, token } = await apiUrlResponse.json();
|
|
889
|
-
console.log('✅ Received API URL:', apiUrl);
|
|
890
|
-
console.log('✅ Received token:', token?.substring(0, 20) + '...');
|
|
891
|
-
|
|
892
|
-
// Now make the inference call with the provided data
|
|
893
|
-
const inferenceResponse = await fetch(apiUrl, {
|
|
894
|
-
method: 'POST',
|
|
895
|
-
headers: {
|
|
896
|
-
'Content-Type': 'application/json',
|
|
897
|
-
'Authorization': `Bearer ${token}`,
|
|
898
|
-
},
|
|
899
|
-
body: JSON.stringify({
|
|
900
|
-
...inferenceData,
|
|
901
|
-
userEmail: email.trim(),
|
|
902
|
-
appName: AppName,
|
|
903
|
-
timestamp: new Date().toISOString(),
|
|
904
|
-
})
|
|
905
|
-
});
|
|
906
|
-
|
|
907
|
-
if (!inferenceResponse.ok) {
|
|
908
|
-
throw new Error(`Inference API failed: ${inferenceResponse.status}`);
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
const inferenceResults = await inferenceResponse.json();
|
|
912
|
-
console.log('✅ Auto mode inference results:', inferenceResults);
|
|
913
|
-
|
|
914
|
-
// Complete onboarding with inference results
|
|
915
|
-
onComplete(apiUrl, token, {
|
|
916
|
-
existingAccount: true,
|
|
917
|
-
email: email.trim(),
|
|
918
|
-
dataRequestAccepted: true,
|
|
919
|
-
requestData,
|
|
920
|
-
autoMode: true,
|
|
921
|
-
inferenceResults,
|
|
922
|
-
apiUrl,
|
|
923
|
-
token,
|
|
924
|
-
});
|
|
925
|
-
|
|
926
|
-
} else {
|
|
927
|
-
console.log('📋 Standard mode: Returning API URL for manual use');
|
|
928
|
-
|
|
929
|
-
// Standard mode: just return the API URL
|
|
930
|
-
onComplete('https://api2.onairos.uk', 'existing-session-token', {
|
|
931
|
-
existingAccount: true,
|
|
932
|
-
email: email.trim(),
|
|
933
|
-
dataRequestAccepted: true,
|
|
934
|
-
requestData,
|
|
935
|
-
autoMode: false,
|
|
936
|
-
});
|
|
937
|
-
}
|
|
938
|
-
} catch (error) {
|
|
939
|
-
console.error('❌ Error in data request accept:', error);
|
|
940
|
-
|
|
941
|
-
// Fallback to standard mode
|
|
942
|
-
onComplete('https://api2.onairos.uk', 'existing-session-token', {
|
|
943
|
-
existingAccount: true,
|
|
944
|
-
email: email.trim(),
|
|
945
|
-
dataRequestAccepted: true,
|
|
946
|
-
requestData,
|
|
947
|
-
autoMode: false,
|
|
948
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
949
|
-
});
|
|
950
|
-
}
|
|
951
|
-
}, [email, onComplete, requestData, auto, inferenceData, AppName]);
|
|
952
|
-
|
|
953
|
-
const handleDataRequestDecline = useCallback(() => {
|
|
954
|
-
console.log('Data request declined');
|
|
955
|
-
handleClose();
|
|
956
|
-
}, [handleClose]);
|
|
957
|
-
|
|
958
|
-
const canProceedToPin = useCallback(() => {
|
|
959
|
-
// Test mode: Always allow proceeding (simulates platform connections)
|
|
960
|
-
if (isTestMode || testModeOptions.skipRealConnections) {
|
|
961
|
-
console.log('🧪 Test mode: Allowing proceed without real platform connections');
|
|
962
|
-
return true;
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
// Production: Check if at least one platform is connected
|
|
966
|
-
const hasPlatformConnected = Object.values(platformToggles).some(value => value === true);
|
|
967
|
-
|
|
968
|
-
// Auto mode validation
|
|
969
|
-
if (auto && partner !== 'couplebible' && !inferenceData) {
|
|
970
|
-
console.warn('Auto mode enabled but no inference data provided (and partner is not couplebible)');
|
|
971
|
-
return false;
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
return hasPlatformConnected;
|
|
975
|
-
}, [platformToggles, auto, partner, inferenceData, isTestMode, testModeOptions]);
|
|
976
|
-
|
|
977
|
-
const handleProceed = () => {
|
|
978
|
-
console.log('Proceeding to next step');
|
|
979
|
-
// Show success screen first
|
|
980
|
-
setStep('success');
|
|
981
|
-
|
|
982
|
-
// Clear any existing timeout
|
|
983
|
-
if (successTimeoutRef.current) {
|
|
984
|
-
clearTimeout(successTimeoutRef.current);
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// After a delay, proceed to PIN
|
|
988
|
-
successTimeoutRef.current = setTimeout(() => {
|
|
989
|
-
// Only proceed if component is still mounted and visible
|
|
990
|
-
if (isMountedRef.current && visible) {
|
|
991
|
-
setStep('pin');
|
|
992
|
-
}
|
|
993
|
-
successTimeoutRef.current = null;
|
|
994
|
-
}, 3000);
|
|
995
|
-
};
|
|
996
|
-
|
|
997
|
-
return (
|
|
998
|
-
<Modal
|
|
999
|
-
visible={visible}
|
|
1000
|
-
transparent
|
|
1001
|
-
animationType="none"
|
|
1002
|
-
statusBarTranslucent
|
|
1003
|
-
onRequestClose={handleClose}
|
|
1004
|
-
>
|
|
1005
|
-
<TouchableWithoutFeedback onPress={handleClose}>
|
|
1006
|
-
<View style={styles.modalOverlay}>
|
|
1007
|
-
<TouchableWithoutFeedback onPress={e => e.stopPropagation()}>
|
|
1008
|
-
<Animated.View
|
|
1009
|
-
style={[
|
|
1010
|
-
styles.bottomSheet,
|
|
1011
|
-
{
|
|
1012
|
-
transform: [{ translateY: slideAnim }],
|
|
1013
|
-
}
|
|
1014
|
-
]}
|
|
1015
|
-
>
|
|
1016
|
-
<SafeAreaView style={styles.container}>
|
|
1017
|
-
<View style={styles.handleContainer}>
|
|
1018
|
-
<View style={styles.handle} />
|
|
1019
|
-
</View>
|
|
1020
|
-
|
|
1021
|
-
{step === 'email' && (
|
|
1022
|
-
<View style={styles.emailInputContainer}>
|
|
1023
|
-
<View style={styles.emailHeader}>
|
|
1024
|
-
<View style={styles.onairosIcon}>
|
|
1025
|
-
<Image
|
|
1026
|
-
source={require('../assets/images/onairos_logo.png')}
|
|
1027
|
-
style={styles.onairosLogo}
|
|
1028
|
-
resizeMode="contain"
|
|
1029
|
-
/>
|
|
1030
|
-
</View>
|
|
1031
|
-
<Text style={styles.emailTitle}>Welcome to Onairos</Text>
|
|
1032
|
-
<Text style={styles.emailSubtitle}>Enter your email to get started</Text>
|
|
1033
|
-
</View>
|
|
1034
|
-
|
|
1035
|
-
<View style={styles.emailInputSection}>
|
|
1036
|
-
<TextInput
|
|
1037
|
-
style={styles.emailInput}
|
|
1038
|
-
value={email}
|
|
1039
|
-
onChangeText={setEmail}
|
|
1040
|
-
placeholder="Enter your email address"
|
|
1041
|
-
keyboardType="email-address"
|
|
1042
|
-
autoCapitalize="none"
|
|
1043
|
-
autoCorrect={false}
|
|
1044
|
-
autoFocus
|
|
1045
|
-
/>
|
|
1046
|
-
|
|
1047
|
-
<TouchableOpacity
|
|
1048
|
-
style={[styles.emailSubmitButton, !email.trim() && styles.emailSubmitButtonDisabled]}
|
|
1049
|
-
onPress={handleEmailSubmit}
|
|
1050
|
-
disabled={!email.trim()}
|
|
1051
|
-
>
|
|
1052
|
-
<Text style={styles.emailSubmitButtonText}>Continue</Text>
|
|
1053
|
-
</TouchableOpacity>
|
|
1054
|
-
</View>
|
|
1055
|
-
</View>
|
|
1056
|
-
)}
|
|
1057
|
-
|
|
1058
|
-
{step === 'verify' && (
|
|
1059
|
-
<View style={styles.emailInputContainer}>
|
|
1060
|
-
<View style={styles.emailHeader}>
|
|
1061
|
-
<View style={styles.onairosIcon}>
|
|
1062
|
-
<Image
|
|
1063
|
-
source={require('../assets/images/onairos_logo.png')}
|
|
1064
|
-
style={styles.onairosLogo}
|
|
1065
|
-
resizeMode="contain"
|
|
1066
|
-
/>
|
|
1067
|
-
</View>
|
|
1068
|
-
<Text style={styles.emailTitle}>Enter Verification Code</Text>
|
|
1069
|
-
<Text style={styles.emailSubtitle}>
|
|
1070
|
-
We've sent a 6-digit code to {email}
|
|
1071
|
-
</Text>
|
|
1072
|
-
{isTestMode && (
|
|
1073
|
-
<Text style={styles.developmentNote}>
|
|
1074
|
-
🔍 Test Mode: Any 6-digit code will work
|
|
1075
|
-
</Text>
|
|
1076
|
-
)}
|
|
1077
|
-
</View>
|
|
1078
|
-
|
|
1079
|
-
<View style={styles.emailInputSection}>
|
|
1080
|
-
<View style={styles.codeInputContainer}>
|
|
1081
|
-
{[0, 1, 2, 3, 4, 5].map((index) => (
|
|
1082
|
-
<TextInput
|
|
1083
|
-
key={index}
|
|
1084
|
-
ref={(ref) => (codeInputRefs.current[index] = ref)}
|
|
1085
|
-
style={[
|
|
1086
|
-
styles.codeDigit,
|
|
1087
|
-
verificationCode.length === index && styles.codeDigitActive
|
|
1088
|
-
]}
|
|
1089
|
-
value={verificationCode[index] || ''}
|
|
1090
|
-
onChangeText={(text) => {
|
|
1091
|
-
if (text.length <= 1 && /^\d*$/.test(text)) {
|
|
1092
|
-
const newCode = verificationCode.split('');
|
|
1093
|
-
newCode[index] = text;
|
|
1094
|
-
const updatedCode = newCode.join('').slice(0, 6);
|
|
1095
|
-
setVerificationCode(updatedCode);
|
|
1096
|
-
|
|
1097
|
-
// Auto-focus next input
|
|
1098
|
-
if (text && index < 5) {
|
|
1099
|
-
codeInputRefs.current[index + 1]?.focus();
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
}}
|
|
1103
|
-
onKeyPress={({ nativeEvent }) => {
|
|
1104
|
-
// Handle backspace to move to previous input
|
|
1105
|
-
if (nativeEvent.key === 'Backspace' && !verificationCode[index] && index > 0) {
|
|
1106
|
-
codeInputRefs.current[index - 1]?.focus();
|
|
1107
|
-
}
|
|
1108
|
-
}}
|
|
1109
|
-
keyboardType="number-pad"
|
|
1110
|
-
maxLength={1}
|
|
1111
|
-
textAlign="center"
|
|
1112
|
-
autoFocus={index === 0}
|
|
1113
|
-
/>
|
|
1114
|
-
))}
|
|
1115
|
-
</View>
|
|
1116
|
-
|
|
1117
|
-
<TouchableOpacity
|
|
1118
|
-
style={[
|
|
1119
|
-
styles.emailSubmitButton,
|
|
1120
|
-
(verificationCode.length !== 6 || isVerifyingCode) && styles.emailSubmitButtonDisabled
|
|
1121
|
-
]}
|
|
1122
|
-
onPress={handleVerificationSubmit}
|
|
1123
|
-
disabled={verificationCode.length !== 6 || isVerifyingCode}
|
|
1124
|
-
>
|
|
1125
|
-
{isVerifyingCode ? (
|
|
1126
|
-
<ActivityIndicator size="small" color="#fff" />
|
|
1127
|
-
) : (
|
|
1128
|
-
<Text style={styles.emailSubmitButtonText}>Verify</Text>
|
|
1129
|
-
)}
|
|
1130
|
-
</TouchableOpacity>
|
|
1131
|
-
|
|
1132
|
-
<TouchableOpacity
|
|
1133
|
-
style={styles.backButton}
|
|
1134
|
-
onPress={() => setStep('email')}
|
|
1135
|
-
>
|
|
1136
|
-
<Text style={styles.backButtonText}>← Back to email</Text>
|
|
1137
|
-
</TouchableOpacity>
|
|
1138
|
-
</View>
|
|
1139
|
-
</View>
|
|
1140
|
-
)}
|
|
1141
|
-
|
|
1142
|
-
{step === 'connect' && (
|
|
1143
|
-
<>
|
|
1144
|
-
{/* Header with Onairos icon and arrow to app icon */}
|
|
1145
|
-
<View style={styles.header}>
|
|
1146
|
-
<View style={styles.headerContent}>
|
|
1147
|
-
<View style={styles.onairosIcon}>
|
|
1148
|
-
<Image
|
|
1149
|
-
source={require('../assets/images/onairos_logo.png')}
|
|
1150
|
-
style={styles.onairosLogo}
|
|
1151
|
-
resizeMode="contain"
|
|
1152
|
-
/>
|
|
1153
|
-
</View>
|
|
1154
|
-
<Icon name="arrow-forward" size={24} color="#666" style={styles.arrow} />
|
|
1155
|
-
<View style={styles.appIcon}>
|
|
1156
|
-
{appIcon ? (
|
|
1157
|
-
<Image
|
|
1158
|
-
source={appIcon}
|
|
1159
|
-
style={styles.appIconImage}
|
|
1160
|
-
resizeMode="contain"
|
|
1161
|
-
/>
|
|
1162
|
-
) : (
|
|
1163
|
-
<Text style={styles.appIconText}>
|
|
1164
|
-
{AppName.charAt(0)}
|
|
1165
|
-
</Text>
|
|
1166
|
-
)}
|
|
1167
|
-
</View>
|
|
1168
|
-
</View>
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
</View>
|
|
1172
|
-
|
|
1173
|
-
<ScrollView
|
|
1174
|
-
style={styles.content}
|
|
1175
|
-
contentContainerStyle={styles.scrollContent}
|
|
1176
|
-
showsVerticalScrollIndicator={true}
|
|
1177
|
-
bounces={true}
|
|
1178
|
-
scrollEnabled={true}
|
|
1179
|
-
nestedScrollEnabled={true}
|
|
1180
|
-
keyboardShouldPersistTaps="handled"
|
|
1181
|
-
>
|
|
1182
|
-
{/* Main title and description */}
|
|
1183
|
-
<View style={styles.titleContainer}>
|
|
1184
|
-
<Text style={styles.mainTitle}>
|
|
1185
|
-
Let {AppName} learn about you from your data and apps
|
|
1186
|
-
</Text>
|
|
1187
|
-
<Text style={styles.privacyMessage}>
|
|
1188
|
-
None of your app data is shared with ANYONE
|
|
1189
|
-
</Text>
|
|
1190
|
-
{(debug || testMode) && (
|
|
1191
|
-
<Text style={styles.developmentNote}>
|
|
1192
|
-
🧪 Test Mode: You can proceed without connecting any platforms
|
|
1193
|
-
</Text>
|
|
1194
|
-
)}
|
|
1195
|
-
</View>
|
|
1196
|
-
|
|
1197
|
-
{/* Platform connection options */}
|
|
1198
|
-
<View style={styles.platformsContainer}>
|
|
1199
|
-
{platformsToDisplay.map((platform) => (
|
|
1200
|
-
<TouchableOpacity
|
|
1201
|
-
key={platform.id}
|
|
1202
|
-
style={styles.platformItem}
|
|
1203
|
-
onPress={() => togglePlatform(platform.id)}
|
|
1204
|
-
disabled={isConnectingPlatform}
|
|
1205
|
-
>
|
|
1206
|
-
<View style={styles.platformInfo}>
|
|
1207
|
-
<Image
|
|
1208
|
-
source={platform.icon}
|
|
1209
|
-
style={styles.platformIcon}
|
|
1210
|
-
resizeMode="contain"
|
|
1211
|
-
/>
|
|
1212
|
-
<Text style={styles.platformName}>
|
|
1213
|
-
{platform.name}
|
|
1214
|
-
</Text>
|
|
1215
|
-
</View>
|
|
1216
|
-
|
|
1217
|
-
{isConnectingPlatform && currentPlatform === platform.id ? (
|
|
1218
|
-
<ActivityIndicator size="small" color={COLORS.primary} />
|
|
1219
|
-
) : (
|
|
1220
|
-
<View style={[
|
|
1221
|
-
styles.platformToggle,
|
|
1222
|
-
platformToggles[platform.id] && styles.platformToggleActive
|
|
1223
|
-
]}>
|
|
1224
|
-
<View style={[
|
|
1225
|
-
styles.platformToggleThumb,
|
|
1226
|
-
platformToggles[platform.id] && styles.platformToggleThumbActive
|
|
1227
|
-
]} />
|
|
1228
|
-
</View>
|
|
1229
|
-
)}
|
|
1230
|
-
</TouchableOpacity>
|
|
1231
|
-
))}
|
|
1232
|
-
|
|
1233
|
-
{/* Show more/less platforms button */}
|
|
1234
|
-
{additionalPlatforms.length > 0 && (
|
|
1235
|
-
<TouchableOpacity
|
|
1236
|
-
style={styles.expandButton}
|
|
1237
|
-
onPress={() => setShowAllPlatforms(!showAllPlatforms)}
|
|
1238
|
-
>
|
|
1239
|
-
<Icon
|
|
1240
|
-
name={showAllPlatforms ? "expand_less" : "add"}
|
|
1241
|
-
size={24}
|
|
1242
|
-
color={COLORS.primary}
|
|
1243
|
-
/>
|
|
1244
|
-
<Text style={styles.expandButtonText}>
|
|
1245
|
-
{showAllPlatforms
|
|
1246
|
-
? "Show Less"
|
|
1247
|
-
: `${additionalPlatforms.length} More Connectors`
|
|
1248
|
-
}
|
|
1249
|
-
</Text>
|
|
1250
|
-
</TouchableOpacity>
|
|
1251
|
-
)}
|
|
1252
|
-
</View>
|
|
1253
|
-
|
|
1254
|
-
{/* Test mode controls - Simple 2-flow system */}
|
|
1255
|
-
{showTestControls && (
|
|
1256
|
-
<View style={styles.testModeContainer}>
|
|
1257
|
-
<Text style={styles.testModeTitle}>🧪 Test Mode - 2 Main Flows</Text>
|
|
1258
|
-
|
|
1259
|
-
<TouchableOpacity
|
|
1260
|
-
style={styles.testExistingUserButton}
|
|
1261
|
-
onPress={() => {
|
|
1262
|
-
// Flow 1: Existing User
|
|
1263
|
-
setIsExistingUser(true);
|
|
1264
|
-
setStep('dataRequest');
|
|
1265
|
-
}}
|
|
1266
|
-
>
|
|
1267
|
-
<Icon name="person" size={20} color="#28a745" />
|
|
1268
|
-
<Text style={styles.testExistingUserButtonText}>
|
|
1269
|
-
Flow 1: Existing User (Email → Code → Data Request → Close)
|
|
1270
|
-
</Text>
|
|
1271
|
-
</TouchableOpacity>
|
|
1272
|
-
|
|
1273
|
-
<TouchableOpacity
|
|
1274
|
-
style={styles.testSkipToTrainingButton}
|
|
1275
|
-
onPress={() => {
|
|
1276
|
-
// Flow 2: New User - Skip to connect step
|
|
1277
|
-
setStep('connect');
|
|
1278
|
-
}}
|
|
1279
|
-
>
|
|
1280
|
-
<Icon name="person-add" size={20} color="#17a2b8" />
|
|
1281
|
-
<Text style={styles.testSkipToTrainingButtonText}>
|
|
1282
|
-
Flow 2: New User (Connect → PIN → Training)
|
|
1283
|
-
</Text>
|
|
1284
|
-
</TouchableOpacity>
|
|
1285
|
-
|
|
1286
|
-
<TouchableOpacity
|
|
1287
|
-
style={styles.testDataRequestButton}
|
|
1288
|
-
onPress={() => setStep('dataRequest')}
|
|
1289
|
-
>
|
|
1290
|
-
<Icon name="preview" size={20} color={COLORS.primary} />
|
|
1291
|
-
<Text style={styles.testDataRequestButtonText}>
|
|
1292
|
-
Preview Data Request Screen
|
|
1293
|
-
</Text>
|
|
1294
|
-
</TouchableOpacity>
|
|
1295
|
-
</View>
|
|
1296
|
-
)}
|
|
1297
|
-
</ScrollView>
|
|
1298
|
-
|
|
1299
|
-
<View style={styles.footer}>
|
|
1300
|
-
<TouchableOpacity
|
|
1301
|
-
style={styles.footerButtonCancel}
|
|
1302
|
-
onPress={handleClose}
|
|
1303
|
-
>
|
|
1304
|
-
<Text style={styles.footerButtonText}>Cancel</Text>
|
|
1305
|
-
</TouchableOpacity>
|
|
1306
|
-
|
|
1307
|
-
<TouchableOpacity
|
|
1308
|
-
style={[
|
|
1309
|
-
styles.footerButtonConfirm,
|
|
1310
|
-
!canProceedToPin() && styles.footerButtonDisabled
|
|
1311
|
-
]}
|
|
1312
|
-
onPress={handleProceed}
|
|
1313
|
-
disabled={!canProceedToPin()}
|
|
1314
|
-
>
|
|
1315
|
-
<Text style={styles.footerButtonTextConfirm}>Connect</Text>
|
|
1316
|
-
</TouchableOpacity>
|
|
1317
|
-
</View>
|
|
1318
|
-
</>
|
|
1319
|
-
)}
|
|
1320
|
-
|
|
1321
|
-
{step === 'success' && (
|
|
1322
|
-
<View style={styles.successContainer}>
|
|
1323
|
-
<View style={styles.successContent}>
|
|
1324
|
-
{/* Big green checkmark */}
|
|
1325
|
-
<View style={styles.successIcon}>
|
|
1326
|
-
<Icon name="check" size={48} color="#fff" />
|
|
1327
|
-
</View>
|
|
1328
|
-
|
|
1329
|
-
<Text style={styles.successTitle}>Never Connect Again!</Text>
|
|
1330
|
-
<Text style={styles.successSubtitle}>
|
|
1331
|
-
Your login session has been saved
|
|
1332
|
-
</Text>
|
|
1333
|
-
|
|
1334
|
-
<View style={styles.successMessage}>
|
|
1335
|
-
<Text style={styles.successMessageText}>
|
|
1336
|
-
Your Onairos account and platform connections are now saved in your browser cookies.
|
|
1337
|
-
Next time you use any app with Onairos, you'll be automatically signed in without
|
|
1338
|
-
needing to reconnect your accounts.
|
|
1339
|
-
</Text>
|
|
1340
|
-
</View>
|
|
1341
|
-
|
|
1342
|
-
{/* Auto-progress indicator */}
|
|
1343
|
-
<View style={styles.progressIndicator}>
|
|
1344
|
-
<ActivityIndicator size="small" color="#4CAF50" />
|
|
1345
|
-
<Text style={styles.progressText}>Continuing...</Text>
|
|
1346
|
-
</View>
|
|
1347
|
-
</View>
|
|
1348
|
-
</View>
|
|
1349
|
-
)}
|
|
1350
|
-
|
|
1351
|
-
{step === 'pin' && (
|
|
1352
|
-
<PinInput
|
|
1353
|
-
onSubmit={handlePinSubmit}
|
|
1354
|
-
minLength={8}
|
|
1355
|
-
requireSpecialChar
|
|
1356
|
-
requireNumber
|
|
1357
|
-
onBack={() => setStep('connect')}
|
|
1358
|
-
/>
|
|
1359
|
-
)}
|
|
1360
|
-
|
|
1361
|
-
{step === 'training' && (
|
|
1362
|
-
<TrainingModal
|
|
1363
|
-
visible={step === 'training'}
|
|
1364
|
-
progress={training.progress}
|
|
1365
|
-
eta={training.eta}
|
|
1366
|
-
onCancel={handleClose}
|
|
1367
|
-
onComplete={handleTrainingComplete}
|
|
1368
|
-
modelKey="onairosTrainingModel"
|
|
1369
|
-
username={username}
|
|
1370
|
-
test={isTestMode}
|
|
1371
|
-
/>
|
|
1372
|
-
)}
|
|
1373
|
-
|
|
1374
|
-
{step === 'dataRequest' && (
|
|
1375
|
-
<DataRequestScreen
|
|
1376
|
-
onAccept={handleDataRequestAccept}
|
|
1377
|
-
onDecline={handleDataRequestDecline}
|
|
1378
|
-
requestData={requestData || {}}
|
|
1379
|
-
AppName={AppName}
|
|
1380
|
-
appIcon={appIcon}
|
|
1381
|
-
/>
|
|
1382
|
-
)}
|
|
1383
|
-
|
|
1384
|
-
{step === 'oauth' && oauthUrl && (
|
|
1385
|
-
<OAuthWebView
|
|
1386
|
-
url={oauthUrl}
|
|
1387
|
-
platform={currentPlatform}
|
|
1388
|
-
onClose={() => {
|
|
1389
|
-
setStep('connect');
|
|
1390
|
-
setOauthUrl('');
|
|
1391
|
-
}}
|
|
1392
|
-
onSuccess={handleOAuthSuccess}
|
|
1393
|
-
onComplete={() => setStep('connect')}
|
|
1394
|
-
/>
|
|
1395
|
-
)}
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
</SafeAreaView>
|
|
1400
|
-
</Animated.View>
|
|
1401
|
-
</TouchableWithoutFeedback>
|
|
1402
|
-
</View>
|
|
1403
|
-
</TouchableWithoutFeedback>
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
</Modal>
|
|
1407
|
-
);
|
|
1408
|
-
};
|
|
1409
|
-
|
|
1410
|
-
const styles = StyleSheet.create({
|
|
1411
|
-
modalOverlay: {
|
|
1412
|
-
flex: 1,
|
|
1413
|
-
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
1414
|
-
justifyContent: 'flex-end',
|
|
1415
|
-
alignItems: 'center',
|
|
1416
|
-
},
|
|
1417
|
-
bottomSheet: {
|
|
1418
|
-
backgroundColor: '#fff',
|
|
1419
|
-
width: width,
|
|
1420
|
-
height: height * 0.8,
|
|
1421
|
-
borderTopLeftRadius: 24,
|
|
1422
|
-
borderTopRightRadius: 24,
|
|
1423
|
-
overflow: 'hidden',
|
|
1424
|
-
},
|
|
1425
|
-
container: {
|
|
1426
|
-
flex: 1,
|
|
1427
|
-
backgroundColor: '#fff',
|
|
1428
|
-
},
|
|
1429
|
-
handleContainer: {
|
|
1430
|
-
width: '100%',
|
|
1431
|
-
alignItems: 'center',
|
|
1432
|
-
paddingTop: 12,
|
|
1433
|
-
paddingBottom: 8,
|
|
1434
|
-
},
|
|
1435
|
-
handle: {
|
|
1436
|
-
width: 40,
|
|
1437
|
-
height: 5,
|
|
1438
|
-
borderRadius: 3,
|
|
1439
|
-
backgroundColor: '#E0E0E0',
|
|
1440
|
-
},
|
|
1441
|
-
header: {
|
|
1442
|
-
padding: 24,
|
|
1443
|
-
alignItems: 'center',
|
|
1444
|
-
},
|
|
1445
|
-
headerContent: {
|
|
1446
|
-
flexDirection: 'row',
|
|
1447
|
-
alignItems: 'center',
|
|
1448
|
-
justifyContent: 'center',
|
|
1449
|
-
marginBottom: 16,
|
|
1450
|
-
},
|
|
1451
|
-
appIcon: {
|
|
1452
|
-
width: 48,
|
|
1453
|
-
height: 48,
|
|
1454
|
-
borderRadius: 16,
|
|
1455
|
-
backgroundColor: '#F5F5F5',
|
|
1456
|
-
alignItems: 'center',
|
|
1457
|
-
justifyContent: 'center',
|
|
1458
|
-
},
|
|
1459
|
-
appIconText: {
|
|
1460
|
-
fontSize: 24,
|
|
1461
|
-
color: '#000',
|
|
1462
|
-
},
|
|
1463
|
-
appIconImage: {
|
|
1464
|
-
width: 32,
|
|
1465
|
-
height: 32,
|
|
1466
|
-
},
|
|
1467
|
-
arrow: {
|
|
1468
|
-
marginHorizontal: 16,
|
|
1469
|
-
},
|
|
1470
|
-
onairosIcon: {
|
|
1471
|
-
width: 48,
|
|
1472
|
-
height: 48,
|
|
1473
|
-
borderRadius: 16,
|
|
1474
|
-
backgroundColor: '#F5F5F5',
|
|
1475
|
-
alignItems: 'center',
|
|
1476
|
-
justifyContent: 'center',
|
|
1477
|
-
},
|
|
1478
|
-
onairosIconText: {
|
|
1479
|
-
fontSize: 24,
|
|
1480
|
-
color: '#000',
|
|
1481
|
-
},
|
|
1482
|
-
onairosLogo: {
|
|
1483
|
-
width: 32,
|
|
1484
|
-
height: 32,
|
|
1485
|
-
},
|
|
1486
|
-
titleContainer: {
|
|
1487
|
-
marginBottom: 20,
|
|
1488
|
-
},
|
|
1489
|
-
mainTitle: {
|
|
1490
|
-
fontSize: 20,
|
|
1491
|
-
fontWeight: '600',
|
|
1492
|
-
color: '#000',
|
|
1493
|
-
textAlign: 'center',
|
|
1494
|
-
marginBottom: 12,
|
|
1495
|
-
},
|
|
1496
|
-
privacyMessage: {
|
|
1497
|
-
fontSize: 14,
|
|
1498
|
-
color: '#666',
|
|
1499
|
-
textAlign: 'center',
|
|
1500
|
-
marginBottom: 12,
|
|
1501
|
-
},
|
|
1502
|
-
content: {
|
|
1503
|
-
flex: 1,
|
|
1504
|
-
paddingHorizontal: 24,
|
|
1505
|
-
},
|
|
1506
|
-
scrollContent: {
|
|
1507
|
-
flexGrow: 1,
|
|
1508
|
-
paddingBottom: 20,
|
|
1509
|
-
},
|
|
1510
|
-
platformsContainer: {
|
|
1511
|
-
marginTop: 16,
|
|
1512
|
-
},
|
|
1513
|
-
platformItem: {
|
|
1514
|
-
flexDirection: 'row',
|
|
1515
|
-
justifyContent: 'space-between',
|
|
1516
|
-
alignItems: 'center',
|
|
1517
|
-
padding: 12,
|
|
1518
|
-
backgroundColor: '#fff',
|
|
1519
|
-
borderRadius: 12,
|
|
1520
|
-
marginBottom: 8,
|
|
1521
|
-
borderWidth: 1,
|
|
1522
|
-
borderColor: '#eee',
|
|
1523
|
-
},
|
|
1524
|
-
platformInfo: {
|
|
1525
|
-
flexDirection: 'row',
|
|
1526
|
-
alignItems: 'center',
|
|
1527
|
-
flex: 1,
|
|
1528
|
-
},
|
|
1529
|
-
platformIcon: {
|
|
1530
|
-
width: 24,
|
|
1531
|
-
height: 24,
|
|
1532
|
-
marginRight: 12,
|
|
1533
|
-
},
|
|
1534
|
-
platformName: {
|
|
1535
|
-
fontSize: 16,
|
|
1536
|
-
fontWeight: '500',
|
|
1537
|
-
color: '#000',
|
|
1538
|
-
},
|
|
1539
|
-
footer: {
|
|
1540
|
-
flexDirection: 'row',
|
|
1541
|
-
alignItems: 'center',
|
|
1542
|
-
justifyContent: 'space-between',
|
|
1543
|
-
padding: 24,
|
|
1544
|
-
borderTopWidth: 1,
|
|
1545
|
-
borderTopColor: '#eee',
|
|
1546
|
-
backgroundColor: '#fff',
|
|
1547
|
-
},
|
|
1548
|
-
footerButtonCancel: {
|
|
1549
|
-
paddingVertical: 8,
|
|
1550
|
-
paddingHorizontal: 16,
|
|
1551
|
-
},
|
|
1552
|
-
footerButtonConfirm: {
|
|
1553
|
-
paddingVertical: 16,
|
|
1554
|
-
paddingHorizontal: 32,
|
|
1555
|
-
borderRadius: 16,
|
|
1556
|
-
backgroundColor: '#fff',
|
|
1557
|
-
borderWidth: 1,
|
|
1558
|
-
borderColor: '#000',
|
|
1559
|
-
},
|
|
1560
|
-
footerButtonDisabled: {
|
|
1561
|
-
opacity: 0.5,
|
|
1562
|
-
},
|
|
1563
|
-
footerButtonText: {
|
|
1564
|
-
color: '#666',
|
|
1565
|
-
fontSize: 16,
|
|
1566
|
-
},
|
|
1567
|
-
footerButtonTextConfirm: {
|
|
1568
|
-
color: '#000',
|
|
1569
|
-
fontSize: 16,
|
|
1570
|
-
fontWeight: '600',
|
|
1571
|
-
},
|
|
1572
|
-
|
|
1573
|
-
successContainer: {
|
|
1574
|
-
flex: 1,
|
|
1575
|
-
justifyContent: 'center',
|
|
1576
|
-
alignItems: 'center',
|
|
1577
|
-
},
|
|
1578
|
-
successContent: {
|
|
1579
|
-
backgroundColor: '#fff',
|
|
1580
|
-
padding: 24,
|
|
1581
|
-
borderRadius: 16,
|
|
1582
|
-
alignItems: 'center',
|
|
1583
|
-
},
|
|
1584
|
-
successIcon: {
|
|
1585
|
-
backgroundColor: '#4CAF50',
|
|
1586
|
-
borderRadius: 24,
|
|
1587
|
-
padding: 12,
|
|
1588
|
-
marginBottom: 16,
|
|
1589
|
-
},
|
|
1590
|
-
successTitle: {
|
|
1591
|
-
fontSize: 22,
|
|
1592
|
-
fontWeight: '600',
|
|
1593
|
-
color: '#000',
|
|
1594
|
-
textAlign: 'center',
|
|
1595
|
-
marginBottom: 16,
|
|
1596
|
-
},
|
|
1597
|
-
successSubtitle: {
|
|
1598
|
-
fontSize: 14,
|
|
1599
|
-
color: '#666',
|
|
1600
|
-
textAlign: 'center',
|
|
1601
|
-
marginBottom: 16,
|
|
1602
|
-
},
|
|
1603
|
-
successMessage: {
|
|
1604
|
-
backgroundColor: '#f0f0f0',
|
|
1605
|
-
padding: 16,
|
|
1606
|
-
borderRadius: 8,
|
|
1607
|
-
marginBottom: 16,
|
|
1608
|
-
},
|
|
1609
|
-
successMessageText: {
|
|
1610
|
-
fontSize: 14,
|
|
1611
|
-
color: '#666',
|
|
1612
|
-
},
|
|
1613
|
-
platformToggle: {
|
|
1614
|
-
width: 50,
|
|
1615
|
-
height: 28,
|
|
1616
|
-
borderRadius: 14,
|
|
1617
|
-
borderWidth: 1,
|
|
1618
|
-
borderColor: '#ddd',
|
|
1619
|
-
backgroundColor: '#f0f0f0',
|
|
1620
|
-
justifyContent: 'center',
|
|
1621
|
-
paddingHorizontal: 2,
|
|
1622
|
-
},
|
|
1623
|
-
platformToggleActive: {
|
|
1624
|
-
borderColor: '#4CAF50',
|
|
1625
|
-
backgroundColor: '#4CAF50',
|
|
1626
|
-
},
|
|
1627
|
-
platformToggleThumb: {
|
|
1628
|
-
width: 22,
|
|
1629
|
-
height: 22,
|
|
1630
|
-
borderRadius: 11,
|
|
1631
|
-
backgroundColor: '#fff',
|
|
1632
|
-
shadowColor: '#000',
|
|
1633
|
-
shadowOffset: { width: 0, height: 1 },
|
|
1634
|
-
shadowOpacity: 0.2,
|
|
1635
|
-
shadowRadius: 2,
|
|
1636
|
-
elevation: 2,
|
|
1637
|
-
},
|
|
1638
|
-
platformToggleThumbActive: {
|
|
1639
|
-
alignSelf: 'flex-end',
|
|
1640
|
-
},
|
|
1641
|
-
// Dark mode styles
|
|
1642
|
-
darkPlatformItem: {
|
|
1643
|
-
backgroundColor: '#333',
|
|
1644
|
-
borderColor: '#555',
|
|
1645
|
-
},
|
|
1646
|
-
darkText: {
|
|
1647
|
-
color: '#fff',
|
|
1648
|
-
},
|
|
1649
|
-
darkSubText: {
|
|
1650
|
-
color: '#ccc',
|
|
1651
|
-
},
|
|
1652
|
-
progressIndicator: {
|
|
1653
|
-
flexDirection: 'row',
|
|
1654
|
-
alignItems: 'center',
|
|
1655
|
-
marginTop: 16,
|
|
1656
|
-
},
|
|
1657
|
-
progressText: {
|
|
1658
|
-
fontSize: 16,
|
|
1659
|
-
fontWeight: '500',
|
|
1660
|
-
color: '#000',
|
|
1661
|
-
marginLeft: 8,
|
|
1662
|
-
},
|
|
1663
|
-
// Email input styles
|
|
1664
|
-
emailInputContainer: {
|
|
1665
|
-
flex: 1,
|
|
1666
|
-
justifyContent: 'flex-start',
|
|
1667
|
-
alignItems: 'center',
|
|
1668
|
-
padding: 24,
|
|
1669
|
-
paddingTop: 60,
|
|
1670
|
-
},
|
|
1671
|
-
emailHeader: {
|
|
1672
|
-
alignItems: 'center',
|
|
1673
|
-
marginBottom: 32,
|
|
1674
|
-
},
|
|
1675
|
-
emailTitle: {
|
|
1676
|
-
fontSize: 24,
|
|
1677
|
-
fontWeight: '600',
|
|
1678
|
-
color: '#000',
|
|
1679
|
-
textAlign: 'center',
|
|
1680
|
-
marginTop: 16,
|
|
1681
|
-
marginBottom: 8,
|
|
1682
|
-
},
|
|
1683
|
-
emailSubtitle: {
|
|
1684
|
-
fontSize: 16,
|
|
1685
|
-
color: '#666',
|
|
1686
|
-
textAlign: 'center',
|
|
1687
|
-
},
|
|
1688
|
-
emailInputSection: {
|
|
1689
|
-
width: '100%',
|
|
1690
|
-
maxWidth: 320,
|
|
1691
|
-
},
|
|
1692
|
-
emailInput: {
|
|
1693
|
-
borderWidth: 1,
|
|
1694
|
-
borderColor: '#ddd',
|
|
1695
|
-
borderRadius: 12,
|
|
1696
|
-
padding: 16,
|
|
1697
|
-
fontSize: 16,
|
|
1698
|
-
marginBottom: 16,
|
|
1699
|
-
backgroundColor: '#fff',
|
|
1700
|
-
},
|
|
1701
|
-
emailSubmitButton: {
|
|
1702
|
-
backgroundColor: '#4CAF50',
|
|
1703
|
-
paddingVertical: 16,
|
|
1704
|
-
paddingHorizontal: 32,
|
|
1705
|
-
borderRadius: 12,
|
|
1706
|
-
alignItems: 'center',
|
|
1707
|
-
},
|
|
1708
|
-
emailSubmitButtonDisabled: {
|
|
1709
|
-
opacity: 0.5,
|
|
1710
|
-
},
|
|
1711
|
-
emailSubmitButtonText: {
|
|
1712
|
-
color: '#fff',
|
|
1713
|
-
fontSize: 16,
|
|
1714
|
-
fontWeight: '600',
|
|
1715
|
-
},
|
|
1716
|
-
// Verification code styles
|
|
1717
|
-
developmentNote: {
|
|
1718
|
-
fontSize: 14,
|
|
1719
|
-
color: '#FF9800',
|
|
1720
|
-
textAlign: 'center',
|
|
1721
|
-
marginTop: 8,
|
|
1722
|
-
backgroundColor: '#FFF3E0',
|
|
1723
|
-
padding: 8,
|
|
1724
|
-
borderRadius: 4,
|
|
1725
|
-
},
|
|
1726
|
-
codeInputContainer: {
|
|
1727
|
-
flexDirection: 'row',
|
|
1728
|
-
justifyContent: 'space-between',
|
|
1729
|
-
marginBottom: 24,
|
|
1730
|
-
paddingHorizontal: 20,
|
|
1731
|
-
},
|
|
1732
|
-
codeDigit: {
|
|
1733
|
-
width: 45,
|
|
1734
|
-
height: 55,
|
|
1735
|
-
borderWidth: 2,
|
|
1736
|
-
borderColor: '#ddd',
|
|
1737
|
-
borderRadius: 8,
|
|
1738
|
-
fontSize: 24,
|
|
1739
|
-
fontWeight: '600',
|
|
1740
|
-
color: '#000',
|
|
1741
|
-
backgroundColor: '#fff',
|
|
1742
|
-
},
|
|
1743
|
-
codeDigitActive: {
|
|
1744
|
-
borderColor: '#4CAF50',
|
|
1745
|
-
},
|
|
1746
|
-
backButton: {
|
|
1747
|
-
paddingVertical: 12,
|
|
1748
|
-
alignItems: 'center',
|
|
1749
|
-
},
|
|
1750
|
-
backButtonText: {
|
|
1751
|
-
color: '#666',
|
|
1752
|
-
fontSize: 16,
|
|
1753
|
-
},
|
|
1754
|
-
// Expand button styles
|
|
1755
|
-
expandButton: {
|
|
1756
|
-
flexDirection: 'row',
|
|
1757
|
-
alignItems: 'center',
|
|
1758
|
-
justifyContent: 'center',
|
|
1759
|
-
padding: 12,
|
|
1760
|
-
backgroundColor: '#f8f9fa',
|
|
1761
|
-
borderRadius: 12,
|
|
1762
|
-
borderWidth: 1,
|
|
1763
|
-
borderColor: '#e9ecef',
|
|
1764
|
-
marginTop: 8,
|
|
1765
|
-
},
|
|
1766
|
-
expandButtonText: {
|
|
1767
|
-
fontSize: 14,
|
|
1768
|
-
fontWeight: '500',
|
|
1769
|
-
color: COLORS.primary,
|
|
1770
|
-
marginLeft: 8,
|
|
1771
|
-
},
|
|
1772
|
-
// Test mode styles
|
|
1773
|
-
testModeContainer: {
|
|
1774
|
-
marginTop: 16,
|
|
1775
|
-
paddingHorizontal: 16,
|
|
1776
|
-
backgroundColor: '#f8f9fa',
|
|
1777
|
-
borderRadius: 12,
|
|
1778
|
-
padding: 16,
|
|
1779
|
-
borderWidth: 1,
|
|
1780
|
-
borderColor: '#e9ecef',
|
|
1781
|
-
},
|
|
1782
|
-
testModeTitle: {
|
|
1783
|
-
fontSize: 16,
|
|
1784
|
-
fontWeight: '600',
|
|
1785
|
-
color: '#495057',
|
|
1786
|
-
marginBottom: 12,
|
|
1787
|
-
textAlign: 'center',
|
|
1788
|
-
},
|
|
1789
|
-
testDataRequestButton: {
|
|
1790
|
-
flexDirection: 'row',
|
|
1791
|
-
alignItems: 'center',
|
|
1792
|
-
justifyContent: 'center',
|
|
1793
|
-
padding: 12,
|
|
1794
|
-
backgroundColor: '#fff3cd',
|
|
1795
|
-
borderRadius: 12,
|
|
1796
|
-
borderWidth: 1,
|
|
1797
|
-
borderColor: '#ffeaa7',
|
|
1798
|
-
marginBottom: 8,
|
|
1799
|
-
},
|
|
1800
|
-
testDataRequestButtonText: {
|
|
1801
|
-
fontSize: 14,
|
|
1802
|
-
fontWeight: '500',
|
|
1803
|
-
color: '#856404',
|
|
1804
|
-
marginLeft: 8,
|
|
1805
|
-
},
|
|
1806
|
-
testExistingUserButton: {
|
|
1807
|
-
flexDirection: 'row',
|
|
1808
|
-
alignItems: 'center',
|
|
1809
|
-
justifyContent: 'center',
|
|
1810
|
-
padding: 12,
|
|
1811
|
-
backgroundColor: '#d4edda',
|
|
1812
|
-
borderRadius: 12,
|
|
1813
|
-
borderWidth: 1,
|
|
1814
|
-
borderColor: '#c3e6cb',
|
|
1815
|
-
marginBottom: 8,
|
|
1816
|
-
},
|
|
1817
|
-
testExistingUserButtonText: {
|
|
1818
|
-
fontSize: 14,
|
|
1819
|
-
fontWeight: '500',
|
|
1820
|
-
color: '#155724',
|
|
1821
|
-
marginLeft: 8,
|
|
1822
|
-
},
|
|
1823
|
-
testSkipToTrainingButton: {
|
|
1824
|
-
flexDirection: 'row',
|
|
1825
|
-
alignItems: 'center',
|
|
1826
|
-
justifyContent: 'center',
|
|
1827
|
-
padding: 12,
|
|
1828
|
-
backgroundColor: '#d1ecf1',
|
|
1829
|
-
borderRadius: 12,
|
|
1830
|
-
borderWidth: 1,
|
|
1831
|
-
borderColor: '#bee5eb',
|
|
1832
|
-
},
|
|
1833
|
-
testSkipToTrainingButtonText: {
|
|
1834
|
-
fontSize: 14,
|
|
1835
|
-
fontWeight: '500',
|
|
1836
|
-
color: '#0c5460',
|
|
1837
|
-
marginLeft: 8,
|
|
1838
|
-
},
|
|
1839
|
-
});
|