@umituz/react-native-settings 4.23.72 → 4.23.74
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/about/presentation/screens/AboutScreen.tsx +10 -173
- package/src/domains/about/presentation/screens/AboutScreenContainer.tsx +109 -0
- package/src/domains/about/presentation/screens/AboutScreenContent.tsx +122 -0
- package/src/domains/dev/presentation/screens/EnvViewerScreen.tsx +51 -50
- package/src/domains/disclaimer/presentation/screens/DisclaimerScreen.tsx +28 -40
- package/src/domains/feedback/presentation/components/FeedbackModal.tsx +32 -43
- package/src/domains/gamification/components/GamificationScreen/GamificationScreen.tsx +122 -0
- package/src/domains/gamification/components/GamificationScreen/GamificationScreenWithConfig.tsx +72 -0
- package/src/domains/gamification/components/GamificationScreen/index.tsx +8 -178
- package/src/domains/gamification/components/index.ts +2 -1
- package/src/domains/legal/presentation/screens/LegalContentScreen.tsx +19 -29
- package/src/domains/notifications/infrastructure/hooks/useNotificationSettings.ts +11 -1
- package/src/domains/notifications/infrastructure/services/NotificationManager.ts +0 -2
- package/src/domains/notifications/infrastructure/services/NotificationService.ts +17 -3
- package/src/domains/notifications/reminders/infrastructure/hooks/useReminderActions.ts +4 -3
- package/src/infrastructure/utils/index.ts +7 -0
- package/src/infrastructure/utils/memoUtils.ts +159 -0
- package/src/infrastructure/utils/styleUtils.ts +190 -0
- package/src/presentation/screens/SettingsScreen.tsx +0 -5
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.74",
|
|
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",
|
|
@@ -4,29 +4,20 @@
|
|
|
4
4
|
* Fully configurable and generic
|
|
5
5
|
* Optimized for performance and memory safety
|
|
6
6
|
*/
|
|
7
|
-
import React
|
|
8
|
-
import {
|
|
9
|
-
View,
|
|
10
|
-
StyleSheet,
|
|
11
|
-
ScrollView,
|
|
12
|
-
ViewStyle,
|
|
13
|
-
TextStyle,
|
|
14
|
-
} from 'react-native';
|
|
15
|
-
import { AboutHeader } from '../components/AboutHeader';
|
|
16
|
-
import { AboutContent } from '../components/AboutContent';
|
|
17
|
-
import { AboutConfig } from '../../domain/entities/AppInfo';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { AboutScreenContainer } from './AboutScreenContainer';
|
|
18
9
|
|
|
19
10
|
export interface AboutScreenProps {
|
|
20
11
|
/** Configuration for the about screen */
|
|
21
|
-
config: AboutConfig;
|
|
12
|
+
config: import('../../domain/entities/AppInfo').AboutConfig;
|
|
22
13
|
/** Custom container style */
|
|
23
|
-
containerStyle?: ViewStyle;
|
|
14
|
+
containerStyle?: import('react-native').ViewStyle;
|
|
24
15
|
/** Custom header style */
|
|
25
|
-
headerStyle?: ViewStyle;
|
|
16
|
+
headerStyle?: import('react-native').ViewStyle;
|
|
26
17
|
/** Custom title style */
|
|
27
|
-
titleStyle?: TextStyle;
|
|
18
|
+
titleStyle?: import('react-native').TextStyle;
|
|
28
19
|
/** Custom version style */
|
|
29
|
-
versionStyle?: TextStyle;
|
|
20
|
+
versionStyle?: import('react-native').TextStyle;
|
|
30
21
|
/** Show app header with name and version */
|
|
31
22
|
showHeader?: boolean;
|
|
32
23
|
/** Custom header component */
|
|
@@ -37,160 +28,6 @@ export interface AboutScreenProps {
|
|
|
37
28
|
testID?: string;
|
|
38
29
|
}
|
|
39
30
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
export const AboutScreen: React.FC<AboutScreenProps> = ({
|
|
44
|
-
config,
|
|
45
|
-
containerStyle,
|
|
46
|
-
headerStyle,
|
|
47
|
-
titleStyle,
|
|
48
|
-
versionStyle,
|
|
49
|
-
showHeader = true,
|
|
50
|
-
headerComponent,
|
|
51
|
-
footerComponent,
|
|
52
|
-
testID,
|
|
53
|
-
}) => {
|
|
54
|
-
const tokens = useAppDesignTokens();
|
|
55
|
-
const styles = getStyles(tokens);
|
|
56
|
-
const colors = tokens.colors;
|
|
57
|
-
|
|
58
|
-
const { appInfo, loading, error } = useAboutInfo({
|
|
59
|
-
autoInit: true,
|
|
60
|
-
initialConfig: config,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Memoize header rendering to prevent unnecessary re-renders
|
|
64
|
-
const renderHeader = useCallback(() => {
|
|
65
|
-
if (headerComponent) {
|
|
66
|
-
return headerComponent;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (!showHeader || !appInfo) {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return (
|
|
74
|
-
<AboutHeader
|
|
75
|
-
appInfo={appInfo}
|
|
76
|
-
containerStyle={headerStyle}
|
|
77
|
-
titleStyle={titleStyle}
|
|
78
|
-
versionStyle={versionStyle}
|
|
79
|
-
versionPrefix={config.texts?.versionPrefix}
|
|
80
|
-
/>
|
|
81
|
-
);
|
|
82
|
-
}, [headerComponent, showHeader, appInfo, headerStyle, titleStyle, versionStyle, config.texts?.versionPrefix]);
|
|
83
|
-
|
|
84
|
-
// Memoize footer rendering
|
|
85
|
-
const renderFooter = useCallback(() => {
|
|
86
|
-
if (!footerComponent) {
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<View style={[styles.footer, { borderTopColor: colors.border }]}>
|
|
92
|
-
{footerComponent}
|
|
93
|
-
</View>
|
|
94
|
-
);
|
|
95
|
-
}, [footerComponent, colors.border, styles]);
|
|
96
|
-
|
|
97
|
-
// Memoize content rendering
|
|
98
|
-
const renderContent = useCallback(() => {
|
|
99
|
-
if (!appInfo) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
<AboutContent
|
|
105
|
-
appInfo={appInfo}
|
|
106
|
-
config={config}
|
|
107
|
-
/>
|
|
108
|
-
);
|
|
109
|
-
}, [appInfo, config]);
|
|
110
|
-
|
|
111
|
-
// Memoize container style to prevent unnecessary re-renders
|
|
112
|
-
const containerStyles = useMemo(() => {
|
|
113
|
-
return [
|
|
114
|
-
styles.container,
|
|
115
|
-
{ backgroundColor: colors.backgroundPrimary },
|
|
116
|
-
containerStyle
|
|
117
|
-
];
|
|
118
|
-
}, [containerStyle, colors.backgroundPrimary, styles]);
|
|
119
|
-
|
|
120
|
-
const texts = config.texts || {};
|
|
121
|
-
|
|
122
|
-
if (loading) {
|
|
123
|
-
return (
|
|
124
|
-
<View style={containerStyles} testID={testID}>
|
|
125
|
-
<AtomicText
|
|
126
|
-
type="bodyMedium"
|
|
127
|
-
color="textSecondary"
|
|
128
|
-
style={styles.loadingText}
|
|
129
|
-
>
|
|
130
|
-
{texts.loading}
|
|
131
|
-
</AtomicText>
|
|
132
|
-
</View>
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (error) {
|
|
137
|
-
return (
|
|
138
|
-
<View style={containerStyles} testID={testID}>
|
|
139
|
-
<AtomicText
|
|
140
|
-
type="bodyMedium"
|
|
141
|
-
color="error"
|
|
142
|
-
style={styles.errorText}
|
|
143
|
-
>
|
|
144
|
-
{texts.errorPrefix} {error}
|
|
145
|
-
</AtomicText>
|
|
146
|
-
</View>
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (!appInfo) {
|
|
151
|
-
return (
|
|
152
|
-
<View style={containerStyles} testID={testID}>
|
|
153
|
-
<AtomicText
|
|
154
|
-
type="bodyMedium"
|
|
155
|
-
color="textSecondary"
|
|
156
|
-
style={styles.errorText}
|
|
157
|
-
>
|
|
158
|
-
{texts.noInfo}
|
|
159
|
-
</AtomicText>
|
|
160
|
-
</View>
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return (
|
|
165
|
-
<ScrollView
|
|
166
|
-
style={containerStyles}
|
|
167
|
-
testID={testID}
|
|
168
|
-
contentContainerStyle={{ paddingBottom: 32 }}
|
|
169
|
-
>
|
|
170
|
-
{renderHeader()}
|
|
171
|
-
{renderContent()}
|
|
172
|
-
{renderFooter()}
|
|
173
|
-
</ScrollView>
|
|
174
|
-
);
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
const getStyles = (tokens: DesignTokens) => StyleSheet.create({
|
|
178
|
-
container: {
|
|
179
|
-
flex: 1,
|
|
180
|
-
},
|
|
181
|
-
footer: {
|
|
182
|
-
paddingVertical: 16,
|
|
183
|
-
paddingHorizontal: 16,
|
|
184
|
-
borderTopWidth: 1,
|
|
185
|
-
},
|
|
186
|
-
loadingText: {
|
|
187
|
-
textAlign: 'center',
|
|
188
|
-
fontSize: tokens.typography.bodyMedium.responsiveFontSize,
|
|
189
|
-
marginTop: 20,
|
|
190
|
-
},
|
|
191
|
-
errorText: {
|
|
192
|
-
textAlign: 'center',
|
|
193
|
-
fontSize: tokens.typography.bodyMedium.responsiveFontSize,
|
|
194
|
-
marginTop: 20,
|
|
195
|
-
},
|
|
196
|
-
});
|
|
31
|
+
export const AboutScreen: React.FC<AboutScreenProps> = (props) => {
|
|
32
|
+
return <AboutScreenContainer {...props} />;
|
|
33
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AboutScreen Container Component
|
|
3
|
+
* Handles business logic and state management for About screen
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { View, StyleSheet } from 'react-native';
|
|
7
|
+
import { AboutScreenContent } from './AboutScreenContent';
|
|
8
|
+
import { useAboutInfo } from '../hooks/useAboutInfo';
|
|
9
|
+
import { useAppDesignTokens, AtomicText, type DesignTokens } from '@umituz/react-native-design-system';
|
|
10
|
+
import type { AboutScreenProps } from './AboutScreen';
|
|
11
|
+
|
|
12
|
+
export const AboutScreenContainer: React.FC<AboutScreenProps> = ({
|
|
13
|
+
config,
|
|
14
|
+
containerStyle,
|
|
15
|
+
headerStyle,
|
|
16
|
+
titleStyle,
|
|
17
|
+
versionStyle,
|
|
18
|
+
showHeader = true,
|
|
19
|
+
headerComponent,
|
|
20
|
+
footerComponent,
|
|
21
|
+
testID,
|
|
22
|
+
}) => {
|
|
23
|
+
const tokens = useAppDesignTokens();
|
|
24
|
+
const styles = getStyles(tokens);
|
|
25
|
+
|
|
26
|
+
const { appInfo, loading, error } = useAboutInfo({
|
|
27
|
+
autoInit: true,
|
|
28
|
+
initialConfig: config,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const containerStyles = React.useMemo(() => {
|
|
32
|
+
return [
|
|
33
|
+
styles.container,
|
|
34
|
+
{ backgroundColor: tokens.colors.backgroundPrimary },
|
|
35
|
+
containerStyle
|
|
36
|
+
];
|
|
37
|
+
}, [containerStyle, tokens.colors.backgroundPrimary, styles]);
|
|
38
|
+
|
|
39
|
+
const texts = config.texts || {};
|
|
40
|
+
|
|
41
|
+
if (loading) {
|
|
42
|
+
return (
|
|
43
|
+
<View style={containerStyles} testID={testID}>
|
|
44
|
+
<AtomicText
|
|
45
|
+
type="bodyMedium"
|
|
46
|
+
color="textSecondary"
|
|
47
|
+
style={styles.statusText}
|
|
48
|
+
>
|
|
49
|
+
{texts.loading}
|
|
50
|
+
</AtomicText>
|
|
51
|
+
</View>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (error) {
|
|
56
|
+
return (
|
|
57
|
+
<View style={containerStyles} testID={testID}>
|
|
58
|
+
<AtomicText
|
|
59
|
+
type="bodyMedium"
|
|
60
|
+
color="error"
|
|
61
|
+
style={styles.statusText}
|
|
62
|
+
>
|
|
63
|
+
{texts.errorPrefix} {error}
|
|
64
|
+
</AtomicText>
|
|
65
|
+
</View>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!appInfo) {
|
|
70
|
+
return (
|
|
71
|
+
<View style={containerStyles} testID={testID}>
|
|
72
|
+
<AtomicText
|
|
73
|
+
type="bodyMedium"
|
|
74
|
+
color="textSecondary"
|
|
75
|
+
style={styles.statusText}
|
|
76
|
+
>
|
|
77
|
+
{texts.noInfo}
|
|
78
|
+
</AtomicText>
|
|
79
|
+
</View>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<AboutScreenContent
|
|
85
|
+
appInfo={appInfo}
|
|
86
|
+
config={config}
|
|
87
|
+
containerStyle={containerStyle}
|
|
88
|
+
headerStyle={headerStyle}
|
|
89
|
+
titleStyle={titleStyle}
|
|
90
|
+
versionStyle={versionStyle}
|
|
91
|
+
showHeader={showHeader}
|
|
92
|
+
headerComponent={headerComponent}
|
|
93
|
+
footerComponent={footerComponent}
|
|
94
|
+
testID={testID}
|
|
95
|
+
_tokens={tokens}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const getStyles = (tokens: DesignTokens) => StyleSheet.create({
|
|
101
|
+
container: {
|
|
102
|
+
flex: 1,
|
|
103
|
+
},
|
|
104
|
+
statusText: {
|
|
105
|
+
textAlign: 'center',
|
|
106
|
+
fontSize: tokens.typography.bodyMedium.responsiveFontSize,
|
|
107
|
+
marginTop: 20,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AboutScreen Content Component
|
|
3
|
+
* Pure presentational component for About screen
|
|
4
|
+
* No business logic, only rendering
|
|
5
|
+
*/
|
|
6
|
+
import React, { useMemo, useCallback } from 'react';
|
|
7
|
+
import {
|
|
8
|
+
View,
|
|
9
|
+
StyleSheet,
|
|
10
|
+
ScrollView,
|
|
11
|
+
} from 'react-native';
|
|
12
|
+
import { AboutHeader } from '../components/AboutHeader';
|
|
13
|
+
import { AboutContent } from '../components/AboutContent';
|
|
14
|
+
import { AboutConfig, AppInfo } from '../../domain/entities/AppInfo';
|
|
15
|
+
import type { DesignTokens } from '@umituz/react-native-design-system';
|
|
16
|
+
import type { AboutScreenProps } from './AboutScreen';
|
|
17
|
+
|
|
18
|
+
export interface AboutScreenContentProps extends Omit<AboutScreenProps, 'config'> {
|
|
19
|
+
/** App info data */
|
|
20
|
+
appInfo: AppInfo;
|
|
21
|
+
/** Configuration for the about screen */
|
|
22
|
+
config: AboutConfig;
|
|
23
|
+
/** Design tokens */
|
|
24
|
+
_tokens: DesignTokens;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const AboutScreenContent: React.FC<AboutScreenContentProps> = ({
|
|
28
|
+
appInfo,
|
|
29
|
+
config,
|
|
30
|
+
containerStyle,
|
|
31
|
+
headerStyle,
|
|
32
|
+
titleStyle,
|
|
33
|
+
versionStyle,
|
|
34
|
+
showHeader = true,
|
|
35
|
+
headerComponent,
|
|
36
|
+
footerComponent,
|
|
37
|
+
testID,
|
|
38
|
+
_tokens,
|
|
39
|
+
}) => {
|
|
40
|
+
const styles = getStyles(_tokens);
|
|
41
|
+
const colors = _tokens.colors;
|
|
42
|
+
|
|
43
|
+
// Memoize header rendering to prevent unnecessary re-renders
|
|
44
|
+
const renderHeader = useCallback(() => {
|
|
45
|
+
if (headerComponent) {
|
|
46
|
+
return headerComponent;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!showHeader || !appInfo) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<AboutHeader
|
|
55
|
+
appInfo={appInfo}
|
|
56
|
+
containerStyle={headerStyle}
|
|
57
|
+
titleStyle={titleStyle}
|
|
58
|
+
versionStyle={versionStyle}
|
|
59
|
+
versionPrefix={config.texts?.versionPrefix}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}, [headerComponent, showHeader, appInfo, headerStyle, titleStyle, versionStyle, config.texts?.versionPrefix]);
|
|
63
|
+
|
|
64
|
+
// Memoize footer rendering
|
|
65
|
+
const renderFooter = useCallback(() => {
|
|
66
|
+
if (!footerComponent) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<View style={[styles.footer, { borderTopColor: colors.border }]}>
|
|
72
|
+
{footerComponent}
|
|
73
|
+
</View>
|
|
74
|
+
);
|
|
75
|
+
}, [footerComponent, colors.border, styles]);
|
|
76
|
+
|
|
77
|
+
// Memoize content rendering
|
|
78
|
+
const renderContent = useCallback(() => {
|
|
79
|
+
if (!appInfo) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<AboutContent
|
|
85
|
+
appInfo={appInfo}
|
|
86
|
+
config={config}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
}, [appInfo, config]);
|
|
90
|
+
|
|
91
|
+
// Memoize container style to prevent unnecessary re-renders
|
|
92
|
+
const containerStyles = useMemo(() => {
|
|
93
|
+
return [
|
|
94
|
+
styles.container,
|
|
95
|
+
{ backgroundColor: colors.backgroundPrimary },
|
|
96
|
+
containerStyle
|
|
97
|
+
];
|
|
98
|
+
}, [containerStyle, colors.backgroundPrimary, styles]);
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<ScrollView
|
|
102
|
+
style={containerStyles}
|
|
103
|
+
testID={testID}
|
|
104
|
+
contentContainerStyle={{ paddingBottom: 32 }}
|
|
105
|
+
>
|
|
106
|
+
{renderHeader()}
|
|
107
|
+
{renderContent()}
|
|
108
|
+
{renderFooter()}
|
|
109
|
+
</ScrollView>
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const getStyles = (_tokens: DesignTokens) => StyleSheet.create({
|
|
114
|
+
container: {
|
|
115
|
+
flex: 1,
|
|
116
|
+
},
|
|
117
|
+
footer: {
|
|
118
|
+
paddingVertical: 16,
|
|
119
|
+
paddingHorizontal: 16,
|
|
120
|
+
borderTopWidth: 1,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
* DEV-only feature with hardcoded English text
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { useState } from "react";
|
|
8
|
-
import { View,
|
|
7
|
+
import React, { useState, useMemo } from "react";
|
|
8
|
+
import { View, StyleSheet } from "react-native";
|
|
9
9
|
import {
|
|
10
10
|
AtomicText,
|
|
11
11
|
AtomicIcon,
|
|
12
12
|
AtomicTouchable,
|
|
13
13
|
useAppDesignTokens,
|
|
14
|
-
useSafeAreaInsets,
|
|
15
14
|
useAppNavigation,
|
|
16
15
|
AlertService,
|
|
16
|
+
ScreenLayout,
|
|
17
17
|
NavigationHeader,
|
|
18
18
|
} from "@umituz/react-native-design-system";
|
|
19
19
|
import * as Clipboard from "expo-clipboard";
|
|
@@ -26,7 +26,6 @@ export interface EnvViewerScreenProps {
|
|
|
26
26
|
|
|
27
27
|
export const EnvViewerScreen: React.FC<EnvViewerScreenProps> = ({ config }) => {
|
|
28
28
|
const tokens = useAppDesignTokens();
|
|
29
|
-
const { bottom } = useSafeAreaInsets();
|
|
30
29
|
const navigation = useAppNavigation();
|
|
31
30
|
const [revealedKeys, setRevealedKeys] = useState<Set<string>>(new Set());
|
|
32
31
|
|
|
@@ -94,62 +93,64 @@ export const EnvViewerScreen: React.FC<EnvViewerScreenProps> = ({ config }) => {
|
|
|
94
93
|
);
|
|
95
94
|
};
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<ScrollView
|
|
102
|
-
showsVerticalScrollIndicator={false}
|
|
103
|
-
contentContainerStyle={{ paddingBottom: bottom + tokens.spacing.lg }}
|
|
104
|
-
>
|
|
105
|
-
{config.environmentName && (
|
|
106
|
-
<View style={[styles.infoCard, { backgroundColor: tokens.colors.surfaceSecondary }]}>
|
|
107
|
-
<AtomicText type="labelSmall" color="textSecondary">
|
|
108
|
-
Environment
|
|
109
|
-
</AtomicText>
|
|
110
|
-
<AtomicText type="titleMedium" color="textPrimary">
|
|
111
|
-
{config.environmentName}
|
|
112
|
-
</AtomicText>
|
|
113
|
-
</View>
|
|
114
|
-
)}
|
|
96
|
+
const header = useMemo(() => (
|
|
97
|
+
<NavigationHeader title="Environment Variables" onBackPress={() => navigation.goBack()} />
|
|
98
|
+
), [navigation]);
|
|
115
99
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
Configuration
|
|
100
|
+
return (
|
|
101
|
+
<ScreenLayout
|
|
102
|
+
scrollable={true}
|
|
103
|
+
header={header}
|
|
104
|
+
hideScrollIndicator={false}
|
|
105
|
+
contentContainerStyle={styles.scrollContent}
|
|
106
|
+
>
|
|
107
|
+
{config.environmentName && (
|
|
108
|
+
<View style={[styles.infoCard, { backgroundColor: tokens.colors.surfaceSecondary }]}>
|
|
109
|
+
<AtomicText type="labelSmall" color="textSecondary">
|
|
110
|
+
Environment
|
|
111
|
+
</AtomicText>
|
|
112
|
+
<AtomicText type="titleMedium" color="textPrimary">
|
|
113
|
+
{config.environmentName}
|
|
131
114
|
</AtomicText>
|
|
132
|
-
{config.variables.map(renderVariable)}
|
|
133
115
|
</View>
|
|
116
|
+
)}
|
|
134
117
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
<AtomicText
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
118
|
+
{config.version && (
|
|
119
|
+
<View style={[styles.infoCard, { backgroundColor: tokens.colors.surfaceSecondary }]}>
|
|
120
|
+
<AtomicText type="labelSmall" color="textSecondary">
|
|
121
|
+
Version
|
|
122
|
+
</AtomicText>
|
|
123
|
+
<AtomicText type="titleMedium" color="textPrimary">
|
|
124
|
+
{config.version}
|
|
125
|
+
{config.buildNumber && ` (${config.buildNumber})`}
|
|
143
126
|
</AtomicText>
|
|
144
127
|
</View>
|
|
145
|
-
|
|
146
|
-
|
|
128
|
+
)}
|
|
129
|
+
|
|
130
|
+
<View style={styles.section}>
|
|
131
|
+
<AtomicText type="titleMedium" color="textPrimary" style={{ marginBottom: tokens.spacing.md }}>
|
|
132
|
+
Configuration
|
|
133
|
+
</AtomicText>
|
|
134
|
+
{config.variables.map(renderVariable)}
|
|
135
|
+
</View>
|
|
136
|
+
|
|
137
|
+
<View style={[styles.warningCard, { backgroundColor: tokens.colors.errorContainer }]}>
|
|
138
|
+
<AtomicIcon name="alert-circle" size="sm" color="error" />
|
|
139
|
+
<AtomicText
|
|
140
|
+
type="bodySmall"
|
|
141
|
+
color="error"
|
|
142
|
+
style={{ marginLeft: tokens.spacing.sm, flex: 1 }}
|
|
143
|
+
>
|
|
144
|
+
This screen is only visible in development mode. Never share sensitive values.
|
|
145
|
+
</AtomicText>
|
|
146
|
+
</View>
|
|
147
|
+
</ScreenLayout>
|
|
147
148
|
);
|
|
148
149
|
};
|
|
149
150
|
|
|
150
151
|
const styles = StyleSheet.create({
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
scrollContent: {
|
|
153
|
+
paddingBottom: 20,
|
|
153
154
|
},
|
|
154
155
|
infoCard: {
|
|
155
156
|
padding: 16,
|
|
@@ -13,10 +13,8 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import React from 'react';
|
|
16
|
-
import { View, StyleSheet
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
import { useAppDesignTokens, withAlpha } from '@umituz/react-native-design-system';
|
|
16
|
+
import { View, StyleSheet } from 'react-native';
|
|
17
|
+
import { useAppDesignTokens, withAlpha, ScreenLayout } from '@umituz/react-native-design-system';
|
|
20
18
|
import { AtomicText, AtomicIcon } from '@umituz/react-native-design-system';
|
|
21
19
|
import type { IconName } from '@umituz/react-native-design-system';
|
|
22
20
|
import { useLocalization } from '../../../localization';
|
|
@@ -49,52 +47,42 @@ export const DisclaimerScreen: React.FC<DisclaimerScreenProps> = ({
|
|
|
49
47
|
const displayContent = content || t(contentKey);
|
|
50
48
|
|
|
51
49
|
return (
|
|
52
|
-
<
|
|
53
|
-
|
|
50
|
+
<ScreenLayout
|
|
51
|
+
scrollable={true}
|
|
54
52
|
edges={['bottom']}
|
|
53
|
+
contentContainerStyle={styles.scrollContent}
|
|
54
|
+
hideScrollIndicator={false}
|
|
55
55
|
>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
borderColor: withAlpha(tokens.colors.warning, 0.3),
|
|
69
|
-
},
|
|
70
|
-
]}
|
|
71
|
-
>
|
|
72
|
-
<AtomicIcon name={iconName as IconName} color="warning" size="xl" />
|
|
73
|
-
</View>
|
|
56
|
+
{/* Icon Header */}
|
|
57
|
+
<View style={styles.iconHeader}>
|
|
58
|
+
<View
|
|
59
|
+
style={[
|
|
60
|
+
styles.iconContainer,
|
|
61
|
+
{
|
|
62
|
+
backgroundColor: withAlpha(tokens.colors.warning, 0.1),
|
|
63
|
+
borderColor: withAlpha(tokens.colors.warning, 0.3),
|
|
64
|
+
},
|
|
65
|
+
]}
|
|
66
|
+
>
|
|
67
|
+
<AtomicIcon name={iconName as IconName} color="warning" size="xl" />
|
|
74
68
|
</View>
|
|
69
|
+
</View>
|
|
75
70
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
{/* Title */}
|
|
72
|
+
<AtomicText type="headlineMedium" color="primary" style={styles.title}>
|
|
73
|
+
{displayTitle}
|
|
74
|
+
</AtomicText>
|
|
80
75
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
</SafeAreaView>
|
|
76
|
+
{/* Content */}
|
|
77
|
+
<AtomicText type="bodyMedium" color="secondary" style={styles.content}>
|
|
78
|
+
{displayContent}
|
|
79
|
+
</AtomicText>
|
|
80
|
+
</ScreenLayout>
|
|
87
81
|
);
|
|
88
82
|
};
|
|
89
83
|
|
|
90
84
|
const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
91
85
|
StyleSheet.create({
|
|
92
|
-
container: {
|
|
93
|
-
flex: 1,
|
|
94
|
-
},
|
|
95
|
-
scrollView: {
|
|
96
|
-
flex: 1,
|
|
97
|
-
},
|
|
98
86
|
scrollContent: {
|
|
99
87
|
padding: tokens.spacing.lg,
|
|
100
88
|
paddingTop: tokens.spacing.xl,
|