@oxyhq/services 5.11.11 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/README.md +48 -7
  2. package/lib/commonjs/core/OxyServices.js +162 -12
  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/FollowButton.js +1 -1
  9. package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
  10. package/lib/commonjs/ui/components/GroupedItem.js +2 -1
  11. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
  12. package/lib/commonjs/ui/components/Header.js +4 -3
  13. package/lib/commonjs/ui/components/Header.js.map +1 -1
  14. package/lib/commonjs/ui/components/OxyProvider.js +112 -105
  15. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  16. package/lib/commonjs/ui/components/ProfileCard.js +5 -1
  17. package/lib/commonjs/ui/components/ProfileCard.js.map +1 -1
  18. package/lib/commonjs/ui/components/Section.js +1 -1
  19. package/lib/commonjs/ui/components/StepBasedScreen.js +17 -17
  20. package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -1
  21. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +15 -3
  22. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
  23. package/lib/commonjs/ui/components/internal/PinInput.js +10 -4
  24. package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
  25. package/lib/commonjs/ui/context/OxyContext.js +128 -12
  26. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  27. package/lib/commonjs/ui/hooks/useI18n.js +22 -0
  28. package/lib/commonjs/ui/hooks/useI18n.js.map +1 -0
  29. package/lib/commonjs/ui/navigation/OxyRouter.js +11 -131
  30. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  31. package/lib/commonjs/ui/navigation/routes.js +127 -0
  32. package/lib/commonjs/ui/navigation/routes.js.map +1 -0
  33. package/lib/commonjs/ui/navigation/types.js +7 -0
  34. package/lib/commonjs/ui/navigation/types.js.map +1 -1
  35. package/lib/commonjs/ui/screens/AccountCenterScreen.js +55 -47
  36. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +69 -61
  38. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +378 -37
  40. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +52 -34
  42. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/FeedbackScreen.js +40 -36
  44. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  45. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +105 -78
  46. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  47. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +2 -2
  48. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +92 -60
  50. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  51. package/lib/commonjs/ui/screens/ProfileScreen.js +21 -11
  52. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/RecoverAccountScreen.js +30 -8
  54. package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/SignInScreen.js +47 -26
  56. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  57. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +31 -24
  58. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  59. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +11 -7
  60. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  61. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +12 -6
  62. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  63. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +11 -7
  64. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  65. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +15 -11
  66. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  67. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +19 -27
  68. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  69. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +8 -4
  70. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  71. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +14 -10
  72. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  73. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +7 -3
  74. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  75. package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +19 -14
  76. package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -1
  77. package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js +130 -0
  78. package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -0
  79. package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +13 -13
  80. package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
  81. package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +14 -20
  82. package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
  83. package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +22 -8
  84. package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -1
  85. package/lib/commonjs/ui/screens/steps/SignInTotpStep.js +161 -0
  86. package/lib/commonjs/ui/screens/steps/SignInTotpStep.js.map +1 -0
  87. package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +12 -6
  88. package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -1
  89. package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +10 -6
  90. package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
  91. package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +10 -6
  92. package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
  93. package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +34 -4
  94. package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
  95. package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +9 -10
  96. package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
  97. package/lib/commonjs/ui/styles/authStyles.js +1 -2
  98. package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
  99. package/lib/commonjs/utils/deviceManager.js +1 -1
  100. package/lib/commonjs/utils/deviceManager.js.map +1 -1
  101. package/lib/commonjs/utils/validationUtils.js +4 -2
  102. package/lib/commonjs/utils/validationUtils.js.map +1 -1
  103. package/lib/module/core/OxyServices.js +162 -12
  104. package/lib/module/core/OxyServices.js.map +1 -1
  105. package/lib/module/i18n/index.js +35 -0
  106. package/lib/module/i18n/index.js.map +1 -0
  107. package/lib/module/i18n/locales/en-US.json +681 -0
  108. package/lib/module/i18n/locales/es-ES.json +689 -0
  109. package/lib/module/ui/components/FollowButton.js +1 -1
  110. package/lib/module/ui/components/FollowButton.js.map +1 -1
  111. package/lib/module/ui/components/GroupedItem.js +2 -1
  112. package/lib/module/ui/components/GroupedItem.js.map +1 -1
  113. package/lib/module/ui/components/Header.js +4 -3
  114. package/lib/module/ui/components/Header.js.map +1 -1
  115. package/lib/module/ui/components/OxyProvider.js +111 -105
  116. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  117. package/lib/module/ui/components/ProfileCard.js +5 -1
  118. package/lib/module/ui/components/ProfileCard.js.map +1 -1
  119. package/lib/module/ui/components/Section.js +1 -1
  120. package/lib/module/ui/components/StepBasedScreen.js +17 -17
  121. package/lib/module/ui/components/StepBasedScreen.js.map +1 -1
  122. package/lib/module/ui/components/internal/GroupedPillButtons.js +15 -3
  123. package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
  124. package/lib/module/ui/components/internal/PinInput.js +9 -4
  125. package/lib/module/ui/components/internal/PinInput.js.map +1 -1
  126. package/lib/module/ui/context/OxyContext.js +128 -12
  127. package/lib/module/ui/context/OxyContext.js.map +1 -1
  128. package/lib/module/ui/hooks/useI18n.js +18 -0
  129. package/lib/module/ui/hooks/useI18n.js.map +1 -0
  130. package/lib/module/ui/navigation/OxyRouter.js +7 -124
  131. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  132. package/lib/module/ui/navigation/routes.js +122 -0
  133. package/lib/module/ui/navigation/routes.js.map +1 -0
  134. package/lib/module/ui/navigation/types.js +19 -1
  135. package/lib/module/ui/navigation/types.js.map +1 -1
  136. package/lib/module/ui/screens/AccountCenterScreen.js +55 -47
  137. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  138. package/lib/module/ui/screens/AccountOverviewScreen.js +69 -61
  139. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  140. package/lib/module/ui/screens/AccountSettingsScreen.js +378 -37
  141. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  142. package/lib/module/ui/screens/AccountSwitcherScreen.js +52 -34
  143. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  144. package/lib/module/ui/screens/FeedbackScreen.js +40 -36
  145. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  146. package/lib/module/ui/screens/LanguageSelectorScreen.js +107 -80
  147. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  148. package/lib/module/ui/screens/PaymentGatewayScreen.js +2 -2
  149. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  150. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +92 -60
  151. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  152. package/lib/module/ui/screens/ProfileScreen.js +21 -11
  153. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  154. package/lib/module/ui/screens/RecoverAccountScreen.js +30 -8
  155. package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
  156. package/lib/module/ui/screens/SignInScreen.js +47 -26
  157. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  158. package/lib/module/ui/screens/WelcomeNewUserScreen.js +31 -24
  159. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  160. package/lib/module/ui/screens/internal/SignInPasswordStep.js +11 -7
  161. package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  162. package/lib/module/ui/screens/internal/SignInUsernameStep.js +12 -6
  163. package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  164. package/lib/module/ui/screens/karma/KarmaAboutScreen.js +11 -7
  165. package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  166. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +15 -11
  167. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  168. package/lib/module/ui/screens/karma/KarmaFAQScreen.js +19 -27
  169. package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  170. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +8 -4
  171. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  172. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +14 -10
  173. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  174. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +7 -3
  175. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  176. package/lib/module/ui/screens/steps/RecoverRequestStep.js +19 -14
  177. package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -1
  178. package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js +125 -0
  179. package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -0
  180. package/lib/module/ui/screens/steps/RecoverSuccessStep.js +13 -13
  181. package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
  182. package/lib/module/ui/screens/steps/RecoverVerifyStep.js +14 -20
  183. package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
  184. package/lib/module/ui/screens/steps/SignInPasswordStep.js +22 -8
  185. package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -1
  186. package/lib/module/ui/screens/steps/SignInTotpStep.js +156 -0
  187. package/lib/module/ui/screens/steps/SignInTotpStep.js.map +1 -0
  188. package/lib/module/ui/screens/steps/SignInUsernameStep.js +12 -6
  189. package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -1
  190. package/lib/module/ui/screens/steps/SignUpIdentityStep.js +10 -6
  191. package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
  192. package/lib/module/ui/screens/steps/SignUpSecurityStep.js +10 -6
  193. package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
  194. package/lib/module/ui/screens/steps/SignUpSummaryStep.js +34 -4
  195. package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
  196. package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +9 -10
  197. package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
  198. package/lib/module/ui/styles/authStyles.js +1 -2
  199. package/lib/module/ui/styles/authStyles.js.map +1 -1
  200. package/lib/module/utils/deviceManager.js +1 -1
  201. package/lib/module/utils/deviceManager.js.map +1 -1
  202. package/lib/module/utils/validationUtils.js +4 -2
  203. package/lib/module/utils/validationUtils.js.map +1 -1
  204. package/lib/typescript/core/OxyServices.d.ts +57 -3
  205. package/lib/typescript/core/OxyServices.d.ts.map +1 -1
  206. package/lib/typescript/i18n/index.d.ts +4 -0
  207. package/lib/typescript/i18n/index.d.ts.map +1 -0
  208. package/lib/typescript/models/interfaces.d.ts +4 -0
  209. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  210. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
  211. package/lib/typescript/ui/components/Header.d.ts.map +1 -1
  212. package/lib/typescript/ui/components/OxyProvider.d.ts +1 -1
  213. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  214. package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -1
  215. package/lib/typescript/ui/components/StepBasedScreen.d.ts +2 -1
  216. package/lib/typescript/ui/components/StepBasedScreen.d.ts.map +1 -1
  217. package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
  218. package/lib/typescript/ui/components/internal/PinInput.d.ts +6 -3
  219. package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
  220. package/lib/typescript/ui/context/OxyContext.d.ts +7 -4
  221. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  222. package/lib/typescript/ui/hooks/useI18n.d.ts +5 -0
  223. package/lib/typescript/ui/hooks/useI18n.d.ts.map +1 -0
  224. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
  225. package/lib/typescript/ui/navigation/routes.d.ts +9 -0
  226. package/lib/typescript/ui/navigation/routes.d.ts.map +1 -0
  227. package/lib/typescript/ui/navigation/types.d.ts +24 -10
  228. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  229. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  230. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  231. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  232. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  233. package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
  234. package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
  235. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
  236. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
  237. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
  238. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  239. package/lib/typescript/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  240. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +2 -1
  241. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
  242. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
  243. package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -1
  244. package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -1
  245. package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -1
  246. package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -1
  247. package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
  248. package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -1
  249. package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts +4 -1
  250. package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -1
  251. package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts +24 -0
  252. package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts.map +1 -0
  253. package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts +2 -1
  254. package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -1
  255. package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts +3 -1
  256. package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -1
  257. package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +1 -0
  258. package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -1
  259. package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts +19 -0
  260. package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts.map +1 -0
  261. package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts +2 -1
  262. package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -1
  263. package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts +2 -1
  264. package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -1
  265. package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts +2 -1
  266. package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -1
  267. package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts +2 -1
  268. package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -1
  269. package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts +2 -1
  270. package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -1
  271. package/lib/typescript/ui/styles/authStyles.d.ts +0 -1
  272. package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -1
  273. package/lib/typescript/utils/validationUtils.d.ts.map +1 -1
  274. package/package.json +49 -15
  275. package/src/core/OxyServices.ts +138 -19
  276. package/src/i18n/index.ts +39 -0
  277. package/src/i18n/locales/en-US.json +681 -0
  278. package/src/i18n/locales/es-ES.json +689 -0
  279. package/src/models/interfaces.ts +6 -1
  280. package/src/ui/components/FollowButton.tsx +2 -2
  281. package/src/ui/components/GroupedItem.tsx +2 -1
  282. package/src/ui/components/Header.tsx +4 -3
  283. package/src/ui/components/OxyProvider.tsx +107 -114
  284. package/src/ui/components/ProfileCard.tsx +5 -1
  285. package/src/ui/components/Section.tsx +1 -1
  286. package/src/ui/components/StepBasedScreen.tsx +17 -14
  287. package/src/ui/components/internal/GroupedPillButtons.tsx +10 -6
  288. package/src/ui/components/internal/PinInput.tsx +15 -6
  289. package/src/ui/context/OxyContext.tsx +123 -20
  290. package/src/ui/hooks/useI18n.ts +12 -0
  291. package/src/ui/navigation/OxyRouter.tsx +15 -134
  292. package/src/ui/navigation/routes.ts +153 -0
  293. package/src/ui/navigation/types.ts +28 -10
  294. package/src/ui/screens/AccountCenterScreen.tsx +47 -45
  295. package/src/ui/screens/AccountOverviewScreen.tsx +68 -70
  296. package/src/ui/screens/AccountSettingsScreen.tsx +265 -41
  297. package/src/ui/screens/AccountSwitcherScreen.tsx +35 -33
  298. package/src/ui/screens/FeedbackScreen.tsx +39 -37
  299. package/src/ui/screens/LanguageSelectorScreen.tsx +99 -70
  300. package/src/ui/screens/PaymentGatewayScreen.tsx +6 -6
  301. package/src/ui/screens/PremiumSubscriptionScreen.tsx +56 -54
  302. package/src/ui/screens/ProfileScreen.tsx +14 -8
  303. package/src/ui/screens/RecoverAccountScreen.tsx +29 -8
  304. package/src/ui/screens/SignInScreen.tsx +39 -30
  305. package/src/ui/screens/WelcomeNewUserScreen.tsx +31 -17
  306. package/src/ui/screens/internal/SignInPasswordStep.tsx +11 -8
  307. package/src/ui/screens/internal/SignInUsernameStep.tsx +10 -8
  308. package/src/ui/screens/karma/KarmaAboutScreen.tsx +23 -11
  309. package/src/ui/screens/karma/KarmaCenterScreen.tsx +21 -11
  310. package/src/ui/screens/karma/KarmaFAQScreen.tsx +15 -33
  311. package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +6 -4
  312. package/src/ui/screens/karma/KarmaRewardsScreen.tsx +28 -10
  313. package/src/ui/screens/karma/KarmaRulesScreen.tsx +5 -3
  314. package/src/ui/screens/steps/RecoverRequestStep.tsx +20 -17
  315. package/src/ui/screens/steps/RecoverResetPasswordStep.tsx +133 -0
  316. package/src/ui/screens/steps/RecoverSuccessStep.tsx +12 -19
  317. package/src/ui/screens/steps/RecoverVerifyStep.tsx +15 -24
  318. package/src/ui/screens/steps/SignInPasswordStep.tsx +19 -6
  319. package/src/ui/screens/steps/SignInTotpStep.tsx +129 -0
  320. package/src/ui/screens/steps/SignInUsernameStep.tsx +11 -10
  321. package/src/ui/screens/steps/SignUpIdentityStep.tsx +10 -11
  322. package/src/ui/screens/steps/SignUpSecurityStep.tsx +10 -11
  323. package/src/ui/screens/steps/SignUpSummaryStep.tsx +24 -9
  324. package/src/ui/screens/steps/SignUpWelcomeStep.tsx +8 -14
  325. package/src/ui/styles/authStyles.ts +0 -1
  326. package/src/utils/deviceManager.ts +1 -1
  327. package/src/utils/validationUtils.ts +5 -3
