@umituz/react-native-settings 4.23.109 → 4.23.114

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 (27) hide show
  1. package/package.json +1 -1
  2. package/src/domains/feedback/presentation/components/FeedbackForm.tsx +1 -15
  3. package/src/domains/feedback/presentation/components/FeedbackFormProps.ts +26 -0
  4. package/src/domains/feedback/presentation/components/FeedbackModal.tsx +1 -1
  5. package/src/domains/gamification/components/AchievementCard.tsx +1 -2
  6. package/src/domains/gamification/components/AchievementItem.tsx +6 -92
  7. package/src/domains/gamification/components/GamificationScreen/AchievementsList.tsx +1 -1
  8. package/src/domains/gamification/components/GamificationScreen/types.ts +1 -1
  9. package/src/domains/gamification/components/index.ts +2 -1
  10. package/src/domains/gamification/components/styles/achievementItemStyles.ts +74 -0
  11. package/src/domains/gamification/components/types/AchievementItemProps.ts +25 -0
  12. package/src/infrastructure/utils/errorHandlers.ts +2 -3
  13. package/src/infrastructure/utils/styleUtils.ts +3 -186
  14. package/src/infrastructure/utils/styles/componentStyles.ts +90 -0
  15. package/src/infrastructure/utils/styles/index.ts +9 -0
  16. package/src/infrastructure/utils/styles/layoutStyles.ts +56 -0
  17. package/src/infrastructure/utils/styles/spacingStyles.ts +33 -0
  18. package/src/infrastructure/utils/styles/styleHelpers.ts +22 -0
  19. package/src/presentation/hooks/useSettingsScreenConfig.ts +1 -2
  20. package/src/presentation/navigation/utils/navigationTranslations.ts +1 -1
  21. package/src/presentation/screens/components/SettingsContent.tsx +6 -74
  22. package/src/presentation/screens/components/types/SettingsContentProps.ts +51 -0
  23. package/src/presentation/screens/components/utils/featureChecker.ts +32 -0
  24. package/src/presentation/screens/types/SettingsConfig.ts +1 -136
  25. package/src/presentation/screens/types/SettingsTranslations.ts +140 -0
  26. package/src/presentation/screens/types/index.ts +2 -1
  27. package/src/presentation/utils/useAuthHandlers.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-settings",
3
- "version": "4.23.109",
3
+ "version": "4.23.114",
4
4
  "description": "Complete settings hub for React Native apps - consolidated package with settings, localization, about, legal, appearance, feedback, FAQs, rating, and gamification",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -8,23 +8,9 @@ import { View, TouchableOpacity, ScrollView, TextInput } from "react-native";
8
8
  import { useAppDesignTokens, AtomicText, AtomicButton, AtomicIcon } from "@umituz/react-native-design-system";
9
9
  import type { FeedbackType, FeedbackRating } from "../../domain/entities/FeedbackEntity";
10
10
  import { validateFeedbackForm } from "../../../../infrastructure/utils/validation";
11
-
11
+ import type { FeedbackFormProps } from "./FeedbackFormProps";
12
12
  import { getFeedbackFormStyles as getStyles } from "./FeedbackForm.styles";
13
13
 
