@umituz/react-native-settings 4.17.30 → 4.17.32
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/faqs/presentation/screens/FAQScreen.tsx +1 -1
- package/src/index.ts +4 -0
- package/src/presentation/screens/components/sections/FeatureSettingsSection.tsx +52 -39
- package/src/presentation/screens/components/sections/SubscriptionSettingsItem.tsx +157 -0
- package/src/presentation/screens/hooks/useFeatureDetection.ts +2 -1
- package/src/presentation/screens/types/FeatureConfig.ts +17 -10
- package/src/presentation/screens/types/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-settings",
|
|
3
|
-
"version": "4.17.
|
|
3
|
+
"version": "4.17.32",
|
|
4
4
|
"description": "Complete settings hub for React Native apps - consolidated package with settings, about, legal, appearance, feedback, FAQs, and rating",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -120,7 +120,7 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
return (
|
|
123
|
-
<ScreenLayout edges={['bottom']}>
|
|
123
|
+
<ScreenLayout edges={['bottom']} scrollable={false}>
|
|
124
124
|
<View style={[styles.container, customStyles?.container]}>
|
|
125
125
|
{renderContent()}
|
|
126
126
|
</View>
|
package/src/index.ts
CHANGED
|
@@ -64,6 +64,7 @@ export type {
|
|
|
64
64
|
SettingsConfig,
|
|
65
65
|
CustomSettingsSection,
|
|
66
66
|
SubscriptionConfig,
|
|
67
|
+
SubscriptionSettingsItemConfig,
|
|
67
68
|
} from './presentation/screens/types';
|
|
68
69
|
|
|
69
70
|
// =============================================================================
|
|
@@ -87,6 +88,9 @@ export type { StorageClearSettingProps } from './presentation/components/Storage
|
|
|
87
88
|
export { DevSettingsSection } from './presentation/components/DevSettingsSection';
|
|
88
89
|
export type { DevSettingsProps } from './presentation/components/DevSettingsSection';
|
|
89
90
|
|
|
91
|
+
export { SubscriptionSettingsItem } from './presentation/screens/components/sections/SubscriptionSettingsItem';
|
|
92
|
+
export type { SubscriptionSettingsItemProps } from './presentation/screens/components/sections/SubscriptionSettingsItem';
|
|
93
|
+
|
|
90
94
|
// =============================================================================
|
|
91
95
|
// DOMAIN EXPORTS - Consolidated Features
|
|
92
96
|
// =============================================================================
|
|
@@ -3,53 +3,66 @@ import { AppearanceSection } from "../../../../domains/appearance/presentation/c
|
|
|
3
3
|
import { LanguageSection } from "@umituz/react-native-localization";
|
|
4
4
|
import { NotificationsSection } from "@umituz/react-native-notifications";
|
|
5
5
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
6
|
+
import { SubscriptionSettingsItem } from "./SubscriptionSettingsItem";
|
|
6
7
|
import type { NormalizedConfig } from "../../utils/normalizeConfig";
|
|
7
8
|
|
|
8
9
|
interface FeatureSettingsSectionProps {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
normalizedConfig: NormalizedConfig;
|
|
11
|
+
features: {
|
|
12
|
+
appearance: boolean;
|
|
13
|
+
language: boolean;
|
|
14
|
+
notifications: boolean;
|
|
15
|
+
subscription: boolean;
|
|
16
|
+
};
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
export const FeatureSettingsSection: React.FC<FeatureSettingsSectionProps> = ({
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
normalizedConfig,
|
|
21
|
+
features,
|
|
16
22
|
}) => {
|
|
17
|
-
|
|
23
|
+
const { t } = useLocalization();
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
return (
|
|
26
|
+
<>
|
|
27
|
+
{features.appearance && (
|
|
28
|
+
<AppearanceSection
|
|
29
|
+
config={{
|
|
30
|
+
...normalizedConfig.appearance.config,
|
|
31
|
+
title: t("settings.appearance.title"),
|
|
32
|
+
description: t("settings.appearance.description"),
|
|
33
|
+
}}
|
|
34
|
+
sectionTitle={t("settings.appearance.title")}
|
|
35
|
+
/>
|
|
36
|
+
)}
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
{features.language && (
|
|
39
|
+
<LanguageSection
|
|
40
|
+
config={{
|
|
41
|
+
...normalizedConfig.language.config,
|
|
42
|
+
title: t("settings.languageSelection.title"),
|
|
43
|
+
description:
|
|
44
|
+
normalizedConfig.language.config?.description ||
|
|
45
|
+
t("settings.languageSelection.description"),
|
|
46
|
+
}}
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
{features.notifications && (
|
|
51
|
+
<NotificationsSection
|
|
52
|
+
config={{
|
|
53
|
+
...normalizedConfig.notifications.config,
|
|
54
|
+
title: t("settings.notifications.title"),
|
|
55
|
+
description: t("settings.notifications.description"),
|
|
56
|
+
}}
|
|
57
|
+
/>
|
|
58
|
+
)}
|
|
59
|
+
|
|
60
|
+
{features.subscription && normalizedConfig.subscription.config?.settingsItem && (
|
|
61
|
+
<SubscriptionSettingsItem
|
|
62
|
+
config={normalizedConfig.subscription.config.settingsItem}
|
|
63
|
+
sectionTitle={t("settings.subscription.title")}
|
|
64
|
+
/>
|
|
65
|
+
)}
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
55
68
|
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subscription Settings Item
|
|
3
|
+
* Settings-style item for subscription/premium status display
|
|
4
|
+
* Follows same visual pattern as other settings items
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from "react";
|
|
8
|
+
import { View, Pressable, StyleSheet } from "react-native";
|
|
9
|
+
import {
|
|
10
|
+
useResponsiveDesignTokens,
|
|
11
|
+
AtomicIcon,
|
|
12
|
+
AtomicText,
|
|
13
|
+
} from "@umituz/react-native-design-system";
|
|
14
|
+
|
|
15
|
+
export interface SubscriptionSettingsItemConfig {
|
|
16
|
+
title: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
isPremium: boolean;
|
|
19
|
+
statusLabel: string;
|
|
20
|
+
icon?: string;
|
|
21
|
+
onPress?: () => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface SubscriptionSettingsItemProps {
|
|
25
|
+
config: SubscriptionSettingsItemConfig;
|
|
26
|
+
sectionTitle?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const SubscriptionSettingsItem: React.FC<SubscriptionSettingsItemProps> = ({
|
|
30
|
+
config,
|
|
31
|
+
sectionTitle,
|
|
32
|
+
}) => {
|
|
33
|
+
const tokens = useResponsiveDesignTokens();
|
|
34
|
+
const colors = tokens.colors;
|
|
35
|
+
|
|
36
|
+
const { title, description, isPremium, statusLabel, icon, onPress } = config;
|
|
37
|
+
const displaySectionTitle = sectionTitle || title;
|
|
38
|
+
|
|
39
|
+
if (!title) return null;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<View style={[styles.sectionContainer, { backgroundColor: colors.surface }]}>
|
|
43
|
+
{!!displaySectionTitle && (
|
|
44
|
+
<View style={styles.headerContainer}>
|
|
45
|
+
<AtomicText type="titleMedium" color="primary">
|
|
46
|
+
{displaySectionTitle}
|
|
47
|
+
</AtomicText>
|
|
48
|
+
</View>
|
|
49
|
+
)}
|
|
50
|
+
<Pressable
|
|
51
|
+
style={({ pressed }) => [
|
|
52
|
+
styles.itemContainer,
|
|
53
|
+
{ backgroundColor: pressed ? `${colors.primary}08` : "transparent" },
|
|
54
|
+
]}
|
|
55
|
+
onPress={onPress}
|
|
56
|
+
>
|
|
57
|
+
<View style={styles.content}>
|
|
58
|
+
<View
|
|
59
|
+
style={[
|
|
60
|
+
styles.iconContainer,
|
|
61
|
+
{ backgroundColor: isPremium ? `${colors.primary}15` : `${colors.textTertiary}15` },
|
|
62
|
+
]}
|
|
63
|
+
>
|
|
64
|
+
<AtomicIcon
|
|
65
|
+
name={icon || "diamond"}
|
|
66
|
+
size="lg"
|
|
67
|
+
color={isPremium ? "primary" : "secondary"}
|
|
68
|
+
/>
|
|
69
|
+
</View>
|
|
70
|
+
<View style={styles.textContainer}>
|
|
71
|
+
<View style={styles.titleRow}>
|
|
72
|
+
<AtomicText
|
|
73
|
+
type="bodyLarge"
|
|
74
|
+
color="primary"
|
|
75
|
+
numberOfLines={1}
|
|
76
|
+
style={styles.title}
|
|
77
|
+
>
|
|
78
|
+
{title}
|
|
79
|
+
</AtomicText>
|
|
80
|
+
<View
|
|
81
|
+
style={[
|
|
82
|
+
styles.statusBadge,
|
|
83
|
+
{ backgroundColor: isPremium ? colors.success : colors.textTertiary },
|
|
84
|
+
]}
|
|
85
|
+
>
|
|
86
|
+
<AtomicText type="labelSmall" style={styles.statusText}>
|
|
87
|
+
{statusLabel}
|
|
88
|
+
</AtomicText>
|
|
89
|
+
</View>
|
|
90
|
+
</View>
|
|
91
|
+
{!!description && (
|
|
92
|
+
<AtomicText type="bodyMedium" color="secondary" numberOfLines={2}>
|
|
93
|
+
{description}
|
|
94
|
+
</AtomicText>
|
|
95
|
+
)}
|
|
96
|
+
</View>
|
|
97
|
+
<AtomicIcon name="chevron-forward" size="md" color="secondary" />
|
|
98
|
+
</View>
|
|
99
|
+
</Pressable>
|
|
100
|
+
</View>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const styles = StyleSheet.create({
|
|
105
|
+
sectionContainer: {
|
|
106
|
+
marginBottom: 16,
|
|
107
|
+
borderRadius: 12,
|
|
108
|
+
overflow: "hidden",
|
|
109
|
+
},
|
|
110
|
+
headerContainer: {
|
|
111
|
+
paddingHorizontal: 16,
|
|
112
|
+
paddingTop: 16,
|
|
113
|
+
paddingBottom: 8,
|
|
114
|
+
},
|
|
115
|
+
itemContainer: {
|
|
116
|
+
flexDirection: "row",
|
|
117
|
+
alignItems: "center",
|
|
118
|
+
paddingHorizontal: 16,
|
|
119
|
+
paddingVertical: 16,
|
|
120
|
+
minHeight: 72,
|
|
121
|
+
},
|
|
122
|
+
content: {
|
|
123
|
+
flex: 1,
|
|
124
|
+
flexDirection: "row",
|
|
125
|
+
alignItems: "center",
|
|
126
|
+
},
|
|
127
|
+
iconContainer: {
|
|
128
|
+
width: 48,
|
|
129
|
+
height: 48,
|
|
130
|
+
borderRadius: 12,
|
|
131
|
+
justifyContent: "center",
|
|
132
|
+
alignItems: "center",
|
|
133
|
+
marginRight: 16,
|
|
134
|
+
},
|
|
135
|
+
textContainer: {
|
|
136
|
+
flex: 1,
|
|
137
|
+
marginRight: 8,
|
|
138
|
+
},
|
|
139
|
+
titleRow: {
|
|
140
|
+
flexDirection: "row",
|
|
141
|
+
alignItems: "center",
|
|
142
|
+
marginBottom: 4,
|
|
143
|
+
},
|
|
144
|
+
title: {
|
|
145
|
+
flex: 1,
|
|
146
|
+
},
|
|
147
|
+
statusBadge: {
|
|
148
|
+
paddingHorizontal: 8,
|
|
149
|
+
paddingVertical: 2,
|
|
150
|
+
borderRadius: 4,
|
|
151
|
+
marginLeft: 8,
|
|
152
|
+
},
|
|
153
|
+
statusText: {
|
|
154
|
+
color: "#FFFFFF",
|
|
155
|
+
fontWeight: "600",
|
|
156
|
+
},
|
|
157
|
+
});
|
|
@@ -110,7 +110,8 @@ export function useFeatureDetection(
|
|
|
110
110
|
userProfile: userProfile.enabled,
|
|
111
111
|
subscription:
|
|
112
112
|
subscription.enabled &&
|
|
113
|
-
subscription.config?.
|
|
113
|
+
(subscription.config?.settingsItem !== undefined ||
|
|
114
|
+
subscription.config?.sectionConfig !== undefined),
|
|
114
115
|
feedback: feedback.enabled,
|
|
115
116
|
rating: rating.enabled,
|
|
116
117
|
faqs: faqs.enabled,
|
|
@@ -149,22 +149,29 @@ export interface UserProfileConfig {
|
|
|
149
149
|
accountSettingsRoute?: string;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Subscription Settings Item Config
|
|
154
|
+
* Simplified config for settings list item display
|
|
155
|
+
*/
|
|
156
|
+
export interface SubscriptionSettingsItemConfig {
|
|
157
|
+
title: string;
|
|
158
|
+
description?: string;
|
|
159
|
+
isPremium: boolean;
|
|
160
|
+
statusLabel: string;
|
|
161
|
+
icon?: string;
|
|
162
|
+
onPress?: () => void;
|
|
163
|
+
}
|
|
164
|
+
|
|
152
165
|
/**
|
|
153
166
|
* Subscription Settings Configuration
|
|
154
|
-
* App must provide all data via
|
|
167
|
+
* App must provide all data via props (no internal fetch)
|
|
155
168
|
*/
|
|
156
169
|
export interface SubscriptionConfig {
|
|
157
170
|
/** Show subscription section */
|
|
158
171
|
enabled?: FeatureVisibility;
|
|
159
|
-
/**
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
description?: string;
|
|
163
|
-
/** Custom icon name (Ionicons) */
|
|
164
|
-
icon?: string;
|
|
165
|
-
/** Custom section title for grouping */
|
|
166
|
-
sectionTitle?: string;
|
|
167
|
-
/** Section configuration (app provides all data) */
|
|
172
|
+
/** Settings item configuration (for settings list display) */
|
|
173
|
+
settingsItem?: SubscriptionSettingsItemConfig;
|
|
174
|
+
/** Detail section configuration (for detail screen) */
|
|
168
175
|
sectionConfig?: {
|
|
169
176
|
statusType: "active" | "expired" | "none";
|
|
170
177
|
isPremium: boolean;
|