@@ -19,6 +19,7 @@ import { toast } from '../../lib/sonner';
19
19
  import { confirmAction } from '../utils/confirmAction';
20
20
  import { Ionicons } from '@expo/vector-icons';
21
21
  import Avatar from '../components/Avatar';
22
+ import { useI18n } from '../hooks/useI18n';
22
23
 
23
24
  interface SubscriptionPlan {
24
25
  id: string;
@@ -79,6 +80,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
79
80
  const [currentAppPackage, setCurrentAppPackage] = useState<string>('mention'); // Default to mention for demo
80
81
 
81
82
  const isDarkTheme = theme === 'dark';
83
+ const { t } = useI18n();
82
84
  const textColor = isDarkTheme ? '#FFFFFF' : '#000000';
83
85
  const backgroundColor = isDarkTheme ? '#121212' : '#FFFFFF';
84
86
  const secondaryBackgroundColor = isDarkTheme ? '#222222' : '#F5F5F5';
@@ -403,14 +405,14 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
403
405
  const selectedPlan = mockPlans.find(plan => plan.id === planId);
404
406
  if (!selectedPlan?.applicableApps.includes(currentAppPackage)) {
405
407
  console.log(`❌ Subscription blocked: Plan "${selectedPlan?.name}" not available for app "${currentAppPackage}"`);
406
- toast.error(`This plan is not available for the current app (${currentAppPackage})`);
408
+ toast.error(t('premium.toasts.planUnavailable', { app: currentAppPackage }) || `This plan is not available for the current app (${currentAppPackage})`);
407
409
  return;
408
410
  }
409
411
 
410
412
  // Special restriction for Mention+ plan - only available in mention app
411
413
  if (planId === 'mention-plus' && currentAppPackage !== 'mention') {
412
414
  console.log(`❌ Subscription blocked: Mention+ plan requires app to be "mention", current app is "${currentAppPackage}"`);
413
- toast.error('Mention+ is only available in the Mention app');
415
+ toast.error(t('premium.toasts.mentionOnly') || 'Mention+ is only available in the Mention app');
414
416
  return;
415
417
  }
416
418
 
@@ -421,7 +423,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
421
423
  // Mock payment processing
422
424
  await new Promise(resolve => setTimeout(resolve, 2000));
423
425
 
424
- toast.success('Subscription activated successfully!');
426
+ toast.success(t('premium.toasts.activated') || 'Subscription activated successfully!');
425
427
 
426
428
  // Mock subscription update
427
429
  setSubscription({
@@ -438,7 +440,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
438
440
 
439
441
  } catch (error) {
440
442
  console.error('Payment failed:', error);
441
- toast.error('Payment failed. Please try again.');
443
+ toast.error(t('premium.toasts.paymentFailed') || 'Payment failed. Please try again.');
442
444
  } finally {
443
445
  setProcessingPayment(false);
444
446
  }
@@ -446,7 +448,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
446
448
 
447
449
  const handleCancelSubscription = () => {
448
450
  confirmAction(
449
- 'Are you sure you want to cancel your subscription? You will lose access to premium features at the end of your current billing period.',
451
+ t('premium.confirms.cancelSub') || 'Are you sure you want to cancel your subscription? You will lose access to premium features at the end of your current billing period.',
450
452
  async () => {
451
453
  try {
452
454
  // Mock cancellation
@@ -454,9 +456,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
454
456
  ...prev,
455
457
  cancelAtPeriodEnd: true
456
458
  } : null);
457
- toast.success('Subscription will be canceled at the end of the billing period');
459
+ toast.success(t('premium.toasts.willCancel') || 'Subscription will be canceled at the end of the billing period');
458
460
  } catch (error) {
459
- toast.error('Failed to cancel subscription');
461
+ toast.error(t('premium.toasts.cancelFailed') || 'Failed to cancel subscription');
460
462
  }
461
463
  }
462
464
  );
@@ -468,9 +470,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
468
470
  ...prev,
469
471
  cancelAtPeriodEnd: false
470
472
  } : null);
