@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.
Files changed (574) hide show
  1. package/README.md +423 -374
  2. package/lib/commonjs/api/index.js +9 -145
  3. package/lib/commonjs/assets/animations/loaderani.json +1 -0
  4. package/lib/commonjs/assets/animations/persona-animation.json +1 -0
  5. package/lib/commonjs/assets/fonts/EBGaramond-VariableFont_wght.ttf +0 -0
  6. package/lib/commonjs/assets/fonts/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
  7. package/lib/commonjs/assets/icons/Facebookicon.png +0 -0
  8. package/lib/commonjs/assets/icons/Gmail.png +0 -0
  9. package/lib/commonjs/assets/icons/Linkedinicon.png +0 -0
  10. package/lib/commonjs/assets/icons/Redditicon.png +0 -0
  11. package/lib/commonjs/assets/icons/YouTubeicon2.png +0 -0
  12. package/lib/commonjs/assets/icons/YouTubeicon3.png +0 -0
  13. package/lib/commonjs/assets/icons/chatgpt.png +0 -0
  14. package/lib/commonjs/assets/icons/claude.png +0 -0
  15. package/lib/commonjs/assets/icons/gemini.png +0 -0
  16. package/lib/commonjs/assets/icons/grok.png +0 -0
  17. package/lib/commonjs/assets/images/Checkbox.svg +3 -0
  18. package/lib/commonjs/assets/images/EnochE.svg +19 -0
  19. package/lib/commonjs/assets/images/Enochicon1.png +0 -0
  20. package/lib/commonjs/assets/images/Face_ID_logo.png +0 -0
  21. package/lib/commonjs/assets/images/Facebookicon.png +0 -0
  22. package/lib/commonjs/assets/images/Gmail.png +0 -0
  23. package/lib/commonjs/assets/images/Googlelogo.png +0 -0
  24. package/lib/commonjs/assets/images/Linkedinicon.png +0 -0
  25. package/lib/commonjs/assets/images/OnairosNewLogo.png +0 -0
  26. package/lib/commonjs/assets/images/Onairoslogo.png +0 -0
  27. package/lib/commonjs/assets/images/Personalityprofile.svg +3 -0
  28. package/lib/commonjs/assets/images/Personalitytraits.svg +3 -0
  29. package/lib/commonjs/assets/images/Redditicon.png +0 -0
  30. package/lib/commonjs/assets/images/Userpreferences.svg +3 -0
  31. package/lib/commonjs/assets/images/YouTubeicon3.png +0 -0
  32. package/lib/commonjs/assets/images/arrow.svg +20 -0
  33. package/lib/commonjs/assets/images/basicproficon.svg +43 -0
  34. package/lib/commonjs/assets/images/basicprofile.svg +3 -0
  35. package/lib/commonjs/assets/images/chatgpt.png +0 -0
  36. package/lib/commonjs/assets/images/checkmark.svg +4 -0
  37. package/lib/commonjs/assets/images/claude.png +0 -0
  38. package/lib/commonjs/assets/images/contentanalysis.svg +3 -0
  39. package/lib/commonjs/assets/images/contenticon.svg +23 -0
  40. package/lib/commonjs/assets/images/gemini.png +0 -0
  41. package/lib/commonjs/assets/images/grok.png +0 -0
  42. package/lib/commonjs/assets/images/persona1.png +0 -0
  43. package/lib/commonjs/assets/images/persona2.png +0 -0
  44. package/lib/commonjs/assets/images/persona3.png +0 -0
  45. package/lib/commonjs/assets/images/persona4.png +0 -0
  46. package/lib/commonjs/assets/images/persona5.png +0 -0
  47. package/lib/commonjs/assets/images/personalityicon.svg +18 -0
  48. package/lib/commonjs/assets/images/x-close.svg +3 -0
  49. package/lib/commonjs/components/BodyText.js +9 -0
  50. package/lib/commonjs/components/BrandMark.js +10 -0
  51. package/lib/commonjs/components/CodeInput.js +9 -0
  52. package/lib/commonjs/components/EmailInput.js +8 -0
  53. package/lib/commonjs/components/GoogleButton.js +9 -0
  54. package/lib/commonjs/components/HeadingGroup.js +9 -0
  55. package/lib/commonjs/components/LLMDataInputModal.js +14 -0
  56. package/lib/commonjs/components/ModalHeader.js +9 -0
  57. package/lib/commonjs/components/ModalSheet.js +9 -0
  58. package/lib/commonjs/components/Onairos.js +14 -374
  59. package/lib/commonjs/components/OnairosButton.js +13 -309
  60. package/lib/commonjs/components/OnairosSignInButton.js +12 -0
  61. package/lib/commonjs/components/Overlay.js +13 -483
  62. package/lib/commonjs/components/PersonaImage.js +10 -0
  63. package/lib/commonjs/components/PersonaLoadingScreen.js +12 -0
  64. package/lib/commonjs/components/PersonalizationConsentScreen.js +13 -0
  65. package/lib/commonjs/components/PinCreationScreen.js +12 -0
  66. package/lib/commonjs/components/PinInput.js +9 -302
  67. package/lib/commonjs/components/PlatformConnectorsStep.js +23 -0
  68. package/lib/commonjs/components/PlatformList.js +10 -137
  69. package/lib/commonjs/components/PlatformToggle.js +9 -0
  70. package/lib/commonjs/components/PrimaryButton.js +10 -0
  71. package/lib/commonjs/components/SignInMatchAnimation.js +9 -0
  72. package/lib/commonjs/components/SignInStep.js +12 -0
  73. package/lib/commonjs/components/UniversalOnboarding.js +30 -1702
  74. package/lib/commonjs/components/VerificationStep.js +11 -0
  75. package/lib/commonjs/components/WelcomeScreen.js +22 -0
  76. package/lib/commonjs/components/icons/Basicproficon.js +8 -0
  77. package/lib/commonjs/components/icons/Basicprofile.js +8 -0
  78. package/lib/commonjs/components/icons/Checkbox.js +8 -0
  79. package/lib/commonjs/components/icons/Checkmark.js +8 -0
  80. package/lib/commonjs/components/icons/Contentanalysis.js +8 -0
  81. package/lib/commonjs/components/icons/Contenticon.js +8 -0
  82. package/lib/commonjs/components/icons/EnochE.js +8 -0
  83. package/lib/commonjs/components/icons/Personalityicon.js +8 -0
  84. package/lib/commonjs/components/icons/Personalityprofile.js +8 -0
  85. package/lib/commonjs/components/icons/Personalitytraits.js +8 -0
  86. package/lib/commonjs/components/icons/Userpreferences.js +8 -0
  87. package/lib/commonjs/components/icons/index.js +17 -0
  88. package/lib/commonjs/components/onboarding/OAuthWebView.js +18 -827
  89. package/lib/commonjs/components/onboarding/OnboardingHeader.js +10 -74
  90. package/lib/commonjs/components/onboarding/PinInput.js +10 -283
  91. package/lib/commonjs/components/onboarding/PlatformConnector.js +11 -249
  92. package/lib/commonjs/config/api.js +7 -0
  93. package/lib/commonjs/constants/index.js +7 -83
  94. package/lib/commonjs/context/AuthContext.js +10 -0
  95. package/lib/commonjs/hooks/useConnectedAccounts.js +9 -0
  96. package/lib/commonjs/hooks/useConnections.js +8 -159
  97. package/lib/commonjs/hooks/useCredentials.js +10 -177
  98. package/lib/commonjs/hooks/useUserConnections.js +10 -0
  99. package/lib/commonjs/index.js +34 -106
  100. package/lib/commonjs/services/SDK_API_KEY_VALIDATION.md +421 -421
  101. package/lib/commonjs/services/apiClient.js +8 -0
  102. package/lib/commonjs/services/apiKeyService.js +9 -952
  103. package/lib/commonjs/services/authService.js +10 -0
  104. package/lib/commonjs/services/biometricPinService.js +8 -0
  105. package/lib/commonjs/services/chatGPTConversationExtractor.js +8 -0
  106. package/lib/commonjs/services/chatGPTConversationService.js +9 -0
  107. package/lib/commonjs/services/claudeConversationExtractor.js +8 -0
  108. package/lib/commonjs/services/claudeConversationService.js +9 -0
  109. package/lib/commonjs/services/connectedAccountsService.js +10 -0
  110. package/lib/commonjs/services/googleAuthService.js +11 -0
  111. package/lib/commonjs/services/hingeDataExtractor.js +8 -0
  112. package/lib/commonjs/services/hingeDataService.js +9 -0
  113. package/lib/commonjs/services/imageCompressionService.js +7 -0
  114. package/lib/commonjs/services/instagramDataExtractor.js +8 -0
  115. package/lib/commonjs/services/instagramDataService.js +9 -0
  116. package/lib/commonjs/services/jwtStorageService.js +7 -0
  117. package/lib/commonjs/services/linkedinDOMExtractor.js +7 -0
  118. package/lib/commonjs/services/linkedinProfileService.js +9 -0
  119. package/lib/commonjs/services/linkedinScrapingService.js +8 -0
  120. package/lib/commonjs/services/llmDataStorage.js +8 -0
  121. package/lib/commonjs/services/mobileTrainingService.js +8 -0
  122. package/lib/commonjs/services/oauthService.js +11 -390
  123. package/lib/commonjs/services/pinEncryptionService.js +8 -0
  124. package/lib/commonjs/services/pinStorageUtils.js +7 -0
  125. package/lib/commonjs/services/platformAuthService.js +12 -1067
  126. package/lib/commonjs/services/sephoraDataExtractor.js +8 -0
  127. package/lib/commonjs/services/sephoraDataService.js +9 -0
  128. package/lib/commonjs/services/storageService.js +8 -0
  129. package/lib/commonjs/services/telegramDataExtractor.js +8 -0
  130. package/lib/commonjs/services/telegramDataService.js +11 -0
  131. package/lib/commonjs/services/trainingApiHelpers.js +7 -0
  132. package/lib/commonjs/services/userConnectionsService.js +10 -0
  133. package/lib/commonjs/services/youtubeMigrationService.js +10 -0
  134. package/lib/commonjs/theme/index.js +7 -0
  135. package/lib/commonjs/types/ambient.d.js +1 -2
  136. package/lib/commonjs/types/declarations.d.js +1 -2
  137. package/lib/commonjs/types/index.js +1 -6
  138. package/lib/commonjs/types/node-fix.d.js +1 -2
  139. package/lib/commonjs/types/node-override.d.js +1 -2
  140. package/lib/commonjs/types/opacity.d.js +1 -2
  141. package/lib/commonjs/types.js +1 -14
  142. package/lib/commonjs/utils/Portal.js +8 -98
  143. package/lib/commonjs/utils/api.js +9 -129
  144. package/lib/commonjs/utils/assetRegistry.js +33 -0
  145. package/lib/commonjs/utils/auth.js +9 -111
  146. package/lib/commonjs/utils/connectorTests.js +29 -0
  147. package/lib/commonjs/utils/crypto.js +8 -62
  148. package/lib/commonjs/utils/debugHelper.js +1 -64
  149. package/lib/commonjs/utils/encryption.js +7 -76
  150. package/lib/commonjs/utils/eventUtils.js +1 -0
  151. package/lib/commonjs/utils/haptics.js +9 -0
  152. package/lib/commonjs/utils/imagePreloader.js +1 -0
  153. package/lib/commonjs/utils/networkDiagnostics.js +8 -0
  154. package/lib/commonjs/utils/onairosApi.js +9 -350
  155. package/lib/commonjs/utils/programmaticFlow.js +9 -117
  156. package/lib/commonjs/utils/retryHelper.js +1 -220
  157. package/lib/commonjs/utils/secureStorage.js +10 -349
  158. package/lib/commonjs/utils/webviewScripts/chatgpt.js +1 -0
  159. package/lib/commonjs/utils/webviewScripts/claude.js +1 -0
  160. package/lib/commonjs/utils/webviewScripts/hinge.js +1 -0
  161. package/lib/commonjs/utils/webviewScripts/index.js +13 -0
  162. package/lib/commonjs/utils/webviewScripts/instagram.js +1 -0
  163. package/lib/commonjs/utils/webviewScripts/linkedin.js +1 -0
  164. package/lib/commonjs/utils/webviewScripts/sephora.js +1 -0
  165. package/lib/commonjs/utils/webviewScripts/telegram.js +1 -0
  166. package/lib/module/api/index.js +1 -139
  167. package/lib/module/assets/animations/loaderani.json +1 -0
  168. package/lib/module/assets/animations/persona-animation.json +1 -0
  169. package/lib/module/assets/fonts/EBGaramond-VariableFont_wght.ttf +0 -0
  170. package/lib/module/assets/fonts/IBMPlexSans-VariableFont_wdth,wght.ttf +0 -0
  171. package/lib/module/assets/icons/Facebookicon.png +0 -0
  172. package/lib/module/assets/icons/Gmail.png +0 -0
  173. package/lib/module/assets/icons/Linkedinicon.png +0 -0
  174. package/lib/module/assets/icons/Redditicon.png +0 -0
  175. package/lib/module/assets/icons/YouTubeicon2.png +0 -0
  176. package/lib/module/assets/icons/YouTubeicon3.png +0 -0
  177. package/lib/module/assets/icons/chatgpt.png +0 -0
  178. package/lib/module/assets/icons/claude.png +0 -0
  179. package/lib/module/assets/icons/farcaster.png +0 -0
  180. package/lib/module/assets/icons/gemini.png +0 -0
  181. package/lib/module/assets/icons/grok.png +0 -0
  182. package/lib/module/assets/icons/instagram.png +0 -0
  183. package/lib/module/assets/icons/pinterest.png +0 -0
  184. package/lib/module/assets/icons/swerv_logo.png +0 -0
  185. package/lib/module/assets/icons/twitter.jpg +0 -0
  186. package/lib/module/assets/images/Checkbox.svg +3 -0
  187. package/lib/module/assets/images/EnochE.svg +19 -0
  188. package/lib/module/assets/images/Enochicon1.png +0 -0
  189. package/lib/module/assets/images/Face_ID_logo.png +0 -0
  190. package/lib/module/assets/images/Facebookicon.png +0 -0
  191. package/lib/module/assets/images/Gmail.png +0 -0
  192. package/lib/module/assets/images/Googlelogo.png +0 -0
  193. package/lib/module/assets/images/Linkedinicon.png +0 -0
  194. package/lib/module/assets/images/OnairosNewLogo.png +0 -0
  195. package/lib/module/assets/images/Onairoslogo.png +0 -0
  196. package/lib/module/assets/images/Personalityprofile.svg +3 -0
  197. package/lib/module/assets/images/Personalitytraits.svg +3 -0
  198. package/lib/module/assets/images/Redditicon.png +0 -0
  199. package/lib/module/assets/images/Userpreferences.svg +3 -0
  200. package/lib/module/assets/images/YouTubeicon3.png +0 -0
  201. package/lib/module/assets/images/arrow.svg +20 -0
  202. package/lib/module/assets/images/basicproficon.svg +43 -0
  203. package/lib/module/assets/images/basicprofile.svg +3 -0
  204. package/lib/module/assets/images/chatgpt.png +0 -0
  205. package/lib/module/assets/images/checkmark.svg +4 -0
  206. package/lib/module/assets/images/claude.png +0 -0
  207. package/lib/module/assets/images/contentanalysis.svg +3 -0
  208. package/lib/module/assets/images/contenticon.svg +23 -0
  209. package/lib/module/assets/images/gemini.png +0 -0
  210. package/lib/module/assets/images/grok.png +0 -0
  211. package/lib/module/assets/images/persona1.png +0 -0
  212. package/lib/module/assets/images/persona2.png +0 -0
  213. package/lib/module/assets/images/persona3.png +0 -0
  214. package/lib/module/assets/images/persona4.png +0 -0
  215. package/lib/module/assets/images/persona5.png +0 -0
  216. package/lib/module/assets/images/personalityicon.svg +18 -0
  217. package/lib/module/assets/images/x-close.svg +3 -0
  218. package/lib/module/components/BodyText.js +1 -0
  219. package/lib/module/components/BrandMark.js +1 -0
  220. package/lib/module/components/CodeInput.js +1 -0
  221. package/lib/module/components/EmailInput.js +1 -0
  222. package/lib/module/components/GoogleButton.js +1 -0
  223. package/lib/module/components/HeadingGroup.js +1 -0
  224. package/lib/module/components/LLMDataInputModal.js +8 -0
  225. package/lib/module/components/ModalHeader.js +1 -0
  226. package/lib/module/components/ModalSheet.js +1 -0
  227. package/lib/module/components/Onairos.js +1 -367
  228. package/lib/module/components/OnairosButton.js +1 -302
  229. package/lib/module/components/OnairosSignInButton.js +1 -0
  230. package/lib/module/components/Overlay.js +1 -474
  231. package/lib/module/components/PersonaImage.js +1 -0
  232. package/lib/module/components/PersonaLoadingScreen.js +1 -0
  233. package/lib/module/components/PersonalizationConsentScreen.js +1 -0
  234. package/lib/module/components/PinCreationScreen.js +1 -0
  235. package/lib/module/components/PinInput.js +1 -293
  236. package/lib/module/components/PlatformConnectorsStep.js +7 -0
  237. package/lib/module/components/PlatformList.js +1 -129
  238. package/lib/module/components/PlatformToggle.js +1 -0
  239. package/lib/module/components/PrimaryButton.js +1 -0
  240. package/lib/module/components/SignInMatchAnimation.js +1 -0
  241. package/lib/module/components/SignInStep.js +1 -0
  242. package/lib/module/components/UniversalOnboarding.js +1 -1693
  243. package/lib/module/components/VerificationStep.js +1 -0
  244. package/lib/module/components/WelcomeScreen.js +1 -0
  245. package/lib/module/components/icons/Basicproficon.js +1 -0
  246. package/lib/module/components/icons/Basicprofile.js +1 -0
  247. package/lib/module/components/icons/Checkbox.js +1 -0
  248. package/lib/module/components/icons/Checkmark.js +1 -0
  249. package/lib/module/components/icons/Contentanalysis.js +1 -0
  250. package/lib/module/components/icons/Contenticon.js +1 -0
  251. package/lib/module/components/icons/EnochE.js +1 -0
  252. package/lib/module/components/icons/Personalityicon.js +1 -0
  253. package/lib/module/components/icons/Personalityprofile.js +1 -0
  254. package/lib/module/components/icons/Personalitytraits.js +1 -0
  255. package/lib/module/components/icons/Userpreferences.js +1 -0
  256. package/lib/module/components/icons/index.js +1 -0
  257. package/lib/module/components/onboarding/OAuthWebView.js +1 -818
  258. package/lib/module/components/onboarding/OnboardingHeader.js +1 -66
  259. package/lib/module/components/onboarding/PinInput.js +1 -274
  260. package/lib/module/components/onboarding/PlatformConnector.js +1 -240
  261. package/lib/module/config/api.js +1 -0
  262. package/lib/module/constants/index.js +1 -77
  263. package/lib/module/context/AuthContext.js +1 -0
  264. package/lib/module/hooks/useConnectedAccounts.js +1 -0
  265. package/lib/module/hooks/useConnections.js +1 -152
  266. package/lib/module/hooks/useCredentials.js +6 -169
  267. package/lib/module/hooks/useUserConnections.js +1 -0
  268. package/lib/module/index.js +1 -32
  269. package/lib/module/services/SDK_API_KEY_VALIDATION.md +421 -421
  270. package/lib/module/services/apiClient.js +1 -0
  271. package/lib/module/services/apiKeyService.js +1 -925
  272. package/lib/module/services/authService.js +1 -0
  273. package/lib/module/services/biometricPinService.js +1 -0
  274. package/lib/module/services/chatGPTConversationExtractor.js +1 -0
  275. package/lib/module/services/chatGPTConversationService.js +1 -0
  276. package/lib/module/services/claudeConversationExtractor.js +1 -0
  277. package/lib/module/services/claudeConversationService.js +1 -0
  278. package/lib/module/services/connectedAccountsService.js +1 -0
  279. package/lib/module/services/googleAuthService.js +1 -0
  280. package/lib/module/services/hingeDataExtractor.js +1 -0
  281. package/lib/module/services/hingeDataService.js +1 -0
  282. package/lib/module/services/imageCompressionService.js +1 -0
  283. package/lib/module/services/instagramDataExtractor.js +1 -0
  284. package/lib/module/services/instagramDataService.js +1 -0
  285. package/lib/module/services/jwtStorageService.js +1 -0
  286. package/lib/module/services/linkedinDOMExtractor.js +1 -0
  287. package/lib/module/services/linkedinProfileService.js +1 -0
  288. package/lib/module/services/linkedinScrapingService.js +1 -0
  289. package/lib/module/services/llmDataStorage.js +1 -0
  290. package/lib/module/services/mobileTrainingService.js +1 -0
  291. package/lib/module/services/oauthService.js +1 -380
  292. package/lib/module/services/pinEncryptionService.js +7 -0
  293. package/lib/module/services/pinStorageUtils.js +1 -0
  294. package/lib/module/services/platformAuthService.js +1 -1041
  295. package/lib/module/services/sephoraDataExtractor.js +1 -0
  296. package/lib/module/services/sephoraDataService.js +1 -0
  297. package/lib/module/services/storageService.js +1 -0
  298. package/lib/module/services/telegramDataExtractor.js +1 -0
  299. package/lib/module/services/telegramDataService.js +8 -0
  300. package/lib/module/services/trainingApiHelpers.js +1 -0
  301. package/lib/module/services/userConnectionsService.js +1 -0
  302. package/lib/module/services/youtubeMigrationService.js +1 -0
  303. package/lib/module/theme/index.js +1 -0
  304. package/lib/module/types.js +1 -10
  305. package/lib/module/utils/Portal.js +1 -90
  306. package/lib/module/utils/api.js +1 -117
  307. package/lib/module/utils/assetRegistry.js +33 -0
  308. package/lib/module/utils/auth.js +1 -99
  309. package/lib/module/utils/connectorTests.js +28 -0
  310. package/lib/module/utils/crypto.js +1 -54
  311. package/lib/module/utils/debugHelper.js +1 -54
  312. package/lib/module/utils/encryption.js +1 -67
  313. package/lib/module/utils/eventUtils.js +1 -0
  314. package/lib/module/utils/haptics.js +8 -0
  315. package/lib/module/utils/imagePreloader.js +1 -0
  316. package/lib/module/utils/networkDiagnostics.js +1 -0
  317. package/lib/module/utils/onairosApi.js +1 -333
  318. package/lib/module/utils/programmaticFlow.js +1 -111
  319. package/lib/module/utils/retryHelper.js +1 -211
  320. package/lib/module/utils/secureStorage.js +6 -330
  321. package/lib/module/utils/webviewScripts/chatgpt.js +1 -0
  322. package/lib/module/utils/webviewScripts/claude.js +1 -0
  323. package/lib/module/utils/webviewScripts/hinge.js +1 -0
  324. package/lib/module/utils/webviewScripts/index.js +1 -0
  325. package/lib/module/utils/webviewScripts/instagram.js +1 -0
  326. package/lib/module/utils/webviewScripts/linkedin.js +1 -0
  327. package/lib/module/utils/webviewScripts/sephora.js +1 -0
  328. package/lib/module/utils/webviewScripts/telegram.js +1 -0
  329. package/package.json +62 -39
  330. package/lib/commonjs/api/index.js.map +0 -1
  331. package/lib/commonjs/assets/images/email.png +0 -0
  332. package/lib/commonjs/assets/images/linkedin.png +0 -0
  333. package/lib/commonjs/assets/images/reddit.png +0 -0
  334. package/lib/commonjs/assets/images/youtube.png +0 -0
  335. package/lib/commonjs/components/DataRequestModal.js +0 -228
  336. package/lib/commonjs/components/DataRequestModal.js.map +0 -1
  337. package/lib/commonjs/components/DataRequestScreen.js +0 -329
  338. package/lib/commonjs/components/DataRequestScreen.js.map +0 -1
  339. package/lib/commonjs/components/EmailVerificationModal.js +0 -320
  340. package/lib/commonjs/components/EmailVerificationModal.js.map +0 -1
  341. package/lib/commonjs/components/Onairos.js.map +0 -1
  342. package/lib/commonjs/components/OnairosButton.js.map +0 -1
  343. package/lib/commonjs/components/Overlay.js.map +0 -1
  344. package/lib/commonjs/components/PinInput.js.map +0 -1
  345. package/lib/commonjs/components/PlatformList.js.map +0 -1
  346. package/lib/commonjs/components/TrainingModal.js +0 -717
  347. package/lib/commonjs/components/TrainingModal.js.map +0 -1
  348. package/lib/commonjs/components/UniversalOnboarding.js.map +0 -1
  349. package/lib/commonjs/components/UniversalOnboarding.tsx.new +0 -455
  350. package/lib/commonjs/components/onboarding/OAuthWebView.js.map +0 -1
  351. package/lib/commonjs/components/onboarding/OnboardingHeader.js.map +0 -1
  352. package/lib/commonjs/components/onboarding/PinInput.js.map +0 -1
  353. package/lib/commonjs/components/onboarding/PlatformConnector.js.map +0 -1
  354. package/lib/commonjs/components/screens/ConnectorScreen.js +0 -146
  355. package/lib/commonjs/components/screens/ConnectorScreen.js.map +0 -1
  356. package/lib/commonjs/components/screens/LoadingScreen.js +0 -91
  357. package/lib/commonjs/components/screens/LoadingScreen.js.map +0 -1
  358. package/lib/commonjs/components/screens/PinCreationScreen.js +0 -61
  359. package/lib/commonjs/components/screens/PinCreationScreen.js.map +0 -1
  360. package/lib/commonjs/constants/index.js.map +0 -1
  361. package/lib/commonjs/hooks/useConnections.js.map +0 -1
  362. package/lib/commonjs/hooks/useCredentials.js.map +0 -1
  363. package/lib/commonjs/index.js.map +0 -1
  364. package/lib/commonjs/services/apiKeyService.js.map +0 -1
  365. package/lib/commonjs/services/oauthService.js.map +0 -1
  366. package/lib/commonjs/services/platformAuthService.js.map +0 -1
  367. package/lib/commonjs/types/ambient.d.js.map +0 -1
  368. package/lib/commonjs/types/declarations.d.js.map +0 -1
  369. package/lib/commonjs/types/index.d.js.map +0 -1
  370. package/lib/commonjs/types/index.js.map +0 -1
  371. package/lib/commonjs/types/node-fix.d.js.map +0 -1
  372. package/lib/commonjs/types/node-override.d.js.map +0 -1
  373. package/lib/commonjs/types/opacity.d.js.map +0 -1
  374. package/lib/commonjs/types/types.d.js.map +0 -1
  375. package/lib/commonjs/types.js.map +0 -1
  376. package/lib/commonjs/utils/Portal.js.map +0 -1
  377. package/lib/commonjs/utils/api.js.map +0 -1
  378. package/lib/commonjs/utils/auth.js.map +0 -1
  379. package/lib/commonjs/utils/crypto.js.map +0 -1
  380. package/lib/commonjs/utils/debugHelper.js.map +0 -1
  381. package/lib/commonjs/utils/encryption.js.map +0 -1
  382. package/lib/commonjs/utils/onairosApi.js.map +0 -1
  383. package/lib/commonjs/utils/programmaticFlow.js.map +0 -1
  384. package/lib/commonjs/utils/retryHelper.js.map +0 -1
  385. package/lib/commonjs/utils/secureStorage.js.map +0 -1
  386. package/lib/module/api/index.js.map +0 -1
  387. package/lib/module/assets/images/email.png +0 -0
  388. package/lib/module/assets/images/linkedin.png +0 -0
  389. package/lib/module/assets/images/reddit.png +0 -0
  390. package/lib/module/assets/images/youtube.png +0 -0
  391. package/lib/module/components/DataRequestModal.js +0 -220
  392. package/lib/module/components/DataRequestModal.js.map +0 -1
  393. package/lib/module/components/DataRequestScreen.js +0 -321
  394. package/lib/module/components/DataRequestScreen.js.map +0 -1
  395. package/lib/module/components/EmailVerificationModal.js +0 -311
  396. package/lib/module/components/EmailVerificationModal.js.map +0 -1
  397. package/lib/module/components/Onairos.js.map +0 -1
  398. package/lib/module/components/OnairosButton.js.map +0 -1
  399. package/lib/module/components/Overlay.js.map +0 -1
  400. package/lib/module/components/PinInput.js.map +0 -1
  401. package/lib/module/components/PlatformList.js.map +0 -1
  402. package/lib/module/components/TrainingModal.js +0 -708
  403. package/lib/module/components/TrainingModal.js.map +0 -1
  404. package/lib/module/components/UniversalOnboarding.js.map +0 -1
  405. package/lib/module/components/UniversalOnboarding.tsx.new +0 -455
  406. package/lib/module/components/onboarding/OAuthWebView.js.map +0 -1
  407. package/lib/module/components/onboarding/OnboardingHeader.js.map +0 -1
  408. package/lib/module/components/onboarding/PinInput.js.map +0 -1
  409. package/lib/module/components/onboarding/PlatformConnector.js.map +0 -1
  410. package/lib/module/components/screens/ConnectorScreen.js +0 -138
  411. package/lib/module/components/screens/ConnectorScreen.js.map +0 -1
  412. package/lib/module/components/screens/LoadingScreen.js +0 -83
  413. package/lib/module/components/screens/LoadingScreen.js.map +0 -1
  414. package/lib/module/components/screens/PinCreationScreen.js +0 -53
  415. package/lib/module/components/screens/PinCreationScreen.js.map +0 -1
  416. package/lib/module/constants/index.js.map +0 -1
  417. package/lib/module/hooks/useConnections.js.map +0 -1
  418. package/lib/module/hooks/useCredentials.js.map +0 -1
  419. package/lib/module/index.js.map +0 -1
  420. package/lib/module/services/apiKeyService.js.map +0 -1
  421. package/lib/module/services/oauthService.js.map +0 -1
  422. package/lib/module/services/platformAuthService.js.map +0 -1
  423. package/lib/module/types/ambient.d.js.map +0 -1
  424. package/lib/module/types/declarations.d.js.map +0 -1
  425. package/lib/module/types/index.d.js.map +0 -1
  426. package/lib/module/types/index.js.map +0 -1
  427. package/lib/module/types/node-fix.d.js.map +0 -1
  428. package/lib/module/types/node-override.d.js.map +0 -1
  429. package/lib/module/types/opacity.d.js.map +0 -1
  430. package/lib/module/types/types.d.js.map +0 -1
  431. package/lib/module/types.js.map +0 -1
  432. package/lib/module/utils/Portal.js.map +0 -1
  433. package/lib/module/utils/api.js.map +0 -1
  434. package/lib/module/utils/auth.js.map +0 -1
  435. package/lib/module/utils/crypto.js.map +0 -1
  436. package/lib/module/utils/debugHelper.js.map +0 -1
  437. package/lib/module/utils/encryption.js.map +0 -1
  438. package/lib/module/utils/onairosApi.js.map +0 -1
  439. package/lib/module/utils/programmaticFlow.js.map +0 -1
  440. package/lib/module/utils/retryHelper.js.map +0 -1
  441. package/lib/module/utils/secureStorage.js.map +0 -1
  442. package/lib/typescript/api/index.d.ts +0 -8
  443. package/lib/typescript/api/index.d.ts.map +0 -1
  444. package/lib/typescript/components/DataRequestModal.d.ts +0 -11
  445. package/lib/typescript/components/DataRequestModal.d.ts.map +0 -1
  446. package/lib/typescript/components/DataRequestScreen.d.ts +0 -11
  447. package/lib/typescript/components/DataRequestScreen.d.ts.map +0 -1
  448. package/lib/typescript/components/EmailVerificationModal.d.ts +0 -11
  449. package/lib/typescript/components/EmailVerificationModal.d.ts.map +0 -1
  450. package/lib/typescript/components/Onairos.d.ts +0 -4
  451. package/lib/typescript/components/Onairos.d.ts.map +0 -1
  452. package/lib/typescript/components/OnairosButton.d.ts +0 -12
  453. package/lib/typescript/components/OnairosButton.d.ts.map +0 -1
  454. package/lib/typescript/components/Overlay.d.ts +0 -4
  455. package/lib/typescript/components/Overlay.d.ts.map +0 -1
  456. package/lib/typescript/components/PinInput.d.ts +0 -4
  457. package/lib/typescript/components/PinInput.d.ts.map +0 -1
  458. package/lib/typescript/components/PlatformList.d.ts +0 -4
  459. package/lib/typescript/components/PlatformList.d.ts.map +0 -1
  460. package/lib/typescript/components/TrainingModal.d.ts +0 -4
  461. package/lib/typescript/components/TrainingModal.d.ts.map +0 -1
  462. package/lib/typescript/components/UniversalOnboarding.d.ts +0 -4
  463. package/lib/typescript/components/UniversalOnboarding.d.ts.map +0 -1
  464. package/lib/typescript/components/onboarding/OAuthWebView.d.ts +0 -10
  465. package/lib/typescript/components/onboarding/OAuthWebView.d.ts.map +0 -1
  466. package/lib/typescript/components/onboarding/OnboardingHeader.d.ts +0 -11
  467. package/lib/typescript/components/onboarding/OnboardingHeader.d.ts.map +0 -1
  468. package/lib/typescript/components/onboarding/PinInput.d.ts +0 -4
  469. package/lib/typescript/components/onboarding/PinInput.d.ts.map +0 -1
  470. package/lib/typescript/components/onboarding/PlatformConnector.d.ts +0 -13
  471. package/lib/typescript/components/onboarding/PlatformConnector.d.ts.map +0 -1
  472. package/lib/typescript/components/screens/ConnectorScreen.d.ts +0 -9
  473. package/lib/typescript/components/screens/ConnectorScreen.d.ts.map +0 -1
  474. package/lib/typescript/components/screens/LoadingScreen.d.ts +0 -9
  475. package/lib/typescript/components/screens/LoadingScreen.d.ts.map +0 -1
  476. package/lib/typescript/components/screens/PinCreationScreen.d.ts +0 -10
  477. package/lib/typescript/components/screens/PinCreationScreen.d.ts.map +0 -1
  478. package/lib/typescript/constants/index.d.ts +0 -53
  479. package/lib/typescript/constants/index.d.ts.map +0 -1
  480. package/lib/typescript/hooks/useConnections.d.ts +0 -9
  481. package/lib/typescript/hooks/useConnections.d.ts.map +0 -1
  482. package/lib/typescript/hooks/useCredentials.d.ts +0 -9
  483. package/lib/typescript/hooks/useCredentials.d.ts.map +0 -1
  484. package/lib/typescript/index.d.ts +0 -18
  485. package/lib/typescript/index.d.ts.map +0 -1
  486. package/lib/typescript/services/apiKeyService.d.ts +0 -132
  487. package/lib/typescript/services/apiKeyService.d.ts.map +0 -1
  488. package/lib/typescript/services/oauthService.d.ts +0 -50
  489. package/lib/typescript/services/oauthService.d.ts.map +0 -1
  490. package/lib/typescript/services/platformAuthService.d.ts +0 -144
  491. package/lib/typescript/services/platformAuthService.d.ts.map +0 -1
  492. package/lib/typescript/types/index.d.ts +0 -231
  493. package/lib/typescript/types/index.d.ts.map +0 -1
  494. package/lib/typescript/types.d.ts +0 -270
  495. package/lib/typescript/types.d.ts.map +0 -1
  496. package/lib/typescript/utils/Portal.d.ts +0 -14
  497. package/lib/typescript/utils/Portal.d.ts.map +0 -1
  498. package/lib/typescript/utils/api.d.ts +0 -6
  499. package/lib/typescript/utils/api.d.ts.map +0 -1
  500. package/lib/typescript/utils/auth.d.ts +0 -6
  501. package/lib/typescript/utils/auth.d.ts.map +0 -1
  502. package/lib/typescript/utils/crypto.d.ts +0 -4
  503. package/lib/typescript/utils/crypto.d.ts.map +0 -1
  504. package/lib/typescript/utils/debugHelper.d.ts +0 -29
  505. package/lib/typescript/utils/debugHelper.d.ts.map +0 -1
  506. package/lib/typescript/utils/encryption.d.ts +0 -19
  507. package/lib/typescript/utils/encryption.d.ts.map +0 -1
  508. package/lib/typescript/utils/onairosApi.d.ts +0 -87
  509. package/lib/typescript/utils/onairosApi.d.ts.map +0 -1
  510. package/lib/typescript/utils/programmaticFlow.d.ts +0 -23
  511. package/lib/typescript/utils/programmaticFlow.d.ts.map +0 -1
  512. package/lib/typescript/utils/retryHelper.d.ts +0 -69
  513. package/lib/typescript/utils/retryHelper.d.ts.map +0 -1
  514. package/lib/typescript/utils/secureStorage.d.ts +0 -94
  515. package/lib/typescript/utils/secureStorage.d.ts.map +0 -1
  516. package/src/api/index.ts +0 -111
  517. package/src/assets/images/email.png +0 -0
  518. package/src/assets/images/linkedin.png +0 -0
  519. package/src/assets/images/onairos_logo.png +0 -0
  520. package/src/assets/images/reddit.png +0 -0
  521. package/src/assets/images/youtube.png +0 -0
  522. package/src/components/DataRequestModal.tsx +0 -227
  523. package/src/components/DataRequestScreen.tsx +0 -356
  524. package/src/components/EmailVerificationModal.tsx +0 -364
  525. package/src/components/Onairos.tsx +0 -425
  526. package/src/components/OnairosButton.tsx +0 -359
  527. package/src/components/Overlay.tsx +0 -506
  528. package/src/components/PinInput.tsx +0 -343
  529. package/src/components/PlatformList.tsx +0 -145
  530. package/src/components/TrainingModal.tsx +0 -737
  531. package/src/components/UniversalOnboarding.tsx +0 -1839
  532. package/src/components/UniversalOnboarding.tsx.new +0 -455
  533. package/src/components/onboarding/OAuthWebView.tsx +0 -838
  534. package/src/components/onboarding/OnboardingHeader.tsx +0 -70
  535. package/src/components/onboarding/PinInput.tsx +0 -356
  536. package/src/components/onboarding/PlatformConnector.tsx +0 -302
  537. package/src/components/screens/ConnectorScreen.tsx +0 -153
  538. package/src/components/screens/LoadingScreen.tsx +0 -100
  539. package/src/components/screens/PinCreationScreen.tsx +0 -67
  540. package/src/constants/index.ts +0 -83
  541. package/src/hooks/useConnections.ts +0 -163
  542. package/src/hooks/useCredentials.ts +0 -175
  543. package/src/index.js +0 -14
  544. package/src/index.ts +0 -50
  545. package/src/services/SDK_API_KEY_VALIDATION.md +0 -421
  546. package/src/services/apiKeyService.ts +0 -984
  547. package/src/services/oauthService.ts +0 -412
  548. package/src/services/platformAuthService.ts +0 -1113
  549. package/src/types/ambient.d.ts +0 -29
  550. package/src/types/declarations.d.ts +0 -26
  551. package/src/types/index.d.ts +0 -274
  552. package/src/types/index.ts +0 -244
  553. package/src/types/node-fix.d.ts +0 -19
  554. package/src/types/node-override.d.ts +0 -24
  555. package/src/types/opacity.d.ts +0 -16
  556. package/src/types/types.d.ts +0 -18
  557. package/src/types.ts +0 -298
  558. package/src/utils/Portal.tsx +0 -83
  559. package/src/utils/api.js +0 -112
  560. package/src/utils/auth.js +0 -104
  561. package/src/utils/crypto.js +0 -60
  562. package/src/utils/debugHelper.ts +0 -53
  563. package/src/utils/encryption.ts +0 -69
  564. package/src/utils/onairosApi.ts +0 -391
  565. package/src/utils/programmaticFlow.ts +0 -113
  566. package/src/utils/retryHelper.ts +0 -275
  567. package/src/utils/secureStorage.ts +0 -361
  568. package/types/index.d.ts +0 -218
  569. package/types/node-env.d.ts +0 -15
  570. /package/{src/assets/images → lib/commonjs/assets/icons}/farcaster.png +0 -0
  571. /package/{src/assets/images → lib/commonjs/assets/icons}/instagram.png +0 -0
  572. /package/{src/assets/images → lib/commonjs/assets/icons}/pinterest.png +0 -0
  573. /package/{src/assets/images → lib/commonjs/assets/icons}/swerv_logo.png +0 -0
  574. /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
- });