@umituz/react-native-settings 4.23.97 → 4.23.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/package.json +1 -1
  2. package/src/domains/about/domain/entities/AppInfo.ts +1 -0
  3. package/src/domains/about/presentation/components/AboutContent.tsx +6 -6
  4. package/src/domains/about/presentation/screens/AboutScreen.tsx +2 -4
  5. package/src/domains/appearance/presentation/screens/AppearanceScreen.tsx +9 -12
  6. package/src/domains/disclaimer/presentation/components/DisclaimerSetting.tsx +9 -20
  7. package/src/domains/disclaimer/presentation/screens/DisclaimerScreen.tsx +2 -6
  8. package/src/domains/gamification/types/index.ts +12 -12
  9. package/src/domains/localization/presentation/components/LanguageSection.tsx +3 -3
  10. package/src/domains/localization/presentation/screens/LanguageSelectionScreen.tsx +1 -1
  11. package/src/domains/notifications/presentation/components/NotificationsSection.tsx +2 -4
  12. package/src/domains/notifications/presentation/screens/NotificationSettingsScreen.tsx +1 -3
  13. package/src/infrastructure/utils/configFactory.ts +3 -14
  14. package/src/presentation/hooks/useSettingsScreenConfig.ts +27 -12
  15. package/src/presentation/navigation/SettingsStackNavigator.tsx +9 -8
  16. package/src/presentation/navigation/hooks/useNavigationHandlers.ts +4 -2
  17. package/src/presentation/navigation/hooks/useSettingsScreens.ts +10 -10
  18. package/src/presentation/navigation/utils/navigationTranslations.ts +29 -32
  19. package/src/presentation/screens/SettingsScreen.tsx +5 -1
  20. package/src/presentation/screens/components/GamificationSettingsItem.tsx +3 -6
  21. package/src/presentation/screens/components/SettingsContent.tsx +9 -5
  22. package/src/presentation/screens/components/SettingsHeader.tsx +4 -3
  23. package/src/presentation/screens/components/SubscriptionSettingsItem.tsx +3 -4
  24. package/src/presentation/screens/components/VideoTutorialSettingsItem.tsx +2 -4
  25. package/src/presentation/screens/components/WalletSettingsItem.tsx +3 -4
  26. package/src/presentation/screens/components/sections/FeatureSettingsSection.tsx +11 -13
  27. package/src/presentation/screens/components/sections/IdentitySettingsSection.tsx +5 -6
  28. package/src/presentation/screens/components/sections/ProfileSectionLoader.tsx +11 -9
  29. package/src/presentation/screens/components/sections/SupportSettingsSection.tsx +22 -23
  30. package/src/presentation/screens/types/SettingsConfig.ts +97 -6
  31. package/src/presentation/utils/accountConfigUtils.ts +9 -17
  32. package/src/presentation/utils/config-creators/base-configs.ts +0 -22
  33. package/src/presentation/utils/config-creators/feature-configs.ts +0 -20
  34. package/src/presentation/utils/config-creators/support-configs.ts +2 -12
  35. package/src/presentation/utils/faqTranslator.ts +5 -18
  36. package/src/presentation/utils/settingsConfigFactory.ts +10 -13
  37. package/src/presentation/utils/useAuthHandlers.ts +13 -20
  38. package/src/presentation/utils/userProfileUtils.ts +2 -16
  39. package/src/domains/disclaimer/README.md +0 -87
  40. package/src/domains/disclaimer/presentation/components/DisclaimerCard.test.tsx +0 -208
  41. package/src/domains/disclaimer/presentation/components/DisclaimerModal.test.tsx +0 -236
  42. package/src/domains/disclaimer/presentation/components/DisclaimerSetting.test.tsx +0 -74
  43. package/src/domains/disclaimer/presentation/components/README.md +0 -97
  44. package/src/domains/localization/presentation/components/__tests__/LanguageItem.test.tsx +0 -106
@@ -1,45 +1,42 @@
1
- /**
2
- * Navigation Translations Utility
3
- * Creates translation objects for navigation screens
4
- */
1
+ import type { SettingsTranslations } from "../../screens/types/SettingsConfig";
5
2
 