471
- toast.success('Subscription reactivated successfully');
473
+ toast.success(t('premium.toasts.reactivated') || 'Subscription reactivated successfully');
472
474
  } catch (error) {
473
- toast.error('Failed to reactivate subscription');
475
+ toast.error(t('premium.toasts.reactivateFailed') || 'Failed to reactivate subscription');
474
476
  }
475
477
  };
476
478
 
@@ -525,11 +527,11 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
525
527
  );
526
528
 
527
529
  const feature = individualFeatures.find(f => f.id === featureId);
528
- toast.success(`Subscribed to ${feature?.name} successfully!`);
530
+ toast.success((t('premium.toasts.featureSubscribed', { name: feature?.name ?? '' }) ?? `Subscribed to ${feature?.name} successfully!`));
529
531
 
530
532
  } catch (error) {
531
533
  console.error('Feature subscription failed:', error);
532
- toast.error('Feature subscription failed. Please try again.');
534
+ toast.error(t('premium.toasts.featureSubscribeFailed') || 'Feature subscription failed. Please try again.');
533
535
  } finally {
534
536
  setProcessingPayment(false);
535
537
  }
@@ -538,7 +540,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
538
540
  const handleFeatureUnsubscribe = async (featureId: string) => {
539
541
  const feature = individualFeatures.find(f => f.id === featureId);
540
542
  confirmAction(
541
- `Are you sure you want to unsubscribe from ${feature?.name}?`,
543
+ (t('premium.confirms.unsubscribeFeature', { name: feature?.name ?? '' }) ?? `Are you sure you want to unsubscribe from ${feature?.name}?`),
542
544
  async () => {
543
545
  try {
544
546
  setIndividualFeatures(prev =>
@@ -548,9 +550,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
548
550
  : f
549
551
  )
550
552
  );
551
- toast.success(`Unsubscribed from ${feature?.name}`);
553
+ toast.success((t('premium.toasts.featureUnsubscribed', { name: feature?.name ?? '' }) ?? `Unsubscribed from ${feature?.name}`));
552
554
  } catch (error) {
553
- toast.error('Failed to unsubscribe from feature');
555
+ toast.error(t('premium.toasts.featureUnsubscribeFailed') || 'Failed to unsubscribe from feature');
554
556
  }
555
557
  }
556
558
  );
