@oxyhq/services 5.11.12 → 5.12.1

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 (322) hide show
  1. package/README.md +48 -7
  2. package/lib/commonjs/core/OxyServices.js +168 -5
  3. package/lib/commonjs/core/OxyServices.js.map +1 -1
  4. package/lib/commonjs/i18n/index.js +40 -0
  5. package/lib/commonjs/i18n/index.js.map +1 -0
  6. package/lib/commonjs/i18n/locales/en-US.json +681 -0
  7. package/lib/commonjs/i18n/locales/es-ES.json +689 -0
  8. package/lib/commonjs/ui/components/GroupedItem.js +2 -1
  9. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
  10. package/lib/commonjs/ui/components/Header.js +4 -3
  11. package/lib/commonjs/ui/components/Header.js.map +1 -1
  12. package/lib/commonjs/ui/components/OxyProvider.js +110 -103
  13. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  14. package/lib/commonjs/ui/components/ProfileCard.js +5 -1
  15. package/lib/commonjs/ui/components/ProfileCard.js.map +1 -1
  16. package/lib/commonjs/ui/components/Section.js +1 -1
  17. package/lib/commonjs/ui/components/StepBasedScreen.js +16 -16
  18. package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -1
  19. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +15 -3
  20. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
  21. package/lib/commonjs/ui/components/internal/PinInput.js +10 -4
  22. package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
  23. package/lib/commonjs/ui/context/OxyContext.js +128 -12
  24. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  25. package/lib/commonjs/ui/hooks/useI18n.js +22 -0
  26. package/lib/commonjs/ui/hooks/useI18n.js.map +1 -0
  27. package/lib/commonjs/ui/navigation/OxyRouter.js +11 -131
  28. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  29. package/lib/commonjs/ui/navigation/routes.js +127 -0
  30. package/lib/commonjs/ui/navigation/routes.js.map +1 -0
  31. package/lib/commonjs/ui/navigation/types.js +7 -0
  32. package/lib/commonjs/ui/navigation/types.js.map +1 -1
  33. package/lib/commonjs/ui/screens/AccountCenterScreen.js +55 -47
  34. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  35. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +69 -61
  36. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +378 -37
  38. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +52 -34
  40. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/FeedbackScreen.js +40 -36
  42. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +105 -78
  44. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  45. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +1 -1
  46. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  47. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +92 -60
  48. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/ProfileScreen.js +21 -11
  50. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  51. package/lib/commonjs/ui/screens/RecoverAccountScreen.js +30 -8
  52. package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/SignInScreen.js +47 -26
  54. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +31 -24
  56. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  57. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +11 -7
  58. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  59. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +12 -6
  60. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  61. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +11 -7
  62. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  63. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +15 -11
  64. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  65. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +19 -27
  66. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  67. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +8 -4
  68. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  69. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +14 -10
  70. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  71. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +7 -3
  72. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  73. package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +19 -14
  74. package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -1
  75. package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js +130 -0
  76. package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -0
  77. package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +13 -13
  78. package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
  79. package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +14 -20
  80. package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
  81. package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +22 -8
  82. package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -1
  83. package/lib/commonjs/ui/screens/steps/SignInTotpStep.js +161 -0
  84. package/lib/commonjs/ui/screens/steps/SignInTotpStep.js.map +1 -0
  85. package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +12 -6
  86. package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -1
  87. package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +10 -6
  88. package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
  89. package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +10 -6
  90. package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
  91. package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +34 -4
  92. package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
  93. package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +9 -10
  94. package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
  95. package/lib/commonjs/ui/styles/authStyles.js +1 -2
  96. package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
  97. package/lib/commonjs/utils/deviceManager.js +1 -1
  98. package/lib/commonjs/utils/deviceManager.js.map +1 -1
  99. package/lib/commonjs/utils/validationUtils.js +4 -2
  100. package/lib/commonjs/utils/validationUtils.js.map +1 -1
  101. package/lib/module/core/OxyServices.js +168 -5
  102. package/lib/module/core/OxyServices.js.map +1 -1
  103. package/lib/module/i18n/index.js +35 -0
  104. package/lib/module/i18n/index.js.map +1 -0
  105. package/lib/module/i18n/locales/en-US.json +681 -0
  106. package/lib/module/i18n/locales/es-ES.json +689 -0
  107. package/lib/module/ui/components/GroupedItem.js +2 -1
  108. package/lib/module/ui/components/GroupedItem.js.map +1 -1
  109. package/lib/module/ui/components/Header.js +4 -3
  110. package/lib/module/ui/components/Header.js.map +1 -1
  111. package/lib/module/ui/components/OxyProvider.js +109 -103
  112. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  113. package/lib/module/ui/components/ProfileCard.js +5 -1
  114. package/lib/module/ui/components/ProfileCard.js.map +1 -1
  115. package/lib/module/ui/components/Section.js +1 -1
  116. package/lib/module/ui/components/StepBasedScreen.js +16 -16
  117. package/lib/module/ui/components/StepBasedScreen.js.map +1 -1
  118. package/lib/module/ui/components/internal/GroupedPillButtons.js +15 -3
  119. package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
  120. package/lib/module/ui/components/internal/PinInput.js +9 -4
  121. package/lib/module/ui/components/internal/PinInput.js.map +1 -1
  122. package/lib/module/ui/context/OxyContext.js +128 -12
  123. package/lib/module/ui/context/OxyContext.js.map +1 -1
  124. package/lib/module/ui/hooks/useI18n.js +18 -0
  125. package/lib/module/ui/hooks/useI18n.js.map +1 -0
  126. package/lib/module/ui/navigation/OxyRouter.js +7 -124
  127. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  128. package/lib/module/ui/navigation/routes.js +122 -0
  129. package/lib/module/ui/navigation/routes.js.map +1 -0
  130. package/lib/module/ui/navigation/types.js +19 -1
  131. package/lib/module/ui/navigation/types.js.map +1 -1
  132. package/lib/module/ui/screens/AccountCenterScreen.js +55 -47
  133. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  134. package/lib/module/ui/screens/AccountOverviewScreen.js +69 -61
  135. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  136. package/lib/module/ui/screens/AccountSettingsScreen.js +378 -37
  137. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  138. package/lib/module/ui/screens/AccountSwitcherScreen.js +52 -34
  139. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  140. package/lib/module/ui/screens/FeedbackScreen.js +40 -36
  141. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  142. package/lib/module/ui/screens/LanguageSelectorScreen.js +107 -80
  143. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  144. package/lib/module/ui/screens/PaymentGatewayScreen.js +1 -1
  145. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  146. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +92 -60
  147. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  148. package/lib/module/ui/screens/ProfileScreen.js +21 -11
  149. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  150. package/lib/module/ui/screens/RecoverAccountScreen.js +30 -8
  151. package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
  152. package/lib/module/ui/screens/SignInScreen.js +47 -26
  153. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  154. package/lib/module/ui/screens/WelcomeNewUserScreen.js +31 -24
  155. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  156. package/lib/module/ui/screens/internal/SignInPasswordStep.js +11 -7
  157. package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  158. package/lib/module/ui/screens/internal/SignInUsernameStep.js +12 -6
  159. package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  160. package/lib/module/ui/screens/karma/KarmaAboutScreen.js +11 -7
  161. package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  162. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +15 -11
  163. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  164. package/lib/module/ui/screens/karma/KarmaFAQScreen.js +19 -27
  165. package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  166. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +8 -4
  167. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  168. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +14 -10
  169. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  170. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +7 -3
  171. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  172. package/lib/module/ui/screens/steps/RecoverRequestStep.js +19 -14
  173. package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -1
  174. package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js +125 -0
  175. package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -0
  176. package/lib/module/ui/screens/steps/RecoverSuccessStep.js +13 -13
  177. package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
  178. package/lib/module/ui/screens/steps/RecoverVerifyStep.js +14 -20
  179. package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
  180. package/lib/module/ui/screens/steps/SignInPasswordStep.js +22 -8
  181. package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -1
  182. package/lib/module/ui/screens/steps/SignInTotpStep.js +156 -0
  183. package/lib/module/ui/screens/steps/SignInTotpStep.js.map +1 -0
  184. package/lib/module/ui/screens/steps/SignInUsernameStep.js +12 -6
  185. package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -1
  186. package/lib/module/ui/screens/steps/SignUpIdentityStep.js +10 -6
  187. package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
  188. package/lib/module/ui/screens/steps/SignUpSecurityStep.js +10 -6
  189. package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
  190. package/lib/module/ui/screens/steps/SignUpSummaryStep.js +34 -4
  191. package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
  192. package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +9 -10
  193. package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
  194. package/lib/module/ui/styles/authStyles.js +1 -2
  195. package/lib/module/ui/styles/authStyles.js.map +1 -1
  196. package/lib/module/utils/deviceManager.js +1 -1
  197. package/lib/module/utils/deviceManager.js.map +1 -1
  198. package/lib/module/utils/validationUtils.js +4 -2
  199. package/lib/module/utils/validationUtils.js.map +1 -1
  200. package/lib/typescript/core/OxyServices.d.ts +58 -3
  201. package/lib/typescript/core/OxyServices.d.ts.map +1 -1
  202. package/lib/typescript/i18n/index.d.ts +4 -0
  203. package/lib/typescript/i18n/index.d.ts.map +1 -0
  204. package/lib/typescript/models/interfaces.d.ts +4 -0
  205. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  206. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
  207. package/lib/typescript/ui/components/Header.d.ts.map +1 -1
  208. package/lib/typescript/ui/components/OxyProvider.d.ts +1 -1
  209. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  210. package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -1
  211. package/lib/typescript/ui/components/StepBasedScreen.d.ts +2 -1
  212. package/lib/typescript/ui/components/StepBasedScreen.d.ts.map +1 -1
  213. package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
  214. package/lib/typescript/ui/components/internal/PinInput.d.ts +6 -3
  215. package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
  216. package/lib/typescript/ui/context/OxyContext.d.ts +7 -4
  217. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  218. package/lib/typescript/ui/hooks/useI18n.d.ts +5 -0
  219. package/lib/typescript/ui/hooks/useI18n.d.ts.map +1 -0
  220. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
  221. package/lib/typescript/ui/navigation/routes.d.ts +9 -0
  222. package/lib/typescript/ui/navigation/routes.d.ts.map +1 -0
  223. package/lib/typescript/ui/navigation/types.d.ts +24 -10
  224. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  225. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  226. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  227. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  228. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  229. package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
  230. package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
  231. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
  232. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
  233. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
  234. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  235. package/lib/typescript/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  236. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +2 -1
  237. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
  238. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
  239. package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -1
  240. package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -1
  241. package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -1
  242. package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -1
  243. package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
  244. package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -1
  245. package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts +4 -1
  246. package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -1
  247. package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts +24 -0
  248. package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts.map +1 -0
  249. package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts +2 -1
  250. package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -1
  251. package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts +3 -1
  252. package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -1
  253. package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +1 -0
  254. package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -1
  255. package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts +19 -0
  256. package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts.map +1 -0
  257. package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts +2 -1
  258. package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -1
  259. package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts +2 -1
  260. package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -1
  261. package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts +2 -1
  262. package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -1
  263. package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts +2 -1
  264. package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -1
  265. package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts +2 -1
  266. package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -1
  267. package/lib/typescript/ui/styles/authStyles.d.ts +0 -1
  268. package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -1
  269. package/lib/typescript/utils/validationUtils.d.ts.map +1 -1
  270. package/package.json +48 -14
  271. package/src/core/OxyServices.ts +143 -9
  272. package/src/i18n/index.ts +39 -0
  273. package/src/i18n/locales/en-US.json +681 -0
  274. package/src/i18n/locales/es-ES.json +689 -0
  275. package/src/models/interfaces.ts +6 -1
  276. package/src/ui/components/GroupedItem.tsx +2 -1
  277. package/src/ui/components/Header.tsx +4 -3
  278. package/src/ui/components/OxyProvider.tsx +105 -112
  279. package/src/ui/components/ProfileCard.tsx +5 -1
  280. package/src/ui/components/Section.tsx +1 -1
  281. package/src/ui/components/StepBasedScreen.tsx +16 -13
  282. package/src/ui/components/internal/GroupedPillButtons.tsx +10 -6
  283. package/src/ui/components/internal/PinInput.tsx +15 -6
  284. package/src/ui/context/OxyContext.tsx +123 -20
  285. package/src/ui/hooks/useI18n.ts +12 -0
  286. package/src/ui/navigation/OxyRouter.tsx +15 -134
  287. package/src/ui/navigation/routes.ts +153 -0
  288. package/src/ui/navigation/types.ts +28 -10
  289. package/src/ui/screens/AccountCenterScreen.tsx +47 -45
  290. package/src/ui/screens/AccountOverviewScreen.tsx +68 -70
  291. package/src/ui/screens/AccountSettingsScreen.tsx +265 -41
  292. package/src/ui/screens/AccountSwitcherScreen.tsx +35 -33
  293. package/src/ui/screens/FeedbackScreen.tsx +39 -37
  294. package/src/ui/screens/LanguageSelectorScreen.tsx +99 -70
  295. package/src/ui/screens/PaymentGatewayScreen.tsx +5 -5
  296. package/src/ui/screens/PremiumSubscriptionScreen.tsx +56 -54
  297. package/src/ui/screens/ProfileScreen.tsx +14 -8
  298. package/src/ui/screens/RecoverAccountScreen.tsx +29 -8
  299. package/src/ui/screens/SignInScreen.tsx +39 -30
  300. package/src/ui/screens/WelcomeNewUserScreen.tsx +31 -17
  301. package/src/ui/screens/internal/SignInPasswordStep.tsx +11 -8
  302. package/src/ui/screens/internal/SignInUsernameStep.tsx +10 -8
  303. package/src/ui/screens/karma/KarmaAboutScreen.tsx +23 -11
  304. package/src/ui/screens/karma/KarmaCenterScreen.tsx +21 -11
  305. package/src/ui/screens/karma/KarmaFAQScreen.tsx +15 -33
  306. package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +6 -4
  307. package/src/ui/screens/karma/KarmaRewardsScreen.tsx +28 -10
  308. package/src/ui/screens/karma/KarmaRulesScreen.tsx +5 -3
  309. package/src/ui/screens/steps/RecoverRequestStep.tsx +20 -17
  310. package/src/ui/screens/steps/RecoverResetPasswordStep.tsx +133 -0
  311. package/src/ui/screens/steps/RecoverSuccessStep.tsx +12 -19
  312. package/src/ui/screens/steps/RecoverVerifyStep.tsx +15 -24
  313. package/src/ui/screens/steps/SignInPasswordStep.tsx +19 -6
  314. package/src/ui/screens/steps/SignInTotpStep.tsx +129 -0
  315. package/src/ui/screens/steps/SignInUsernameStep.tsx +11 -10
  316. package/src/ui/screens/steps/SignUpIdentityStep.tsx +10 -11
  317. package/src/ui/screens/steps/SignUpSecurityStep.tsx +10 -11
  318. package/src/ui/screens/steps/SignUpSummaryStep.tsx +24 -9
  319. package/src/ui/screens/steps/SignUpWelcomeStep.tsx +8 -14
  320. package/src/ui/styles/authStyles.ts +0 -1
  321. package/src/utils/deviceManager.ts +1 -1
  322. package/src/utils/validationUtils.ts +5 -3
