@umituz/react-native-settings 4.21.8 → 4.21.10
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/presentation/navigation/SettingsStackNavigator.tsx +22 -30
- package/src/presentation/navigation/utils/index.ts +0 -1
- package/src/presentation/screens/components/SettingsContent.tsx +22 -8
- package/src/presentation/screens/types/UserFeatureConfig.ts +3 -1
- package/src/presentation/utils/configCreators.ts +5 -2
- package/src/presentation/navigation/utils/navigationScreenOptions.ts +0 -82
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-settings",
|
|
3
|
-
"version": "4.21.
|
|
3
|
+
"version": "4.21.10",
|
|
4
4
|
"description": "Complete settings hub for React Native apps - consolidated package with settings, about, legal, appearance, feedback, FAQs, rating, and gamification",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -10,7 +10,7 @@ import { createStackNavigator } from "@react-navigation/stack";
|
|
|
10
10
|
import { useLocalization, LanguageSelectionScreen } from "@umituz/react-native-localization";
|
|
11
11
|
import { NotificationSettingsScreen } from "@umituz/react-native-notifications";
|
|
12
12
|
import { AccountScreen } from "@umituz/react-native-auth";
|
|
13
|
-
import { useAppDesignTokens } from "@umituz/react-native-design-system";
|
|
13
|
+
import { useAppDesignTokens, createScreenOptions } from "@umituz/react-native-design-system";
|
|
14
14
|
import { AppearanceScreen } from "../screens/AppearanceScreen";
|
|
15
15
|
import { FAQScreen } from "../../domains/faqs";
|
|
16
16
|
import { useNavigationHandlers } from "./hooks";
|
|
@@ -23,16 +23,6 @@ import {
|
|
|
23
23
|
createNotificationTranslations,
|
|
24
24
|
createQuietHoursTranslations,
|
|
25
25
|
createLegalScreenProps,
|
|
26
|
-
createScreenOptions,
|
|
27
|
-
createAppearanceScreenOptions,
|
|
28
|
-
createAboutScreenOptions,
|
|
29
|
-
createLegalScreenOptions,
|
|
30
|
-
createNotificationsScreenOptions,
|
|
31
|
-
createFAQScreenOptions,
|
|
32
|
-
createLanguageSelectionScreenOptions,
|
|
33
|
-
createGamificationScreenOptions,
|
|
34
|
-
createAccountScreenOptions,
|
|
35
|
-
createSettingsMainScreenOptions,
|
|
36
26
|
} from "./utils";
|
|
37
27
|
import type { SettingsStackParamList, SettingsStackNavigatorProps } from "./types";
|
|
38
28
|
import { GamificationScreenWrapper } from "../../domains/gamification";
|
|
@@ -58,7 +48,18 @@ export const SettingsStackNavigator: React.FC<SettingsStackNavigatorProps> = ({
|
|
|
58
48
|
const { handlePrivacyPress, handleTermsPress, handleEulaPress, aboutConfig } =
|
|
59
49
|
useNavigationHandlers(appInfo, legalUrls);
|
|
60
50
|
|
|
61
|
-
const screenOptions = React.useMemo(
|
|
51
|
+
const screenOptions = React.useMemo(
|
|
52
|
+
() =>
|
|
53
|
+
createScreenOptions({
|
|
54
|
+
colors: {
|
|
55
|
+
surface: tokens.colors.surface,
|
|
56
|
+
textPrimary: tokens.colors.textPrimary,
|
|
57
|
+
borderLight: tokens.colors.borderLight,
|
|
58
|
+
},
|
|
59
|
+
backTitle: t("settings.title"),
|
|
60
|
+
}),
|
|
61
|
+
[tokens, t]
|
|
62
|
+
);
|
|
62
63
|
const notificationTranslations = React.useMemo(() => createNotificationTranslations(t), [t]);
|
|
63
64
|
const quietHoursTranslations = React.useMemo(() => createQuietHoursTranslations(t), [t]);
|
|
64
65
|
const legalScreenProps = React.useMemo(
|
|
@@ -70,7 +71,7 @@ export const SettingsStackNavigator: React.FC<SettingsStackNavigatorProps> = ({
|
|
|
70
71
|
<Stack.Navigator screenOptions={screenOptions}>
|
|
71
72
|
<Stack.Screen
|
|
72
73
|
name="SettingsMain"
|
|
73
|
-
options={showHeader ?
|
|
74
|
+
options={showHeader ? { headerTitle: t("settings.title") } : { headerShown: false }}
|
|
74
75
|
>
|
|
75
76
|
{() => (
|
|
76
77
|
<SettingsScreenWrapper
|
|
@@ -88,26 +89,20 @@ export const SettingsStackNavigator: React.FC<SettingsStackNavigatorProps> = ({
|
|
|
88
89
|
<Stack.Screen
|
|
89
90
|
name="Appearance"
|
|
90
91
|
component={AppearanceScreen}
|
|
91
|
-
options={
|
|
92
|
+
options={{ headerTitle: t("settings.appearance.title") }}
|
|
92
93
|
/>
|
|
93
94
|
|
|
94
|
-
<Stack.Screen
|
|
95
|
-
name="About"
|
|
96
|
-
options={createAboutScreenOptions(t)}
|
|
97
|
-
>
|
|
95
|
+
<Stack.Screen name="About" options={{ headerTitle: t("settings.about.title") }}>
|
|
98
96
|
{() => <AboutScreenWrapper config={aboutConfig} />}
|
|
99
97
|
</Stack.Screen>
|
|
100
98
|
|
|
101
|
-
<Stack.Screen
|
|
102
|
-
name="Legal"
|
|
103
|
-
options={createLegalScreenOptions(t)}
|
|
104
|
-
>
|
|
99
|
+
<Stack.Screen name="Legal" options={{ headerTitle: t("settings.legal.title") }}>
|
|
105
100
|
{() => <LegalScreenWrapper {...legalScreenProps} />}
|
|
106
101
|
</Stack.Screen>
|
|
107
102
|
|
|
108
103
|
<Stack.Screen
|
|
109
104
|
name="Notifications"
|
|
110
|
-
options={
|
|
105
|
+
options={{ headerTitle: t("settings.notifications.title") }}
|
|
111
106
|
>
|
|
112
107
|
{() => (
|
|
113
108
|
<NotificationSettingsScreen
|
|
@@ -118,7 +113,7 @@ export const SettingsStackNavigator: React.FC<SettingsStackNavigatorProps> = ({
|
|
|
118
113
|
</Stack.Screen>
|
|
119
114
|
|
|
120
115
|
{faqData && faqData.categories.length > 0 && (
|
|
121
|
-
<Stack.Screen name="FAQ" options={
|
|
116
|
+
<Stack.Screen name="FAQ" options={{ headerTitle: t("settings.faqs.title") }}>
|
|
122
117
|
{() => (
|
|
123
118
|
<FAQScreen
|
|
124
119
|
categories={faqData.categories}
|
|
@@ -153,7 +148,7 @@ export const SettingsStackNavigator: React.FC<SettingsStackNavigatorProps> = ({
|
|
|
153
148
|
{gamificationConfig?.enabled && (
|
|
154
149
|
<Stack.Screen
|
|
155
150
|
name="Gamification"
|
|
156
|
-
options={
|
|
151
|
+
options={{ headerTitle: t("settings.gamification.title") }}
|
|
157
152
|
>
|
|
158
153
|
{() => <GamificationScreenWrapper config={gamificationConfig} />}
|
|
159
154
|
</Stack.Screen>
|
|
@@ -161,7 +156,7 @@ export const SettingsStackNavigator: React.FC<SettingsStackNavigatorProps> = ({
|
|
|
161
156
|
|
|
162
157
|
<Stack.Screen
|
|
163
158
|
name="LanguageSelection"
|
|
164
|
-
options={
|
|
159
|
+
options={{ headerTitle: t("settings.language.title") }}
|
|
165
160
|
>
|
|
166
161
|
{() => (
|
|
167
162
|
<LanguageSelectionScreen
|
|
@@ -171,10 +166,7 @@ export const SettingsStackNavigator: React.FC<SettingsStackNavigatorProps> = ({
|
|
|
171
166
|
</Stack.Screen>
|
|
172
167
|
|
|
173
168
|
{accountConfig && (
|
|
174
|
-
<Stack.Screen
|
|
175
|
-
name="Account"
|
|
176
|
-
options={createAccountScreenOptions(t)}
|
|
177
|
-
>
|
|
169
|
+
<Stack.Screen name="Account" options={{ headerTitle: t("settings.account.title") }}>
|
|
178
170
|
{() => <AccountScreen config={accountConfig} />}
|
|
179
171
|
</Stack.Screen>
|
|
180
172
|
)}
|
|
@@ -34,6 +34,26 @@ const WalletSettingsItem: React.FC<{ config: WalletConfig; t: (key: string) => s
|
|
|
34
34
|
);
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
const SubscriptionSettingsItem: React.FC<{ config: any; t: (key: string) => string }> = ({ config, t }) => {
|
|
38
|
+
const navigation = useNavigation();
|
|
39
|
+
const handlePress = () => {
|
|
40
|
+
if (config.route) {
|
|
41
|
+
navigation.navigate(config.route as never);
|
|
42
|
+
} else if (config.onPress) {
|
|
43
|
+
config.onPress();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
return (
|
|
47
|
+
<SettingsItemCard
|
|
48
|
+
title={config.title || t("settings.subscription.title")}
|
|
49
|
+
description={config.description || t("settings.subscription.description")}
|
|
50
|
+
icon={(config.icon || "star") as IconName}
|
|
51
|
+
onPress={handlePress}
|
|
52
|
+
sectionTitle={config.sectionTitle}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
37
57
|
interface SettingsContentProps {
|
|
38
58
|
normalizedConfig: NormalizedConfig;
|
|
39
59
|
config?: any;
|
|
@@ -98,14 +118,8 @@ export const SettingsContent: React.FC<SettingsContentProps> = ({
|
|
|
98
118
|
|
|
99
119
|
<CustomSettingsList customSections={customSections} />
|
|
100
120
|
|
|
101
|
-
{features.subscription && normalizedConfig.subscription.config?.onPress && (
|
|
102
|
-
<
|
|
103
|
-
title={normalizedConfig.subscription.config.title || t("settings.subscription.title")}
|
|
104
|
-
description={normalizedConfig.subscription.config.description || t("settings.subscription.description")}
|
|
105
|
-
icon={(normalizedConfig.subscription.config.icon || "star") as IconName}
|
|
106
|
-
onPress={normalizedConfig.subscription.config.onPress}
|
|
107
|
-
sectionTitle={normalizedConfig.subscription.config.sectionTitle}
|
|
108
|
-
/>
|
|
121
|
+
{features.subscription && (normalizedConfig.subscription.config?.route || normalizedConfig.subscription.config?.onPress) && (
|
|
122
|
+
<SubscriptionSettingsItem config={normalizedConfig.subscription.config} t={t} />
|
|
109
123
|
)}
|
|
110
124
|
|
|
111
125
|
{features.wallet && normalizedConfig.wallet.config?.route && (
|
|
@@ -112,7 +112,9 @@ export interface SubscriptionConfig {
|
|
|
112
112
|
icon?: string;
|
|
113
113
|
/** Custom section title for grouping */
|
|
114
114
|
sectionTitle?: string;
|
|
115
|
-
/**
|
|
115
|
+
/** Navigation route for subscription screen (preferred over onPress) */
|
|
116
|
+
route?: string;
|
|
117
|
+
/** Handler to open subscription screen (use route instead for stack navigation) */
|
|
116
118
|
onPress?: () => void;
|
|
117
119
|
/** Whether user is premium (to show active status) */
|
|
118
120
|
isPremium?: boolean;
|
|
@@ -130,11 +130,13 @@ export const createFAQConfig = (
|
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
132
|
* Create subscription configuration
|
|
133
|
+
* @param route - Navigation route name (preferred for stack navigation)
|
|
134
|
+
* @param onPress - Callback function (use route instead when possible)
|
|
133
135
|
*/
|
|
134
136
|
export const createSubscriptionConfig = (
|
|
135
137
|
t: TranslationFunction,
|
|
136
138
|
isPremium: boolean,
|
|
137
|
-
|
|
139
|
+
routeOrOnPress: string | (() => void),
|
|
138
140
|
): SubscriptionConfig => ({
|
|
139
141
|
enabled: true,
|
|
140
142
|
title: t("settings.subscription.title"),
|
|
@@ -143,6 +145,7 @@ export const createSubscriptionConfig = (
|
|
|
143
145
|
: t("settings.subscription.description"),
|
|
144
146
|
icon: "diamond",
|
|
145
147
|
sectionTitle: t("settings.sections.subscription").toUpperCase(),
|
|
146
|
-
|
|
148
|
+
route: typeof routeOrOnPress === "string" ? routeOrOnPress : undefined,
|
|
149
|
+
onPress: typeof routeOrOnPress === "function" ? routeOrOnPress : undefined,
|
|
147
150
|
isPremium,
|
|
148
151
|
});
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Navigation Screen Options Utility
|
|
3
|
-
* Creates screen options for settings navigation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { DesignTokens } from "@umituz/react-native-design-system";
|
|
7
|
-
|
|
8
|
-
type TranslationFunction = (key: string) => string;
|
|
9
|
-
|
|
10
|
-
export const createScreenOptions = (tokens: DesignTokens, t: TranslationFunction) => ({
|
|
11
|
-
headerStyle: {
|
|
12
|
-
backgroundColor: tokens.colors.surface,
|
|
13
|
-
borderBottomColor: tokens.colors.borderLight,
|
|
14
|
-
borderBottomWidth: 1,
|
|
15
|
-
},
|
|
16
|
-
headerTitleStyle: {
|
|
17
|
-
fontSize: 18,
|
|
18
|
-
fontWeight: "600" as const,
|
|
19
|
-
color: tokens.colors.textPrimary,
|
|
20
|
-
},
|
|
21
|
-
headerTintColor: tokens.colors.textPrimary,
|
|
22
|
-
headerBackTitle: t("settings.title"),
|
|
23
|
-
headerBackTitleStyle: {
|
|
24
|
-
fontSize: 16,
|
|
25
|
-
color: tokens.colors.textPrimary,
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
export const createAppearanceScreenOptions = (t: any) => ({
|
|
30
|
-
headerShown: true,
|
|
31
|
-
headerTitle: t("settings.appearance.title"),
|
|
32
|
-
headerTitleAlign: "center" as const,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
export const createAboutScreenOptions = (t: any) => ({
|
|
36
|
-
headerShown: true,
|
|
37
|
-
headerTitle: t("settings.about.title"),
|
|
38
|
-
headerTitleAlign: "center" as const,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
export const createLegalScreenOptions = (t: any) => ({
|
|
42
|
-
headerShown: true,
|
|
43
|
-
headerTitle: t("settings.legal.title"),
|
|
44
|
-
headerTitleAlign: "center" as const,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
export const createNotificationsScreenOptions = (t: any) => ({
|
|
48
|
-
headerShown: true,
|
|
49
|
-
headerTitle: t("settings.notifications.title"),
|
|
50
|
-
headerTitleAlign: "center" as const,
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
export const createFAQScreenOptions = (t: any) => ({
|
|
54
|
-
headerShown: true,
|
|
55
|
-
headerTitle: t("settings.faqs.title"),
|
|
56
|
-
headerTitleAlign: "center" as const,
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
export const createLanguageSelectionScreenOptions = (t: any) => ({
|
|
60
|
-
headerShown: true,
|
|
61
|
-
headerTitle: t("settings.language.title"),
|
|
62
|
-
headerTitleAlign: "center" as const,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
export const createGamificationScreenOptions = (t: any) => ({
|
|
66
|
-
headerShown: true,
|
|
67
|
-
headerTitle: t("settings.gamification.title"),
|
|
68
|
-
headerTitleAlign: "center" as const,
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
export const createAccountScreenOptions = (t: any) => ({
|
|
72
|
-
headerShown: true,
|
|
73
|
-
headerTitle: t("settings.account.title"),
|
|
74
|
-
headerTitleAlign: "center" as const,
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
export const createSettingsMainScreenOptions = (t: any) => ({
|
|
78
|
-
headerShown: true,
|
|
79
|
-
headerTitle: t("settings.title"),
|
|
80
|
-
headerTitleAlign: "center" as const,
|
|
81
|
-
});
|
|
82
|
-
|