@@ -575,9 +577,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
575
577
  <Ionicons name="arrow-back" size={24} color={textColor} />
576
578
  </TouchableOpacity>
577
579
  <View style={styles.headerTitleContainer}>
578
- <Text style={[styles.headerTitle, { color: textColor }]}>Oxy+ Subscriptions</Text>
580
+ <Text style={[styles.headerTitle, { color: textColor }]}>{t('premium.title') || 'Oxy+ Subscriptions'}</Text>
579
581
  <Text style={[styles.currentAppText, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
580
- for {getAppDisplayName(currentAppPackage)}
582
+ {t('premium.forApp', { app: getAppDisplayName(currentAppPackage) }) || `for ${getAppDisplayName(currentAppPackage)}`}
581
583
  </Text>
582
584
  </View>
583
585
  {onClose && (
@@ -602,7 +604,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
602
604
 
603
605
  return (
604
606
  <View style={styles.section}>
605
- <Text style={[styles.sectionTitle, { color: textColor }]}>Current Subscription</Text>
607
+ <Text style={[styles.sectionTitle, { color: textColor }]}>{t('premium.current.title') || 'Current Subscription'}</Text>
606
608
 
607
609
  <View style={[styles.currentSubscriptionCard, { backgroundColor: secondaryBackgroundColor, borderColor }]}>
608
610
  <View style={styles.subscriptionHeader}>
@@ -620,14 +622,14 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
620
622
  </View>
621
623
 
622
624
  <Text style={[styles.subscriptionDetail, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
623
- Renews on {new Date(subscription.currentPeriodEnd).toLocaleDateString()}
625
+ {t('premium.current.renewsOn', { date: new Date(subscription.currentPeriodEnd).toLocaleDateString() }) || `Renews on ${new Date(subscription.currentPeriodEnd).toLocaleDateString()}`}
624
626
  </Text>
625
627
 
626
628
  {subscription.cancelAtPeriodEnd && (
627
629
  <View style={styles.cancelNotice}>
628
630
  <Ionicons name="warning" size={16} color={warningColor} />
629
631
  <Text style={[styles.cancelText, { color: warningColor }]}>
630
- Subscription will cancel on {new Date(subscription.currentPeriodEnd).toLocaleDateString()}
632
+ {t('premium.current.willCancelOn', { date: new Date(subscription.currentPeriodEnd).toLocaleDateString() }) || `Subscription will cancel on ${new Date(subscription.currentPeriodEnd).toLocaleDateString()}`}
631
633
  </Text>
632
634
  </View>
633
635
  )}
@@ -638,14 +640,14 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
638
640
  style={[styles.actionButton, { backgroundColor: successColor }]}
639
641
  onPress={handleReactivateSubscription}
640
642
  >
641
- <Text style={styles.actionButtonText}>Reactivate</Text>
643
+ <Text style={styles.actionButtonText}>{t('premium.actions.reactivate') || 'Reactivate'}</Text>
642
644
  </TouchableOpacity>
643
645
  ) : (
644
646
  <TouchableOpacity
645
647
  style={[styles.actionButton, { backgroundColor: dangerColor }]}
646
648
  onPress={handleCancelSubscription}
647
649
  >
648
- <Text style={styles.actionButtonText}>Cancel Subscription</Text>
650
+ <Text style={styles.actionButtonText}>{t('premium.actions.cancelSubBtn') || 'Cancel Subscription'}</Text>
649
651
  </TouchableOpacity>
650
652
  )}
651
653
 
@@ -653,7 +655,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
653
655
  style={[styles.actionButton, styles.secondaryButton, { borderColor }]}
654
656
 
655
657
  >
656
- <Text style={[styles.actionButtonText, { color: textColor }]}>Manage Billing</Text>
658
+ <Text style={[styles.actionButtonText, { color: textColor }]}>{t('premium.actions.manageBilling') || 'Manage Billing'}</Text>
657
659
  </TouchableOpacity>
658
660
  </View>
659
661
  </View>
@@ -675,7 +677,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
675
677
  styles.billingOptionText,
676
678
  { color: billingInterval === 'month' ? '#FFFFFF' : textColor }
677
679
  ]}>
678
- Monthly
680
+ {t('premium.billing.monthly') || 'Monthly'}
679
681
  </Text>
680
682
  </TouchableOpacity>
681
683
 
@@ -690,14 +692,14 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
690
692
  styles.billingOptionText,
691
693
  { color: billingInterval === 'year' ? '#FFFFFF' : textColor }
692
694
  ]}>
693
- Yearly
695
+ {t('premium.billing.yearly') || 'Yearly'}
694
696
  </Text>
695
697
  </TouchableOpacity>
696
698
  </View>
697
699
 
698
700
  {billingInterval === 'year' && (
699
701
  <Text style={[styles.savingsText, { color: successColor }]}>
700
- 💰 Save 20% with yearly billing
702
+ {t('premium.billing.saveYearly') || '💰 Save 20% with yearly billing'}
701
703
  </Text>
702
704
  )}
703
705
  </View>
@@ -712,12 +714,12 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
712
714
 
713
715
  const getAppScopeText = () => {
714
716
  if (plan.appScope === 'ecosystem') {
715
- return 'Works across all Oxy apps';
717
+ return t('premium.plan.scope.allApps') || 'Works across all Oxy apps';
716
718
  } else if (isAppSpecific) {
717
719
  const appName = plan.applicableApps[0];
718
- return `Exclusive to ${appName} app`;
720
+ return t('premium.plan.scope.exclusive', { app: appName }) || `Exclusive to ${appName} app`;
719
721
  } else {
720
- return `Available in: ${plan.applicableApps.join(', ')}`;
722
+ return t('premium.plan.scope.availableIn', { apps: plan.applicableApps.join(', ') }) || `Available in: ${plan.applicableApps.join(', ')}`;
721
723
  }
722
724
  };
723
725
 
@@ -726,7 +728,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
726
728
  const requiredApp = plan.applicableApps[0];
727
729
  return {
728
730
  available: false,
729
- reason: `Only available in ${requiredApp} app`
731
+ reason: t('premium.plan.scope.exclusive', { app: requiredApp }) || `Only available in ${requiredApp} app`
730
732
  };
731
733
  }
