@onairos/react-native 3.4.1 → 3.5.4

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