@@ -5,6 +5,7 @@ import { Ionicons } from '@expo/vector-icons';
5
5
  import Avatar from '../../components/Avatar';
6
6
  import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
7
7
  import TextField from '../../components/internal/TextField';
8
+ import { useI18n } from '../../hooks/useI18n';
8
9
 
9
10
  interface SignInPasswordStepProps {
10
11
  // Common props from StepBasedScreen
@@ -39,6 +40,7 @@ interface SignInPasswordStepProps {
39
40
 
40
41
  // Sign-in function
41
42
  handleSignIn: () => Promise<void>;
43
+ mfaToken?: string | null;
42
44
  }
43
45
 
44
46
  const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
@@ -46,6 +48,7 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
46
48
  styles,
47
49
  theme,
48
50
  navigate,
51
+ nextStep,
49
52
  prevStep,
50
53
  password,
51
54
  setPassword,
@@ -57,8 +60,10 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
57
60
  userProfile,
58
61
  username,
59
62
  handleSignIn,
63
+ mfaToken,
60
64
  }) => {
61
65
  const inputRef = useRef<any>(null);
66
+ const { t } = useI18n();
62
67
 
63
68
  const handlePasswordChange = (text: string) => {
64
69
  setPassword(text);
@@ -89,6 +94,14 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
89
94
  }
90
95
  }, [errorMessage]);