732
734
  return { available: true, reason: null };
@@ -756,7 +758,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
756
758
  backgroundColor: isAvailableForCurrentApp ? successColor : warningColor
757
759
  }]}>
758
760
  <Text style={styles.appSpecificText}>
759
- {isAvailableForCurrentApp ? 'App Exclusive' : 'Not Available'}
761
+ {isAvailableForCurrentApp ? (t('premium.plan.badge.appExclusive') || 'App Exclusive') : (t('premium.plan.badge.notAvailable') || 'Not Available')}
760
762
  </Text>
761
763
  </View>
762
764
  )}
@@ -781,7 +783,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
781
783
  {pricing.formatted}
782
784
  </Text>
783
785
  <Text style={[styles.planInterval, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
784
- per {pricing.interval}
786
+ {t('premium.plan.perInterval', { interval: pricing.interval }) || `per ${pricing.interval}`}
785
787
  </Text>
786
788
  </View>
787
789
 
@@ -796,12 +798,12 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
796
798
 
797
799
  {isCurrentPlan ? (
798
800
  <View style={[styles.currentPlanButton, { backgroundColor: successColor }]}>
799
- <Text style={styles.currentPlanText}>Current Plan</Text>
801
+ <Text style={styles.currentPlanText}>{t('premium.plan.current') || 'Current Plan'}</Text>
800
802
  </View>
801
803
  ) : !availability.available ? (
802
804
  <View style={[styles.unavailablePlanButton, { backgroundColor: isDarkTheme ? '#444444' : '#E0E0E0' }]}>
803
805
  <Text style={[styles.unavailablePlanText, { color: isDarkTheme ? '#888888' : '#999999' }]}>
804
- Not Available in Current App
806
+ {t('premium.plan.notAvailableInApp') || 'Not Available in Current App'}
805
807
  </Text>
806
808
  </View>
807
809
  ) : (
@@ -820,7 +822,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
820
822
  styles.selectPlanText,
821
823
  { color: plan.isPopular ? '#FFFFFF' : textColor }
822
824
  ]}>
823
- Subscribe to {plan.name}
825
+ {t('premium.actions.subscribeTo', { name: plan.name }) || `Subscribe to ${plan.name}`}
824
826
  </Text>
825
827
  )}