14
- export interface FeedbackFormProps {
15
- onSubmit: (data: { type: FeedbackType; rating: FeedbackRating; description: string; title: string }) => Promise<void>;
16
- texts: {
17
- ratingLabel: string;
18
- descriptionPlaceholder: string;
19
- submitButton: string;
20
- submittingButton: string;
21
- feedbackTypes: Array<{ type: FeedbackType; label: string }>;
22
- defaultTitle: (type: FeedbackType) => string;
23
- };
24
- initialType?: FeedbackType;
25
- isSubmitting?: boolean;
26
- }
27
-
28
14
  export const FeedbackForm: React.FC<FeedbackFormProps> = ({
29
15
  onSubmit,
30
16
  texts,
@@ -0,0 +1,26 @@
1
+ /**
2
+ * FeedbackForm Props Types
3
+ */
4
+
5
+ import type { FeedbackType, FeedbackRating } from "../../domain/entities/FeedbackEntity";
6
+
7
+ export interface FeedbackFormTexts {
8
+ ratingLabel: string;
9
+ descriptionPlaceholder: string;
10
+ submitButton: string;
11
+ submittingButton: string;
12
+ feedbackTypes: Array<{ type: FeedbackType; label: string }>;
13
+ defaultTitle: (type: FeedbackType) => string;
14
+ }
15
+
16
+ export interface FeedbackFormProps {
17
+ onSubmit: (data: {
18
+ type: FeedbackType;
19
+ rating: FeedbackRating;
20
+ description: string;
21
+ title: string;
22
+ }) => Promise<void>;
23
+ texts: FeedbackFormTexts;
24
+ initialType?: FeedbackType;
25
+ isSubmitting?: boolean;
26
+ }
@@ -8,7 +8,7 @@ import { View, StyleSheet, TouchableOpacity } from "react-native";
8
8
  import { useAppDesignTokens, AtomicText, AtomicIcon, BaseModal, ScreenLayout } from "@umituz/react-native-design-system";
9
9
  import { FeedbackForm } from "./FeedbackForm";
10
10
  import type { FeedbackType, FeedbackRating } from "../../domain/entities/FeedbackEntity";
11
- import type { FeedbackFormProps } from "./FeedbackForm";
11
+ import type { FeedbackFormProps } from "./FeedbackFormProps";
12
12
 
13
13
  export interface FeedbackModalProps {
14
14
  visible: boolean;
@@ -90,7 +90,7 @@ export const AchievementCard: React.FC<AchievementCardProps> = ({
90
90
 
91
91
  {isUnlocked && (
92
92
  <View style={[styles.checkmark, { backgroundColor: finalUnlockedColor }]}>
93
- <AtomicText style={styles.checkmarkText}>✓</AtomicText>
93
+ <AtomicText style={[styles.checkmarkText, { color: tokens.colors.onPrimary }]}>✓</AtomicText>
94
94
  </View>
95
95
  )}
96
96
  </View>
@@ -142,7 +142,6 @@ const styles = StyleSheet.create({
142
142
  alignItems: "center",
143
143
  },
144
144
  checkmarkText: {
145
- color: "#FFFFFF",
146
145
  fontSize: 14,
147
146
  fontWeight: "bold",
148
147
  },
@@ -4,28 +4,10 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { View, StyleSheet, type ViewStyle, type TextStyle } from "react-native";
7
+ import { View } from "react-native";
8
8
  import { useAppDesignTokens, AtomicText, AtomicIcon, withAlpha } from "@umituz/react-native-design-system";
9
-
10
- export interface AchievementItemProps {
11
- title: string;
12
- description: string;
13
- icon: React.ReactNode | string;
14
- isUnlocked: boolean;
15
- progress: number;
16
- threshold: number;
17
- progressLabel?: string;
18
- // Customization
19
- containerStyle?: ViewStyle;
20
- titleStyle?: TextStyle;
21
- descriptionStyle?: TextStyle;
22
- // Colors
23
- accentColor?: string;
24
- backgroundColor?: string;
25
- textColor?: string;
26
- subtextColor?: string;
27
- lockedOpacity?: number;
28
- }
9
+ import type { AchievementItemProps } from "./types/AchievementItemProps";
10
+ import { achievementItemStyles as styles } from "./styles/achievementItemStyles";
29
11
 
30
12
  export const AchievementItem: React.FC<AchievementItemProps> = ({
31
13
  title,
@@ -78,7 +60,9 @@ export const AchievementItem: React.FC<AchievementItemProps> = ({
78
60
  </AtomicText>
79
61
  {isUnlocked && (
80
62
  <View style={[styles.checkmark, { backgroundColor: finalAccentColor }]}>
81
- <AtomicText style={styles.checkmarkText}>✓</AtomicText>
63
+ <AtomicText style={[styles.checkmarkText, { color: tokens.colors.background }]}>
64
+
65
+ </AtomicText>
82
66
  </View>
83
67
  )}
84
68
  </View>
@@ -116,73 +100,3 @@ export const AchievementItem: React.FC<AchievementItemProps> = ({
116
100
  </View>
117
101
  );
118
102
  };
119
-
120
- const styles = StyleSheet.create({
121
- container: {
122
- flexDirection: "row",
123
- alignItems: "center",
124
- padding: 12,
125
- borderRadius: 12,
126
- marginBottom: 8,
127
- },
128
- iconContainer: {
129
- width: 48,
130
- height: 48,
131
- borderRadius: 24,
132
- alignItems: "center",
133
- justifyContent: "center",
134
- marginRight: 12,
135
- },
136
- content: {
137
- flex: 1,
138
- },
139
- header: {
140
- flexDirection: "row",
141
- alignItems: "center",
142
- justifyContent: "space-between",
143
- marginBottom: 4,
144
- },
145
- title: {
146
- fontSize: 16,
147
- fontWeight: "600",
148
- flex: 1,
149
- },
150
- checkmark: {
151
- width: 20,
152
- height: 20,
153
- borderRadius: 10,
154
- alignItems: "center",
155
- justifyContent: "center",
156
- marginLeft: 8,
157
- },
158
- checkmarkText: {
159
- color: "#000",
160
- fontSize: 12,
161
- fontWeight: "bold",
162
- },
163
- description: {
164
- fontSize: 13,
165
- lineHeight: 18,
166
- },
167
- progressContainer: {
168
- marginTop: 8,
169
- flexDirection: "row",
170
- alignItems: "center",
171
- gap: 8,
172
- },
173
- progressBar: {
174
- flex: 1,
175
- height: 4,
176
- borderRadius: 2,
177
- overflow: "hidden",
178
- },
179
- progressFill: {
180
- height: "100%",
181
- borderRadius: 2,
182
- },
183
- progressText: {
184
- fontSize: 11,
185
- minWidth: 40,
186
- textAlign: "right",
187
- },
188
- });
@@ -7,7 +7,7 @@ import { View, type TextStyle } from "react-native";
7
7
  import { AtomicText } from "@umituz/react-native-design-system";
8
8
  import { AchievementItem } from "../AchievementItem";
9
9
  import { styles } from "./styles";
10
- import type { AchievementItemProps } from "../AchievementItem";
10
+ import type { AchievementItemProps } from "../types/AchievementItemProps";
11
11
 
12
12
  export interface AchievementsListProps {
13
13
  achievementsTitle: string;
@@ -6,7 +6,7 @@
6
6
  import type React from 'react';
7
7
  import type { LevelProgressProps } from "../LevelProgress";
8
8
  import type { StatsCardProps } from "../StatsCard";
9
- import type { AchievementItemProps } from "../AchievementItem";
9
+ import type { AchievementItemProps } from "../types/AchievementItemProps";
10
10
  import type { StreakDisplayProps } from "../StreakDisplay";
11
11
  import type { ViewStyle, TextStyle } from "react-native";
12
12
  import type { GamificationConfig } from "../../types";
@@ -9,6 +9,7 @@ export { AchievementCard, type AchievementCardProps } from "./AchievementCard";
9
9
  export { AchievementToast, type AchievementToastProps } from "./AchievementToast";
10
10
  export { StreakDisplay, type StreakDisplayProps } from "./StreakDisplay";
11
11
  export { StatsCard, type StatsCardProps } from "./StatsCard";
12
- export { AchievementItem, type AchievementItemProps } from "./AchievementItem";
12
+ export { AchievementItem } from "./AchievementItem";
13
+ export type { AchievementItemProps } from "./types/AchievementItemProps";
13
14
  export { GamificationScreen } from "./GamificationScreen/index";
14
15
  export type { GamificationScreenProps, GamificationConfigProps } from "./GamificationScreen/types";
@@ -0,0 +1,74 @@
1
+ /**
2
+ * AchievementItem Styles
3
+ */
4
+
5
+ import { StyleSheet } from 'react-native';
6
+
7
+ export const achievementItemStyles = StyleSheet.create({
8
+ container: {
9
+ flexDirection: "row",
10
+ alignItems: "center",
11
+ padding: 12,
12
+ borderRadius: 12,
13
+ marginBottom: 8,
14
+ },
15
+ iconContainer: {
16
+ width: 48,
17
+ height: 48,
18
+ borderRadius: 24,
19
+ alignItems: "center",
20
+ justifyContent: "center",
21
+ marginRight: 12,
22
+ },
23
+ content: {
24
+ flex: 1,
25
+ },
26
+ header: {
27
+ flexDirection: "row",
28
+ alignItems: "center",
29
+ justifyContent: "space-between",
30
+ marginBottom: 4,
31
+ },
32
+ title: {
33
+ fontSize: 16,
34
+ fontWeight: "600",
35
+ flex: 1,
36
+ },
37
+ checkmark: {
38
+ width: 20,
39
+ height: 20,
40
+ borderRadius: 10,
41
+ alignItems: "center",
42
+ justifyContent: "center",
43
+ marginLeft: 8,
44
+ },
45
+ checkmarkText: {
46
+ fontSize: 12,
47
+ fontWeight: "bold",
48
+ },
49
+ description: {
50
+ fontSize: 13,
51
+ lineHeight: 18,
52
+ },
53
+ progressContainer: {
54
+ marginTop: 8,
55
+ flexDirection: "row",
56
+ alignItems: "center",
57
+ gap: 8,
58
+ },
59
+ progressBar: {
60
+ flex: 1,
61
+ height: 4,
62
+ borderRadius: 2,
63
+ overflow: "hidden",
64
+ },
65
+ progressFill: {
66
+ height: "100%",
67
+ borderRadius: 2,
68
+ },
69
+ progressText: {
70
+ fontSize: 11,
71
+ minWidth: 40,
72
+ textAlign: "right",
73
+ },
74
+ });
@@ -0,0 +1,25 @@
1
+ /**
2
+ * AchievementItem Props Types
3
+ */
4
+
5
+ import type { ViewStyle, TextStyle } from 'react-native';
6
+
7
+ export interface AchievementItemProps {
8
+ title: string;
9
+ description: string;
10
+ icon: React.ReactNode | string;
11
+ isUnlocked: boolean;
12
+ progress: number;
13
+ threshold: number;
14
+ progressLabel?: string;
15
+ // Customization
16
+ containerStyle?: ViewStyle;
17
+ titleStyle?: TextStyle;
18
+ descriptionStyle?: TextStyle;
19
+ // Colors
20
+ accentColor?: string;
21
+ backgroundColor?: string;
22
+ textColor?: string;
23
+ subtextColor?: string;
24
+ lockedOpacity?: number;
25
+ }
@@ -181,13 +181,12 @@ export const logError = (
181
181
  ...context?.additionalInfo,
182
182
  };
183
183
 
184
- // In production, send to error tracking service
184
+ // Log errors in development mode
185
185
  if (typeof __DEV__ !== "undefined" && __DEV__) {
186
186
  console.error("[Error]", logData);
187
187
  }
188
188
 
189
- // TODO: Send to error tracking service in production
190
- // ErrorTracking.captureException(error, logData);
189
+ // Note: Apps can integrate error tracking services (e.g., Sentry) by wrapping this function
191
190
  };
192
191
 
193
192
  /**
@@ -1,190 +1,7 @@
1
1
  /**
2
2
  * Style Utilities
3
- * Centralized style creation functions to reduce code duplication
3
+ * Re-exports from organized style modules
4
+ * @deprecated Import from specific modules instead: styles/layoutStyles, styles/componentStyles, etc.
4
5
  */
5
- import { StyleSheet, ViewStyle, TextStyle, ImageStyle } from 'react-native';
6
- import type { DesignTokens } from '@umituz/react-native-design-system';
7
6
 
8
- /**
9
- * Creates a container style with flex 1
10
- */
11
- export const createContainerStyle = (overrides: ViewStyle = {}): ViewStyle => ({
12
- flex: 1,
13
- ...overrides,
14
- });
15
-
16
- /**
17
- * Creates a centered container style
18
- */
19
- export const createCenteredContainerStyle = (overrides: ViewStyle = {}): ViewStyle => ({
20
- flex: 1,
21
- justifyContent: 'center',
22
- alignItems: 'center',
23
- ...overrides,
24
- });
25
-
26
- /**
27
- * Creates a row style for horizontal layouts
28
- */
29
- export const createRowStyle = (overrides: ViewStyle = {}): ViewStyle => ({
30
- flexDirection: 'row',
31
- alignItems: 'center',
32
- ...overrides,
33
- });
34
-
35
- /**
36
- * Creates a header style
37
- */
38
- export const createHeaderStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
39
- paddingHorizontal: tokens.spacing.lg,
40
- paddingVertical: tokens.spacing.md,
41
- ...overrides,
42
- });
43
-
44
- /**
45
- * Creates a section style
46
- */
47
- export const createSectionStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
48
- padding: tokens.spacing.lg,
49
- ...overrides,
50
- });
51
-
52
- /**
53
- * Creates a card style
54
- */
55
- export const createCardStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
56
- backgroundColor: tokens.colors.surface,
57
- borderRadius: tokens.borders.radius.md,
58
- padding: tokens.spacing.lg,
59
- ...overrides,
60
- });
61
-
62
- /**
63
- * Creates a title text style
64
- */
65
- export const createTitleStyle = (tokens: DesignTokens, overrides: TextStyle = {}): TextStyle => ({
66
- fontSize: tokens.typography.headlineMedium.responsiveFontSize,
67
- fontWeight: '600',
68
- color: tokens.colors.textPrimary,
69
- ...overrides,
70
- });
71
-
72
- /**
73
- * Creates a subtitle text style
74
- */
75
- export const createSubtitleStyle = (tokens: DesignTokens, overrides: TextStyle = {}): TextStyle => ({
76
- fontSize: tokens.typography.bodyMedium.responsiveFontSize,
77
- color: tokens.colors.textSecondary,
78
- ...overrides,
79
- });
80
-
81
- /**
82
- * Creates a button style
83
- */
84
- export const createButtonStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
85
- backgroundColor: tokens.colors.primary,
86
- borderRadius: tokens.borders.radius.md,
87
- paddingVertical: tokens.spacing.md,
88
- paddingHorizontal: tokens.spacing.lg,
89
- ...overrides,
90
- });
91
-
92
- /**
93
- * Creates an icon container style
94
- */
95
- export const createIconContainerStyle = (
96
- size: number = 48,
97
- tokens: DesignTokens,
98
- overrides: ViewStyle = {}
99
- ): ViewStyle => ({
100
- width: size,
101
- height: size,
102
- borderRadius: size / 2,
103
- justifyContent: 'center',
104
- alignItems: 'center',
105
- backgroundColor: tokens.colors.surfaceSecondary,
106
- ...overrides,
107
- });
108
-
109
- /**
110
- * Creates a scroll content style
111
- */
112
- export const createScrollContentStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
113
- padding: tokens.spacing.lg,
114
- ...overrides,
115
- });
116
-
117
- /**
118
- * Creates a separator/border style
119
- */
120
- export const createSeparatorStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
121
- height: 1,
122
- backgroundColor: tokens.colors.border,
123
- ...overrides,
124
- });
125
-
126
- /**
127
- * Creates a margin utility style
128
- */
129
- export const createMarginStyle = (
130
- spacing: 'xs' | 'sm' | 'md' | 'lg' | 'xl',
131
- tokens: DesignTokens,
132
- overrides: ViewStyle = {}
133
- ): ViewStyle => ({
134
- margin: tokens.spacing[spacing],
135
- ...overrides,
136
- });
137
-
138
- /**
139
- * Creates a padding utility style
140
- */
141
- export const createPaddingStyle = (
142
- spacing: 'xs' | 'sm' | 'md' | 'lg' | 'xl',
143
- tokens: DesignTokens,
144
- overrides: ViewStyle = {}
145
- ): ViewStyle => ({
146
- padding: tokens.spacing[spacing],
147
- ...overrides,
148
- });
149
-
150
- /**
151
- * Combines multiple styles into one
152
- */
153
- export const combineStyles = (
154
- ...styles: (ViewStyle | TextStyle | ImageStyle | undefined | false)[]
155
- ): ViewStyle | TextStyle | ImageStyle => {
156
- return StyleSheet.flatten(styles.filter(Boolean));
157
- };
158
-
159
- /**
160
- * Creates a responsive style based on screen dimensions
161
- */
162
- export const createResponsiveStyle = (
163
- _tokens: DesignTokens,
164
- phoneStyle: ViewStyle,
165
- _tabletStyle?: ViewStyle
166
- ): ViewStyle => {
167
- // For now, return phone style. Can be enhanced with actual responsive logic
168
- return phoneStyle;
169
- };
170
-
171
- /**
172
- * Type guard for ViewStyle
173
- */
174
- export const isViewStyle = (style: any): style is ViewStyle => {
175
- return style && typeof style === 'object';
176
- };
177
-
178
- /**
179
- * Creates a safe area aware style
180
- */
181
- export const createSafeAreaStyle = (
182
- insets: { top?: number; bottom?: number; left?: number; right?: number },
183
- overrides: ViewStyle = {}
184
- ): ViewStyle => ({
185
- paddingTop: insets.top,
186
- paddingBottom: insets.bottom,
187
- paddingLeft: insets.left,
188
- paddingRight: insets.right,
189
- ...overrides,
190
- });
7
+ export * from './styles';
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Component Style Utilities
3
+ * Reusable component styling patterns
4
+ */
5
+
6
+ import type { ViewStyle, TextStyle } from 'react-native';
7
+ import type { DesignTokens } from '@umituz/react-native-design-system';
8
+
9
+ /**
10
+ * Creates a header style
11
+ */
12
+ export const createHeaderStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
13
+ paddingHorizontal: tokens.spacing.lg,
14
+ paddingVertical: tokens.spacing.md,
15
+ ...overrides,
16
+ });
17
+
18
+ /**
19
+ * Creates a section style
20
+ */
21
+ export const createSectionStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
22
+ padding: tokens.spacing.lg,
23
+ ...overrides,
24
+ });
25
+
26
+ /**
27
+ * Creates a card style
28
+ */
29
+ export const createCardStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
30
+ backgroundColor: tokens.colors.surface,
31
+ borderRadius: tokens.borders.radius.md,
32
+ padding: tokens.spacing.lg,
33
+ ...overrides,
34
+ });
35
+
36
+ /**
37
+ * Creates a button style
38
+ */
39
+ export const createButtonStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
40
+ backgroundColor: tokens.colors.primary,
41
+ borderRadius: tokens.borders.radius.md,
42
+ paddingVertical: tokens.spacing.md,
43
+ paddingHorizontal: tokens.spacing.lg,
44
+ ...overrides,
45
+ });
46
+
47
+ /**
48
+ * Creates an icon container style
49
+ */
50
+ export const createIconContainerStyle = (
51
+ size: number = 48,
52
+ tokens: DesignTokens,
53
+ overrides: ViewStyle = {}
54
+ ): ViewStyle => ({
55
+ width: size,
56
+ height: size,
57
+ borderRadius: size / 2,
58
+ justifyContent: 'center',
59
+ alignItems: 'center',
60
+ backgroundColor: tokens.colors.surfaceSecondary,
61
+ ...overrides,
62
+ });
63
+
64
+ /**
65
+ * Creates a separator/border style
66
+ */
67
+ export const createSeparatorStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
68
+ height: 1,
69
+ backgroundColor: tokens.colors.border,
70
+ ...overrides,
71
+ });
72
+
73
+ /**
74
+ * Creates a title text style
75
+ */
76
+ export const createTitleStyle = (tokens: DesignTokens, overrides: TextStyle = {}): TextStyle => ({
77
+ fontSize: tokens.typography.headlineMedium.responsiveFontSize,
78
+ fontWeight: '600',
79
+ color: tokens.colors.textPrimary,
80
+ ...overrides,
81
+ });
82
+
83
+ /**
84
+ * Creates a subtitle text style
85
+ */
86
+ export const createSubtitleStyle = (tokens: DesignTokens, overrides: TextStyle = {}): TextStyle => ({
87
+ fontSize: tokens.typography.bodyMedium.responsiveFontSize,
88
+ color: tokens.colors.textSecondary,
89
+ ...overrides,
90
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Style Utilities - Index
3
+ * Centralized exports for all style utilities
4
+ */
5
+
6
+ export * from './layoutStyles';
7
+ export * from './componentStyles';
8
+ export * from './spacingStyles';
9
+ export * from './styleHelpers';
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Layout Style Utilities
3
+ * Common layout patterns
4
+ */
5
+
6
+ import type { ViewStyle } from 'react-native';
7
+ import type { DesignTokens } from '@umituz/react-native-design-system';
8
+
9
+ /**
10
+ * Creates a container style with flex 1
11
+ */
12
+ export const createContainerStyle = (overrides: ViewStyle = {}): ViewStyle => ({
13
+ flex: 1,
14
+ ...overrides,
15
+ });
16
+
17
+ /**
18
+ * Creates a centered container style
19
+ */
20
+ export const createCenteredContainerStyle = (overrides: ViewStyle = {}): ViewStyle => ({
21
+ flex: 1,
22
+ justifyContent: 'center',
23
+ alignItems: 'center',
24
+ ...overrides,
25
+ });
26
+
27
+ /**
28
+ * Creates a row style for horizontal layouts
29
+ */
30
+ export const createRowStyle = (overrides: ViewStyle = {}): ViewStyle => ({
31
+ flexDirection: 'row',
32
+ alignItems: 'center',
33
+ ...overrides,
34
+ });
35
+
36
+ /**
37
+ * Creates a scroll content style
38
+ */
39
+ export const createScrollContentStyle = (tokens: DesignTokens, overrides: ViewStyle = {}): ViewStyle => ({
40
+ padding: tokens.spacing.lg,
41
+ ...overrides,
42
+ });
43
+
44
+ /**
45
+ * Creates a safe area aware style
46
+ */
47
+ export const createSafeAreaStyle = (
48
+ insets: { top?: number; bottom?: number; left?: number; right?: number },
49
+ overrides: ViewStyle = {}
50
+ ): ViewStyle => ({
51
+ paddingTop: insets.top,
52
+ paddingBottom: insets.bottom,
53
+ paddingLeft: insets.left,
54
+ paddingRight: insets.right,
55
+ ...overrides,
56
+ });
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Spacing Style Utilities
3
+ * Margin and padding helpers
4
+ */
5
+
6
+ import type { ViewStyle } from 'react-native';
7
+ import type { DesignTokens } from '@umituz/react-native-design-system';
8
+
9
+ type SpacingSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
10
+
11
+ /**
12
+ * Creates a margin utility style
13
+ */
14
+ export const createMarginStyle = (
15
+ spacing: SpacingSize,
16
+ tokens: DesignTokens,
17
+ overrides: ViewStyle = {}
18
+ ): ViewStyle => ({
19
+ margin: tokens.spacing[spacing],
20
+ ...overrides,
21
+ });
22
+
23
+ /**
24
+ * Creates a padding utility style
25
+ */
26
+ export const createPaddingStyle = (
27
+ spacing: SpacingSize,
28
+ tokens: DesignTokens,
29
+ overrides: ViewStyle = {}
30
+ ): ViewStyle => ({
31
+ padding: tokens.spacing[spacing],
32
+ ...overrides,
33
+ });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Style Helper Utilities
3
+ * Generic style manipulation functions
4
+ */
5
+
6
+ import { StyleSheet, ViewStyle, TextStyle, ImageStyle } from 'react-native';
7
+
8
+ /**
9
+ * Combines multiple styles into one
10
+ */
11
+ export const combineStyles = (
12
+ ...styles: (ViewStyle | TextStyle | ImageStyle | undefined | false | null)[]
13
+ ): ViewStyle | TextStyle | ImageStyle => {
14
+ return StyleSheet.flatten(styles.filter(Boolean));
15
+ };
16
+
17
+ /**
18
+ * Type guard for ViewStyle
19
+ */
20
+ export const isViewStyle = (style: unknown): style is ViewStyle => {
21
+ return typeof style === 'object' && style !== null;
22
+ };
@@ -13,11 +13,10 @@ import { createAccountConfig } from "../utils/accountConfigUtils";
13
13
  import { useAuthHandlers } from "../utils/useAuthHandlers";
14
14
  import { translateFAQData } from "../utils/faqTranslator";
15
15
  import { useSettingsConfigFactory } from "../utils/settingsConfigFactory";
16
- import type { SettingsConfig } from "../screens/types";
16
+ import type { SettingsConfig, SettingsTranslations } from "../screens/types";
17
17
  import type { FeedbackFormData } from "../utils/config-creators";
18
18
  import type { AppInfo, FAQData, UserProfileDisplay, AdditionalScreen } from "../navigation/types";
19
19
  import type { AccountScreenConfig } from "@umituz/react-native-auth";
20
- import type { SettingsTranslations } from "../screens/types/SettingsConfig";
21
20
 
22
21
  export interface SettingsFeatures {
23
22
  notifications?: boolean;
@@ -1,4 +1,4 @@
1
- import type { SettingsTranslations } from "../../screens/types/SettingsConfig";
1
+ import type { SettingsTranslations } from "../../screens/types";
2
2
 
3
3
  export const createNotificationTranslations = (translations?: SettingsTranslations["features"]) => ({
4
4
  screenTitle: translations?.notifications?.title || "",
@@ -2,15 +2,15 @@ import React, { useMemo } from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
3
  import { SettingsFooter } from "../../components/SettingsFooter";
4
4
  import { SettingsSection } from "../../components/SettingsSection";
5
- import { DevSettingsSection, DevSettingsProps } from "../../../domains/dev";
5
+ import { DevSettingsSection } from "../../../domains/dev";
6
6
  import { DisclaimerSetting } from "../../../domains/disclaimer";
7
7
  import { ProfileSectionLoader } from "./sections/ProfileSectionLoader";
8
8
  import { FeatureSettingsSection } from "./sections/FeatureSettingsSection";
9
9
  import { IdentitySettingsSection } from "./sections/IdentitySettingsSection";
10
10
  import { SupportSettingsSection } from "./sections/SupportSettingsSection";
11
11
  import { CustomSettingsList } from "./sections/CustomSettingsList";
12
- import type { NormalizedConfig } from "../utils/normalizeConfig";
13
- import type { CustomSettingsSection } from "../types";
12
+ import { hasAnyFeaturesEnabled } from "./utils/featureChecker";
13
+ import type { SettingsContentProps } from "./types/SettingsContentProps";
14
14
 
15
15
  // Extracted Item Components
16
16
  import { SubscriptionSettingsItem } from "./SubscriptionSettingsItem";
@@ -18,44 +18,6 @@ import { WalletSettingsItem } from "./WalletSettingsItem";
18
18
  import { GamificationSettingsItem } from "./GamificationSettingsItem";
19
19
  import { VideoTutorialSettingsItem } from "./VideoTutorialSettingsItem";
20
20
 
21
- interface SettingsContentProps {
22
- normalizedConfig: NormalizedConfig;
23
- features: {
24
- appearance: boolean;
25
- language: boolean;
26
- notifications: boolean;
27
- about: boolean;
28
- legal: boolean;
29
- disclaimer: boolean;
30
- userProfile: boolean;
31
- feedback: boolean;
32
- rating: boolean;
33
- faqs: boolean;
34
- subscription: boolean;
35
- wallet: boolean;
36
- gamification: boolean;
37
- videoTutorial: boolean;
38
- };
39
- showUserProfile?: boolean;
40
- userProfile?: {
41
- displayName?: string;
42
- userId?: string;
43
- isAnonymous?: boolean;
44
- avatarUrl?: string;
45
- accountSettingsRoute?: string;
46
- onPress?: () => void;
47
- anonymousDisplayName?: string;
48
- avatarServiceUrl?: string;
49
- };
50
- showFooter?: boolean;
51
- footerText?: string;
52
- appVersion?: string;
53
- customSections?: CustomSettingsSection[];
54
- emptyStateText?: string;
55
- devSettings?: DevSettingsProps;
56
- gamificationConfig?: import("../../../domains/gamification").GamificationSettingsConfig;
57
- }
58
-
59
21
  export const SettingsContent: React.FC<SettingsContentProps> = ({
60
22
  normalizedConfig,
61
23
  features,
@@ -70,39 +32,9 @@ export const SettingsContent: React.FC<SettingsContentProps> = ({
70
32
  gamificationConfig,
71
33
  }) => {
72
34
  const translations = normalizedConfig.translations;
73
-
74
- // Optimize: Only track individual feature flags instead of entire object
75
- const hasAnyFeatures = useMemo(() =>
76
- features.appearance ||
77
- features.language ||
78
- features.notifications ||
79
- features.about ||
80
- features.legal ||
81
- features.disclaimer ||
82
- features.feedback ||
83
- features.rating ||
84
- features.faqs ||
85
- features.subscription ||
86
- features.wallet ||
87
- features.gamification ||
88
- features.videoTutorial ||
89
- customSections.length > 0,
90
- [
91
- features.appearance,
92
- features.language,
93
- features.notifications,
94
- features.about,
95
- features.legal,
96
- features.disclaimer,
97
- features.feedback,
98
- features.rating,
99
- features.faqs,
100
- features.subscription,
101
- features.wallet,
102
- features.gamification,
103
- features.videoTutorial,
104
- customSections.length,
105
- ]
35
+ const hasAnyFeatures = useMemo(
36
+ () => hasAnyFeaturesEnabled(features, customSections),
37
+ [features, customSections]
106
38
  );
107
39
 
108
40
  return (
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Settings Content Component Props
3
+ */
4
+
5
+ import type { NormalizedConfig } from "../../utils/normalizeConfig";
6
+ import type { CustomSettingsSection } from "../../types";
7
+ import type { DevSettingsProps } from "../../../../domains/dev";
8
+ import type { GamificationSettingsConfig } from "../../../../domains/gamification";
9
+
10
+ export interface SettingsContentFeatures {
11
+ [key: string]: boolean;
12
+ appearance: boolean;
13
+ language: boolean;
14
+ notifications: boolean;
15
+ about: boolean;
16
+ legal: boolean;
17
+ disclaimer: boolean;
18
+ userProfile: boolean;
19
+ feedback: boolean;
20
+ rating: boolean;
21
+ faqs: boolean;
22
+ subscription: boolean;
23
+ wallet: boolean;
24
+ gamification: boolean;
25
+ videoTutorial: boolean;
26
+ }
27
+
28
+ export interface SettingsContentUserProfile {
29
+ displayName?: string;
30
+ userId?: string;
31
+ isAnonymous?: boolean;
32
+ avatarUrl?: string;
33
+ accountSettingsRoute?: string;
34
+ onPress?: () => void;
35
+ anonymousDisplayName?: string;
36
+ avatarServiceUrl?: string;
37
+ }
38
+
39
+ export interface SettingsContentProps {
40
+ normalizedConfig: NormalizedConfig;
41
+ features: SettingsContentFeatures;
42
+ showUserProfile?: boolean;
43
+ userProfile?: SettingsContentUserProfile;
44
+ showFooter?: boolean;
45
+ footerText?: string;
46
+ appVersion?: string;
47
+ customSections?: CustomSettingsSection[];
48
+ emptyStateText?: string;
49
+ devSettings?: DevSettingsProps;
50
+ gamificationConfig?: GamificationSettingsConfig;
51
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Feature Checker Utilities
3
+ * Centralized logic for checking if features are enabled
4
+ */
5
+
6
+ import type { SettingsContentFeatures } from "../types/SettingsContentProps";
7
+ import type { CustomSettingsSection } from "../../types";
8
+
9
+ /**
10
+ * Check if any settings features are enabled
11
+ */
12
+ export function hasAnyFeaturesEnabled(
13
+ features: SettingsContentFeatures,
14
+ customSections: CustomSettingsSection[]
15
+ ): boolean {
16
+ return (
17
+ features.appearance ||
18
+ features.language ||
19
+ features.notifications ||
20
+ features.about ||
21
+ features.legal ||
22
+ features.disclaimer ||
23
+ features.feedback ||
24
+ features.rating ||
25
+ features.faqs ||
26
+ features.subscription ||
27
+ features.wallet ||
28
+ features.gamification ||
29
+ features.videoTutorial ||
30
+ customSections.length > 0
31
+ );
32
+ }
@@ -23,6 +23,7 @@ import type {
23
23
  GamificationItemConfig,
24
24
  VideoTutorialConfig,
25
25
  } from "./UserFeatureConfig";
26
+ import type { SettingsTranslations } from "./SettingsTranslations";
26
27
 
27
28
  /**
28
29
  * Main Settings Configuration
@@ -55,142 +56,6 @@ import type {
55
56
  * },
56
57
  * };
57
58
  */
58
- /**
59
- * Global Settings Translations
60
- */
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
- };
73
- sections?: {
74
- app?: string;
75
- progress?: string;
76
- about?: string;
77
- support?: string;
78
- subscription?: string;
79
- };
80
- features?: {
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
- };
138
- feedback?: { title?: string; description?: string };
139
- rating?: { 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
- };
159
- gamification?: {
160
- title?: string;
161
- description?: string;
162
- };
163
- };
164
- feedbackModal?: {
165
- title?: string;
166
- ratingLabel?: string;
167
- descriptionPlaceholder?: string;
168
- submitButton?: string;
169
- submittingButton?: string;
170
- types?: {
171
- general?: string;
172
- bugReport?: string;
173
- featureRequest?: string;
174
- improvement?: string;
175
- other?: string;
176
- };
177
- };
178
- noOptionsAvailable?: string;
179
- footer?: {
180
- version?: string;
181
- };
182
- errors?: {
183
- common?: string;
184
- unknown?: string;
185
- unknownError?: string;
186
- appStoreUrlMissing?: string;
187
- appStoreUrlNotConfigured?: string;
188
- unableToOpenAppStore?: string;
189
- failedToOpenAppStore?: string;
190
- deleteAccountError?: string;
191
- };
192
- }
193
-
194
59
  export interface SettingsConfig {
195
60
  /**
196
61
  * Application-wide translations
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Settings Translations Type
3
+ * Defines all translation keys for the settings package
4
+ */
5
+
6
+ /**
7
+ * Global Settings Translations
8
+ */
9
+ export interface SettingsTranslations {
10
+ title?: string;
11
+ profile?: {
12
+ guest?: string;
13
+ anonymousName?: string;
14
+ signIn?: string;
15
+ signInDescription?: string;
16
+ anonymousBenefits?: {
17
+ title?: string;
18
+ items?: string[];
19
+ };
20
+ };
21
+ sections?: {
22
+ app?: string;
23
+ progress?: string;
24
+ about?: string;
25
+ support?: string;
26
+ subscription?: string;
27
+ };
28
+ features?: {
29
+ appearance?: {
30
+ title?: string;
31
+ description?: string;
32
+ themeModes?: {
33
+ light?: string;
34
+ dark?: string;
35
+ auto?: string;
36
+ };
37
+ };
38
+ language?: {
39
+ title?: string;
40
+ description?: string;
41
+ searchPlaceholder?: string;
42
+ };
43
+ notifications?: {
44
+ title?: string;
45
+ description?: string;
46
+ masterToggleTitle?: string;
47
+ masterToggleDescription?: string;
48
+ soundTitle?: string;
49
+ soundDescription?: string;
50
+ vibrationTitle?: string;
51
+ vibrationDescription?: string;
52
+ remindersTitle?: string;
53
+ remindersDescription?: string;
54
+ quietHoursTitle?: string;
55
+ quietHoursDescription?: string;
56
+ quietHours?: {
57
+ title?: string;
58
+ description?: string;
59
+ startTimeLabel?: string;
60
+ endTimeLabel?: string;
61
+ enabledLabel?: string;
62
+ };
63
+ };
64
+ about?: {
65
+ title?: string;
66
+ description?: string;
67
+ contact?: string;
68
+ more?: string;
69
+ developer?: string;
70
+ email?: string;
71
+ website?: string;
72
+ moreApps?: string;
73
+ versionPrefix?: string;
74
+ };
75
+ legal?: {
76
+ title?: string;
77
+ description?: string;
78
+ documentsHeader?: string;
79
+ privacyTitle?: string;
80
+ privacyDescription?: string;
81
+ termsTitle?: string;
82
+ termsDescription?: string;
83
+ eulaTitle?: string;
84
+ eulaDescription?: string;
85
+ };
86
+ feedback?: { title?: string; description?: string };
87
+ rating?: { title?: string; description?: string };
88
+ faqs?: {
89
+ title?: string;
90
+ description?: string;
91
+ searchPlaceholder?: string;
92
+ emptySearchTitle?: string;
93
+ emptySearchMessage?: string;
94
+ headerTitle?: string;
95
+ };
96
+ languageSelection?: {
97
+ searchPlaceholder?: string;
98
+ };
99
+ subscription?: {
100
+ title?: string;
101
+ description?: string;
102
+ };
103
+ videoTutorial?: {
104
+ title?: string;
105
+ description?: string;
106
+ };
107
+ gamification?: {
108
+ title?: string;
109
+ description?: string;
110
+ };
111
+ };
112
+ feedbackModal?: {
113
+ title?: string;
114
+ ratingLabel?: string;
115
+ descriptionPlaceholder?: string;
116
+ submitButton?: string;
117
+ submittingButton?: string;
118
+ types?: {
119
+ general?: string;
120
+ bugReport?: string;
121
+ featureRequest?: string;
122
+ improvement?: string;
123
+ other?: string;
124
+ };
125
+ };
126
+ noOptionsAvailable?: string;
127
+ footer?: {
128
+ version?: string;
129
+ };
130
+ errors?: {
131
+ common?: string;
132
+ unknown?: string;
133
+ unknownError?: string;
134
+ appStoreUrlMissing?: string;
135
+ appStoreUrlNotConfigured?: string;
136
+ unableToOpenAppStore?: string;
137
+ failedToOpenAppStore?: string;
138
+ deleteAccountError?: string;
139
+ };
140
+ }
@@ -24,5 +24,6 @@ export type {
24
24
  VideoTutorialConfig,
25
25
  } from "./UserFeatureConfig";
26
26
  export type { GamificationSettingsConfig as GamificationConfig } from "../../../domains/gamification";
27
- export type { SettingsConfig, SettingsTranslations } from "./SettingsConfig";
27
+ export type { SettingsConfig } from "./SettingsConfig";
28
+ export type { SettingsTranslations } from "./SettingsTranslations";
28
29
  export type { CustomSettingsSection } from "./CustomSection";
@@ -13,7 +13,7 @@ import {
13
13
  } from "@umituz/react-native-auth";
14
14
  import { AlertService } from "@umituz/react-native-design-system";
15
15
  import type { AppInfo } from "../navigation/types";
16
- import type { SettingsTranslations } from "../screens/types/SettingsConfig";
16
+ import type { SettingsTranslations } from "../screens/types";
17
17
 
18
18
  declare const __DEV__: boolean;
19
19