@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.
- package/package.json +1 -1
- package/src/domains/feedback/presentation/components/FeedbackForm.tsx +1 -15
- package/src/domains/feedback/presentation/components/FeedbackFormProps.ts +26 -0
- package/src/domains/feedback/presentation/components/FeedbackModal.tsx +1 -1
- package/src/domains/gamification/components/AchievementCard.tsx +1 -2
- package/src/domains/gamification/components/AchievementItem.tsx +6 -92
- package/src/domains/gamification/components/GamificationScreen/AchievementsList.tsx +1 -1
- package/src/domains/gamification/components/GamificationScreen/types.ts +1 -1
- package/src/domains/gamification/components/index.ts +2 -1
- package/src/domains/gamification/components/styles/achievementItemStyles.ts +74 -0
- package/src/domains/gamification/components/types/AchievementItemProps.ts +25 -0
- package/src/infrastructure/utils/errorHandlers.ts +2 -3
- package/src/infrastructure/utils/styleUtils.ts +3 -186
- package/src/infrastructure/utils/styles/componentStyles.ts +90 -0
- package/src/infrastructure/utils/styles/index.ts +9 -0
- package/src/infrastructure/utils/styles/layoutStyles.ts +56 -0
- package/src/infrastructure/utils/styles/spacingStyles.ts +33 -0
- package/src/infrastructure/utils/styles/styleHelpers.ts +22 -0
- package/src/presentation/hooks/useSettingsScreenConfig.ts +1 -2
- package/src/presentation/navigation/utils/navigationTranslations.ts +1 -1
- package/src/presentation/screens/components/SettingsContent.tsx +6 -74
- package/src/presentation/screens/components/types/SettingsContentProps.ts +51 -0
- package/src/presentation/screens/components/utils/featureChecker.ts +32 -0
- package/src/presentation/screens/types/SettingsConfig.ts +1 -136
- package/src/presentation/screens/types/SettingsTranslations.ts +140 -0
- package/src/presentation/screens/types/index.ts +2 -1
- 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.
|
|
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 "./
|
|
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
|
|
7
|
+
import { View } from "react-native";
|
|
8
8
|
import { useAppDesignTokens, AtomicText, AtomicIcon, withAlpha } from "@umituz/react-native-design-system";
|
|
9
|
-
|
|
10
|
-
|
|
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}
|
|
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 "../
|
|
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 "../
|
|
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
|
|
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
|
-
//
|
|
184
|
+
// Log errors in development mode
|
|
185
185
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
186
186
|
console.error("[Error]", logData);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
//
|
|
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
|
-
*
|
|
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,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
|
|
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
|
|
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
|
|
13
|
-
import type {
|
|
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
|
-
|
|
75
|
-
|
|
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
|
|
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
|
|
16
|
+
import type { SettingsTranslations } from "../screens/types";
|
|
17
17
|
|
|
18
18
|
declare const __DEV__: boolean;
|
|
19
19
|
|