@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.
- package/README.md +48 -7
- package/lib/commonjs/core/OxyServices.js +162 -12
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/i18n/index.js +40 -0
- package/lib/commonjs/i18n/index.js.map +1 -0
- package/lib/commonjs/i18n/locales/en-US.json +681 -0
- package/lib/commonjs/i18n/locales/es-ES.json +689 -0
- package/lib/commonjs/ui/components/FollowButton.js +1 -1
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/GroupedItem.js +2 -1
- package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
- package/lib/commonjs/ui/components/Header.js +4 -3
- package/lib/commonjs/ui/components/Header.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +112 -105
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileCard.js +5 -1
- package/lib/commonjs/ui/components/ProfileCard.js.map +1 -1
- package/lib/commonjs/ui/components/Section.js +1 -1
- package/lib/commonjs/ui/components/StepBasedScreen.js +17 -17
- package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +15 -3
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +10 -4
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +128 -12
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/useI18n.js +22 -0
- package/lib/commonjs/ui/hooks/useI18n.js.map +1 -0
- package/lib/commonjs/ui/navigation/OxyRouter.js +11 -131
- package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/commonjs/ui/navigation/routes.js +127 -0
- package/lib/commonjs/ui/navigation/routes.js.map +1 -0
- package/lib/commonjs/ui/navigation/types.js +7 -0
- package/lib/commonjs/ui/navigation/types.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +55 -47
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +69 -61
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +378 -37
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +52 -34
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +40 -36
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +105 -78
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +2 -2
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +92 -60
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +21 -11
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js +30 -8
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +47 -26
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +31 -24
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +11 -7
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +12 -6
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +11 -7
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +15 -11
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +19 -27
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +8 -4
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +14 -10
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +7 -3
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +19 -14
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js +130 -0
- package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +13 -13
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +14 -20
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +22 -8
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInTotpStep.js +161 -0
- package/lib/commonjs/ui/screens/steps/SignInTotpStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +12 -6
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +10 -6
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +10 -6
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +34 -4
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +9 -10
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
- package/lib/commonjs/ui/styles/authStyles.js +1 -2
- package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
- package/lib/commonjs/utils/deviceManager.js +1 -1
- package/lib/commonjs/utils/deviceManager.js.map +1 -1
- package/lib/commonjs/utils/validationUtils.js +4 -2
- package/lib/commonjs/utils/validationUtils.js.map +1 -1
- package/lib/module/core/OxyServices.js +162 -12
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/i18n/index.js +35 -0
- package/lib/module/i18n/index.js.map +1 -0
- package/lib/module/i18n/locales/en-US.json +681 -0
- package/lib/module/i18n/locales/es-ES.json +689 -0
- package/lib/module/ui/components/FollowButton.js +1 -1
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/GroupedItem.js +2 -1
- package/lib/module/ui/components/GroupedItem.js.map +1 -1
- package/lib/module/ui/components/Header.js +4 -3
- package/lib/module/ui/components/Header.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +111 -105
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/ProfileCard.js +5 -1
- package/lib/module/ui/components/ProfileCard.js.map +1 -1
- package/lib/module/ui/components/Section.js +1 -1
- package/lib/module/ui/components/StepBasedScreen.js +17 -17
- package/lib/module/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js +15 -3
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +9 -4
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +128 -12
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/useI18n.js +18 -0
- package/lib/module/ui/hooks/useI18n.js.map +1 -0
- package/lib/module/ui/navigation/OxyRouter.js +7 -124
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/module/ui/navigation/routes.js +122 -0
- package/lib/module/ui/navigation/routes.js.map +1 -0
- package/lib/module/ui/navigation/types.js +19 -1
- package/lib/module/ui/navigation/types.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +55 -47
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +69 -61
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +378 -37
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +52 -34
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +40 -36
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +107 -80
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js +2 -2
- package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +92 -60
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +21 -11
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js +30 -8
- package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +47 -26
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/WelcomeNewUserScreen.js +31 -24
- package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +11 -7
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +12 -6
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js +11 -7
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +15 -11
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js +19 -27
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +8 -4
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +14 -10
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js +7 -3
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverRequestStep.js +19 -14
- package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js +125 -0
- package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -0
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js +13 -13
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js +14 -20
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInPasswordStep.js +22 -8
- package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInTotpStep.js +156 -0
- package/lib/module/ui/screens/steps/SignInTotpStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignInUsernameStep.js +12 -6
- package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js +10 -6
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js +10 -6
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js +34 -4
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +9 -10
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
- package/lib/module/ui/styles/authStyles.js +1 -2
- package/lib/module/ui/styles/authStyles.js.map +1 -1
- package/lib/module/utils/deviceManager.js +1 -1
- package/lib/module/utils/deviceManager.js.map +1 -1
- package/lib/module/utils/validationUtils.js +4 -2
- package/lib/module/utils/validationUtils.js.map +1 -1
- package/lib/typescript/core/OxyServices.d.ts +57 -3
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/i18n/index.d.ts +4 -0
- package/lib/typescript/i18n/index.d.ts.map +1 -0
- package/lib/typescript/models/interfaces.d.ts +4 -0
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
- package/lib/typescript/ui/components/Header.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -1
- package/lib/typescript/ui/components/StepBasedScreen.d.ts +2 -1
- package/lib/typescript/ui/components/StepBasedScreen.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts +6 -3
- package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +7 -4
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useI18n.d.ts +5 -0
- package/lib/typescript/ui/hooks/useI18n.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/routes.d.ts +9 -0
- package/lib/typescript/ui/navigation/routes.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/types.d.ts +24 -10
- package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +2 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts +4 -1
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts +24 -0
- package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts +3 -1
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +1 -0
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts +19 -0
- package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -1
- package/lib/typescript/ui/styles/authStyles.d.ts +0 -1
- package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -1
- package/lib/typescript/utils/validationUtils.d.ts.map +1 -1
- package/package.json +49 -15
- package/src/core/OxyServices.ts +138 -19
- package/src/i18n/index.ts +39 -0
- package/src/i18n/locales/en-US.json +681 -0
- package/src/i18n/locales/es-ES.json +689 -0
- package/src/models/interfaces.ts +6 -1
- package/src/ui/components/FollowButton.tsx +2 -2
- package/src/ui/components/GroupedItem.tsx +2 -1
- package/src/ui/components/Header.tsx +4 -3
- package/src/ui/components/OxyProvider.tsx +107 -114
- package/src/ui/components/ProfileCard.tsx +5 -1
- package/src/ui/components/Section.tsx +1 -1
- package/src/ui/components/StepBasedScreen.tsx +17 -14
- package/src/ui/components/internal/GroupedPillButtons.tsx +10 -6
- package/src/ui/components/internal/PinInput.tsx +15 -6
- package/src/ui/context/OxyContext.tsx +123 -20
- package/src/ui/hooks/useI18n.ts +12 -0
- package/src/ui/navigation/OxyRouter.tsx +15 -134
- package/src/ui/navigation/routes.ts +153 -0
- package/src/ui/navigation/types.ts +28 -10
- package/src/ui/screens/AccountCenterScreen.tsx +47 -45
- package/src/ui/screens/AccountOverviewScreen.tsx +68 -70
- package/src/ui/screens/AccountSettingsScreen.tsx +265 -41
- package/src/ui/screens/AccountSwitcherScreen.tsx +35 -33
- package/src/ui/screens/FeedbackScreen.tsx +39 -37
- package/src/ui/screens/LanguageSelectorScreen.tsx +99 -70
- package/src/ui/screens/PaymentGatewayScreen.tsx +6 -6
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +56 -54
- package/src/ui/screens/ProfileScreen.tsx +14 -8
- package/src/ui/screens/RecoverAccountScreen.tsx +29 -8
- package/src/ui/screens/SignInScreen.tsx +39 -30
- package/src/ui/screens/WelcomeNewUserScreen.tsx +31 -17
- package/src/ui/screens/internal/SignInPasswordStep.tsx +11 -8
- package/src/ui/screens/internal/SignInUsernameStep.tsx +10 -8
- package/src/ui/screens/karma/KarmaAboutScreen.tsx +23 -11
- package/src/ui/screens/karma/KarmaCenterScreen.tsx +21 -11
- package/src/ui/screens/karma/KarmaFAQScreen.tsx +15 -33
- package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +6 -4
- package/src/ui/screens/karma/KarmaRewardsScreen.tsx +28 -10
- package/src/ui/screens/karma/KarmaRulesScreen.tsx +5 -3
- package/src/ui/screens/steps/RecoverRequestStep.tsx +20 -17
- package/src/ui/screens/steps/RecoverResetPasswordStep.tsx +133 -0
- package/src/ui/screens/steps/RecoverSuccessStep.tsx +12 -19
- package/src/ui/screens/steps/RecoverVerifyStep.tsx +15 -24
- package/src/ui/screens/steps/SignInPasswordStep.tsx +19 -6
- package/src/ui/screens/steps/SignInTotpStep.tsx +129 -0
- package/src/ui/screens/steps/SignInUsernameStep.tsx +11 -10
- package/src/ui/screens/steps/SignUpIdentityStep.tsx +10 -11
- package/src/ui/screens/steps/SignUpSecurityStep.tsx +10 -11
- package/src/ui/screens/steps/SignUpSummaryStep.tsx +24 -9
- package/src/ui/screens/steps/SignUpWelcomeStep.tsx +8 -14
- package/src/ui/styles/authStyles.ts +0 -1
- package/src/utils/deviceManager.ts +1 -1
- package/src/utils/validationUtils.ts +5 -3
|
@@ -23,6 +23,8 @@ import { fontFamilies } from '../styles/fonts';
|
|
|
23
23
|
import { confirmAction } from '../utils/confirmAction';
|
|
24
24
|
import { useAuthStore } from '../stores/authStore';
|
|
25
25
|
import { Header, GroupedSection } from '../components';
|
|
26
|
+
import { useI18n } from '../hooks/useI18n';
|
|
27
|
+
import QRCode from 'react-native-qrcode-svg';
|
|
26
28
|
|
|
27
29
|
const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
28
30
|
onClose,
|
|
@@ -30,11 +32,20 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
30
32
|
goBack,
|
|
31
33
|
navigate,
|
|
32
34
|
}) => {
|
|
33
|
-
const { user, oxyServices, isLoading: authLoading, isAuthenticated, showBottomSheet } = useOxy();
|
|
35
|
+
const { user, oxyServices, isLoading: authLoading, isAuthenticated, showBottomSheet, activeSessionId } = useOxy();
|
|
36
|
+
const { t } = useI18n();
|
|
34
37
|
const updateUser = useAuthStore((state) => state.updateUser);
|
|
35
38
|
const [isLoading, setIsLoading] = useState(false);
|
|
36
39
|
const [isSaving, setIsSaving] = useState(false);
|
|
37
40
|
|
|
41
|
+
// Two-Factor (TOTP) state
|
|
42
|
+
const [totpSetupUrl, setTotpSetupUrl] = useState<string | null>(null);
|
|
43
|
+
const [totpCode, setTotpCode] = useState('');
|
|
44
|
+
const [isTotpBusy, setIsTotpBusy] = useState(false);
|
|
45
|
+
const [showRecoveryModal, setShowRecoveryModal] = useState(false);
|
|
46
|
+
const [generatedBackupCodes, setGeneratedBackupCodes] = useState<string[] | null>(null);
|
|
47
|
+
const [generatedRecoveryKey, setGeneratedRecoveryKey] = useState<string | null>(null);
|
|
48
|
+
|
|
38
49
|
// Animation refs
|
|
39
50
|
const saveButtonScale = useRef(new Animated.Value(1)).current;
|
|
40
51
|
|
|
@@ -209,7 +220,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
209
220
|
}
|
|
210
221
|
|
|
211
222
|
await updateUser(updates, oxyServices);
|
|
212
|
-
toast.success('Profile updated successfully');
|
|
223
|
+
toast.success(t('editProfile.toasts.profileUpdated') || 'Profile updated successfully');
|
|
213
224
|
|
|
214
225
|
animateSaveButton(1); // Scale back to normal
|
|
215
226
|
|
|
@@ -219,7 +230,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
219
230
|
goBack();
|
|
220
231
|
}
|
|
221
232
|
} catch (error: any) {
|
|
222
|
-
toast.error(error.message || 'Failed to update profile');
|
|
233
|
+
toast.error(error.message || t('editProfile.toasts.updateFailed') || 'Failed to update profile');
|
|
223
234
|
animateSaveButton(1); // Scale back to normal on error
|
|
224
235
|
} finally {
|
|
225
236
|
setIsSaving(false);
|
|
@@ -227,9 +238,9 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
227
238
|
};
|
|
228
239
|
|
|
229
240
|
const handleAvatarRemove = () => {
|
|
230
|
-
confirmAction('Remove your profile picture?', () => {
|
|
241
|
+
confirmAction(t('editProfile.confirms.removeAvatar') || 'Remove your profile picture?', () => {
|
|
231
242
|
setAvatarFileId('');
|
|
232
|
-
toast.success('Avatar removed');
|
|
243
|
+
toast.success(t('editProfile.toasts.avatarRemoved') || 'Avatar removed');
|
|
233
244
|
});
|
|
234
245
|
};
|
|
235
246
|
|
|
@@ -242,16 +253,16 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
242
253
|
afterSelect: 'back',
|
|
243
254
|
onSelect: (file: FileMetadata) => {
|
|
244
255
|
if (!file.contentType.startsWith('image/')) {
|
|
245
|
-
toast.error('Please select an image file');
|
|
256
|
+
toast.error(t('editProfile.toasts.selectImage') || 'Please select an image file');
|
|
246
257
|
return;
|
|
247
258
|
}
|
|
248
259
|
// If already selected, do nothing
|
|
249
260
|
if (file.id === avatarFileId) {
|
|
250
|
-
toast.info?.('Avatar unchanged');
|
|
261
|
+
toast.info?.(t('editProfile.toasts.avatarUnchanged') || 'Avatar unchanged');
|
|
251
262
|
return;
|
|
252
263
|
}
|
|
253
264
|
setAvatarFileId(file.id);
|
|
254
|
-
toast.success('Avatar selected');
|
|
265
|
+
toast.success(t('editProfile.toasts.avatarSelected') || 'Avatar selected');
|
|
255
266
|
// Auto-save avatar immediately (does not close edit profile screen)
|
|
256
267
|
(async () => {
|
|
257
268
|
try {
|
|
@@ -260,10 +271,10 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
260
271
|
await updateUser({ avatar: file.id }, oxyServices);
|
|
261
272
|
// Force refresh current user cache (updateUser already does a fetch with force=true internally)
|
|
262
273
|
// Extra safeguard: ensure avatarFileId reflects saved id (already set) and trigger any dependent UI.
|
|
263
|
-
toast.success('Avatar updated');
|
|
274
|
+
toast.success(t('editProfile.toasts.avatarUpdated') || 'Avatar updated');
|
|
264
275
|
} catch (e: any) {
|
|
265
276
|
console.error('[AccountSettings] Failed to auto-save avatar', e);
|
|
266
|
-
toast.error(e.message || 'Failed to update avatar');
|
|
277
|
+
toast.error(e.message || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
|
|
267
278
|
} finally {
|
|
268
279
|
setIsSaving(false);
|
|
269
280
|
}
|
|
@@ -297,6 +308,11 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
297
308
|
// Don't reset the metadata - keep the existing rich metadata
|
|
298
309
|
// The tempLinksWithMetadata should already contain the rich data from the database
|
|
299
310
|
break;
|
|
311
|
+
case 'twoFactor':
|
|
312
|
+
// Reset TOTP temp state
|
|
313
|
+
setTotpSetupUrl(null);
|
|
314
|
+
setTotpCode('');
|
|
315
|
+
break;
|
|
300
316
|
}
|
|
301
317
|
setEditingField(type);
|
|
302
318
|
};
|
|
@@ -457,6 +473,131 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
457
473
|
};
|
|
458
474
|
|
|
459
475
|
const renderEditingField = (type: string) => {
|
|
476
|
+
if (type === 'twoFactor') {
|
|
477
|
+
const enabled = !!user?.privacySettings?.twoFactorEnabled;
|
|
478
|
+
return (
|
|
479
|
+
<View style={[styles.editingFieldContainer, { backgroundColor: themeStyles.backgroundColor }]}>
|
|
480
|
+
<View style={styles.editingFieldContent}>
|
|
481
|
+
<View style={styles.newValueSection}>
|
|
482
|
+
<View style={styles.editingFieldHeader}>
|
|
483
|
+
<Text style={[styles.editingFieldLabel, { color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A' }]}>Two‑Factor Authentication (TOTP)</Text>
|
|
484
|
+
</View>
|
|
485
|
+
|
|
486
|
+
{!enabled ? (
|
|
487
|
+
<>
|
|
488
|
+
<Text style={styles.editingFieldDescription}>
|
|
489
|
+
Protect your account with a 6‑digit code from an authenticator app. Scan the QR code then enter the code to enable.
|
|
490
|
+
</Text>
|
|
491
|
+
{!totpSetupUrl ? (
|
|
492
|
+
<TouchableOpacity
|
|
493
|
+
style={styles.primaryButton}
|
|
494
|
+
disabled={isTotpBusy}
|
|
495
|
+
onPress={async () => {
|
|
496
|
+
if (!activeSessionId) { toast.error(t('editProfile.toasts.noActiveSession') || 'No active session'); return; }
|
|
497
|
+
setIsTotpBusy(true);
|
|
498
|
+
try {
|
|
499
|
+
const { otpauthUrl } = await oxyServices.startTotpEnrollment(activeSessionId);
|
|
500
|
+
setTotpSetupUrl(otpauthUrl);
|
|
501
|
+
} catch (e: any) {
|
|
502
|
+
toast.error(e?.message || (t('editProfile.toasts.totpStartFailed') || 'Failed to start TOTP enrollment'));
|
|
503
|
+
} finally {
|
|
504
|
+
setIsTotpBusy(false);
|
|
505
|
+
}
|
|
506
|
+
}}
|
|
507
|
+
>
|
|
508
|
+
<Ionicons name="shield-checkmark" size={18} color="#fff" />
|
|
509
|
+
<Text style={styles.primaryButtonText}>Generate QR Code</Text>
|
|
510
|
+
</TouchableOpacity>
|
|
511
|
+
) : (
|
|
512
|
+
<View style={{ alignItems: 'center', gap: 16 }}>
|
|
513
|
+
<View style={{ padding: 16, backgroundColor: '#fff', borderRadius: 12 }}>
|
|
514
|
+
<QRCode value={totpSetupUrl} size={180} />
|
|
515
|
+
</View>
|
|
516
|
+
<View>
|
|
517
|
+
<Text style={styles.editingFieldLabel}>Enter 6‑digit code</Text>
|
|
518
|
+
<TextInput
|
|
519
|
+
style={styles.editingFieldInput}
|
|
520
|
+
keyboardType="number-pad"
|
|
521
|
+
placeholder="123456"
|
|
522
|
+
value={totpCode}
|
|
523
|
+
onChangeText={setTotpCode}
|
|
524
|
+
maxLength={6}
|
|
525
|
+
/>
|
|
526
|
+
</View>
|
|
527
|
+
<TouchableOpacity
|
|
528
|
+
style={styles.primaryButton}
|
|
529
|
+
disabled={isTotpBusy || totpCode.length !== 6}
|
|
530
|
+
onPress={async () => {
|
|
531
|
+
if (!activeSessionId) { toast.error(t('editProfile.toasts.noActiveSession') || 'No active session'); return; }
|
|
532
|
+
setIsTotpBusy(true);
|
|
533
|
+
try {
|
|
534
|
+
const result = await oxyServices.verifyTotpEnrollment(activeSessionId, totpCode);
|
|
535
|
+
await updateUser({ privacySettings: { twoFactorEnabled: true } }, oxyServices);
|
|
536
|
+
if (result?.backupCodes || result?.recoveryKey) {
|
|
537
|
+
setGeneratedBackupCodes(result.backupCodes || null);
|
|
538
|
+
setGeneratedRecoveryKey(result.recoveryKey || null);
|
|
539
|
+
setShowRecoveryModal(true);
|
|
540
|
+
} else {
|
|
541
|
+
toast.success(t('editProfile.toasts.twoFactorEnabled') || 'Two‑Factor Authentication enabled');
|
|
542
|
+
setEditingField(null);
|
|
543
|
+
}
|
|
544
|
+
} catch (e: any) {
|
|
545
|
+
toast.error(e?.message || (t('editProfile.toasts.invalidCode') || 'Invalid code'));
|
|
546
|
+
} finally {
|
|
547
|
+
setIsTotpBusy(false);
|
|
548
|
+
}
|
|
549
|
+
}}
|
|
550
|
+
>
|
|
551
|
+
<Ionicons name="checkmark-circle" size={18} color="#fff" />
|
|
552
|
+
<Text style={styles.primaryButtonText}>Verify & Enable</Text>
|
|
553
|
+
</TouchableOpacity>
|
|
554
|
+
</View>
|
|
555
|
+
)}
|
|
556
|
+
</>
|
|
557
|
+
) : (
|
|
558
|
+
<>
|
|
559
|
+
<Text style={styles.editingFieldDescription}>
|
|
560
|
+
Two‑Factor Authentication is currently enabled. To disable, enter a code from your authenticator app.
|
|
561
|
+
</Text>
|
|
562
|
+
<View>
|
|
563
|
+
<Text style={styles.editingFieldLabel}>Enter 6‑digit code</Text>
|
|
564
|
+
<TextInput
|
|
565
|
+
style={styles.editingFieldInput}
|
|
566
|
+
keyboardType="number-pad"
|
|
567
|
+
placeholder="123456"
|
|
568
|
+
value={totpCode}
|
|
569
|
+
onChangeText={setTotpCode}
|
|
570
|
+
maxLength={6}
|
|
571
|
+
/>
|
|
572
|
+
</View>
|
|
573
|
+
<TouchableOpacity
|
|
574
|
+
style={[styles.primaryButton, { backgroundColor: '#d9534f' }]}
|
|
575
|
+
disabled={isTotpBusy || totpCode.length !== 6}
|
|
576
|
+
onPress={async () => {
|
|
577
|
+
if (!activeSessionId) { toast.error(t('editProfile.toasts.noActiveSession') || 'No active session'); return; }
|
|
578
|
+
setIsTotpBusy(true);
|
|
579
|
+
try {
|
|
580
|
+
await oxyServices.disableTotp(activeSessionId, totpCode);
|
|
581
|
+
await updateUser({ privacySettings: { twoFactorEnabled: false } }, oxyServices);
|
|
582
|
+
toast.success(t('editProfile.toasts.twoFactorDisabled') || 'Two‑Factor Authentication disabled');
|
|
583
|
+
setEditingField(null);
|
|
584
|
+
} catch (e: any) {
|
|
585
|
+
toast.error(e?.message || t('editProfile.toasts.disableFailed') || 'Failed to disable');
|
|
586
|
+
} finally {
|
|
587
|
+
setIsTotpBusy(false);
|
|
588
|
+
}
|
|
589
|
+
}}
|
|
590
|
+
>
|
|
591
|
+
<Ionicons name="close-circle" size={18} color="#fff" />
|
|
592
|
+
<Text style={styles.primaryButtonText}>Disable 2FA</Text>
|
|
593
|
+
</TouchableOpacity>
|
|
594
|
+
</>
|
|
595
|
+
)}
|
|
596
|
+
</View>
|
|
597
|
+
</View>
|
|
598
|
+
</View>
|
|
599
|
+
);
|
|
600
|
+
}
|
|
460
601
|
if (type === 'displayName') {
|
|
461
602
|
return (
|
|
462
603
|
<View style={[styles.editingFieldContainer, { backgroundColor: themeStyles.backgroundColor }]}>
|
|
@@ -877,18 +1018,18 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
877
1018
|
style={styles.editingBottomIcon}
|
|
878
1019
|
/>
|
|
879
1020
|
<Text style={[styles.editingBottomTitle, { color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A' }]}>
|
|
880
|
-
{editingField === 'displayName' ? 'Display Name' :
|
|
881
|
-
editingField === 'username' ? 'Username' :
|
|
882
|
-
editingField === 'email' ? 'Email' :
|
|
883
|
-
editingField === 'bio' ? 'Bio' :
|
|
884
|
-
editingField === 'location' ? 'Location' :
|
|
885
|
-
editingField === 'links' ? 'Links' : 'Field'}
|
|
1021
|
+
{editingField === 'displayName' ? (t('editProfile.items.displayName.title') || 'Display Name') :
|
|
1022
|
+
editingField === 'username' ? (t('editProfile.items.username.title') || 'Username') :
|
|
1023
|
+
editingField === 'email' ? (t('editProfile.items.email.title') || 'Email') :
|
|
1024
|
+
editingField === 'bio' ? (t('editProfile.items.bio.title') || 'Bio') :
|
|
1025
|
+
editingField === 'location' ? (t('editProfile.items.locations.title') || 'Location') :
|
|
1026
|
+
editingField === 'links' ? (t('editProfile.items.links.title') || 'Links') : 'Field'}
|
|
886
1027
|
</Text>
|
|
887
1028
|
</View>
|
|
888
1029
|
</View>
|
|
889
1030
|
) : (
|
|
890
1031
|
<Header
|
|
891
|
-
title=
|
|
1032
|
+
title={t('editProfile.title') || 'Edit Profile'}
|
|
892
1033
|
theme={theme}
|
|
893
1034
|
onBack={goBack || onClose}
|
|
894
1035
|
rightAction={{
|
|
@@ -910,9 +1051,44 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
910
1051
|
) : (
|
|
911
1052
|
// Show all settings when not editing
|
|
912
1053
|
<>
|
|
1054
|
+
{showRecoveryModal && (
|
|
1055
|
+
<View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.6)', zIndex: 50, padding: 16, justifyContent: 'center' }}>
|
|
1056
|
+
<View style={{ backgroundColor: '#fff', borderRadius: 16, padding: 20, maxHeight: '80%' }}>
|
|
1057
|
+
<Text style={{ fontSize: 18, fontWeight: '700', marginBottom: 12 }}>Save These Codes Now</Text>
|
|
1058
|
+
<Text style={{ fontSize: 14, color: '#444', marginBottom: 12 }}>
|
|
1059
|
+
Backup codes and your Recovery Key are shown only once. Store them securely (paper or password manager).
|
|
1060
|
+
</Text>
|
|
1061
|
+
{generatedBackupCodes && generatedBackupCodes.length > 0 && (
|
|
1062
|
+
<View style={{ marginBottom: 12 }}>
|
|
1063
|
+
<Text style={{ fontSize: 16, fontWeight: '600', marginBottom: 8 }}>Backup Codes</Text>
|
|
1064
|
+
<View style={{ backgroundColor: '#F8F9FA', borderRadius: 8, padding: 12 }}>
|
|
1065
|
+
{generatedBackupCodes.map((c, idx) => (
|
|
1066
|
+
<Text key={idx} style={{ fontFamily: Platform.OS === 'web' ? 'monospace' as any : 'monospace', fontSize: 14, marginBottom: 4 }}>{c}</Text>
|
|
1067
|
+
))}
|
|
1068
|
+
</View>
|
|
1069
|
+
</View>
|
|
1070
|
+
)}
|
|
1071
|
+
{generatedRecoveryKey && (
|
|
1072
|
+
<View style={{ marginBottom: 12 }}>
|
|
1073
|
+
<Text style={{ fontSize: 16, fontWeight: '600', marginBottom: 8 }}>Recovery Key</Text>
|
|
1074
|
+
<View style={{ backgroundColor: '#F8F9FA', borderRadius: 8, padding: 12 }}>
|
|
1075
|
+
<Text style={{ fontFamily: Platform.OS === 'web' ? 'monospace' as any : 'monospace', fontSize: 14 }}>{generatedRecoveryKey}</Text>
|
|
1076
|
+
</View>
|
|
1077
|
+
</View>
|
|
1078
|
+
)}
|
|
1079
|
+
<TouchableOpacity
|
|
1080
|
+
style={[styles.primaryButton, { alignSelf: 'flex-end', marginTop: 8 }]}
|
|
1081
|
+
onPress={() => { setShowRecoveryModal(false); setEditingField(null); toast.success(t('editProfile.toasts.twoFactorEnabled') || 'Two‑Factor Authentication enabled'); }}
|
|
1082
|
+
>
|
|
1083
|
+
<Ionicons name="checkmark" size={18} color="#fff" />
|
|
1084
|
+
<Text style={styles.primaryButtonText}>I saved them</Text>
|
|
1085
|
+
</TouchableOpacity>
|
|
1086
|
+
</View>
|
|
1087
|
+
</View>
|
|
1088
|
+
)}
|
|
913
1089
|
{/* Profile Picture Section */}
|
|
914
1090
|
<View style={styles.section}>
|
|
915
|
-
<Text style={styles.sectionTitle}>Profile Picture</Text>
|
|
1091
|
+
<Text style={styles.sectionTitle}>{t('editProfile.sections.profilePicture') || 'Profile Picture'}</Text>
|
|
916
1092
|
<GroupedSection
|
|
917
1093
|
items={[
|
|
918
1094
|
{
|
|
@@ -943,7 +1119,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
943
1119
|
|
|
944
1120
|
{/* Basic Information */}
|
|
945
1121
|
<View style={styles.section}>
|
|
946
|
-
<Text style={styles.sectionTitle}>Basic Information</Text>
|
|
1122
|
+
<Text style={styles.sectionTitle}>{t('editProfile.sections.basicInfo') || 'Basic Information'}</Text>
|
|
947
1123
|
|
|
948
1124
|
<GroupedSection
|
|
949
1125
|
items={[
|
|
@@ -951,24 +1127,24 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
951
1127
|
id: 'display-name',
|
|
952
1128
|
icon: 'person',
|
|
953
1129
|
iconColor: '#007AFF',
|
|
954
|
-
title: 'Display Name',
|
|
955
|
-
subtitle: [displayName, lastName].filter(Boolean).join(' ') || 'Add your display name',
|
|
1130
|
+
title: t('editProfile.items.displayName.title') || 'Display Name',
|
|
1131
|
+
subtitle: [displayName, lastName].filter(Boolean).join(' ') || (t('editProfile.items.displayName.add') || 'Add your display name'),
|
|
956
1132
|
onPress: () => startEditing('displayName', ''),
|
|
957
1133
|
},
|
|
958
1134
|
{
|
|
959
1135
|
id: 'username',
|
|
960
1136
|
icon: 'at',
|
|
961
1137
|
iconColor: '#5856D6',
|
|
962
|
-
title: 'Username',
|
|
963
|
-
subtitle: username || 'Choose a username',
|
|
1138
|
+
title: t('editProfile.items.username.title') || 'Username',
|
|
1139
|
+
subtitle: username || (t('editProfile.items.username.choose') || 'Choose a username'),
|
|
964
1140
|
onPress: () => startEditing('username', username),
|
|
965
1141
|
},
|
|
966
1142
|
{
|
|
967
1143
|
id: 'email',
|
|
968
1144
|
icon: 'mail',
|
|
969
1145
|
iconColor: '#FF9500',
|
|
970
|
-
title: 'Email',
|
|
971
|
-
subtitle: email || 'Add your email address',
|
|
1146
|
+
title: t('editProfile.items.email.title') || 'Email',
|
|
1147
|
+
subtitle: email || (t('editProfile.items.email.add') || 'Add your email address'),
|
|
972
1148
|
onPress: () => startEditing('email', email),
|
|
973
1149
|
},
|
|
974
1150
|
]}
|
|
@@ -978,7 +1154,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
978
1154
|
|
|
979
1155
|
{/* About You */}
|
|
980
1156
|
<View style={styles.section}>
|
|
981
|
-
<Text style={styles.sectionTitle}>About You</Text>
|
|
1157
|
+
<Text style={styles.sectionTitle}>{t('editProfile.sections.about') || 'About You'}</Text>
|
|
982
1158
|
|
|
983
1159
|
<GroupedSection
|
|
984
1160
|
items={[
|
|
@@ -986,16 +1162,20 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
986
1162
|
id: 'bio',
|
|
987
1163
|
icon: 'document-text',
|
|
988
1164
|
iconColor: '#34C759',
|
|
989
|
-
title: 'Bio',
|
|
990
|
-
subtitle: bio || 'Tell people about yourself',
|
|
1165
|
+
title: t('editProfile.items.bio.title') || 'Bio',
|
|
1166
|
+
subtitle: bio || (t('editProfile.items.bio.placeholder') || 'Tell people about yourself'),
|
|
991
1167
|
onPress: () => startEditing('bio', bio),
|
|
992
1168
|
},
|
|
993
1169
|
{
|
|
994
1170
|
id: 'locations',
|
|
995
1171
|
icon: 'location',
|
|
996
1172
|
iconColor: '#FF3B30',
|
|
997
|
-
title: 'Locations',
|
|
998
|
-
subtitle: tempLocations.length > 0
|
|
1173
|
+
title: t('editProfile.items.locations.title') || 'Locations',
|
|
1174
|
+
subtitle: tempLocations.length > 0
|
|
1175
|
+
? (tempLocations.length === 1
|
|
1176
|
+
? (t('editProfile.items.locations.count', { count: tempLocations.length }) || `${tempLocations.length} location added`)
|
|
1177
|
+
: (t('editProfile.items.locations.count_plural', { count: tempLocations.length }) || `${tempLocations.length} locations added`))
|
|
1178
|
+
: (t('editProfile.items.locations.add') || 'Add your locations'),
|
|
999
1179
|
onPress: () => startEditing('location', ''),
|
|
1000
1180
|
customContentBelow: tempLocations.length > 0 && (
|
|
1001
1181
|
<View style={styles.linksPreviewContainer}>
|
|
@@ -1030,8 +1210,12 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
1030
1210
|
id: 'links',
|
|
1031
1211
|
icon: 'link',
|
|
1032
1212
|
iconColor: '#32D74B',
|
|
1033
|
-
title: 'Links',
|
|
1034
|
-
subtitle: tempLinksWithMetadata.length > 0
|
|
1213
|
+
title: t('editProfile.items.links.title') || 'Links',
|
|
1214
|
+
subtitle: tempLinksWithMetadata.length > 0
|
|
1215
|
+
? (tempLinksWithMetadata.length === 1
|
|
1216
|
+
? (t('editProfile.items.links.count', { count: tempLinksWithMetadata.length }) || `${tempLinksWithMetadata.length} link added`)
|
|
1217
|
+
: (t('editProfile.items.links.count_plural', { count: tempLinksWithMetadata.length }) || `${tempLinksWithMetadata.length} links added`))
|
|
1218
|
+
: (t('editProfile.items.links.add') || 'Add your links'),
|
|
1035
1219
|
onPress: () => startEditing('links', ''),
|
|
1036
1220
|
multiRow: true,
|
|
1037
1221
|
customContentBelow: tempLinksWithMetadata.length > 0 && (
|
|
@@ -1067,7 +1251,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
1067
1251
|
|
|
1068
1252
|
{/* Quick Actions */}
|
|
1069
1253
|
<View style={styles.section}>
|
|
1070
|
-
<Text style={styles.sectionTitle}>Quick Actions</Text>
|
|
1254
|
+
<Text style={styles.sectionTitle}>{t('editProfile.sections.quickActions') || 'Quick Actions'}</Text>
|
|
1071
1255
|
|
|
1072
1256
|
<GroupedSection
|
|
1073
1257
|
items={[
|
|
@@ -1075,25 +1259,45 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
1075
1259
|
id: 'preview-profile',
|
|
1076
1260
|
icon: 'eye',
|
|
1077
1261
|
iconColor: '#007AFF',
|
|
1078
|
-
title: 'Preview Profile',
|
|
1079
|
-
subtitle: 'See how your profile looks to others',
|
|
1262
|
+
title: t('editProfile.items.previewProfile.title') || 'Preview Profile',
|
|
1263
|
+
subtitle: t('editProfile.items.previewProfile.subtitle') || 'See how your profile looks to others',
|
|
1080
1264
|
onPress: () => navigate?.('Profile', { userId: user?.id }),
|
|
1081
1265
|
},
|
|
1082
1266
|
{
|
|
1083
1267
|
id: 'privacy-settings',
|
|
1084
1268
|
icon: 'shield-checkmark',
|
|
1085
1269
|
iconColor: '#8E8E93',
|
|
1086
|
-
title: 'Privacy Settings',
|
|
1087
|
-
subtitle: 'Control who can see your profile',
|
|
1088
|
-
onPress: () => toast.info('Privacy settings coming soon!'),
|
|
1270
|
+
title: t('editProfile.items.privacySettings.title') || 'Privacy Settings',
|
|
1271
|
+
subtitle: t('editProfile.items.privacySettings.subtitle') || 'Control who can see your profile',
|
|
1272
|
+
onPress: () => toast.info(t('editProfile.items.privacySettings.coming') || 'Privacy settings coming soon!'),
|
|
1089
1273
|
},
|
|
1090
1274
|
{
|
|
1091
1275
|
id: 'verify-account',
|
|
1092
1276
|
icon: 'checkmark-circle',
|
|
1093
1277
|
iconColor: '#30D158',
|
|
1094
|
-
title: 'Verify Account',
|
|
1095
|
-
subtitle: 'Get a verified badge',
|
|
1096
|
-
onPress: () => toast.info('Account verification coming soon!'),
|
|
1278
|
+
title: t('editProfile.items.verifyAccount.title') || 'Verify Account',
|
|
1279
|
+
subtitle: t('editProfile.items.verifyAccount.subtitle') || 'Get a verified badge',
|
|
1280
|
+
onPress: () => toast.info(t('editProfile.items.verifyAccount.coming') || 'Account verification coming soon!'),
|
|
1281
|
+
},
|
|
1282
|
+
]}
|
|
1283
|
+
theme={theme}
|
|
1284
|
+
/>
|
|
1285
|
+
</View>
|
|
1286
|
+
|
|
1287
|
+
{/* Security */}
|
|
1288
|
+
<View style={styles.section}>
|
|
1289
|
+
<Text style={styles.sectionTitle}>{t('editProfile.sections.security') || 'Security'}</Text>
|
|
1290
|
+
<GroupedSection
|
|
1291
|
+
items={[
|
|
1292
|
+
{
|
|
1293
|
+
id: 'two-factor',
|
|
1294
|
+
icon: 'shield-checkmark',
|
|
1295
|
+
iconColor: '#007AFF',
|
|
1296
|
+
title: t('editProfile.items.twoFactor.title') || 'Two‑Factor Authentication',
|
|
1297
|
+
subtitle: user?.privacySettings?.twoFactorEnabled
|
|
1298
|
+
? (t('editProfile.items.twoFactor.enabled') || 'Enabled')
|
|
1299
|
+
: (t('editProfile.items.twoFactor.disabled') || 'Disabled (recommended)'),
|
|
1300
|
+
onPress: () => startEditing('twoFactor', ''),
|
|
1097
1301
|
},
|
|
1098
1302
|
]}
|
|
1099
1303
|
theme={theme}
|
|
@@ -1183,6 +1387,26 @@ const styles = StyleSheet.create({
|
|
|
1183
1387
|
minHeight: 52,
|
|
1184
1388
|
fontWeight: '400',
|
|
1185
1389
|
},
|
|
1390
|
+
editingFieldDescription: {
|
|
1391
|
+
fontSize: 14,
|
|
1392
|
+
color: '#666',
|
|
1393
|
+
marginBottom: 16,
|
|
1394
|
+
},
|
|
1395
|
+
primaryButton: {
|
|
1396
|
+
flexDirection: 'row',
|
|
1397
|
+
alignItems: 'center',
|
|
1398
|
+
justifyContent: 'center',
|
|
1399
|
+
gap: 8,
|
|
1400
|
+
backgroundColor: '#007AFF',
|
|
1401
|
+
paddingVertical: 12,
|
|
1402
|
+
paddingHorizontal: 16,
|
|
1403
|
+
borderRadius: 10,
|
|
1404
|
+
},
|
|
1405
|
+
primaryButtonText: {
|
|
1406
|
+
color: '#fff',
|
|
1407
|
+
fontSize: 16,
|
|
1408
|
+
fontWeight: '600',
|
|
1409
|
+
},
|
|
1186
1410
|
editingFieldTextArea: {
|
|
1187
1411
|
backgroundColor: '#fff',
|
|
1188
1412
|
borderWidth: 2,
|