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