826
828
  </TouchableOpacity>
@@ -843,7 +845,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
843
845
  styles.tabText,
844
846
  { color: activeTab === 'plans' ? primaryColor : textColor }
845
847
  ]}>
846
- Full Plans
848
+ {t('premium.tabs.plans') || 'Full Plans'}
847
849
  </Text>
848
850
  </TouchableOpacity>
849
851
 
@@ -858,7 +860,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
858
860
  styles.tabText,
859
861
  { color: activeTab === 'features' ? primaryColor : textColor }
860
862
  ]}>
861
- Individual Features
863
+ {t('premium.tabs.features') || 'Individual Features'}
862
864
  </Text>
863
865
  </TouchableOpacity>
864
866
  </View>
@@ -895,9 +897,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
895
897
 
896
898
  const getAppScopeText = () => {
897
899
  if (feature.appScope === 'ecosystem') {
898
- return 'Available across all Oxy apps';
900
+ return t('premium.feature.scope.allApps');
899
901
  } else {
900
- return `Available in: ${feature.applicableApps.join(', ')}`;
902
+ return t('premium.feature.scope.availableIn', { apps: feature.applicableApps.join(', ') }) || `Available in: ${feature.applicableApps.join(', ')}`;
901
903
  }
902
904
  };
903
905
 
@@ -943,7 +945,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
943
945
  {pricing.formatted}
944
946
  </Text>
945
947
  <Text style={[styles.featureInterval, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
946
- per {pricing.interval}
948
+ {t('premium.plan.perInterval', { interval: pricing.interval }) || `per ${pricing.interval}`}
947
949
  </Text>
948
950
  </View>
949
951
  )}