91
96
 
97
+ // Auto-advance when MFA is required
98
+ useEffect(() => {
99
+ if (mfaToken) {
100
+ // Move to TOTP step when token is available
101
+ nextStep();
102
+ }
103
+ }, [mfaToken, nextStep]);
104
+
92
105
  return (
93
106
  <>
94
107
  <View style={styles.modernUserProfileContainer}>
@@ -113,7 +126,7 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
113
126
  <View style={styles.modernInputContainer}>
114
127
  <TextField
115
128
  ref={inputRef}
116
- label="Password"
129
+ label={t('common.labels.password')}
117
130
  leading={<Ionicons name="lock-closed-outline" size={24} color={colors.secondaryText} />}
118
131
  value={password}
119
132
  onChangeText={handlePasswordChange}
@@ -128,13 +141,13 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
128
141
  />
129
142
 
130
143
  <View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 16 }}>
131
- <Text style={[styles.footerText, { color: colors.text }]}>Forgot your password? </Text>
144
+ <Text style={[styles.footerText, { color: colors.text }]}>{t('signin.forgotPrompt') || 'Forgot your password?'} </Text>
132
145
  <TouchableOpacity onPress={() => navigate('RecoverAccount', {
133
146
  returnTo: 'SignIn',
134
147
  returnStep: 1,
135
148
  returnData: { username, userProfile }
136
149
  })}>
