@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
@@ -8,11 +8,14 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _OxyContext = require("../context/OxyContext");
10
10
  var _OxyIcon = _interopRequireDefault(require("../components/icon/OxyIcon"));
11
+ var _vectorIcons = require("@expo/vector-icons");
11
12
  var _sonner = require("../../lib/sonner");
12
13
  var _fonts = require("../styles/fonts");
13
14
  var _confirmAction = require("../utils/confirmAction");
14
15
  var _authStore = require("../stores/authStore");
15
16
  var _components = require("../components");
17
+ var _useI18n = require("../hooks/useI18n");
18
+ var _reactNativeQrcodeSvg = _interopRequireDefault(require("react-native-qrcode-svg"));
16
19
  var _jsxRuntime = require("react/jsx-runtime");
17
20
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
21
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -27,12 +30,24 @@ const AccountSettingsScreen = ({
27
30
  oxyServices,
28
31
  isLoading: authLoading,
29
32
  isAuthenticated,
30
- showBottomSheet
33
+ showBottomSheet,
34
+ activeSessionId
31
35
  } = (0, _OxyContext.useOxy)();
36
+ const {
37
+ t
38
+ } = (0, _useI18n.useI18n)();
32
39
  const updateUser = (0, _authStore.useAuthStore)(state => state.updateUser);
33
40
  const [isLoading, setIsLoading] = (0, _react.useState)(false);
34
41
  const [isSaving, setIsSaving] = (0, _react.useState)(false);
35
42
 
43
+ // Two-Factor (TOTP) state
44
+ const [totpSetupUrl, setTotpSetupUrl] = (0, _react.useState)(null);
45
+ const [totpCode, setTotpCode] = (0, _react.useState)('');
46
+ const [isTotpBusy, setIsTotpBusy] = (0, _react.useState)(false);
47
+ const [showRecoveryModal, setShowRecoveryModal] = (0, _react.useState)(false);
48
+ const [generatedBackupCodes, setGeneratedBackupCodes] = (0, _react.useState)(null);
49
+ const [generatedRecoveryKey, setGeneratedRecoveryKey] = (0, _react.useState)(null);
50
+
36
51
  // Animation refs
37
52
  const saveButtonScale = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
38
53
 
@@ -188,7 +203,7 @@ const AccountSettingsScreen = ({
188
203
  updates.avatar = avatarFileId;
189
204
  }
190
205
  await updateUser(updates, oxyServices);
191
- _sonner.toast.success('Profile updated successfully');
206
+ _sonner.toast.success(t('editProfile.toasts.profileUpdated') || 'Profile updated successfully');
192
207
  animateSaveButton(1); // Scale back to normal
193
208
 
194
209
  if (onClose) {
@@ -197,16 +212,16 @@ const AccountSettingsScreen = ({
197
212
  goBack();
198
213
  }
199
214
  } catch (error) {
200
- _sonner.toast.error(error.message || 'Failed to update profile');
215
+ _sonner.toast.error(error.message || t('editProfile.toasts.updateFailed') || 'Failed to update profile');
201
216
  animateSaveButton(1); // Scale back to normal on error
202
217
  } finally {
203
218
  setIsSaving(false);
204
219
  }
205
220
  };
206
221
  const handleAvatarRemove = () => {
207
- (0, _confirmAction.confirmAction)('Remove your profile picture?', () => {
222
+ (0, _confirmAction.confirmAction)(t('editProfile.confirms.removeAvatar') || 'Remove your profile picture?', () => {
208
223
  setAvatarFileId('');
209
- _sonner.toast.success('Avatar removed');
224
+ _sonner.toast.success(t('editProfile.toasts.avatarRemoved') || 'Avatar removed');
210
225
  });
211
226
  };
212
227
  const openAvatarPicker = (0, _react.useCallback)(() => {
@@ -218,16 +233,16 @@ const AccountSettingsScreen = ({
218
233
  afterSelect: 'back',
219
234
  onSelect: file => {
220
235
  if (!file.contentType.startsWith('image/')) {
221
- _sonner.toast.error('Please select an image file');
236
+ _sonner.toast.error(t('editProfile.toasts.selectImage') || 'Please select an image file');
222
237
  return;
223
238
  }
224
239
  // If already selected, do nothing
225
240
  if (file.id === avatarFileId) {
226
- _sonner.toast.info?.('Avatar unchanged');
241
+ _sonner.toast.info?.(t('editProfile.toasts.avatarUnchanged') || 'Avatar unchanged');
227
242
  return;
228
243
  }
229
244
  setAvatarFileId(file.id);
230
- _sonner.toast.success('Avatar selected');
245
+ _sonner.toast.success(t('editProfile.toasts.avatarSelected') || 'Avatar selected');
231
246
  // Auto-save avatar immediately (does not close edit profile screen)
232
247
  (async () => {
233
248
  try {
@@ -238,10 +253,10 @@ const AccountSettingsScreen = ({
238
253
  }, oxyServices);
239
254
  // Force refresh current user cache (updateUser already does a fetch with force=true internally)
240
255
  // Extra safeguard: ensure avatarFileId reflects saved id (already set) and trigger any dependent UI.
241
- _sonner.toast.success('Avatar updated');
256
+ _sonner.toast.success(t('editProfile.toasts.avatarUpdated') || 'Avatar updated');
242
257
  } catch (e) {
243
258
  console.error('[AccountSettings] Failed to auto-save avatar', e);
244
- _sonner.toast.error(e.message || 'Failed to update avatar');
259
+ _sonner.toast.error(e.message || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
245
260
  } finally {
246
261
  setIsSaving(false);
247
262
  }
@@ -274,6 +289,11 @@ const AccountSettingsScreen = ({
274
289
  // Don't reset the metadata - keep the existing rich metadata
275
290
  // The tempLinksWithMetadata should already contain the rich data from the database
276
291
  break;
292
+ case 'twoFactor':
293
+ // Reset TOTP temp state
294
+ setTotpSetupUrl(null);
295
+ setTotpCode('');
296
+ break;
277
297
  }
278
298
  setEditingField(type);
279
299
  };
@@ -405,6 +425,179 @@ const AccountSettingsScreen = ({
405
425
  });
406
426
  };
407
427
  const renderEditingField = type => {
428
+ if (type === 'twoFactor') {
429
+ const enabled = !!user?.privacySettings?.twoFactorEnabled;
430
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
431
+ style: [styles.editingFieldContainer, {
432
+ backgroundColor: themeStyles.backgroundColor
433
+ }],
434
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
435
+ style: styles.editingFieldContent,
436
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
437
+ style: styles.newValueSection,
438
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
439
+ style: styles.editingFieldHeader,
440
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
441
+ style: [styles.editingFieldLabel, {
442
+ color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A'
443
+ }],
444
+ children: "Two\u2011Factor Authentication (TOTP)"
445
+ })
446
+ }), !enabled ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
447
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
448
+ style: styles.editingFieldDescription,
449
+ children: "Protect your account with a 6\u2011digit code from an authenticator app. Scan the QR code then enter the code to enable."
450
+ }), !totpSetupUrl ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
451
+ style: styles.primaryButton,
452
+ disabled: isTotpBusy,
453
+ onPress: async () => {
454
+ if (!activeSessionId) {
455
+ _sonner.toast.error(t('editProfile.toasts.noActiveSession') || 'No active session');
456
+ return;
457
+ }
458
+ setIsTotpBusy(true);
459
+ try {
460
+ const {
461
+ otpauthUrl
462
+ } = await oxyServices.startTotpEnrollment(activeSessionId);
463
+ setTotpSetupUrl(otpauthUrl);
464
+ } catch (e) {
465
+ _sonner.toast.error(e?.message || t('editProfile.toasts.totpStartFailed') || 'Failed to start TOTP enrollment');
466
+ } finally {
467
+ setIsTotpBusy(false);
468
+ }
469
+ },
470
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
471
+ name: "shield-checkmark",
472
+ size: 18,
473
+ color: "#fff"
474
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
475
+ style: styles.primaryButtonText,
476
+ children: "Generate QR Code"
477
+ })]
478
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
479
+ style: {
480
+ alignItems: 'center',
481
+ gap: 16
482
+ },
483
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
484
+ style: {
485
+ padding: 16,
486
+ backgroundColor: '#fff',
487
+ borderRadius: 12
488
+ },
489
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeQrcodeSvg.default, {
490
+ value: totpSetupUrl,
491
+ size: 180
492
+ })
493
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
494
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
495
+ style: styles.editingFieldLabel,
496
+ children: "Enter 6\u2011digit code"
497
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
498
+ style: styles.editingFieldInput,
499
+ keyboardType: "number-pad",
500
+ placeholder: "123456",
501
+ value: totpCode,
502
+ onChangeText: setTotpCode,
503
+ maxLength: 6
504
+ })]
505
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
506
+ style: styles.primaryButton,
507
+ disabled: isTotpBusy || totpCode.length !== 6,
508
+ onPress: async () => {
509
+ if (!activeSessionId) {
510
+ _sonner.toast.error(t('editProfile.toasts.noActiveSession') || 'No active session');
511
+ return;
512
+ }
513
+ setIsTotpBusy(true);
514
+ try {
515
+ const result = await oxyServices.verifyTotpEnrollment(activeSessionId, totpCode);
516
+ await updateUser({
517
+ privacySettings: {
518
+ twoFactorEnabled: true
519
+ }
520
+ }, oxyServices);
521
+ if (result?.backupCodes || result?.recoveryKey) {
522
+ setGeneratedBackupCodes(result.backupCodes || null);
523
+ setGeneratedRecoveryKey(result.recoveryKey || null);
524
+ setShowRecoveryModal(true);
525
+ } else {
526
+ _sonner.toast.success(t('editProfile.toasts.twoFactorEnabled') || 'Two‑Factor Authentication enabled');
527
+ setEditingField(null);
528
+ }
529
+ } catch (e) {
530
+ _sonner.toast.error(e?.message || t('editProfile.toasts.invalidCode') || 'Invalid code');
531
+ } finally {
532
+ setIsTotpBusy(false);
533
+ }
534
+ },
535
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
536
+ name: "checkmark-circle",
537
+ size: 18,
538
+ color: "#fff"
539
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
540
+ style: styles.primaryButtonText,
541
+ children: "Verify & Enable"
542
+ })]
543
+ })]
544
+ })]
545
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
546
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
547
+ style: styles.editingFieldDescription,
548
+ children: "Two\u2011Factor Authentication is currently enabled. To disable, enter a code from your authenticator app."
549
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
550
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
551
+ style: styles.editingFieldLabel,
552
+ children: "Enter 6\u2011digit code"
553
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
554
+ style: styles.editingFieldInput,
555
+ keyboardType: "number-pad",
556
+ placeholder: "123456",
557
+ value: totpCode,
558
+ onChangeText: setTotpCode,
559
+ maxLength: 6
560
+ })]
561
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
562
+ style: [styles.primaryButton, {
563
+ backgroundColor: '#d9534f'
564
+ }],
565
+ disabled: isTotpBusy || totpCode.length !== 6,
566
+ onPress: async () => {
567
+ if (!activeSessionId) {
568
+ _sonner.toast.error(t('editProfile.toasts.noActiveSession') || 'No active session');
569
+ return;
570
+ }
571
+ setIsTotpBusy(true);
572
+ try {
573
+ await oxyServices.disableTotp(activeSessionId, totpCode);
574
+ await updateUser({
575
+ privacySettings: {
576
+ twoFactorEnabled: false
577
+ }
578
+ }, oxyServices);
579
+ _sonner.toast.success(t('editProfile.toasts.twoFactorDisabled') || 'Two‑Factor Authentication disabled');
580
+ setEditingField(null);
581
+ } catch (e) {
582
+ _sonner.toast.error(e?.message || t('editProfile.toasts.disableFailed') || 'Failed to disable');
583
+ } finally {
584
+ setIsTotpBusy(false);
585
+ }
586
+ },
587
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
588
+ name: "close-circle",
589
+ size: 18,
590
+ color: "#fff"
591
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
592
+ style: styles.primaryButtonText,
593
+ children: "Disable 2FA"
594
+ })]
595
+ })]
596
+ })]
597
+ })
598
+ })
599
+ });
600
+ }
408
601
  if (type === 'displayName') {
409
602
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
410
603
  style: [styles.editingFieldContainer, {
@@ -946,11 +1139,11 @@ const AccountSettingsScreen = ({
946
1139
  style: [styles.editingBottomTitle, {
947
1140
  color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A'
948
1141
  }],
949
- children: editingField === 'displayName' ? 'Display Name' : editingField === 'username' ? 'Username' : editingField === 'email' ? 'Email' : editingField === 'bio' ? 'Bio' : editingField === 'location' ? 'Location' : editingField === 'links' ? 'Links' : 'Field'
1142
+ children: editingField === 'displayName' ? t('editProfile.items.displayName.title') || 'Display Name' : editingField === 'username' ? t('editProfile.items.username.title') || 'Username' : editingField === 'email' ? t('editProfile.items.email.title') || 'Email' : editingField === 'bio' ? t('editProfile.items.bio.title') || 'Bio' : editingField === 'location' ? t('editProfile.items.locations.title') || 'Location' : editingField === 'links' ? t('editProfile.items.links.title') || 'Links' : 'Field'
950
1143
  })]
951
1144
  })]
