@umituz/react-native-settings 1.3.8 → 1.4.1
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-settings",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Settings management for React Native apps - user preferences, theme, language, notifications",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
"@umituz/react-native-design-system": "latest",
|
|
34
34
|
"@umituz/react-native-design-system-theme": "latest",
|
|
35
35
|
"@umituz/react-native-localization": "latest",
|
|
36
|
-
"react-native-paper": "^5.12.3",
|
|
37
36
|
"expo-linear-gradient": "~14.0.0"
|
|
38
37
|
},
|
|
39
38
|
"devDependencies": {
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import React from 'react';
|
|
15
|
-
import { View, StyleSheet } from 'react-native';
|
|
16
|
-
import { List } from 'react-native-paper';
|
|
15
|
+
import { View, StyleSheet, TouchableOpacity } from 'react-native';
|
|
17
16
|
import { LinearGradient } from 'expo-linear-gradient';
|
|
18
17
|
import { AtomicText, AtomicIcon } from '@umituz/react-native-design-system';
|
|
19
18
|
import { useAppDesignTokens } from '@umituz/react-native-design-system-theme';
|
|
@@ -63,114 +62,198 @@ export const SettingItem: React.FC<SettingItemProps> = ({
|
|
|
63
62
|
? (iconGradient as unknown as readonly [string, string, ...string[]])
|
|
64
63
|
: [tokens.colors.surface, tokens.colors.surface] as const;
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
if (onPress) {
|
|
66
|
+
return (
|
|
67
|
+
<TouchableOpacity
|
|
68
|
+
onPress={onPress}
|
|
69
|
+
disabled={disabled}
|
|
70
|
+
activeOpacity={0.7}
|
|
71
|
+
style={[styles.listItem, disabled && styles.disabled]}
|
|
72
|
+
testID={testID}
|
|
74
73
|
>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (value) {
|
|
87
|
-
return (
|
|
88
|
-
<View style={styles.rightContainer}>
|
|
89
|
-
<AtomicText type="bodyMedium" color="secondary" style={styles.value} numberOfLines={2}>
|
|
90
|
-
{value}
|
|
91
|
-
</AtomicText>
|
|
74
|
+
{/* Left: Gradient Icon */}
|
|
75
|
+
<View style={styles.leftContainer}>
|
|
76
|
+
<LinearGradient
|
|
77
|
+
colors={gradientColors}
|
|
78
|
+
start={{ x: 0, y: 0 }}
|
|
79
|
+
end={{ x: 1, y: 1 }}
|
|
80
|
+
style={styles.iconContainer}
|
|
81
|
+
>
|
|
82
|
+
<AtomicIcon name={icon} size="md" customColor="#FFFFFF" />
|
|
83
|
+
</LinearGradient>
|
|
92
84
|
</View>
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
85
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
86
|
+
{/* Center: Title and Description */}
|
|
87
|
+
<View style={styles.contentContainer}>
|
|
88
|
+
<AtomicText
|
|
89
|
+
type="bodyLarge"
|
|
90
|
+
color={disabled ? "textDisabled" : "onSurface"}
|
|
91
|
+
style={styles.title}
|
|
92
|
+
numberOfLines={2}
|
|
93
|
+
ellipsizeMode="tail"
|
|
94
|
+
>
|
|
95
|
+
{title}
|
|
96
|
+
</AtomicText>
|
|
97
|
+
{description && (
|
|
98
|
+
<AtomicText
|
|
99
|
+
type="bodySmall"
|
|
100
|
+
color="textSecondary"
|
|
101
|
+
style={styles.description}
|
|
102
|
+
numberOfLines={2}
|
|
103
|
+
ellipsizeMode="tail"
|
|
104
|
+
>
|
|
105
|
+
{description}
|
|
106
|
+
</AtomicText>
|
|
107
|
+
)}
|
|
101
108
|
</View>
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
109
|
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
{/* Right: Value, Chevron, or Custom Element */}
|
|
111
|
+
{rightElement ? (
|
|
112
|
+
<View style={styles.rightContainer}>{rightElement}</View>
|
|
113
|
+
) : value ? (
|
|
114
|
+
<View style={styles.rightContainer}>
|
|
115
|
+
<AtomicText
|
|
116
|
+
type="bodyMedium"
|
|
117
|
+
color="textSecondary"
|
|
118
|
+
style={styles.value}
|
|
119
|
+
numberOfLines={2}
|
|
120
|
+
textAlign="right"
|
|
121
|
+
>
|
|
122
|
+
{value}
|
|
123
|
+
</AtomicText>
|
|
124
|
+
</View>
|
|
125
|
+
) : (showChevron ?? true) ? (
|
|
126
|
+
<View style={styles.rightContainer}>
|
|
127
|
+
<AtomicIcon
|
|
128
|
+
name="ChevronRight"
|
|
129
|
+
size="sm"
|
|
130
|
+
color="textSecondary"
|
|
131
|
+
style={styles.chevron}
|
|
132
|
+
/>
|
|
133
|
+
</View>
|
|
134
|
+
) : null}
|
|
135
|
+
</TouchableOpacity>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
107
138
|
|
|
108
139
|
return (
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
description={description}
|
|
112
|
-
left={renderLeft}
|
|
113
|
-
right={renderRight}
|
|
114
|
-
onPress={onPress}
|
|
115
|
-
disabled={disabled}
|
|
140
|
+
<View
|
|
141
|
+
style={[styles.listItem, disabled && styles.disabled]}
|
|
116
142
|
testID={testID}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
143
|
+
>
|
|
144
|
+
{/* Left: Gradient Icon */}
|
|
145
|
+
<View style={styles.leftContainer}>
|
|
146
|
+
<LinearGradient
|
|
147
|
+
colors={gradientColors}
|
|
148
|
+
start={{ x: 0, y: 0 }}
|
|
149
|
+
end={{ x: 1, y: 1 }}
|
|
150
|
+
style={styles.iconContainer}
|
|
151
|
+
>
|
|
152
|
+
<AtomicIcon name={icon} size="md" customColor="#FFFFFF" />
|
|
153
|
+
</LinearGradient>
|
|
154
|
+
</View>
|
|
155
|
+
|
|
156
|
+
{/* Center: Title and Description */}
|
|
157
|
+
<View style={styles.contentContainer}>
|
|
158
|
+
<AtomicText
|
|
159
|
+
type="bodyLarge"
|
|
160
|
+
color={disabled ? "textDisabled" : "onSurface"}
|
|
161
|
+
style={styles.title}
|
|
162
|
+
numberOfLines={2}
|
|
163
|
+
ellipsizeMode="tail"
|
|
164
|
+
>
|
|
165
|
+
{title}
|
|
166
|
+
</AtomicText>
|
|
167
|
+
{description && (
|
|
168
|
+
<AtomicText
|
|
169
|
+
type="bodySmall"
|
|
170
|
+
color="textSecondary"
|
|
171
|
+
style={styles.description}
|
|
172
|
+
numberOfLines={2}
|
|
173
|
+
ellipsizeMode="tail"
|
|
174
|
+
>
|
|
175
|
+
{description}
|
|
176
|
+
</AtomicText>
|
|
177
|
+
)}
|
|
178
|
+
</View>
|
|
179
|
+
|
|
180
|
+
{/* Right: Value, Chevron, or Custom Element */}
|
|
181
|
+
{rightElement ? (
|
|
182
|
+
<View style={styles.rightContainer}>{rightElement}</View>
|
|
183
|
+
) : value ? (
|
|
184
|
+
<View style={styles.rightContainer}>
|
|
185
|
+
<AtomicText
|
|
186
|
+
type="bodyMedium"
|
|
187
|
+
color="textSecondary"
|
|
188
|
+
style={styles.value}
|
|
189
|
+
numberOfLines={2}
|
|
190
|
+
textAlign="right"
|
|
191
|
+
>
|
|
192
|
+
{value}
|
|
193
|
+
</AtomicText>
|
|
194
|
+
</View>
|
|
195
|
+
) : null}
|
|
196
|
+
</View>
|
|
125
197
|
);
|
|
126
198
|
};
|
|
127
199
|
|
|
128
200
|
const getStyles = (tokens: DesignTokens) =>
|
|
129
201
|
StyleSheet.create({
|
|
130
202
|
listItem: {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
203
|
+
flexDirection: 'row',
|
|
204
|
+
alignItems: 'center',
|
|
205
|
+
paddingVertical: tokens.spacing.md,
|
|
206
|
+
paddingHorizontal: tokens.spacing.lg,
|
|
207
|
+
minHeight: 72,
|
|
208
|
+
},
|
|
209
|
+
disabled: {
|
|
210
|
+
opacity: 0.5,
|
|
134
211
|
},
|
|
135
212
|
leftContainer: {
|
|
136
213
|
marginRight: tokens.spacing.md,
|
|
137
214
|
justifyContent: 'center',
|
|
138
215
|
},
|
|
139
216
|
iconContainer: {
|
|
140
|
-
width:
|
|
141
|
-
height:
|
|
142
|
-
borderRadius:
|
|
217
|
+
width: 48,
|
|
218
|
+
height: 48,
|
|
219
|
+
borderRadius: 24,
|
|
143
220
|
alignItems: 'center',
|
|
144
221
|
justifyContent: 'center',
|
|
145
222
|
overflow: 'hidden',
|
|
146
223
|
borderWidth: 1,
|
|
147
|
-
borderColor: `${tokens.colors.primary}
|
|
224
|
+
borderColor: `${tokens.colors.primary}15`,
|
|
225
|
+
},
|
|
226
|
+
contentContainer: {
|
|
227
|
+
flex: 1,
|
|
228
|
+
justifyContent: 'center',
|
|
229
|
+
minWidth: 0,
|
|
148
230
|
},
|
|
149
231
|
title: {
|
|
150
232
|
fontSize: tokens.typography.bodyLarge.fontSize,
|
|
151
233
|
fontWeight: '600',
|
|
152
|
-
color: tokens.colors.textPrimary,
|
|
153
234
|
flexShrink: 1,
|
|
235
|
+
lineHeight: tokens.typography.bodyLarge.fontSize * 1.4,
|
|
154
236
|
},
|
|
155
237
|
description: {
|
|
156
238
|
fontSize: tokens.typography.bodySmall.fontSize,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
opacity: 0.8,
|
|
239
|
+
marginTop: tokens.spacing.xs / 2,
|
|
240
|
+
opacity: 0.7,
|
|
160
241
|
flexShrink: 1,
|
|
242
|
+
lineHeight: tokens.typography.bodySmall.fontSize * 1.4,
|
|
161
243
|
},
|
|
162
244
|
rightContainer: {
|
|
163
245
|
justifyContent: 'center',
|
|
164
246
|
alignItems: 'flex-end',
|
|
247
|
+
marginLeft: tokens.spacing.md,
|
|
165
248
|
maxWidth: '50%',
|
|
166
249
|
flexShrink: 0,
|
|
167
250
|
},
|
|
168
251
|
value: {
|
|
169
252
|
fontWeight: '500',
|
|
170
|
-
|
|
253
|
+
lineHeight: tokens.typography.bodyMedium.fontSize * 1.4,
|
|
171
254
|
},
|
|
172
255
|
chevron: {
|
|
173
|
-
opacity: 0.
|
|
256
|
+
opacity: 0.5,
|
|
174
257
|
},
|
|
175
258
|
});
|
|
176
259
|
|
|
@@ -11,18 +11,18 @@
|
|
|
11
11
|
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import { View, StyleSheet } from 'react-native';
|
|
14
|
-
import { List } from 'react-native-paper';
|
|
15
14
|
|
|
16
15
|
import { useNavigation } from '@react-navigation/native';
|
|
17
|
-
import {
|
|
18
|
-
import { AtomicText, ScreenLayout } from '@umituz/react-native-design-system';
|
|
16
|
+
import { useDesignSystemTheme, useAppDesignTokens, type DesignTokens } from '@umituz/react-native-design-system-theme';
|
|
17
|
+
import { AtomicText, ScreenLayout, SectionHeader, SectionContainer } from '@umituz/react-native-design-system';
|
|
19
18
|
import { useLocalization, getLanguageByCode } from '@umituz/react-native-localization';
|
|
20
19
|
import { SettingItem } from '../components/SettingItem';
|
|
21
20
|
|
|
22
21
|
export const AppearanceScreen: React.FC = () => {
|
|
23
22
|
const { t, currentLanguage } = useLocalization();
|
|
24
23
|
const navigation = useNavigation();
|
|
25
|
-
|
|
24
|
+
// Only read themeMode, no toggle logic here - theme logic belongs in theme package
|
|
25
|
+
const { themeMode } = useDesignSystemTheme();
|
|
26
26
|
const tokens = useAppDesignTokens();
|
|
27
27
|
const styles = getStyles(tokens);
|
|
28
28
|
|
|
@@ -35,7 +35,13 @@ export const AppearanceScreen: React.FC = () => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
const handleThemeToggle = () => {
|
|
38
|
-
|
|
38
|
+
// Theme toggle logic should be handled by app, not this package
|
|
39
|
+
// This screen only displays current theme mode
|
|
40
|
+
// App should provide toggle functionality via navigation params or event emitter
|
|
41
|
+
// For now, just navigate back - app can handle toggle in its own theme management
|
|
42
|
+
if (navigation.canGoBack()) {
|
|
43
|
+
navigation.goBack();
|
|
44
|
+
}
|
|
39
45
|
};
|
|
40
46
|
|
|
41
47
|
return (
|
|
@@ -51,8 +57,8 @@ export const AppearanceScreen: React.FC = () => {
|
|
|
51
57
|
</View>
|
|
52
58
|
|
|
53
59
|
{/* Language Section */}
|
|
54
|
-
<
|
|
55
|
-
<
|
|
60
|
+
<SectionContainer>
|
|
61
|
+
<SectionHeader>{t('settings.language')}</SectionHeader>
|
|
56
62
|
<SettingItem
|
|
57
63
|
icon="Languages"
|
|
58
64
|
iconGradient={((tokens.colors as any).settingGradients?.language as unknown as string[]) || [tokens.colors.primary, tokens.colors.secondary]}
|
|
@@ -61,11 +67,11 @@ export const AppearanceScreen: React.FC = () => {
|
|
|
61
67
|
onPress={handleLanguagePress}
|
|
62
68
|
testID="language-button"
|
|
63
69
|
/>
|
|
64
|
-
</
|
|
70
|
+
</SectionContainer>
|
|
65
71
|
|
|
66
72
|
{/* Theme Section */}
|
|
67
|
-
<
|
|
68
|
-
<
|
|
73
|
+
<SectionContainer>
|
|
74
|
+
<SectionHeader>{t('settings.appearance.darkMode')}</SectionHeader>
|
|
69
75
|
<SettingItem
|
|
70
76
|
icon={themeMode === 'dark' ? 'Moon' : 'Sun'}
|
|
71
77
|
iconGradient={
|
|
@@ -78,7 +84,7 @@ export const AppearanceScreen: React.FC = () => {
|
|
|
78
84
|
onPress={handleThemeToggle}
|
|
79
85
|
testID="theme-button"
|
|
80
86
|
/>
|
|
81
|
-
</
|
|
87
|
+
</SectionContainer>
|
|
82
88
|
</ScreenLayout>
|
|
83
89
|
);
|
|
84
90
|
};
|
|
@@ -12,13 +12,12 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import React, { useMemo } from 'react';
|
|
15
|
-
import { List, Divider } from 'react-native-paper';
|
|
16
15
|
import { DeviceEventEmitter, Alert, View, TouchableOpacity, StyleSheet } from 'react-native';
|
|
17
16
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
18
17
|
|
|
19
18
|
import { useNavigation, CommonActions } from '@react-navigation/native';
|
|
20
|
-
import {
|
|
21
|
-
import { ScreenLayout, AtomicIcon, AtomicText } from '@umituz/react-native-design-system';
|
|
19
|
+
import { useDesignSystemTheme, useAppDesignTokens } from '@umituz/react-native-design-system-theme';
|
|
20
|
+
import { ScreenLayout, AtomicIcon, AtomicText, SectionHeader, SectionContainer, AtomicDivider } from '@umituz/react-native-design-system';
|
|
22
21
|
import { SettingItem } from '../components/SettingItem';
|
|
23
22
|
import { getLanguageByCode, useLocalization } from '@umituz/react-native-localization';
|
|
24
23
|
import { SettingsConfig } from './types';
|
|
@@ -87,7 +86,8 @@ export const SettingsScreen: React.FC<SettingsScreenProps> = ({
|
|
|
87
86
|
config = {}
|
|
88
87
|
}) => {
|
|
89
88
|
const navigation = useNavigation();
|
|
90
|
-
|
|
89
|
+
// Only read themeMode, no theme logic here - theme logic belongs in theme package
|
|
90
|
+
const { themeMode } = useDesignSystemTheme();
|
|
91
91
|
const tokens = useAppDesignTokens();
|
|
92
92
|
const insets = useSafeAreaInsets();
|
|
93
93
|
const { currentLanguage, t } = useLocalization();
|
|
@@ -247,12 +247,12 @@ export const SettingsScreen: React.FC<SettingsScreenProps> = ({
|
|
|
247
247
|
<View style={[
|
|
248
248
|
styles.header,
|
|
249
249
|
{
|
|
250
|
-
borderBottomColor:
|
|
251
|
-
backgroundColor:
|
|
250
|
+
borderBottomColor: tokens.colors.borderLight,
|
|
251
|
+
backgroundColor: tokens.colors.surface,
|
|
252
252
|
paddingTop: insets.top,
|
|
253
253
|
}
|
|
254
254
|
]}>
|
|
255
|
-
<AtomicText type="headlineLarge" style={{ color:
|
|
255
|
+
<AtomicText type="headlineLarge" style={{ color: tokens.colors.textPrimary, flex: 1 }}>
|
|
256
256
|
{t('navigation.settings') || 'Settings'}
|
|
257
257
|
</AtomicText>
|
|
258
258
|
<TouchableOpacity
|
|
@@ -267,84 +267,84 @@ export const SettingsScreen: React.FC<SettingsScreenProps> = ({
|
|
|
267
267
|
|
|
268
268
|
{/* Appearance Section */}
|
|
269
269
|
{features.appearance && (
|
|
270
|
-
<
|
|
271
|
-
<
|
|
270
|
+
<SectionContainer>
|
|
271
|
+
<SectionHeader>{t('settings.sections.appearance')}</SectionHeader>
|
|
272
272
|
<SettingItem
|
|
273
273
|
icon="Palette"
|
|
274
|
-
iconGradient={
|
|
274
|
+
iconGradient={((tokens.colors as any).settingGradients?.themeLight as unknown as string[]) || [tokens.colors.primary, tokens.colors.secondary]}
|
|
275
275
|
title={t('settings.appearance.title')}
|
|
276
276
|
description={t('settings.appearance.themeDescription')}
|
|
277
277
|
onPress={handleAppearancePress}
|
|
278
278
|
testID="appearance-button"
|
|
279
279
|
/>
|
|
280
|
-
</
|
|
280
|
+
</SectionContainer>
|
|
281
281
|
)}
|
|
282
282
|
|
|
283
283
|
{/* General Section - Notifications */}
|
|
284
284
|
{features.notifications && (
|
|
285
|
-
<
|
|
286
|
-
<
|
|
285
|
+
<SectionContainer>
|
|
286
|
+
<SectionHeader>{t('settings.sections.general')}</SectionHeader>
|
|
287
287
|
<SettingItem
|
|
288
288
|
icon="Bell"
|
|
289
|
-
iconGradient={
|
|
289
|
+
iconGradient={((tokens.colors as any).settingGradients?.notifications as unknown as string[]) || [tokens.colors.primary, tokens.colors.secondary]}
|
|
290
290
|
title={t('settings.notifications.title')}
|
|
291
291
|
description={t('settings.notifications.description')}
|
|
292
292
|
onPress={handleNotificationsPress}
|
|
293
293
|
testID="notifications-button"
|
|
294
294
|
/>
|
|
295
|
-
</
|
|
295
|
+
</SectionContainer>
|
|
296
296
|
)}
|
|
297
297
|
|
|
298
298
|
{/* Development/Test: Show Onboarding */}
|
|
299
299
|
{__DEV__ && useOnboardingStore && (
|
|
300
|
-
<
|
|
301
|
-
<
|
|
300
|
+
<SectionContainer>
|
|
301
|
+
<SectionHeader>Development</SectionHeader>
|
|
302
302
|
<SettingItem
|
|
303
303
|
icon="Play"
|
|
304
|
-
iconGradient={
|
|
304
|
+
iconGradient={((tokens.colors as any).settingGradients?.info as unknown as string[]) || [tokens.colors.primary, tokens.colors.secondary]}
|
|
305
305
|
title="Show Onboarding (Dev)"
|
|
306
306
|
description="Navigate to onboarding screen"
|
|
307
307
|
onPress={handleShowOnboarding}
|
|
308
308
|
testID="show-onboarding-button"
|
|
309
309
|
/>
|
|
310
|
-
</
|
|
310
|
+
</SectionContainer>
|
|
311
311
|
)}
|
|
312
312
|
|
|
313
313
|
{/* About & Legal Section */}
|
|
314
314
|
{(features.about || features.legal) && (
|
|
315
|
-
<
|
|
316
|
-
<
|
|
315
|
+
<SectionContainer>
|
|
316
|
+
<SectionHeader>{t('settings.sections.about')}</SectionHeader>
|
|
317
317
|
{features.about && (
|
|
318
318
|
<SettingItem
|
|
319
319
|
icon="Info"
|
|
320
|
-
iconGradient={
|
|
320
|
+
iconGradient={((tokens.colors as any).settingGradients?.info as unknown as string[]) || [tokens.colors.primary, tokens.colors.secondary]}
|
|
321
321
|
title={t('settings.about.title')}
|
|
322
322
|
description={t('settings.about.description')}
|
|
323
323
|
onPress={handleAboutPress}
|
|
324
324
|
testID="about-button"
|
|
325
325
|
/>
|
|
326
326
|
)}
|
|
327
|
-
{features.about && features.legal && <
|
|
327
|
+
{features.about && features.legal && <AtomicDivider />}
|
|
328
328
|
{features.legal && (
|
|
329
329
|
<SettingItem
|
|
330
330
|
icon="FileText"
|
|
331
|
-
iconGradient={
|
|
331
|
+
iconGradient={((tokens.colors as any).settingGradients?.info as unknown as string[]) || [tokens.colors.primary, tokens.colors.secondary]}
|
|
332
332
|
title={t('settings.legal.title')}
|
|
333
333
|
description={t('settings.legal.description')}
|
|
334
334
|
onPress={handleLegalPress}
|
|
335
335
|
testID="legal-button"
|
|
336
336
|
/>
|
|
337
337
|
)}
|
|
338
|
-
</
|
|
338
|
+
</SectionContainer>
|
|
339
339
|
)}
|
|
340
340
|
|
|
341
341
|
{/* Fallback: Show message if no features are enabled */}
|
|
342
342
|
{!hasAnyFeatures && (
|
|
343
|
-
<
|
|
344
|
-
<
|
|
343
|
+
<SectionContainer>
|
|
344
|
+
<SectionHeader>
|
|
345
345
|
{t('settings.noOptionsAvailable') || 'No settings available'}
|
|
346
|
-
</
|
|
347
|
-
</
|
|
346
|
+
</SectionHeader>
|
|
347
|
+
</SectionContainer>
|
|
348
348
|
)}
|
|
349
349
|
</ScreenLayout>
|
|
350
350
|
);
|