137
- <Text style={[styles.modernLinkText, { color: colors.primary }]}>Recover your account</Text>
150
+ <Text style={[styles.modernLinkText, { color: colors.primary }]}>{t('common.links.recoverAccount')}</Text>
138
151
  </TouchableOpacity>
139
152
  </View>
140
153
  </View>
@@ -142,13 +155,13 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
142
155
  <GroupedPillButtons
143
156
  buttons={[
144
157
  {
145
- text: 'Back',
158
+ text: t('common.actions.back') || 'Back',
146
159
  onPress: prevStep,
147
160
  icon: 'arrow-back',
148
161
  variant: 'transparent',
149
162
  },
150
163
  {
151
- text: 'Sign In',
164
+ text: t('common.actions.signIn') || 'Sign In',
152
165
  onPress: handleSignInSubmit,
153
166
  icon: 'log-in',
154
167
  variant: 'primary',
@@ -162,7 +175,7 @@ const SignInPasswordStep: React.FC<SignInPasswordStepProps> = ({
162
175
  <View style={styles.securityNotice}>
163
176
  <Ionicons name="shield-checkmark" size={14} color={colors.secondaryText} />
164
177
  <Text style={[styles.securityText, { color: colors.secondaryText }]}>
165
- Your data is encrypted and secure
178
+ {t('signin.security.dataSecure') || 'Your data is encrypted and secure'}
166
179
  </Text>
167
180
  </View>
168
181
  </>
@@ -0,0 +1,129 @@
1
+ import type React from 'react';
2
+ import type { RouteName } from '../../navigation/routes';
3
+ import { useRef, useState } from 'react';
4
+ import { View, Text, TouchableOpacity } from 'react-native';
5
+ import { Ionicons } from '@expo/vector-icons';
6
+ import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
7
+ import PinInput, { type PinInputHandle } from '../../components/internal/PinInput';
8
+ import { useI18n } from '../../hooks/useI18n';
9
+
10
+ interface SignInTotpStepProps {
11
+ // Common props
12
+ colors: any;
13
+ styles: any;
14
+ theme: string;
15
+ navigate: (screen: RouteName, props?: Record<string, any>) => void;
16
+
17
+ // Step navigation
18
+ prevStep: () => void;
19
+ nextStep: () => void;
20
+
21
+ // Data
22
+ username: string;
23
+ mfaToken: string;
24
+
25
+ // Context actions
26
+ completeMfaLogin?: (mfaToken: string, code: string) => Promise<any>;
27
+
28
+ // Error/loading
29
+ errorMessage?: string;
30
+ setErrorMessage?: (msg: string) => void;
31
+ isLoading?: boolean;
32
+ }
33
+
34
+ const SignInTotpStep: React.FC<SignInTotpStepProps> = ({
35
+ colors,
36
+ styles,
37
+ navigate,
38
+ prevStep,
39
+ nextStep,
40
+ username,
41
+ mfaToken,
42
+ completeMfaLogin,
43
+ errorMessage,
44
+ setErrorMessage,
45
+ isLoading,
46
+ }) => {
47
+ const [code, setCode] = useState('');
48
+ const inputRef = useRef<PinInputHandle | null>(null);
49
+ const { t } = useI18n();
50
+
51
+ const handleVerify = async () => {
52
+ if (!code || code.length !== 6) {
53
+ setErrorMessage?.(t('recover.enterCode'));
54
+ return;
55
+ }
56
+ try {
57
+ setErrorMessage?.('');
58
+ await completeMfaLogin?.(mfaToken, code);
59
+ // Login completed; higher-level navigation should continue automatically
60
+ } catch (e: any) {
61
+ setErrorMessage?.(e?.message || (t('signin.totp.invalidCode') || 'Invalid code. Please try again.'));
62
+ setTimeout(() => inputRef.current?.focus(), 0);
63
+ }
64
+ };
65
+
66
+ return (
67
+ <>
68
+ <View style={styles.modernHeader}>
69
+ <Text style={[styles.modernTitle, { color: colors.text }]}>{t('signin.totp.title') || 'Two‑Factor Code'}</Text>
70
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
71
+ {t('signin.totp.subtitle', { username }) || `Enter the 6‑digit code from your authenticator app for @${username}`}
72
+ </Text>
73
+ </View>
74
+
75
+ <View style={styles.modernInputContainer}>
76
+ <PinInput
77
+ ref={inputRef}
78
+ value={code}
79
+ onChange={setCode}
80
+ length={6}
81
+ disabled={isLoading}
82
+ autoFocus
83
+ colors={colors}
84
+ />
85
+
86
+ {errorMessage ? (
87
+ <View style={{
88
+ flexDirection: 'row',
89
+ alignItems: 'center',
90
+ marginTop: 16,
91
+ padding: 12,
92
+ backgroundColor: colors.error + '10',
93
+ borderRadius: 8,
94
+ borderWidth: 1,
95
+ borderColor: colors.error + '30',
96
+ }}>
97
+ <Ionicons name="alert-circle" size={20} color={colors.error} style={{ marginRight: 8 }} />
98
+ <Text style={[styles.footerText, { color: colors.error, fontSize: 14 }]}>
99
+ {errorMessage}
100
+ </Text>
101
+ </View>
102
+ ) : null}
103
+ </View>
104
+
105
+ <GroupedPillButtons
106
+ buttons={[
107
+ { text: t('common.actions.back'), onPress: prevStep, icon: 'arrow-back', variant: 'transparent' },
108
+ { text: t('signin.actions.verify'), onPress: handleVerify, icon: 'shield-checkmark', variant: 'primary', loading: isLoading, disabled: isLoading || code.length !== 6 },
109
+ ]}
110
+ colors={colors}
111
+ />
112
+
113
+ <View style={{ marginTop: 12, alignItems: 'center' }}>
114
+ <Text style={[styles.footerText, { color: colors.secondaryText }]}>{t('signin.totp.noAccess') || 'No access to your authenticator?'}</Text>
115
+ <View style={{ flexDirection: 'row', gap: 12, marginTop: 6 }}>
116
+ <TouchableOpacity onPress={() => navigate('RecoverAccount', { prefillUsername: username })}>
117
+ <Text style={[styles.linkText, { color: colors.primary }]}>{t('signin.totp.useBackupCode') || 'Use backup code'}</Text>
118
+ </TouchableOpacity>
119
+ <Text style={[styles.footerText, { color: colors.secondaryText }]}>•</Text>
120
+ <TouchableOpacity onPress={() => navigate('RecoverAccount', { prefillUsername: username })}>
121
+ <Text style={[styles.linkText, { color: colors.primary }]}>{t('signin.totp.useRecoveryKey') || 'Use recovery key'}</Text>
122
+ </TouchableOpacity>
123
+ </View>
124
+ </View>
125
+ </>
126
+ );
127
+ };
128
+
129
+ export default SignInTotpStep;
@@ -1,17 +1,19 @@
1
1
  import type React from 'react';
2
+ import type { RouteName } from '../../navigation/routes';
2
3
  import { useRef, useEffect } from 'react';
3
4
  import { View, Text } from 'react-native';
4
5
  import { Ionicons } from '@expo/vector-icons';
5
6
  import HighFive from '../../../assets/illustrations/HighFive';
6
7
  import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
7
8
  import TextField from '../../components/internal/TextField';
9
+ import { useI18n } from '../../hooks/useI18n';
8
10
 
9
11
  interface SignInUsernameStepProps {
10
12
  // Common props from StepBasedScreen
11
13
  colors: any;
12
14
  styles: any;
13
15
  theme: string;
14
- navigate: (screen: string, props?: Record<string, any>) => void;
16
+ navigate: (screen: RouteName, props?: Record<string, any>) => void;
15
17
 
16
18
  // Step navigation
17
19
  nextStep: () => void;
@@ -58,6 +60,7 @@ const SignInUsernameStep: React.FC<SignInUsernameStepProps> = ({
58
60
  validateUsername,
59
61
  }) => {
60
62
  const inputRef = useRef<any>(null);
63
+ const { t } = useI18n();
61
64
 
62
65
  // Monitor username prop changes
63
66
  useEffect(() => {
@@ -111,13 +114,10 @@ const SignInUsernameStep: React.FC<SignInUsernameStepProps> = ({
111
114
  <HighFive width={100} height={100} />
112
115
  <View style={styles.modernHeader}>
113
116
  <Text style={[styles.modernTitle, { color: colors.text }]}>
114
- {isAddAccountMode ? 'Add Another Account' : 'Sign In'}
117
+ {isAddAccountMode ? t('signin.addAccountTitle') : t('signin.title')}
115
118
  </Text>
116
119
  <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
117
- {isAddAccountMode
118
- ? 'Sign in with another account'
119
- : 'Sign in to continue your journey'
120
- }
120
+ {isAddAccountMode ? t('signin.addAccountSubtitle') : t('signin.subtitle')}
121
121
  </Text>
122
122
  </View>
123
123
 
@@ -125,7 +125,8 @@ const SignInUsernameStep: React.FC<SignInUsernameStepProps> = ({
125
125
  <View style={[styles.modernInfoCard, { backgroundColor: colors.inputBackground }]}>
126
126
  <Ionicons name="information-circle" size={20} color={colors.primary} />
127
127
  <Text style={[styles.modernInfoText, { color: colors.text }]}>
128
- Currently signed in as <Text style={{ fontWeight: 'bold' }}>{user.username}</Text>
128
+ {t('signin.currentlySignedInAs', { username: user.username }) || 'Currently signed in as '}
129
+ <Text style={{ fontWeight: 'bold' }}>{user.username}</Text>
129
130
  </Text>
130
131
  </View>
131
132
  )}
@@ -133,7 +134,7 @@ const SignInUsernameStep: React.FC<SignInUsernameStepProps> = ({
133
134
  <View style={styles.modernInputContainer}>
134
135
  <TextField
135
136
  ref={inputRef}
136
- label="Username"
137
+ label={t('common.labels.username')}
137
138
  leading={<Ionicons name="person-outline" size={24} color={colors.secondaryText} />}
138
139
  value={username}
139
140
  onChangeText={handleUsernameChange}
@@ -152,13 +153,13 @@ const SignInUsernameStep: React.FC<SignInUsernameStepProps> = ({
152
153
  <GroupedPillButtons
153
154
  buttons={[
154
155
  {
155
- text: 'Sign Up',
156
+ text: t('common.links.signUp'),
156
157
  onPress: () => navigate('SignUp'),
157
158
  icon: 'person-add',
158
159
  variant: 'transparent',
159
160
  },
160
161
  {
161
- text: 'Continue',
162
+ text: t('common.actions.continue'),
162
163
  onPress: handleContinue,
163
164
  icon: 'arrow-forward',
164
165
  variant: 'primary',
@@ -1,16 +1,18 @@
1
1
  import type React from 'react';
2
+ import type { RouteName } from '../../navigation/routes';
2
3
  import { useRef, useState, useEffect, useCallback } from 'react';
3
4
  import { View, Text } from 'react-native';
4
5
  import { Ionicons } from '@expo/vector-icons';
5
6
  import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
6
7
  import TextField from '../../components/internal/TextField';
8
+ import { useI18n } from '../../hooks/useI18n';
7
9
 
8
10
  interface SignUpIdentityStepProps {
9
11
  // Common props from StepBasedScreen
10
12
  colors: any;
11
13
  styles: any;
12
14
  theme: string;
13
- navigate: (screen: string, props?: Record<string, any>) => void;
15
+ navigate: (screen: RouteName, props?: Record<string, any>) => void;
14
16
 
15
17
  // Step navigation
16
18
  nextStep: () => void;
@@ -53,6 +55,7 @@ const SignUpIdentityStep: React.FC<SignUpIdentityStepProps> = ({
53
55
  validateUsername,
54
56
  }) => {
55
57
  const usernameRef = useRef<any>(null);
58
+ const { t } = useI18n();
56
59
  const validationTimeoutRef = useRef<NodeJS.Timeout | null>(null);
57
60
 
58
61
  // Debounced username validation
@@ -132,18 +135,14 @@ const SignUpIdentityStep: React.FC<SignUpIdentityStepProps> = ({
132
135
  return (
133
136
  <>
134
137
  <View style={styles.modernHeader}>
135
- <Text style={[styles.modernTitle, { color: colors.text }]}>
136
- Who are you?
137
- </Text>
138
- <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
139
- Choose your username and enter your email
140
- </Text>
138
+ <Text style={[styles.modernTitle, { color: colors.text }]}>{t('signup.identity.title')}</Text>
139
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>{t('signup.identity.subtitle')}</Text>
141
140
  </View>
142
141
 
143
142
  <View style={styles.modernInputContainer}>
144
143
  <TextField
145
144
  ref={usernameRef}
146
- label="Username"
145
+ label={t('common.labels.username')}
147
146
  leading={<Ionicons name="person-outline" size={24} color={colors.secondaryText} />}
148
147
  value={username}
149
148
  onChangeText={handleUsernameChange}
@@ -159,7 +158,7 @@ const SignUpIdentityStep: React.FC<SignUpIdentityStepProps> = ({
159
158
  />
160
159
 
161
160
  <TextField
162
- label="Email"
161
+ label={t('common.labels.email')}
163
162
  leading={<Ionicons name="mail-outline" size={24} color={colors.secondaryText} />}
164
163
  value={email}
165
164
  onChangeText={handleEmailChange}
@@ -176,13 +175,13 @@ const SignUpIdentityStep: React.FC<SignUpIdentityStepProps> = ({
176
175
  <GroupedPillButtons
177
176
  buttons={[
178
177
  {
179
- text: 'Back',
178
+ text: t('common.actions.back'),
180
179
  onPress: prevStep,
181
180
  icon: 'arrow-back',
182
181
  variant: 'transparent',
183
182
  },
184
183
  {
185
- text: 'Next',
184
+ text: t('common.actions.next'),
186
185
  onPress: handleNext,
187
186
  icon: 'arrow-forward',
188
187
  variant: 'primary',
@@ -1,16 +1,18 @@
1
1
  import type React from 'react';
2
+ import type { RouteName } from '../../navigation/routes';
2
3
  import { useRef, useState } from 'react';
3
4
  import { View, Text, TouchableOpacity } from 'react-native';
4
5
  import { Ionicons } from '@expo/vector-icons';
5
6
  import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
6
7
  import TextField from '../../components/internal/TextField';
8
+ import { useI18n } from '../../hooks/useI18n';
7
9
 
8
10
  interface SignUpSecurityStepProps {
9
11
  // Common props from StepBasedScreen
10
12
  colors: any;
11
13
  styles: any;
12
14
  theme: string;
13
- navigate: (screen: string, props?: Record<string, any>) => void;
15
+ navigate: (screen: RouteName, props?: Record<string, any>) => void;
14
16
 
15
17
  // Step navigation
16
18
  nextStep: () => void;
@@ -54,6 +56,7 @@ const SignUpSecurityStep: React.FC<SignUpSecurityStepProps> = ({
54
56
  validatePassword,
55
57
  }) => {
56
58
  const passwordRef = useRef<any>(null);
59
+ const { t } = useI18n();
57
60
 
58
61
  const handlePasswordChange = (text: string) => {
59
62
  setPassword(text);
@@ -96,18 +99,14 @@ const SignUpSecurityStep: React.FC<SignUpSecurityStepProps> = ({
96
99
  return (
97
100
  <>
98
101
  <View style={styles.modernHeader}>
99
- <Text style={[styles.modernTitle, { color: colors.text }]}>
100
- Secure Your Account
101
- </Text>
102
- <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
103
- Create a strong password to protect your account
104
- </Text>
102
+ <Text style={[styles.modernTitle, { color: colors.text }]}>{t('signup.security.title')}</Text>
103
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>{t('signup.security.subtitle')}</Text>
105
104
  </View>
106
105
 
107
106
  <View style={styles.modernInputContainer}>
108
107
  <TextField
109
108
  ref={passwordRef}
110
- label="Password"
109
+ label={t('common.labels.password')}
111
110
  leading={<Ionicons name="lock-closed-outline" size={24} color={colors.secondaryText} />}
112
111
  trailing={
113
112
  <TouchableOpacity
@@ -134,7 +133,7 @@ const SignUpSecurityStep: React.FC<SignUpSecurityStepProps> = ({
134
133
  />
135
134
 
136
135
  <TextField
137
- label="Confirm Password"
136
+ label={t('common.labels.confirmPassword')}
138
137
  leading={<Ionicons name="lock-closed-outline" size={24} color={colors.secondaryText} />}
139
138
  trailing={
140
139
  <TouchableOpacity
@@ -169,13 +168,13 @@ const SignUpSecurityStep: React.FC<SignUpSecurityStepProps> = ({
169
168
  <GroupedPillButtons
170
169
  buttons={[
171
170
  {
172
- text: 'Back',
171
+ text: t('common.actions.back'),
173
172
  onPress: prevStep,
174
173
  icon: 'arrow-back',
175
174
  variant: 'transparent',
176
175
  },
177
176
  {
178
- text: 'Next',
177
+ text: t('common.actions.next'),
179
178
  onPress: handleNext,
180
179
  icon: 'arrow-forward',
181
180
  variant: 'primary',
@@ -1,14 +1,16 @@
1
1
  import type React from 'react';
2
+ import type { RouteName } from '../../navigation/routes';
2
3
  import { View, Text } from 'react-native';
3
4
  import { Ionicons } from '@expo/vector-icons';
4
5
  import GroupedPillButtons from '../../components/internal/GroupedPillButtons';
6
+ import { useI18n } from '../../hooks/useI18n';
5
7
 
6
8
  interface SignUpSummaryStepProps {
7
9
  // Common props from StepBasedScreen
8
10
  colors: any;
9
11
  styles: any;
10
12
  theme: string;
11
- navigate: (screen: string, props?: Record<string, any>) => void;
13
+ navigate: (screen: RouteName, props?: Record<string, any>) => void;
12
14
 
13
15
  // Step navigation
14
16
  nextStep: () => void;
@@ -31,6 +33,7 @@ const SignUpSummaryStep: React.FC<SignUpSummaryStepProps> = ({
31
33
  allStepData,
32
34
  isLoading,
33
35
  }) => {
36
+ const { t } = useI18n();
34
37
  // Extract data from previous steps
35
38
  const identityData = allStepData[1] || {}; // Step 2 (index 1)
36
39
  const securityData = allStepData[2] || {}; // Step 3 (index 2)
@@ -46,12 +49,8 @@ const SignUpSummaryStep: React.FC<SignUpSummaryStepProps> = ({
46
49
  return (
47
50
  <>
48
51
  <View style={styles.modernHeader}>
49
- <Text style={[styles.modernTitle, { color: colors.text }]}>
50
- Almost There!
51
- </Text>
52
- <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
53
- Review your information and create your account
54
- </Text>
52
+ <Text style={[styles.modernTitle, { color: colors.text }]}>{t('signup.summary.title')}</Text>
53
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>{t('signup.summary.subtitle')}</Text>
55
54
  </View>
56
55
 
57
56
  <View style={[styles.modernInputContainer, { marginBottom: 32 }]}>
@@ -87,6 +86,22 @@ const SignUpSummaryStep: React.FC<SignUpSummaryStepProps> = ({
87
86
  </View>
88
87
  </View>
89
88
 
89
+ <View style={{
90
+ flexDirection: 'row',
91
+ alignItems: 'center',
92
+ marginTop: 16,
93
+ padding: 12,
94
+ backgroundColor: colors.warning + '10',
95
+ borderRadius: 8,
96
+ borderWidth: 1,
97
+ borderColor: colors.warning + '30',
98
+ }}>
99
+ <Ionicons name="shield-checkmark" size={20} color={colors.warning} style={{ marginRight: 8 }} />
100
+ <Text style={[styles.footerText, { color: colors.warning, fontSize: 14, flex: 1 }]}>
101
+ For stronger security, we recommend enabling Two‑Factor Authentication (TOTP) from Account Settings after you create your account.
102
+ </Text>
103
+ </View>
104
+
90
105
  <View style={{
91
106
  flexDirection: 'row',
92
107
  alignItems: 'center',
@@ -107,13 +122,13 @@ const SignUpSummaryStep: React.FC<SignUpSummaryStepProps> = ({
107
122
  <GroupedPillButtons
108
123
  buttons={[
109
124
  {
110
- text: 'Back',
125
+ text: t('common.actions.back'),
111
126
  onPress: prevStep,
112
127
  icon: 'arrow-back',
113
128
  variant: 'transparent',
114
129
  },
115
130
  {
116
- text: 'Create Account',
131
+ text: t('common.actions.createAccount'),
117
132
  onPress: nextStep,
118
133
  icon: 'checkmark-circle',
119
134
  variant: 'primary',
@@ -1,14 +1,16 @@
1
1
  import type React from 'react';
2
+ import type { RouteName } from '../../navigation/routes';
2
3
  import { View, Text, TouchableOpacity } from 'react-native';
3
4
  import { Ionicons } from '@expo/vector-icons';
4
5
  import HighFive from '../../../assets/illustrations/HighFive';
6
+ import { useI18n } from '../../hooks/useI18n';
5
7
 
6
8
  interface SignUpWelcomeStepProps {
7
9
  // Common props from StepBasedScreen
8
10
  colors: any;
9
11
  styles: any;
10
12
  theme: string;
11
- navigate: (screen: string, props?: Record<string, any>) => void;
13
+ navigate: (screen: RouteName, props?: Record<string, any>) => void;
12
14
 
13
15
  // Step navigation
14
16
  nextStep: () => void;
@@ -22,16 +24,13 @@ const SignUpWelcomeStep: React.FC<SignUpWelcomeStepProps> = ({
22
24
  navigate,
23
25
  nextStep,
24
26
  }) => {
27
+ const { t } = useI18n();
25
28
  return (
26
29
  <>
27
30
  <HighFive width={120} height={120} />
28
31
  <View style={styles.modernHeader}>
29
- <Text style={[styles.modernTitle, { color: colors.text }]}>
30
- Welcome to Oxy!
31
- </Text>
32
- <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>
33
- Let's create your account in just a few steps
34
- </Text>
32
+ <Text style={[styles.modernTitle, { color: colors.text }]}>{t('signup.welcome.title')}</Text>
33
+ <Text style={[styles.modernSubtitle, { color: colors.secondaryText }]}>{t('signup.welcome.subtitle')}</Text>
35
34
  </View>
36
35
 
37
36
  <View style={styles.modernInputContainer}>
@@ -41,9 +40,7 @@ const SignUpWelcomeStep: React.FC<SignUpWelcomeStepProps> = ({
41
40
  testID="get-started-button"
42
41
  >
43
42
  <Ionicons name="rocket-outline" size={20} color={colors.background} />
44
- <Text style={[styles.buttonText, { color: colors.background }]}>
45
- Get Started
46
- </Text>
43
+ <Text style={[styles.buttonText, { color: colors.background }]}>{t('common.actions.getStarted')}</Text>
47
44
  </TouchableOpacity>
48
45
 
49
46
  <TouchableOpacity
@@ -51,10 +48,7 @@ const SignUpWelcomeStep: React.FC<SignUpWelcomeStepProps> = ({
51
48
  onPress={() => navigate('SignIn')}
52
49
  >
53
50
  <Text style={[styles.footerText, { color: colors.secondaryText }]}>
54
- Already have an account?{' '}
55
- <Text style={[styles.linkText, { color: colors.primary }]}>
56
- Sign In
57
- </Text>
51
+ {t('signin.title')}
58
52
  </Text>
59
53
  </TouchableOpacity>
60
54
  </View>
@@ -23,7 +23,6 @@ export const createAuthStyles = (colors: AuthThemeColors, theme: string) => Styl
23
23
  flexGrow: 1,
24
24
  paddingHorizontal: 24,
25
25
  paddingTop: 4,
26
- paddingBottom: 20,
27
26
  },
28
27
  stepContainer: {
29
28
  flex: 1,
@@ -184,7 +184,7 @@ export class DeviceManager {
184
184
  */
185
185
  static getDefaultDeviceName(): string {
186
186
  const fingerprint = this.getDeviceFingerprint();
187
- const platform = fingerprint.platform.toLowerCase();
187
+ const platform = (fingerprint.platform || '').toLowerCase();
188
188
 
189
189
  if (platform.includes('win')) return 'Windows Computer';
190
190
  if (platform.includes('mac')) return 'Mac Computer';
@@ -15,7 +15,8 @@ export const USERNAME_REGEX = /^[a-zA-Z0-9_-]{3,30}$/;
15
15
  /**
16
16
  * Password validation regex (at least 8 chars, 1 uppercase, 1 lowercase, 1 number)
17
17
  */
18
- export const PASSWORD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{8,}$/;
18
+ // At least 8 characters (tests expect len>=8 without complexity requirements)
19
+ export const PASSWORD_REGEX = /^.{8,}$/;
19
20
 
20
21
  /**
21
22
  * Validate email format
@@ -120,7 +121,8 @@ export function isValidFileType(filename: string, allowedTypes: string[]): boole
120
121
  * Sanitize string input
121
122
  */
122
123
  export function sanitizeString(input: string): string {
123
- return input.trim().replace(/[<>]/g, '');
124
+ // Remove HTML tags entirely and trim whitespace
125
+ return input.trim().replace(/<[^>]*>/g, '');
124
126
  }
125
127
 
126
128
  /**
@@ -155,4 +157,4 @@ export function validateAndSanitizeUserInput(input: unknown, type: 'string' | 'e
155
157
  default:
156
158
  return null;
157
159
  }
158
- }
160
+ }