952
1145
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Header, {
953
- title: "Edit Profile",
1146
+ title: t('editProfile.title') || 'Edit Profile',
954
1147
  theme: theme,
955
1148
  onBack: goBack || onClose,
956
1149
  rightAction: {
@@ -972,11 +1165,115 @@ const AccountSettingsScreen = ({
972
1165
  /*#__PURE__*/
973
1166
  // Show all settings when not editing
974
1167
  (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
975
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1168
+ children: [showRecoveryModal && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
1169
+ style: {
1170
+ position: 'absolute',
1171
+ top: 0,
1172
+ left: 0,
1173
+ right: 0,
1174
+ bottom: 0,
1175
+ backgroundColor: 'rgba(0,0,0,0.6)',
1176
+ zIndex: 50,
1177
+ padding: 16,
1178
+ justifyContent: 'center'
1179
+ },
1180
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1181
+ style: {
1182
+ backgroundColor: '#fff',
1183
+ borderRadius: 16,
1184
+ padding: 20,
1185
+ maxHeight: '80%'
1186
+ },
1187
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1188
+ style: {
1189
+ fontSize: 18,
1190
+ fontWeight: '700',
1191
+ marginBottom: 12
1192
+ },
1193
+ children: "Save These Codes Now"
1194
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1195
+ style: {
1196
+ fontSize: 14,
1197
+ color: '#444',
1198
+ marginBottom: 12
1199
+ },
1200
+ children: "Backup codes and your Recovery Key are shown only once. Store them securely (paper or password manager)."
1201
+ }), generatedBackupCodes && generatedBackupCodes.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1202
+ style: {
1203
+ marginBottom: 12
1204
+ },
1205
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1206
+ style: {
1207
+ fontSize: 16,
1208
+ fontWeight: '600',
1209
+ marginBottom: 8
1210
+ },
1211
+ children: "Backup Codes"
1212
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
1213
+ style: {
1214
+ backgroundColor: '#F8F9FA',
1215
+ borderRadius: 8,
1216
+ padding: 12
1217
+ },
1218
+ children: generatedBackupCodes.map((c, idx) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1219
+ style: {
1220
+ fontFamily: _reactNative.Platform.OS === 'web' ? 'monospace' : 'monospace',
1221
+ fontSize: 14,
1222
+ marginBottom: 4
1223
+ },
1224
+ children: c
1225
+ }, idx))
1226
+ })]
1227
+ }), generatedRecoveryKey && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1228
+ style: {
1229
+ marginBottom: 12
1230
+ },
1231
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1232
+ style: {
1233
+ fontSize: 16,
1234
+ fontWeight: '600',
1235
+ marginBottom: 8
1236
+ },
1237
+ children: "Recovery Key"
1238
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
1239
+ style: {
1240
+ backgroundColor: '#F8F9FA',
1241
+ borderRadius: 8,
1242
+ padding: 12
1243
+ },
1244
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1245
+ style: {
1246
+ fontFamily: _reactNative.Platform.OS === 'web' ? 'monospace' : 'monospace',
1247
+ fontSize: 14
1248
+ },
1249
+ children: generatedRecoveryKey
1250
+ })
1251
+ })]
1252
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
1253
+ style: [styles.primaryButton, {
1254
+ alignSelf: 'flex-end',
1255
+ marginTop: 8
1256
+ }],
1257
+ onPress: () => {
1258
+ setShowRecoveryModal(false);
1259
+ setEditingField(null);
1260
+ _sonner.toast.success(t('editProfile.toasts.twoFactorEnabled') || 'Two‑Factor Authentication enabled');
1261
+ },
1262
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
1263
+ name: "checkmark",
1264
+ size: 18,
1265
+ color: "#fff"
1266
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1267
+ style: styles.primaryButtonText,
1268
+ children: "I saved them"
1269
+ })]
1270
+ })]
1271
+ })
1272
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
976
1273
  style: styles.section,