@@ -951,19 +953,19 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
951
953
  {isIncludedInCurrentPlan ? (
952
954
  <View style={[styles.includedInPlanButton, { backgroundColor: primaryColor }]}>
953
955
  <Ionicons name="checkmark-circle" size={16} color="#FFFFFF" />
954
- <Text style={styles.includedInPlanText}>Included in your plan</Text>
956
+ <Text style={styles.includedInPlanText}>{t('premium.feature.includedInPlan') || 'Included in your plan'}</Text>
955
957
  </View>
956
958
  ) : isSubscribed ? (
957
959
  <View style={styles.featureActions}>
958
960
  <View style={[styles.subscribedButton, { backgroundColor: successColor }]}>
959
961
  <Ionicons name="checkmark" size={16} color="#FFFFFF" />
960
- <Text style={styles.subscribedText}>Subscribed</Text>
962
+ <Text style={styles.subscribedText}>{t('premium.feature.subscribed') || 'Subscribed'}</Text>
961
963
  </View>
962
964
  <TouchableOpacity
963
965
  style={[styles.unsubscribeButton, { borderColor: dangerColor }]}
964
966
  onPress={() => handleFeatureUnsubscribe(feature.id)}
965
967
  >
966
- <Text style={[styles.unsubscribeText, { color: dangerColor }]}>Unsubscribe</Text>
968
+ <Text style={[styles.unsubscribeText, { color: dangerColor }]}>{t('premium.actions.unsubscribe') || 'Unsubscribe'}</Text>
967
969
  </TouchableOpacity>
968
970
  </View>
969
971
  ) : canPurchase ? (
@@ -975,7 +977,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
975
977
  {processingPayment ? (
976
978
  <ActivityIndicator color="#FFFFFF" size="small" />
977
979
  ) : (
978
- <Text style={styles.subscribeFeatureText}>Subscribe</Text>
980
+ <Text style={styles.subscribeFeatureText}>{t('premium.actions.subscribe') || 'Subscribe'}</Text>
979
981
  )}
980
982
  </TouchableOpacity>
981
983
  ) : (
@@ -1064,7 +1066,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
1064
1066
  return (
1065
1067
  <View style={[styles.container, { backgroundColor, justifyContent: 'center' }]}>
1066
1068
  <ActivityIndicator size="large" color={primaryColor} />
1067
- <Text style={[styles.loadingText, { color: textColor }]}>Loading subscription plans...</Text>
1069
+ <Text style={[styles.loadingText, { color: textColor }]}>{t('premium.loading') || 'Loading subscription plans...'}</Text>
1068
1070
  </View>
1069
1071
  );
1070
1072
  }
@@ -1079,9 +1081,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
1079
1081
 
1080
1082
  {!subscription && (
1081
1083
  <View style={styles.section}>
1082
- <Text style={[styles.sectionTitle, { color: textColor }]}>Choose Your Plan</Text>
1084
+ <Text style={[styles.sectionTitle, { color: textColor }]}>{t('premium.choosePlan') || 'Choose Your Plan'}</Text>
1083
1085
  <Text style={[styles.sectionSubtitle, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
1084
- Unlock premium features and take your experience to the next level
1086
+ {t('premium.choosePlanSubtitle') || 'Unlock premium features and take your experience to the next level'}
1085
1087
  </Text>
1086
1088
  </View>
1087
1089
  )}
@@ -1093,7 +1095,7 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
1093
1095
  {activeTab === 'plans' ? (
1094
1096
  <View style={styles.section}>
1095
1097
  {!subscription && (
1096
- <Text style={[styles.sectionTitle, { color: textColor }]}>Available Plans</Text>
1098
+ <Text style={[styles.sectionTitle, { color: textColor }]}>{t('premium.availablePlans') || 'Available Plans'}</Text>
1097
1099
  )}
1098
1100
 
1099
1101
  {plans.map(renderPlanCard)}
@@ -1104,15 +1106,15 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
1104
1106
 
1105
1107
  {/* Features Comparison */}
1106
1108
  <View style={styles.section}>
1107
- <Text style={[styles.sectionTitle, { color: textColor }]}>Why Go Premium?</Text>
1109
+ <Text style={[styles.sectionTitle, { color: textColor }]}>{t('premium.why') || 'Why Go Premium?'}</Text>
1108
1110
 
1109
1111
  <View style={[styles.benefitsCard, { backgroundColor: secondaryBackgroundColor, borderColor }]}>
1110
1112
  <View style={styles.benefitItem}>
1111
1113
  <Ionicons name="flash" size={24} color={primaryColor} />
1112
1114
  <View style={styles.benefitContent}>
1113
- <Text style={[styles.benefitTitle, { color: textColor }]}>Enhanced Performance</Text>
1115
+ <Text style={[styles.benefitTitle, { color: textColor }]}>{t('premium.benefits.performance.title') || 'Enhanced Performance'}</Text>
1114
1116
  <Text style={[styles.benefitDescription, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
1115
- Faster processing and priority access to our servers
1117
+ {t('premium.benefits.performance.desc') || 'Faster processing and priority access to our servers'}
1116
1118
  </Text>
1117
1119
  </View>
1118
1120
  </View>
@@ -1120,9 +1122,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
1120
1122
  <View style={styles.benefitItem}>
1121
1123
  <Ionicons name="shield-checkmark" size={24} color={successColor} />
1122
1124
  <View style={styles.benefitContent}>
1123
- <Text style={[styles.benefitTitle, { color: textColor }]}>Advanced Security</Text>
1125
+ <Text style={[styles.benefitTitle, { color: textColor }]}>{t('premium.benefits.security.title') || 'Advanced Security'}</Text>
1124
1126
  <Text style={[styles.benefitDescription, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
1125
- Enhanced encryption and security features
1127
+ {t('premium.benefits.security.desc') || 'Enhanced encryption and security features'}
1126
1128
  </Text>
1127
1129
  </View>
1128
1130
  </View>
@@ -1130,9 +1132,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
1130
1132
  <View style={styles.benefitItem}>
1131
1133
  <Ionicons name="headset" size={24} color={warningColor} />
1132
1134
  <View style={styles.benefitContent}>
1133
- <Text style={[styles.benefitTitle, { color: textColor }]}>Priority Support</Text>
1135
+ <Text style={[styles.benefitTitle, { color: textColor }]}>{t('premium.benefits.support.title') || 'Priority Support'}</Text>
1134
1136
  <Text style={[styles.benefitDescription, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
1135
- Get help faster with our premium support team
1137
+ {t('premium.benefits.support.desc') || 'Get help faster with our premium support team'}
1136
1138
  </Text>
1137
1139
  </View>
1138
1140
  </View>
@@ -8,6 +8,7 @@ import Avatar from '../components/Avatar';
8
8
  import { FollowButton } from '../components';
9
9
  import { useFollow } from '../hooks/useFollow';
10
10
  import { Ionicons } from '@expo/vector-icons';
11
+ import { useI18n } from '../hooks/useI18n';
11
12
 
12
13
  interface ProfileScreenProps extends BaseScreenProps {
13
14
  userId: string;
@@ -42,6 +43,7 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
42
43
 
43
44
  const colors = useThemeColors(theme);
44
45
  const styles = createStyles(colors);
46
+ const { t } = useI18n();
45
47
 
46
48
  // Check if current user is viewing their own profile
47
49
  const isOwnProfile = currentUser && currentUser.id === userId;
@@ -205,7 +207,7 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
205
207
  style={styles.actionButton}
206
208
  onPress={() => navigate?.('EditProfile')}
207
209
  >
208
- <Text style={styles.actionButtonText}>Edit Profile</Text>
210
+ <Text style={styles.actionButtonText}>{t('editProfile.title') || 'Edit Profile'}</Text>
209
211
  </TouchableOpacity>
210
212
  ) : (
211
213
  <FollowButton
@@ -226,14 +228,16 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
226
228
  <Text style={[styles.subText, { color: colors.secondaryText }]}>@{profile.username}</Text>
227
229
  )}
228
230
  {/* Bio placeholder */}
229
- <Text style={[styles.bio, { color: colors.text }]}>{profile?.bio || 'This user has no bio yet.'}</Text>
231
+ <Text style={[styles.bio, { color: colors.text }]}>{profile?.bio || (t('profile.noBio') || 'This user has no bio yet.')}</Text>
230
232
 
231
233
  {/* Info Grid Row */}
232
234
  <View style={styles.infoGrid}>
233
235
  {profile?.createdAt && (
234
236
  <View style={styles.infoGridItem}>
235
237
  <Ionicons name="calendar-outline" size={16} color={colors.secondaryText} style={{ marginRight: 6 }} />
236
- <Text style={[styles.infoGridText, { color: colors.secondaryText }]}>Joined {new Date(profile.createdAt).toLocaleDateString()}</Text>
238
+ <Text style={[styles.infoGridText, { color: colors.secondaryText }]}>
239
+ {t('profile.joinedOn', { date: new Date(profile.createdAt).toLocaleDateString() }) || `Joined ${new Date(profile.createdAt).toLocaleDateString()}`}
240
+ </Text>
237
241
  </View>
238
242
  )}
239
243
  {profile?.location && (
@@ -269,7 +273,9 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
269
273
  {profile?.birthday && (
270
274
  <View style={styles.infoGridItem}>
271
275
  <Ionicons name="gift-outline" size={16} color={colors.secondaryText} style={{ marginRight: 6 }} />
272
- <Text style={[styles.infoGridText, { color: colors.secondaryText }]}>Born {new Date(profile.birthday).toLocaleDateString()}</Text>
276
+ <Text style={[styles.infoGridText, { color: colors.secondaryText }]}>
277
+ {t('profile.bornOn', { date: new Date(profile.birthday).toLocaleDateString() }) || `Born ${new Date(profile.birthday).toLocaleDateString()}`}
278
+ </Text>
273
279
  </View>
274
280
  )}
275
281
  {links.length > 0 && (
@@ -283,7 +289,7 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
283
289
  </Text>
284
290
  {links.length > 1 && (
285
291
  <Text style={[styles.linksMore, { color: colors.secondaryText }]}>
286
- + {links.length - 1} more
292
+ {t('profile.more', { count: links.length - 1 }) || `+ ${links.length - 1} more`}
287
293
  </Text>
288
294
  )}
289
295
  </TouchableOpacity>
@@ -295,7 +301,7 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
295
301
  <View style={styles.statsRow}>
296
302
  <View style={styles.statItem}>
297
303
  <Text style={[styles.karmaAmount, { color: colors.primary }]}>{karmaTotal !== null && karmaTotal !== undefined ? karmaTotal : '--'}</Text>
298
- <Text style={[styles.karmaLabel, { color: colors.secondaryText }]}>Karma</Text>
304
+ <Text style={[styles.karmaLabel, { color: colors.secondaryText }]}>{t('profile.karma') || 'Karma'}</Text>
299
305
  </View>
300
306
  <View style={styles.statItem}>
301
307
  {isLoadingCounts ? (
@@ -303,7 +309,7 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
303
309
  ) : (
304
310
  <Text style={[styles.karmaAmount, { color: colors.text }]}>{followerCount !== null ? followerCount : '--'}</Text>
305
311
  )}
306
- <Text style={[styles.karmaLabel, { color: colors.secondaryText }]}>Followers</Text>
312
+ <Text style={[styles.karmaLabel, { color: colors.secondaryText }]}>{t('profile.followers') || 'Followers'}</Text>
307
313
  </View>
308
314
  <View style={styles.statItem}>
309
315
  {isLoadingCounts ? (
@@ -311,7 +317,7 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
311
317
  ) : (
312
318
  <Text style={[styles.karmaAmount, { color: colors.text }]}>{followingCount !== null ? followingCount : '--'}</Text>
313
319
  )}
314
- <Text style={[styles.karmaLabel, { color: colors.secondaryText }]}>Following</Text>
320
+ <Text style={[styles.karmaLabel, { color: colors.secondaryText }]}>{t('profile.following') || 'Following'}</Text>
315
321
  </View>
316
322
  </View>
317
323
  </View>
@@ -1,11 +1,13 @@
1
1
  import type React from 'react';
2
2
  import { useState, useRef, useCallback } from 'react';
3
+ import { useI18n } from '../hooks/useI18n';
3
4
  import type { BaseScreenProps } from '../navigation/types';
4
5
  import { useThemeColors } from '../styles';
5
6
  import StepBasedScreen, { type StepConfig } from '../components/StepBasedScreen';
6
7
  import RecoverRequestStep from './steps/RecoverRequestStep';
7
8
  import RecoverVerifyStep from './steps/RecoverVerifyStep';
8
9
  import RecoverSuccessStep from './steps/RecoverSuccessStep';
10
+ import RecoverResetPasswordStep from './steps/RecoverResetPasswordStep';
9
11
 
10
12
  // Constants
11
13
  const PIN_LENGTH = 6;
@@ -18,10 +20,13 @@ const RecoverAccountScreen: React.FC<BaseScreenProps> = ({
18
20
  oxyServices,
19
21
  }) => {
20
22
  const colors = useThemeColors(theme);
23
+ const { t } = useI18n();
21
24
 
22
25
  // Form state
23
26
  const [identifier, setIdentifier] = useState('');
24
27
  const [verificationCode, setVerificationCode] = useState('');
28
+ const [password, setPassword] = useState('');
29
+ const [confirmPassword, setConfirmPassword] = useState('');
25
30
  const [isLoading, setIsLoading] = useState(false);
26
31
  const [errorMessage, setErrorMessage] = useState('');
27
32
  const [successMessage, setSuccessMessage] = useState('');
@@ -48,20 +53,21 @@ const RecoverAccountScreen: React.FC<BaseScreenProps> = ({
48
53
  component: RecoverVerifyStep,
49
54
  canProceed: () => verificationCode.length === PIN_LENGTH,
50
55
  onEnter: () => {
51
- // Simulate sending verification code
52
- setIsLoading(true);
53
- setTimeout(() => {
54
- setIsLoading(false);
55
- setSuccessMessage('A 6-digit code has been sent to your email or phone.');
56
- }, 1000);
56
+ setIsLoading(false);
57
+ setSuccessMessage(t('recover.enterCode'));
57
58
  },
58
59
  },
60
+ {
61
+ id: 'reset',
62
+ component: RecoverResetPasswordStep,
63
+ canProceed: () => true,
64
+ },
59
65
  {
60
66
  id: 'success',
61
67
  component: RecoverSuccessStep,
62
68
  canProceed: () => true,
63
69
  onEnter: () => {
64
- setSuccessMessage('Your account has been verified! You can now reset your password.');
70
+ setSuccessMessage(t('recover.resetSuccess'));
65
71
  },
66
72
  },
67
73
  ];
@@ -93,6 +99,21 @@ const RecoverAccountScreen: React.FC<BaseScreenProps> = ({
93
99
  setSuccessMessage,
94
100
  isLoading,
95
101
  setIsLoading,
102
+ identifier,
103
+ },
104
+ // Reset step
105
+ {
106
+ identifier,
107
+ verificationCode,
108
+ password,
109
+ confirmPassword,
110
+ setPassword,
111
+ setConfirmPassword,
112
+ errorMessage,
113
+ setErrorMessage,
114
+ isLoading,
115
+ setIsLoading,
116
+ oxyServices,
96
117
  },
97
118
  // Success step
98
119
  {
@@ -117,4 +138,4 @@ const RecoverAccountScreen: React.FC<BaseScreenProps> = ({
117
138
 
118
139
 
119
140
 
120
- export default RecoverAccountScreen;
141
+ export default RecoverAccountScreen;