6
- export const createNotificationTranslations = (t: (key: string) => string) => ({
7
- screenTitle: t("settings.notifications.title"),
8
- masterToggleTitle: t("settings.notifications.masterToggleTitle"),
9
- masterToggleDescription: t("settings.notifications.masterToggleDescription"),
10
- soundTitle: t("settings.notifications.soundTitle"),
11
- soundDescription: t("settings.notifications.soundDescription"),
12
- vibrationTitle: t("settings.notifications.vibrationTitle"),
13
- vibrationDescription: t("settings.notifications.vibrationDescription"),
14
- remindersTitle: t("settings.notifications.remindersTitle"),
15
- remindersDescription: t("settings.notifications.remindersDescription"),
16
- quietHoursTitle: t("settings.notifications.quietHoursTitle"),
17
- quietHoursDescription: t("settings.notifications.quietHoursDescription"),
3
+ export const createNotificationTranslations = (translations?: SettingsTranslations["features"]) => ({
4
+ screenTitle: translations?.notifications?.title || "",
5
+ masterToggleTitle: translations?.notifications?.masterToggleTitle || "",
6
+ masterToggleDescription: translations?.notifications?.masterToggleDescription || "",
7
+ soundTitle: translations?.notifications?.soundTitle || "",
8
+ soundDescription: translations?.notifications?.soundDescription || "",
9
+ vibrationTitle: translations?.notifications?.vibrationTitle || "",
10
+ vibrationDescription: translations?.notifications?.vibrationDescription || "",
11
+ remindersTitle: translations?.notifications?.remindersTitle || "",
12
+ remindersDescription: translations?.notifications?.remindersDescription || "",
13
+ quietHoursTitle: translations?.notifications?.quietHoursTitle || "",
14
+ quietHoursDescription: translations?.notifications?.quietHoursDescription || "",
18
15
  });
19
16
 
20
- export const createQuietHoursTranslations = (t: (key: string) => string) => ({
21
- title: t("settings.notifications.quietHours.title"),
22
- description: t("settings.notifications.quietHours.description"),
23
- startTimeLabel: t("settings.notifications.quietHours.startTimeLabel"),
24
- endTimeLabel: t("settings.notifications.quietHours.endTimeLabel"),
25
- enabledLabel: t("settings.notifications.quietHours.enabledLabel"),
17
+ export const createQuietHoursTranslations = (translations?: SettingsTranslations["features"]) => ({
18
+ title: translations?.notifications?.quietHours?.title || "",
19
+ description: translations?.notifications?.quietHours?.description || "",
20
+ startTimeLabel: translations?.notifications?.quietHours?.startTimeLabel || "",
21
+ endTimeLabel: translations?.notifications?.quietHours?.endTimeLabel || "",
22
+ enabledLabel: translations?.notifications?.quietHours?.enabledLabel || "",
26
23
  });
27
24
 
28
25
  export const createLegalScreenProps = (
29
- t: (key: string) => string,
26
+ translations: SettingsTranslations["features"],
30
27
  handlePrivacyPress: () => void,
31
28
  handleTermsPress: () => void,
32
29
  handleEulaPress: () => void
33
30
  ) => ({
34
- title: t("settings.legal.title"),
35
- description: t("settings.legal.description"),
36
- documentsHeader: t("settings.legal.documentsHeader"),
37
- privacyTitle: t("settings.legal.privacyTitle"),
38
- privacyDescription: t("settings.legal.privacyDescription"),
39
- termsTitle: t("settings.legal.termsTitle"),
40
- termsDescription: t("settings.legal.termsDescription"),
41
- eulaTitle: t("settings.legal.eulaTitle"),
42
- eulaDescription: t("settings.legal.eulaDescription"),
31
+ title: translations?.legal?.title || "",
32
+ description: translations?.legal?.description || "",
33
+ documentsHeader: translations?.legal?.documentsHeader || "",
34
+ privacyTitle: translations?.legal?.privacyTitle || "",
35
+ privacyDescription: translations?.legal?.privacyDescription || "",
36
+ termsTitle: translations?.legal?.termsTitle || "",
37
+ termsDescription: translations?.legal?.termsDescription || "",
38
+ eulaTitle: translations?.legal?.eulaTitle || "",
39
+ eulaDescription: translations?.legal?.eulaDescription || "",
43
40
  onPrivacyPress: handlePrivacyPress,
44
41
  onTermsPress: handleTermsPress,
45
42
  onEulaPress: handleEulaPress,
@@ -86,7 +86,11 @@ export const SettingsScreen: React.FC<SettingsScreenProps> = (props) => {
86
86
  });
87
87
 
88
88
  const header = showHeader ? (
89
- <SettingsHeader showCloseButton={showCloseButton} onClose={handleClose} />
89
+ <SettingsHeader
90
+ showCloseButton={showCloseButton}
91
+ onClose={handleClose}
92
+ title={normalizedConfig.translations?.title}
93
+ />
90
94
  ) : undefined;
91
95
 
92
96
  return (
@@ -18,7 +18,6 @@ export interface GamificationSettingsItemProps {
18
18
  const GamificationSettingsItemComponent: React.FC<GamificationSettingsItemProps> = ({
19
19
  config,
20
20
  gamificationConfig,
21
- t,
22
21
  noBackground,
23
22
  hideMargin,
24
23
  }) => {
@@ -31,12 +30,10 @@ const GamificationSettingsItemComponent: React.FC<GamificationSettingsItemProps>
31
30
  }, [navigation, config.route]);
32
31
 
33
32
  const icon = (config.icon || "trophy-outline") as IconName;
34
- const title = config.title || t("settings.gamification.title");
33
+ const title = config.title;
35
34
 
36
- const description = config.description ||
37
- t("settings.gamification.description")
38
- .replace("{level}", level.currentLevel.toString())
39
- .replace("{points}", level.currentPoints.toString());
35
+ const description = config.description ||
36
+ `${level.currentLevel} • ${level.currentPoints}`;
40
37
 
41
38
  return (
42
39
  <SettingsItemCard
@@ -1,6 +1,5 @@
1
1
  import React, { useMemo } from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
- import { useLocalization } from "../../../domains/localization";
4
3
  import { SettingsFooter } from "../../components/SettingsFooter";
5
4
  import { SettingsSection } from "../../components/SettingsSection";
6
5
  import { DevSettingsSection, DevSettingsProps } from "../../../domains/dev";
@@ -108,7 +107,12 @@ export const SettingsContent: React.FC<SettingsContentProps> = ({
108
107
 
109
108
  return (
110
109
  <View style={styles.container}>
111
- {showUserProfile && <ProfileSectionLoader userProfile={userProfile} />}
110
+ {showUserProfile && (
111
+ <ProfileSectionLoader
112
+ userProfile={userProfile}
113
+ translations={translations?.profile}
114
+ />
115
+ )}
112
116
 
113
117
  <CustomSettingsList customSections={customSections} />
114
118
 
@@ -127,7 +131,7 @@ export const SettingsContent: React.FC<SettingsContentProps> = ({
127
131
  <FeatureSettingsSection normalizedConfig={normalizedConfig} features={features} />
128
132
 
129
133
  {(features.gamification || features.videoTutorial) && (
130
- <SettingsSection title={translations?.sections?.progress || "Progress"}>
134
+ <SettingsSection title={translations?.sections?.progress}>
131
135
  {features.gamification && (
132
136
  <GamificationSettingsItem
133
137
  config={normalizedConfig.gamification.config || {}}
@@ -155,7 +159,7 @@ export const SettingsContent: React.FC<SettingsContentProps> = ({
155
159
 
156
160
  {!hasAnyFeatures && (
157
161
  <View style={styles.emptyContainer}>
158
- <SettingsSection title={emptyStateText || translations?.noOptionsAvailable || "No options available"}>
162
+ <SettingsSection title={emptyStateText || translations?.noOptionsAvailable}>
159
163
  <View />
160
164
  </SettingsSection>
161
165
  </View>
@@ -167,7 +171,7 @@ export const SettingsContent: React.FC<SettingsContentProps> = ({
167
171
  <SettingsFooter
168
172
  versionText={footerText}
169
173
  appVersion={appVersion}
170
- versionLabel={translations?.footer?.version || "Version"}
174
+ versionLabel={translations?.footer?.version}
171
175
  />
172
176
  )}
173
177
  </View>
@@ -1,20 +1,21 @@
1
1
  import React from "react";
2
2
  import { Pressable } from "react-native";
3
3
  import { useAppDesignTokens, AtomicIcon, useAppNavigation, NavigationHeader } from "@umituz/react-native-design-system";
4
- import { useLocalization } from "../../../domains/localization";
4
+
5
5
 
6
6
  interface SettingsHeaderProps {
7
7
  showCloseButton?: boolean;
8
8
  onClose?: () => void;
9
+ title?: string;
9
10
  }
10
11
 
11
12
  export const SettingsHeader: React.FC<SettingsHeaderProps> = ({
12
13
  showCloseButton = false,
13
14
  onClose,
15
+ title,
14
16
  }) => {
15
17
  const navigation = useAppNavigation();
16
18
  const tokens = useAppDesignTokens();
17
- const { t } = useLocalization();
18
19
 
19
20
  const handleClose = () => {
20
21
  if (onClose) {
@@ -45,7 +46,7 @@ export const SettingsHeader: React.FC<SettingsHeaderProps> = ({
45
46
 
46
47
  return (
47
48
  <NavigationHeader
48
- title={t('settings.title')}
49
+ title={title}
49
50
  rightElement={rightElement}
50
51
  // If NOT showing close button, we might want a back button?
51
52
  // But usually Settings is a root screen in a modal or stack.
@@ -7,10 +7,9 @@ import { compareConfigAndTranslate } from "../../../infrastructure/utils/memoCom
7
7
 
8
8
  export interface SubscriptionSettingsItemProps {
9
9
  config: SubscriptionConfig;
10
- t?: (key: string) => string;
11
10
  }
12
11
 
13
- const SubscriptionSettingsItemComponent: React.FC<SubscriptionSettingsItemProps> = ({ config, t }) => {
12
+ const SubscriptionSettingsItemComponent: React.FC<SubscriptionSettingsItemProps> = ({ config }) => {
14
13
  const navigation = useAppNavigation();
15
14
 
16
15
  const handlePress = React.useCallback(() => {
@@ -23,8 +22,8 @@ const SubscriptionSettingsItemComponent: React.FC<SubscriptionSettingsItemProps>
23
22
 
24
23
  return (
25
24
  <SettingsItemCard
26
- title={config.title || t("settings.subscription.title")}
27
- description={config.description || t("settings.subscription.description")}
25
+ title={config.title}
26
+ description={config.description}
28
27
  icon={(config.icon || "star") as IconName}
29
28
  onPress={handlePress}
30
29
  sectionTitle={config.sectionTitle}
@@ -7,14 +7,12 @@ import { compareConfigAndTranslate } from "../../../infrastructure/utils/memoCom
7
7
 
8
8
  export interface VideoTutorialSettingsItemProps {
9
9
  config: VideoTutorialConfig;
10
- t?: (key: string) => string;
11
10
  noBackground?: boolean;
12
11
  hideMargin?: boolean;
13
12
  }
14
13
 
15
14
  const VideoTutorialSettingsItemComponent: React.FC<VideoTutorialSettingsItemProps> = ({
16
15
  config,
17
- t,
18
16
  noBackground,
19
17
  hideMargin,
20
18
  }) => {
@@ -30,8 +28,8 @@ const VideoTutorialSettingsItemComponent: React.FC<VideoTutorialSettingsItemProp
30
28
  }, [navigation, config.onPress, config.route]);
31
29
 
32
30
  const icon = (config.icon || "play-circle-outline") as IconName;
33
- const title = config.title || t("settings.videoTutorial.title");
34
- const description = config.description || t("settings.videoTutorial.description");
31
+ const title = config.title;
32
+ const description = config.description;
35
33
 
36
34
  return (
37
35
  <SettingsItemCard
@@ -7,10 +7,9 @@ import { compareConfigAndTranslate } from "../../../infrastructure/utils/memoCom
7
7
 
8
8
  export interface WalletSettingsItemProps {
9
9
  config: WalletConfig;
10
- t?: (key: string) => string;
11
10
  }
12
11
 
13
- const WalletSettingsItemComponent: React.FC<WalletSettingsItemProps> = ({ config, t }) => {
12
+ const WalletSettingsItemComponent: React.FC<WalletSettingsItemProps> = ({ config }) => {
14
13
  const navigation = useAppNavigation();
15
14
 
16
15
  const handlePress = React.useCallback(() => {
@@ -21,8 +20,8 @@ const WalletSettingsItemComponent: React.FC<WalletSettingsItemProps> = ({ config
21
20
 
22
21
  return (
23
22
  <SettingsItemCard
24
- title={config.title || (t ? t("wallet.title") : "Wallet")}
25
- description={config.description || (t ? t("wallet.description") : "View your wallet")}
23
+ title={config.title}
24
+ description={config.description}
26
25
  icon={(config.icon || "wallet") as IconName}
27
26
  onPress={handlePress}
28
27
  sectionTitle={config.sectionTitle}
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { useAppNavigation } from "@umituz/react-native-design-system";
3
3
  import { AppearanceSection } from "../../../../domains/appearance/presentation/components/AppearanceSection";
4
4
  import { NotificationsSection } from "../../../../domains/notifications";
5
- import { useLocalization, getLanguageByCode } from "../../../../domains/localization";
5
+ import { getLanguageByCode } from "../../../../domains/localization";
6
6
  import { SettingsItemCard } from "../../../components/SettingsItemCard";
7
7
  import type { NormalizedConfig } from "../../utils/normalizeConfig";
8
8
  import { SettingsSection } from "../../../components/SettingsSection";
@@ -35,28 +35,26 @@ export const FeatureSettingsSection: React.FC<FeatureSettingsSectionProps> = ({
35
35
  }
36
36
  }, [navigation, normalizedConfig.language.config]);
37
37
 
38
- const currentLanguageData = React.useMemo(() =>
39
- currentLanguage ? getLanguageByCode(currentLanguage) : null,
40
- [currentLanguage]
41
- );
38
+ const langCode = currentLanguage || "en-US";
39
+ const currentLanguageData = React.useMemo(() => getLanguageByCode(langCode), [langCode]);
42
40
 
43
41
  const languageDisplayName = React.useMemo(() => {
44
- if (!currentLanguageData) return currentLanguage || "";
42
+ if (!currentLanguageData) return langCode;
45
43
  return `${currentLanguageData.flag} ${currentLanguageData.nativeName}`;
46
- }, [currentLanguageData, currentLanguage]);
44
+ }, [currentLanguageData, langCode]);
47
45
 
48
46
  if (!features.appearance && !features.language && !features.notifications) return null;
49
47
 
50
48
  return (
51
49
  <SettingsSection
52
- title={translations?.sections?.app || "App Settings"}
50
+ title={translations?.sections?.app}
53
51
  >
54
52
  {features.appearance && (
55
53
  <AppearanceSection
56
54
  config={{
57
55
  ...normalizedConfig.appearance.config,
58
- title: translations?.features?.appearance?.title || "Appearance",
59
- description: translations?.features?.appearance?.description || "Theme settings",
56
+ title: translations?.features?.appearance?.title,
57
+ description: translations?.features?.appearance?.description,
60
58
  }}
61
59
  noBackground={true}
62
60
  hideMargin={true}
@@ -65,7 +63,7 @@ export const FeatureSettingsSection: React.FC<FeatureSettingsSectionProps> = ({
65
63
 
66
64
  {features.language && (
67
65
  <SettingsItemCard
68
- title={translations?.features?.language?.title || "Language"}
66
+ title={translations?.features?.language?.title}
69
67
  description={languageDisplayName}
70
68
  icon="globe-outline"
71
69
  onPress={handleLanguagePress}
@@ -78,8 +76,8 @@ export const FeatureSettingsSection: React.FC<FeatureSettingsSectionProps> = ({
78
76
  <NotificationsSection
79
77
  config={{
80
78
  ...normalizedConfig.notifications.config,
81
- title: translations?.features?.notifications?.title || "Notifications",
82
- description: translations?.features?.notifications?.description || "Push notification settings",
79
+ title: translations?.features?.notifications?.title,
80
+ description: translations?.features?.notifications?.description,
83
81
  }}
84
82
  noBackground={true}
85
83
  hideMargin={true}
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { AboutSection } from "../../../../domains/about/presentation/components/AboutSection";
3
3
  import { LegalSection } from "../../../../domains/legal/presentation/components/LegalSection";
4
- import { useLocalization } from "../../../../domains/localization";
5
4
  import type { NormalizedConfig } from "../../utils/normalizeConfig";
6
5
  import { SettingsSection } from "../../../components/SettingsSection";
7
6
  import { compareConfigAndFeatures } from "../../../../infrastructure/utils/memoComparisonUtils";
@@ -20,13 +19,13 @@ export const IdentitySettingsSection: React.FC<IdentitySettingsSectionProps> = (
20
19
  if (!features.about && !features.legal) return null;
21
20
 
22
21
  return (
23
- <SettingsSection title={translations?.sections?.about || "About"}>
22
+ <SettingsSection title={translations?.sections?.about}>
24
23
  {features.about && (
25
24
  <AboutSection
26
25
  config={{
27
26
  ...normalizedConfig.about.config,
28
- title: translations?.features?.about?.title || "About",
29
- description: translations?.features?.about?.description || "About the app",
27
+ title: translations?.features?.about?.title,
28
+ description: translations?.features?.about?.description,
30
29
  }}
31
30
  noBackground={true}
32
31
  hideMargin={true}
@@ -37,8 +36,8 @@ export const IdentitySettingsSection: React.FC<IdentitySettingsSectionProps> = (
37
36
  <LegalSection
38
37
  config={{
39
38
  ...normalizedConfig.legal.config,
40
- title: translations?.features?.legal?.title || "Legal",
41
- description: translations?.features?.legal?.description || "Privacy Policy & Terms",
39
+ title: translations?.features?.legal?.title,
40
+ description: translations?.features?.legal?.description,
42
41
  }}
43
42
  noBackground={true}
44
43
  hideMargin={true}
@@ -1,9 +1,7 @@
1
1
  import React from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
3
  import { ProfileSection } from "@umituz/react-native-auth";
4
- import { useLocalization } from "../../../../domains/localization";
5
4
  import { useAppNavigation } from "@umituz/react-native-design-system";
6
- import { createSinglePropComparator } from "../../../../infrastructure/utils/memoComparisonUtils";
7
5
 
8
6
  export interface ProfileSectionLoaderProps {
9
7
  userProfile?: {
@@ -15,10 +13,14 @@ export interface ProfileSectionLoaderProps {
15
13
  onPress?: () => void;
16
14
  benefits?: string[];
17
15
  };
16
+ translations?: {
17
+ guest?: string;
18
+ anonymousName?: string;
19
+ signIn?: string;
20
+ };
18
21
  }
19
22
 
20
- export const ProfileSectionLoader: React.FC<ProfileSectionLoaderProps> = React.memo(({ userProfile }) => {
21
- const { t } = useLocalization();
23
+ export const ProfileSectionLoader: React.FC<ProfileSectionLoaderProps> = React.memo(({ userProfile, translations }) => {
22
24
  const navigation = useAppNavigation();
23
25
 
24
26
  const handlePress = React.useCallback(() => {
@@ -33,9 +35,9 @@ export const ProfileSectionLoader: React.FC<ProfileSectionLoaderProps> = React.m
33
35
  const anonymousDisplayName = React.useMemo(() => {
34
36
  if (!userProfile) return "";
35
37
  return userProfile.isAnonymous && userProfile.userId
36
- ? `${t("profile.guest", "Guest")} ${userProfile.userId.substring(0, 8)}`
37
- : t("settings.profile.anonymousName", "Anonymous User");
38
- }, [userProfile, t]);
38
+ ? `${translations?.guest || ""} ${userProfile.userId.substring(0, 8)}`
39
+ : (translations?.anonymousName || "");
40
+ }, [userProfile, translations]);
39
41
 
40
42
  if (!userProfile) return null;
41
43
 
@@ -52,12 +54,12 @@ export const ProfileSectionLoader: React.FC<ProfileSectionLoaderProps> = React.m
52
54
  }}
53
55
  onPress={handlePress}
54
56
  onSignIn={userProfile.onPress}
55
- signInText={t("auth.signIn", "Sign In")}
57
+ signInText={translations?.signIn || ""}
56
58
  anonymousText={anonymousDisplayName}
57
59
  />
58
60
  </View>
59
61
  );
60
- }, createSinglePropComparator("userProfile"));
62
+ }, (prev, next) => prev.userProfile === next.userProfile && prev.translations === next.translations);
61
63
 
62
64
  ProfileSectionLoader.displayName = "ProfileSectionLoader";
63
65
 
@@ -1,5 +1,4 @@
1
1
  import React, { useCallback } from "react";
2
- import { useLocalization } from "../../../../domains/localization";
3
2
  import { useAppNavigation } from "@umituz/react-native-design-system";
4
3
  import { SupportSection } from "../../../../domains/feedback/presentation/components/SupportSection";
5
4
  import { SettingsSection } from "../../../components/SettingsSection";
@@ -26,7 +25,7 @@ export const SupportSettingsSection: React.FC<SupportSettingsSectionProps> = ({
26
25
  if (!(features.feedback || features.rating || features.faqs)) return null;
27
26
 
28
27
  return (
29
- <SettingsSection title={translations?.sections?.support || "Support"}>
28
+ <SettingsSection title={translations?.sections?.support}>
30
29
  {(features.feedback || features.rating) && (
31
30
  <SupportSection
32
31
  renderSection={(props: { title: string; children: React.ReactNode }) => <>{props.children}</>}
@@ -42,8 +41,8 @@ export const SupportSettingsSection: React.FC<SupportSettingsSectionProps> = ({
42
41
  feedbackConfig={{
43
42
  enabled: features.feedback,
44
43
  config: {
45
- title: normalizedConfig.feedback.config?.title || translations?.features?.feedback?.title || "Feedback",
46
- description: normalizedConfig.feedback.config?.description || translations?.features?.feedback?.description || "Give us your feedback",
44
+ title: normalizedConfig.feedback.config?.title || translations?.features?.feedback?.title,
45
+ description: normalizedConfig.feedback.config?.description || translations?.features?.feedback?.description,
47
46
  initialType: normalizedConfig.feedback.config?.initialType,
48
47
  onSubmit: normalizedConfig.feedback.config?.onSubmit,
49
48
  onPress: normalizedConfig.feedback.config?.onPress,
@@ -52,32 +51,32 @@ export const SupportSettingsSection: React.FC<SupportSettingsSectionProps> = ({
52
51
  ratingConfig={{
53
52
  enabled: features.rating,
54
53
  config: {
55
- title: normalizedConfig.rating.config?.title || translations?.features?.rating?.title || "Rate Us",
56
- description: normalizedConfig.rating.config?.description || translations?.features?.rating?.description || "Love the app? Rate us!",
54
+ title: normalizedConfig.rating.config?.title || translations?.features?.rating?.title,
55
+ description: normalizedConfig.rating.config?.description || translations?.features?.rating?.description,
57
56
  storeUrl: normalizedConfig.rating.config?.storeUrl,
58
57
  onRate: normalizedConfig.rating.config?.onRate,
59
58
  }
60
59
  }}
61
60
  feedbackModalTexts={{
62
- title: translations?.feedbackModal?.title || "Send Feedback",
63
- ratingLabel: translations?.feedbackModal?.ratingLabel || "Rating",
64
- descriptionPlaceholder: translations?.feedbackModal?.descriptionPlaceholder || "Feedback",
65
- submitButton: translations?.feedbackModal?.submitButton || "Submit",
66
- submittingButton: translations?.feedbackModal?.submittingButton || "Submitting...",
61
+ title: translations?.feedbackModal?.title,
62
+ ratingLabel: translations?.feedbackModal?.ratingLabel,
63
+ descriptionPlaceholder: translations?.feedbackModal?.descriptionPlaceholder,
64
+ submitButton: translations?.feedbackModal?.submitButton,
65
+ submittingButton: translations?.feedbackModal?.submittingButton,
67
66
  feedbackTypes: [
68
- { type: 'general', label: translations?.feedbackModal?.types?.general || "General" },
69
- { type: 'bug_report', label: translations?.feedbackModal?.types?.bugReport || "Bug Report" },
70
- { type: 'feature_request', label: translations?.feedbackModal?.types?.featureRequest || "Feature Request" },
71
- { type: 'improvement', label: translations?.feedbackModal?.types?.improvement || "Improvement" },
72
- { type: 'other', label: translations?.feedbackModal?.types?.other || "Other" },
67
+ { type: 'general', label: translations?.feedbackModal?.types?.general },
68
+ { type: 'bug_report', label: translations?.feedbackModal?.types?.bugReport },
69
+ { type: 'feature_request', label: translations?.feedbackModal?.types?.featureRequest },
70
+ { type: 'improvement', label: translations?.feedbackModal?.types?.improvement },
71
+ { type: 'other', label: translations?.feedbackModal?.types?.other },
73
72
  ],
74
73
  defaultTitle: (type) => {
75
74
  const titles: Record<string, string> = {
76
- general: translations?.feedbackModal?.types?.general || "General",
77
- bug_report: translations?.feedbackModal?.types?.bugReport || "Bug Report",
78
- feature_request: translations?.feedbackModal?.types?.featureRequest || "Feature Request",
79
- improvement: translations?.feedbackModal?.types?.improvement || "Improvement",
80
- other: translations?.feedbackModal?.types?.other || "Other",
75
+ general: translations?.feedbackModal?.types?.general || type,
76
+ bug_report: translations?.feedbackModal?.types?.bugReport || type,
77
+ feature_request: translations?.feedbackModal?.types?.featureRequest || type,
78
+ improvement: translations?.feedbackModal?.types?.improvement || type,
79
+ other: translations?.feedbackModal?.types?.other || type,
81
80
  };
82
81
  return titles[type] || type;
83
82
  },
@@ -87,8 +86,8 @@ export const SupportSettingsSection: React.FC<SupportSettingsSectionProps> = ({
87
86
 
88
87
  {features.faqs && (
89
88
  <SettingsItemCard
90
- title={normalizedConfig.faqs.config?.title || translations?.features?.faqs?.title || "FAQ"}
91
- description={normalizedConfig.faqs.config?.description || translations?.features?.faqs?.description || "Frequently Asked Questions"}
89
+ title={normalizedConfig.faqs.config?.title || translations?.features?.faqs?.title}
90
+ description={normalizedConfig.faqs.config?.description || translations?.features?.faqs?.description}
92
91
  icon="help-circle-outline"
93
92
  onPress={handleFAQPress}
94
93
  noBackground={true}
@@ -59,6 +59,17 @@ import type {
59
59
  * Global Settings Translations
60
60
  */
61
61
  export interface SettingsTranslations {
62
+ title?: string;
63
+ profile?: {
64
+ guest?: string;
65
+ anonymousName?: string;
66
+ signIn?: string;
67
+ signInDescription?: string;
68
+ anonymousBenefits?: {
69
+ title?: string;
70
+ items?: string[];
71
+ };
72
+ };
62
73
  sections?: {
63
74
  app?: string;
64
75
  progress?: string;
@@ -67,14 +78,84 @@ export interface SettingsTranslations {
67
78
  subscription?: string;
68
79
  };
69
80
  features?: {
70
- appearance?: { title?: string; description?: string };
71
- language?: { title?: string };
72
- notifications?: { title?: string; description?: string };
73
- about?: { title?: string; description?: string };
74
- legal?: { title?: string; description?: string };
81
+ appearance?: {
82
+ title?: string;
83
+ description?: string;
84
+ themeModes?: {
85
+ light?: string;
86
+ dark?: string;
87
+ auto?: string;
88
+ };
89
+ };
90
+ language?: {
91
+ title?: string;
92
+ description?: string;
93
+ searchPlaceholder?: string;
94
+ };
95
+ notifications?: {
96
+ title?: string;
97
+ description?: string;
98
+ masterToggleTitle?: string;
99
+ masterToggleDescription?: string;
100
+ soundTitle?: string;
101
+ soundDescription?: string;
102
+ vibrationTitle?: string;
103
+ vibrationDescription?: string;
104
+ remindersTitle?: string;
105
+ remindersDescription?: string;
106
+ quietHoursTitle?: string;
107
+ quietHoursDescription?: string;
108
+ quietHours?: {
109
+ title?: string;
110
+ description?: string;
111
+ startTimeLabel?: string;
112
+ endTimeLabel?: string;
113
+ enabledLabel?: string;
114
+ };
115
+ };
116
+ about?: {
117
+ title?: string;
118
+ description?: string;
119
+ contact?: string;
120
+ more?: string;
121
+ developer?: string;
122
+ email?: string;
123
+ website?: string;
124
+ moreApps?: string;
125
+ versionPrefix?: string;
126
+ };
127
+ legal?: {
128
+ title?: string;
129
+ description?: string;
130
+ documentsHeader?: string;
131
+ privacyTitle?: string;
132
+ privacyDescription?: string;
133
+ termsTitle?: string;
134
+ termsDescription?: string;
135
+ eulaTitle?: string;
136
+ eulaDescription?: string;
137
+ };
75
138
  feedback?: { title?: string; description?: string };
76
139
  rating?: { title?: string; description?: string };
77
- faqs?: { title?: string; description?: string };
140
+ faqs?: {
141
+ title?: string;
142
+ description?: string;
143
+ searchPlaceholder?: string;
144
+ emptySearchTitle?: string;
145
+ emptySearchMessage?: string;
146
+ headerTitle?: string;
147
+ };
148
+ languageSelection?: {
149
+ searchPlaceholder?: string;
150
+ };
151
+ subscription?: {
152
+ title?: string;
153
+ description?: string;
154
+ };
155
+ videoTutorial?: {
156
+ title?: string;
157
+ description?: string;
158
+ };
78
159
  };
79
160
  feedbackModal?: {
80
161
  title?: string;
@@ -94,6 +175,16 @@ export interface SettingsTranslations {
94
175
  footer?: {
95
176
  version?: string;
96
177
  };
178
+ errors?: {
179
+ common?: string;
180
+ unknown?: string;
181
+ unknownError?: string;
182
+ appStoreUrlMissing?: string;
183
+ appStoreUrlNotConfigured?: string;
184
+ unableToOpenAppStore?: string;
185
+ failedToOpenAppStore?: string;
186
+ deleteAccountError?: string;
187
+ };
97
188
  }
98
189
 
99
190
  export interface SettingsConfig {