977
1274
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
978
1275
  style: styles.sectionTitle,
979
- children: "Profile Picture"
1276
+ children: t('editProfile.sections.profilePicture') || 'Profile Picture'
980
1277
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
981
1278
  items: [{
982
1279
  id: 'profile-photo',
@@ -1002,28 +1299,28 @@ const AccountSettingsScreen = ({
1002
1299
  style: styles.section,
1003
1300
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1004
1301
  style: styles.sectionTitle,
1005
- children: "Basic Information"
1302
+ children: t('editProfile.sections.basicInfo') || 'Basic Information'
1006
1303
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
1007
1304
  items: [{
1008
1305
  id: 'display-name',
1009
1306
  icon: 'person',
1010
1307
  iconColor: '#007AFF',
1011
- title: 'Display Name',
1012
- subtitle: [displayName, lastName].filter(Boolean).join(' ') || 'Add your display name',
1308
+ title: t('editProfile.items.displayName.title') || 'Display Name',
1309
+ subtitle: [displayName, lastName].filter(Boolean).join(' ') || t('editProfile.items.displayName.add') || 'Add your display name',
1013
1310
  onPress: () => startEditing('displayName', '')
1014
1311
  }, {
1015
1312
  id: 'username',
1016
1313
  icon: 'at',
1017
1314
  iconColor: '#5856D6',
1018
- title: 'Username',
1019
- subtitle: username || 'Choose a username',
1315
+ title: t('editProfile.items.username.title') || 'Username',
1316
+ subtitle: username || t('editProfile.items.username.choose') || 'Choose a username',
1020
1317
  onPress: () => startEditing('username', username)
1021
1318
  }, {
1022
1319
  id: 'email',
1023
1320
  icon: 'mail',
1024
1321
  iconColor: '#FF9500',
1025
- title: 'Email',
1026
- subtitle: email || 'Add your email address',
1322
+ title: t('editProfile.items.email.title') || 'Email',
1323
+ subtitle: email || t('editProfile.items.email.add') || 'Add your email address',
1027
1324
  onPress: () => startEditing('email', email)
1028
1325
  }],
1029
1326
  theme: theme
@@ -1032,21 +1329,25 @@ const AccountSettingsScreen = ({
1032
1329
  style: styles.section,
1033
1330
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1034
1331
  style: styles.sectionTitle,
1035
- children: "About You"
1332
+ children: t('editProfile.sections.about') || 'About You'
1036
1333
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
1037
1334
  items: [{
1038
1335
  id: 'bio',
1039
1336
  icon: 'document-text',
1040
1337
  iconColor: '#34C759',
1041
- title: 'Bio',
1042
- subtitle: bio || 'Tell people about yourself',
1338
+ title: t('editProfile.items.bio.title') || 'Bio',
1339
+ subtitle: bio || t('editProfile.items.bio.placeholder') || 'Tell people about yourself',
1043
1340
  onPress: () => startEditing('bio', bio)
1044
1341
  }, {
1045
1342
  id: 'locations',
1046
1343
  icon: 'location',
1047
1344
  iconColor: '#FF3B30',
1048
- title: 'Locations',
1049
- subtitle: tempLocations.length > 0 ? `${tempLocations.length} location${tempLocations.length !== 1 ? 's' : ''} added` : 'Add your locations',
1345
+ title: t('editProfile.items.locations.title') || 'Locations',
1346
+ subtitle: tempLocations.length > 0 ? tempLocations.length === 1 ? t('editProfile.items.locations.count', {
1347
+ count: tempLocations.length
1348
+ }) || `${tempLocations.length} location added` : t('editProfile.items.locations.count_plural', {
1349
+ count: tempLocations.length
1350
+ }) || `${tempLocations.length} locations added` : t('editProfile.items.locations.add') || 'Add your locations',
1050
1351
  onPress: () => startEditing('location', ''),
1051
1352
  customContentBelow: tempLocations.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1052
1353
  style: styles.linksPreviewContainer,
@@ -1078,8 +1379,12 @@ const AccountSettingsScreen = ({
1078
1379
  id: 'links',
1079
1380
  icon: 'link',
1080
1381
  iconColor: '#32D74B',
1081
- title: 'Links',
1082
- subtitle: tempLinksWithMetadata.length > 0 ? `${tempLinksWithMetadata.length} link${tempLinksWithMetadata.length !== 1 ? 's' : ''} added` : 'Add your links',
1382
+ title: t('editProfile.items.links.title') || 'Links',
1383
+ subtitle: tempLinksWithMetadata.length > 0 ? tempLinksWithMetadata.length === 1 ? t('editProfile.items.links.count', {
1384
+ count: tempLinksWithMetadata.length
1385
+ }) || `${tempLinksWithMetadata.length} link added` : t('editProfile.items.links.count_plural', {
1386
+ count: tempLinksWithMetadata.length
1387
+ }) || `${tempLinksWithMetadata.length} links added` : t('editProfile.items.links.add') || 'Add your links',
1083
1388
  onPress: () => startEditing('links', ''),
1084
1389
  multiRow: true,
1085
1390
  customContentBelow: tempLinksWithMetadata.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
@@ -1114,14 +1419,14 @@ const AccountSettingsScreen = ({
1114
1419
  style: styles.section,
1115
1420
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1116
1421
  style: styles.sectionTitle,
1117
- children: "Quick Actions"
1422
+ children: t('editProfile.sections.quickActions') || 'Quick Actions'
1118
1423
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
1119
1424
  items: [{
1120
1425
  id: 'preview-profile',
1121
1426
  icon: 'eye',
1122
1427
  iconColor: '#007AFF',
1123
- title: 'Preview Profile',
1124
- subtitle: 'See how your profile looks to others',
1428
+ title: t('editProfile.items.previewProfile.title') || 'Preview Profile',
1429
+ subtitle: t('editProfile.items.previewProfile.subtitle') || 'See how your profile looks to others',
1125
1430
  onPress: () => navigate?.('Profile', {
1126
1431
  userId: user?.id
1127
1432
  })
@@ -1129,16 +1434,32 @@ const AccountSettingsScreen = ({
1129
1434
  id: 'privacy-settings',
1130
1435
  icon: 'shield-checkmark',
1131
1436
  iconColor: '#8E8E93',
1132
- title: 'Privacy Settings',
1133
- subtitle: 'Control who can see your profile',
1134
- onPress: () => _sonner.toast.info('Privacy settings coming soon!')
1437
+ title: t('editProfile.items.privacySettings.title') || 'Privacy Settings',
1438
+ subtitle: t('editProfile.items.privacySettings.subtitle') || 'Control who can see your profile',
1439
+ onPress: () => _sonner.toast.info(t('editProfile.items.privacySettings.coming') || 'Privacy settings coming soon!')
1135
1440
  }, {
1136
1441
  id: 'verify-account',
1137
1442
  icon: 'checkmark-circle',
1138
1443
  iconColor: '#30D158',
1139
- title: 'Verify Account',
1140
- subtitle: 'Get a verified badge',
1141
- onPress: () => _sonner.toast.info('Account verification coming soon!')
1444
+ title: t('editProfile.items.verifyAccount.title') || 'Verify Account',
1445
+ subtitle: t('editProfile.items.verifyAccount.subtitle') || 'Get a verified badge',
1446
+ onPress: () => _sonner.toast.info(t('editProfile.items.verifyAccount.coming') || 'Account verification coming soon!')
1447
+ }],
1448
+ theme: theme
1449
+ })]
1450
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1451
+ style: styles.section,
1452
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1453
+ style: styles.sectionTitle,
1454
+ children: t('editProfile.sections.security') || 'Security'
1455
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
1456
+ items: [{
1457
+ id: 'two-factor',
1458
+ icon: 'shield-checkmark',
1459
+ iconColor: '#007AFF',
1460
+ title: t('editProfile.items.twoFactor.title') || 'Two‑Factor Authentication',
1461
+ subtitle: user?.privacySettings?.twoFactorEnabled ? t('editProfile.items.twoFactor.enabled') || 'Enabled' : t('editProfile.items.twoFactor.disabled') || 'Disabled (recommended)',
1462
+ onPress: () => startEditing('twoFactor', '')
1142
1463
  }],
1143
1464
  theme: theme
1144
1465
  })]
@@ -1222,6 +1543,26 @@ const styles = _reactNative.StyleSheet.create({
1222
1543
  minHeight: 52,
1223
1544
  fontWeight: '400'
1224
1545
  },
1546
+ editingFieldDescription: {
1547
+ fontSize: 14,
1548
+ color: '#666',
1549
+ marginBottom: 16
1550
+ },
1551
+ primaryButton: {
1552
+ flexDirection: 'row',
1553
+ alignItems: 'center',
1554
+ justifyContent: 'center',
1555
+ gap: 8,
1556
+ backgroundColor: '#007AFF',
1557
+ paddingVertical: 12,
1558
+ paddingHorizontal: 16,
1559
+ borderRadius: 10
1560
+ },
1561
+ primaryButtonText: {
1562
+ color: '#fff',
1563
+ fontSize: 16,
1564
+ fontWeight: '600'
1565
+ },
1225
1566
  editingFieldTextArea: {
1226
1567
  backgroundColor: '#fff',
1227
1568
  borderWidth: 2,