@umituz/react-native-settings 4.23.81 → 4.23.83
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 +49 -3
- package/src/domains/about/presentation/screens/AboutScreenContent.tsx +2 -4
- package/src/domains/disclaimer/presentation/screens/DisclaimerScreen.tsx +15 -1
- package/src/domains/faqs/presentation/screens/FAQScreen.tsx +25 -23
- package/src/domains/feedback/presentation/components/FeedbackForm.styles.ts +51 -0
- package/src/domains/feedback/presentation/components/FeedbackForm.tsx +3 -49
- package/src/domains/gamification/components/GamificationScreen/GamificationScreen.tsx +54 -57
- package/src/domains/legal/presentation/screens/LegalContentScreen.tsx +8 -8
- package/src/domains/legal/presentation/screens/LegalScreen.tsx +14 -3
- package/src/domains/localization/index.ts +2 -2
- package/src/domains/localization/presentation/providers/{LocalizationProvider.tsx → LocalizationManager.tsx} +1 -1
- package/src/domains/localization/presentation/screens/LanguageSelectionScreen.tsx +1 -1
- package/src/domains/notifications/index.ts +1 -1
- package/src/domains/notifications/presentation/screens/NotificationsScreen.tsx +53 -26
- package/src/domains/notifications/reminders/presentation/components/ReminderForm.constants.ts +35 -0
- package/src/domains/notifications/reminders/presentation/components/ReminderForm.styles.ts +22 -0
- package/src/domains/notifications/reminders/presentation/components/ReminderForm.tsx +13 -57
- package/src/domains/notifications/reminders/presentation/screens/ReminderListScreen.tsx +25 -10
- package/src/domains/video-tutorials/presentation/screens/VideoTutorialsScreen.tsx +17 -6
- package/src/presentation/components/SettingsFooter.tsx +3 -3
- package/src/presentation/navigation/SettingsStackNavigator.tsx +32 -174
- package/src/presentation/navigation/hooks/index.ts +1 -0
- package/src/presentation/navigation/hooks/useSettingsScreens.ts +163 -0
- package/src/presentation/screens/SettingsScreen.tsx +38 -58
- package/src/presentation/screens/components/SettingsHeader.tsx +29 -43
- package/src/presentation/screens/hooks/useSettingsScreen.ts +64 -0
- package/src/utils/appUtils.ts +43 -0
- package/src/utils/index.ts +1 -0
- package/src/domains/about/presentation/screens/AboutScreenContainer.tsx +0 -109
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.83",
|
|
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,8 +4,10 @@
|
|
|
4
4
|
* Fully configurable and generic
|
|
5
5
|
* Optimized for performance and memory safety
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
7
|
+
import { ScreenLayout, NavigationHeader, useAppDesignTokens, useAppNavigation, AtomicText, AtomicSpinner } from '@umituz/react-native-design-system';
|
|
8
|
+
import { useLocalization } from '../../../localization';
|
|
9
|
+
import { useAboutInfo } from '../hooks/useAboutInfo';
|
|
10
|
+
import { AboutScreenContent } from './AboutScreenContent';
|
|
9
11
|
|
|
10
12
|
export interface AboutScreenProps {
|
|
11
13
|
/** Configuration for the about screen */
|
|
@@ -29,5 +31,49 @@ export interface AboutScreenProps {
|
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
export const AboutScreen: React.FC<AboutScreenProps> = (props) => {
|
|
32
|
-
|
|
34
|
+
const { config, testID = 'about-screen' } = props;
|
|
35
|
+
const tokens = useAppDesignTokens();
|
|
36
|
+
const navigation = useAppNavigation();
|
|
37
|
+
const { t } = useLocalization();
|
|
38
|
+
|
|
39
|
+
const { appInfo, loading, error } = useAboutInfo({
|
|
40
|
+
autoInit: true,
|
|
41
|
+
initialConfig: config,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const header = (
|
|
45
|
+
<NavigationHeader
|
|
46
|
+
title={t("settings.about.title")}
|
|
47
|
+
onBackPress={() => navigation.goBack()}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (loading) {
|
|
52
|
+
return (
|
|
53
|
+
<ScreenLayout header={header} testID={testID}>
|
|
54
|
+
<AtomicSpinner fullContainer size="lg" />
|
|
55
|
+
</ScreenLayout>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (error || !appInfo) {
|
|
60
|
+
const errorText = error ? `${config.texts?.errorPrefix || 'Error:'} ${error}` : (config.texts?.noInfo || 'No info available');
|
|
61
|
+
return (
|
|
62
|
+
<ScreenLayout header={header} testID={testID}>
|
|
63
|
+
<AtomicText type="bodyMedium" color="error" style={{ textAlign: 'center', marginTop: 20 }}>
|
|
64
|
+
{errorText}
|
|
65
|
+
</AtomicText>
|
|
66
|
+
</ScreenLayout>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<ScreenLayout header={header} testID={testID}>
|
|
72
|
+
<AboutScreenContent
|
|
73
|
+
{...props}
|
|
74
|
+
appInfo={appInfo}
|
|
75
|
+
_tokens={tokens}
|
|
76
|
+
/>
|
|
77
|
+
</ScreenLayout>
|
|
78
|
+
);
|
|
33
79
|
};
|
|
@@ -7,7 +7,6 @@ import React, { useMemo, useCallback } from 'react';
|
|
|
7
7
|
import {
|
|
8
8
|
View,
|
|
9
9
|
StyleSheet,
|
|
10
|
-
ScrollView,
|
|
11
10
|
} from 'react-native';
|
|
12
11
|
import { AboutHeader } from '../components/AboutHeader';
|
|
13
12
|
import { AboutContent } from '../components/AboutContent';
|
|
@@ -98,15 +97,14 @@ export const AboutScreenContent: React.FC<AboutScreenContentProps> = ({
|
|
|
98
97
|
}, [containerStyle, colors.backgroundPrimary, styles]);
|
|
99
98
|
|
|
100
99
|
return (
|
|
101
|
-
<
|
|
100
|
+
<View
|
|
102
101
|
style={containerStyles}
|
|
103
102
|
testID={testID}
|
|
104
|
-
contentContainerStyle={{ paddingBottom: 32 }}
|
|
105
103
|
>
|
|
106
104
|
{renderHeader()}
|
|
107
105
|
{renderContent()}
|
|
108
106
|
{renderFooter()}
|
|
109
|
-
</
|
|
107
|
+
</View>
|
|
110
108
|
);
|
|
111
109
|
};
|
|
112
110
|
|
|
@@ -14,7 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
import React from 'react';
|
|
16
16
|
import { View, StyleSheet } from 'react-native';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
useAppDesignTokens,
|
|
19
|
+
withAlpha,
|
|
20
|
+
ScreenLayout,
|
|
21
|
+
useAppNavigation,
|
|
22
|
+
NavigationHeader
|
|
23
|
+
} from '@umituz/react-native-design-system';
|
|
18
24
|
import { AtomicText, AtomicIcon } from '@umituz/react-native-design-system';
|
|
19
25
|
import type { IconName } from '@umituz/react-native-design-system';
|
|
20
26
|
import { useLocalization } from '../../../localization';
|
|
@@ -46,12 +52,20 @@ export const DisclaimerScreen: React.FC<DisclaimerScreenProps> = ({
|
|
|
46
52
|
const displayTitle = title || t(titleKey);
|
|
47
53
|
const displayContent = content || t(contentKey);
|
|
48
54
|
|
|
55
|
+
const navigation = useAppNavigation();
|
|
56
|
+
|
|
49
57
|
return (
|
|
50
58
|
<ScreenLayout
|
|
51
59
|
scrollable={true}
|
|
52
60
|
edges={['bottom']}
|
|
53
61
|
contentContainerStyle={styles.scrollContent}
|
|
54
62
|
hideScrollIndicator={false}
|
|
63
|
+
header={
|
|
64
|
+
<NavigationHeader
|
|
65
|
+
title={displayTitle}
|
|
66
|
+
onBackPress={() => navigation.goBack()}
|
|
67
|
+
/>
|
|
68
|
+
}
|
|
55
69
|
>
|
|
56
70
|
{/* Icon Header */}
|
|
57
71
|
<View style={styles.iconHeader}>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useMemo } from 'react';
|
|
8
8
|
import { View, ScrollView, StyleSheet, ViewStyle, TextStyle, useWindowDimensions } from 'react-native';
|
|
9
|
-
import { useAppDesignTokens, AtomicText, ScreenLayout, getContentMaxWidth } from '@umituz/react-native-design-system';
|
|
9
|
+
import { useAppDesignTokens, AtomicText, ScreenLayout, getContentMaxWidth, NavigationHeader, useAppNavigation } from '@umituz/react-native-design-system';
|
|
10
10
|
import { FAQCategory } from '../../domain/entities/FAQEntity';
|
|
11
11
|
import { useFAQSearch } from '../hooks/useFAQSearch';
|
|
12
12
|
import { useFAQExpansion } from '../hooks/useFAQExpansion';
|
|
@@ -45,6 +45,7 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
45
45
|
renderHeader,
|
|
46
46
|
styles: customStyles,
|
|
47
47
|
}) => {
|
|
48
|
+
const navigation = useAppNavigation();
|
|
48
49
|
const tokens = useAppDesignTokens();
|
|
49
50
|
const { width: windowWidth } = useWindowDimensions();
|
|
50
51
|
const contentMaxWidth = useMemo(() => getContentMaxWidth(windowWidth), [windowWidth]);
|
|
@@ -67,6 +68,21 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
67
68
|
[tokens]
|
|
68
69
|
);
|
|
69
70
|
|
|
71
|
+
const handleBack = () => {
|
|
72
|
+
if (onBack) {
|
|
73
|
+
onBack();
|
|
74
|
+
} else {
|
|
75
|
+
navigation.goBack();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const header = renderHeader ? renderHeader({ onBack: handleBack }) : (
|
|
80
|
+
<NavigationHeader
|
|
81
|
+
title={headerTitle}
|
|
82
|
+
onBackPress={handleBack}
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
|
|
70
86
|
const renderContent = () => {
|
|
71
87
|
if (searchQuery && !hasResults) {
|
|
72
88
|
return (
|
|
@@ -81,13 +97,6 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
81
97
|
return (
|
|
82
98
|
<View style={{ flex: 1 }}>
|
|
83
99
|
<View style={[styles.header, customStyles?.header]}>
|
|
84
|
-
<AtomicText
|
|
85
|
-
type="headlineMedium"
|
|
86
|
-
color="textPrimary"
|
|
87
|
-
style={{ marginBottom: tokens.spacing.md, fontWeight: '700' }}
|
|
88
|
-
>
|
|
89
|
-
{headerTitle}
|
|
90
|
-
</AtomicText>
|
|
91
100
|
<FAQSearchBar
|
|
92
101
|
value={searchQuery}
|
|
93
102
|
onChangeText={setSearchQuery}
|
|
@@ -116,23 +125,16 @@ export const FAQScreen: React.FC<FAQScreenProps> = ({
|
|
|
116
125
|
);
|
|
117
126
|
};
|
|
118
127
|
|
|
119
|
-
if (renderHeader && onBack) {
|
|
120
|
-
return (
|
|
121
|
-
<View style={{ flex: 1, backgroundColor: tokens.colors.backgroundPrimary }}>
|
|
122
|
-
<View style={[styles.container, customStyles?.container]}>
|
|
123
|
-
<View style={{ alignSelf: 'center', width: '100%', maxWidth: contentMaxWidth }}>
|
|
124
|
-
{renderHeader({ onBack })}
|
|
125
|
-
</View>
|
|
126
|
-
{renderContent()}
|
|
127
|
-
</View>
|
|
128
|
-
</View>
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
128
|
return (
|
|
133
|
-
<ScreenLayout
|
|
129
|
+
<ScreenLayout
|
|
130
|
+
edges={['bottom']}
|
|
131
|
+
scrollable={false}
|
|
132
|
+
header={header}
|
|
133
|
+
>
|
|
134
134
|
<View style={[styles.container, customStyles?.container]}>
|
|
135
|
-
{
|
|
135
|
+
<View style={{ alignSelf: 'center', width: '100%', maxWidth: contentMaxWidth, flex: 1 }}>
|
|
136
|
+
{renderContent()}
|
|
137
|
+
</View>
|
|
136
138
|
</View>
|
|
137
139
|
</ScreenLayout>
|
|
138
140
|
);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
import type { useAppDesignTokens } from "@umituz/react-native-design-system";
|
|
3
|
+
|
|
4
|
+
export const getFeedbackFormStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
5
|
+
StyleSheet.create({
|
|
6
|
+
container: {
|
|
7
|
+
width: "100%",
|
|
8
|
+
},
|
|
9
|
+
typeContainer: {
|
|
10
|
+
marginBottom: 24,
|
|
11
|
+
},
|
|
12
|
+
typeScroll: {
|
|
13
|
+
gap: 8,
|
|
14
|
+
},
|
|
15
|
+
typeButton: {
|
|
16
|
+
flexDirection: "row",
|
|
17
|
+
alignItems: "center",
|
|
18
|
+
paddingHorizontal: 16,
|
|
19
|
+
paddingVertical: 8,
|
|
20
|
+
borderRadius: 20,
|
|
21
|
+
borderWidth: 1,
|
|
22
|
+
gap: 6,
|
|
23
|
+
},
|
|
24
|
+
ratingContainer: {
|
|
25
|
+
alignItems: "center",
|
|
26
|
+
marginBottom: 24,
|
|
27
|
+
},
|
|
28
|
+
stars: {
|
|
29
|
+
flexDirection: "row",
|
|
30
|
+
gap: 8,
|
|
31
|
+
},
|
|
32
|
+
starButton: {
|
|
33
|
+
padding: 4,
|
|
34
|
+
},
|
|
35
|
+
inputContainer: {
|
|
36
|
+
marginBottom: 24,
|
|
37
|
+
},
|
|
38
|
+
textArea: {
|
|
39
|
+
textAlignVertical: "top",
|
|
40
|
+
minHeight: 120,
|
|
41
|
+
borderWidth: 1,
|
|
42
|
+
borderRadius: 8,
|
|
43
|
+
padding: 12,
|
|
44
|
+
},
|
|
45
|
+
errorText: {
|
|
46
|
+
marginTop: 8,
|
|
47
|
+
},
|
|
48
|
+
submitButton: {
|
|
49
|
+
width: "100%",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
@@ -8,6 +8,8 @@ import { View, StyleSheet, TouchableOpacity, ScrollView, TextInput } from "react
|
|
|
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
|
|
|
11
|
+
import { getFeedbackFormStyles as getStyles } from "./FeedbackForm.styles";
|
|
12
|
+
|
|
11
13
|
export interface FeedbackFormProps {
|
|
12
14
|
onSubmit: (data: { type: FeedbackType; rating: FeedbackRating; description: string; title: string }) => Promise<void>;
|
|
13
15
|
texts: {
|
|
@@ -151,6 +153,7 @@ export const FeedbackForm: React.FC<FeedbackFormProps> = ({
|
|
|
151
153
|
color: tokens.colors.textPrimary,
|
|
152
154
|
backgroundColor: tokens.colors.surface,
|
|
153
155
|
borderColor: error ? tokens.colors.error : tokens.colors.border,
|
|
156
|
+
fontSize: tokens.typography.bodyMedium.fontSize,
|
|
154
157
|
}
|
|
155
158
|
]}
|
|
156
159
|
/>
|
|
@@ -176,52 +179,3 @@ export const FeedbackForm: React.FC<FeedbackFormProps> = ({
|
|
|
176
179
|
);
|
|
177
180
|
};
|
|
178
181
|
|
|
179
|
-
const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
|
|
180
|
-
StyleSheet.create({
|
|
181
|
-
container: {
|
|
182
|
-
width: "100%",
|
|
183
|
-
},
|
|
184
|
-
typeContainer: {
|
|
185
|
-
marginBottom: 24,
|
|
186
|
-
},
|
|
187
|
-
typeScroll: {
|
|
188
|
-
gap: 8,
|
|
189
|
-
},
|
|
190
|
-
typeButton: {
|
|
191
|
-
flexDirection: "row",
|
|
192
|
-
alignItems: "center",
|
|
193
|
-
paddingHorizontal: 16,
|
|
194
|
-
paddingVertical: 8,
|
|
195
|
-
borderRadius: 20,
|
|
196
|
-
borderWidth: 1,
|
|
197
|
-
gap: 6,
|
|
198
|
-
},
|
|
199
|
-
ratingContainer: {
|
|
200
|
-
alignItems: "center",
|
|
201
|
-
marginBottom: 24,
|
|
202
|
-
},
|
|
203
|
-
stars: {
|
|
204
|
-
flexDirection: "row",
|
|
205
|
-
gap: 8,
|
|
206
|
-
},
|
|
207
|
-
starButton: {
|
|
208
|
-
padding: 4,
|
|
209
|
-
},
|
|
210
|
-
inputContainer: {
|
|
211
|
-
marginBottom: 24,
|
|
212
|
-
},
|
|
213
|
-
textArea: {
|
|
214
|
-
textAlignVertical: "top",
|
|
215
|
-
minHeight: 120,
|
|
216
|
-
borderWidth: 1,
|
|
217
|
-
borderRadius: 8,
|
|
218
|
-
padding: 12,
|
|
219
|
-
fontSize: tokens.typography.bodyMedium.fontSize,
|
|
220
|
-
},
|
|
221
|
-
errorText: {
|
|
222
|
-
marginTop: 8,
|
|
223
|
-
},
|
|
224
|
-
submitButton: {
|
|
225
|
-
width: "100%",
|
|
226
|
-
},
|
|
227
|
-
});
|
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
import React from "react";
|
|
8
8
|
import { View, ScrollView } from "react-native";
|
|
9
|
-
import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
|
|
9
|
+
import { useAppDesignTokens, AtomicText, ScreenLayout, NavigationHeader, useAppNavigation } from "@umituz/react-native-design-system";
|
|
10
10
|
import { LevelProgress } from "../LevelProgress";
|
|
11
11
|
import { StreakDisplay } from "../StreakDisplay";
|
|
12
|
-
import { Header } from "./Header";
|
|
13
12
|
import { StatsGrid } from "./StatsGrid";
|
|
14
13
|
import { AchievementsList } from "./AchievementsList";
|
|
15
14
|
import { styles } from "./styles";
|
|
@@ -39,6 +38,7 @@ export const GamificationScreenInner: React.FC<GamificationScreenProps> = ({
|
|
|
39
38
|
subtextColor,
|
|
40
39
|
headerComponent,
|
|
41
40
|
}) => {
|
|
41
|
+
const navigation = useAppNavigation();
|
|
42
42
|
const tokens = useAppDesignTokens();
|
|
43
43
|
|
|
44
44
|
// Use tokens for fallbacks
|
|
@@ -48,75 +48,72 @@ export const GamificationScreenInner: React.FC<GamificationScreenProps> = ({
|
|
|
48
48
|
const finalTextColor = textColor || tokens.colors.textPrimary;
|
|
49
49
|
const finalSubtextColor = subtextColor || tokens.colors.textSecondary;
|
|
50
50
|
|
|
51
|
+
const header = (
|
|
52
|
+
<NavigationHeader
|
|
53
|
+
title={title}
|
|
54
|
+
onBackPress={() => navigation.goBack()}
|
|
55
|
+
/>
|
|
56
|
+
);
|
|
57
|
+
|
|
51
58
|
return (
|
|
52
|
-
<
|
|
59
|
+
<ScreenLayout
|
|
60
|
+
header={header}
|
|
61
|
+
contentContainerStyle={styles.scrollContent}
|
|
62
|
+
hideScrollIndicator={false}
|
|
63
|
+
>
|
|
53
64
|
{headerComponent}
|
|
54
65
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<Header
|
|
62
|
-
title={title}
|
|
63
|
-
headerStyle={headerStyle}
|
|
64
|
-
titleStyle={titleStyle}
|
|
66
|
+
{/* Level Progress */}
|
|
67
|
+
<View style={styles.section}>
|
|
68
|
+
<LevelProgress
|
|
69
|
+
{...levelProps}
|
|
70
|
+
primaryColor={finalAccentColor}
|
|
71
|
+
backgroundColor={finalCardBackgroundColor}
|
|
65
72
|
textColor={finalTextColor}
|
|
73
|
+
subtextColor={finalSubtextColor}
|
|
66
74
|
/>
|
|
75
|
+
</View>
|
|
67
76
|
|
|
68
|
-
|
|
77
|
+
{/* Streak (if provided) */}
|
|
78
|
+
{streakProps && (
|
|
69
79
|
<View style={styles.section}>
|
|
70
|
-
<
|
|
71
|
-
{
|
|
80
|
+
<AtomicText
|
|
81
|
+
style={[styles.sectionTitle, { color: finalTextColor }, sectionTitleStyle]}
|
|
82
|
+
>
|
|
83
|
+
{streakTitle}
|
|
84
|
+
</AtomicText>
|
|
85
|
+
<StreakDisplay
|
|
86
|
+
{...streakProps}
|
|
72
87
|
primaryColor={finalAccentColor}
|
|
73
88
|
backgroundColor={finalCardBackgroundColor}
|
|
74
89
|
textColor={finalTextColor}
|
|
75
90
|
subtextColor={finalSubtextColor}
|
|
76
91
|
/>
|
|
77
92
|
</View>
|
|
93
|
+
)}
|
|
78
94
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
primaryColor={finalAccentColor}
|
|
90
|
-
backgroundColor={finalCardBackgroundColor}
|
|
91
|
-
textColor={finalTextColor}
|
|
92
|
-
subtextColor={finalSubtextColor}
|
|
93
|
-
/>
|
|
94
|
-
</View>
|
|
95
|
-
)}
|
|
96
|
-
|
|
97
|
-
{/* Stats Grid */}
|
|
98
|
-
<StatsGrid
|
|
99
|
-
statsTitle={statsTitle}
|
|
100
|
-
stats={stats}
|
|
101
|
-
accentColor={finalAccentColor}
|
|
102
|
-
cardBackgroundColor={finalCardBackgroundColor}
|
|
103
|
-
textColor={finalTextColor}
|
|
104
|
-
subtextColor={finalSubtextColor}
|
|
105
|
-
sectionTitleStyle={sectionTitleStyle}
|
|
106
|
-
/>
|
|
95
|
+
{/* Stats Grid */}
|
|
96
|
+
<StatsGrid
|
|
97
|
+
statsTitle={statsTitle}
|
|
98
|
+
stats={stats}
|
|
99
|
+
accentColor={finalAccentColor}
|
|
100
|
+
cardBackgroundColor={finalCardBackgroundColor}
|
|
101
|
+
textColor={finalTextColor}
|
|
102
|
+
subtextColor={finalSubtextColor}
|
|
103
|
+
sectionTitleStyle={sectionTitleStyle}
|
|
104
|
+
/>
|
|
107
105
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
</View>
|
|
106
|
+
{/* Achievements */}
|
|
107
|
+
<AchievementsList
|
|
108
|
+
achievementsTitle={achievementsTitle}
|
|
109
|
+
achievements={achievements}
|
|
110
|
+
emptyAchievementsText={emptyAchievementsText}
|
|
111
|
+
accentColor={finalAccentColor}
|
|
112
|
+
cardBackgroundColor={finalCardBackgroundColor}
|
|
113
|
+
textColor={finalTextColor}
|
|
114
|
+
subtextColor={finalSubtextColor}
|
|
115
|
+
sectionTitleStyle={sectionTitleStyle}
|
|
116
|
+
/>
|
|
117
|
+
</ScreenLayout>
|
|
121
118
|
);
|
|
122
119
|
};
|
|
@@ -9,6 +9,7 @@ import { AtomicText, AtomicButton } from "@umituz/react-native-design-system";
|
|
|
9
9
|
import { UrlHandlerService } from "../../domain/services/UrlHandlerService";
|
|
10
10
|
import { ContentValidationService } from "../../domain/services/ContentValidationService";
|
|
11
11
|
import { StyleCacheService } from "../../domain/services/StyleCacheService";
|
|
12
|
+
import { useAppNavigation, NavigationHeader } from "@umituz/react-native-design-system";
|
|
12
13
|
|
|
13
14
|
export interface LegalContentScreenProps {
|
|
14
15
|
content?: string;
|
|
@@ -34,6 +35,7 @@ export const LegalContentScreen: React.FC<LegalContentScreenProps> = React.memo(
|
|
|
34
35
|
createStyles,
|
|
35
36
|
}) => {
|
|
36
37
|
const tokens = useAppDesignTokens();
|
|
38
|
+
const navigation = useAppNavigation();
|
|
37
39
|
|
|
38
40
|
const styles = React.useMemo(() => {
|
|
39
41
|
const cacheKey = StyleCacheService.createTokenCacheKey(tokens);
|
|
@@ -101,17 +103,15 @@ export const LegalContentScreen: React.FC<LegalContentScreenProps> = React.memo(
|
|
|
101
103
|
testID={testID}
|
|
102
104
|
scrollable={true}
|
|
103
105
|
hideScrollIndicator={false}
|
|
106
|
+
header={
|
|
107
|
+
<NavigationHeader
|
|
108
|
+
title={title}
|
|
109
|
+
onBackPress={() => navigation.goBack()}
|
|
110
|
+
/>
|
|
111
|
+
}
|
|
104
112
|
contentContainerStyle={styles.scrollContent}
|
|
105
113
|
>
|
|
106
114
|
<View style={styles.content}>
|
|
107
|
-
<AtomicText
|
|
108
|
-
type="headlineLarge"
|
|
109
|
-
color="primary"
|
|
110
|
-
style={styles.title}
|
|
111
|
-
>
|
|
112
|
-
{title}
|
|
113
|
-
</AtomicText>
|
|
114
|
-
|
|
115
115
|
{contentSection}
|
|
116
116
|
</View>
|
|
117
117
|
</ScreenLayout>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import React from "react";
|
|
9
|
-
import { ScreenLayout } from "@umituz/react-native-design-system";
|
|
9
|
+
import { ScreenLayout, NavigationHeader, useAppNavigation } from "@umituz/react-native-design-system";
|
|
10
10
|
import { LegalScreenHeader } from "../components/LegalScreenHeader";
|
|
11
11
|
import { LegalDocumentsList } from "../components/LegalDocumentsList";
|
|
12
12
|
|
|
@@ -45,10 +45,21 @@ export const LegalScreen: React.FC<LegalScreenProps> = React.memo((props) => {
|
|
|
45
45
|
testID = "legal-screen",
|
|
46
46
|
} = props;
|
|
47
47
|
|
|
48
|
+
const navigation = useAppNavigation();
|
|
49
|
+
|
|
48
50
|
return (
|
|
49
|
-
<ScreenLayout
|
|
51
|
+
<ScreenLayout
|
|
52
|
+
testID={testID}
|
|
53
|
+
hideScrollIndicator
|
|
54
|
+
header={
|
|
55
|
+
<NavigationHeader
|
|
56
|
+
title={title || ""}
|
|
57
|
+
onBackPress={() => navigation.goBack()}
|
|
58
|
+
/>
|
|
59
|
+
}
|
|
60
|
+
>
|
|
50
61
|
<LegalScreenHeader title={title} description={description} />
|
|
51
|
-
|
|
62
|
+
|
|
52
63
|
<LegalDocumentsList
|
|
53
64
|
documentsHeader={documentsHeader}
|
|
54
65
|
privacyTitle={privacyTitle}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
export {
|
|
1
|
+
// Managers
|
|
2
|
+
export { LocalizationManager } from './presentation/providers/LocalizationManager';
|
|
3
3
|
|
|
4
4
|
// Hooks
|
|
5
5
|
export { useLocalization } from './infrastructure/hooks/useLocalization';
|
|
@@ -13,7 +13,7 @@ interface LocalizationProviderProps {
|
|
|
13
13
|
defaultLanguage?: string;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export const
|
|
16
|
+
export const LocalizationManager: React.FC<LocalizationProviderProps> = ({
|
|
17
17
|
children,
|
|
18
18
|
translations,
|
|
19
19
|
defaultLanguage = "en-US",
|
|
@@ -43,7 +43,7 @@ export const LanguageSelectionScreen: React.FC<LanguageSelectionScreenProps> = (
|
|
|
43
43
|
}
|
|
44
44
|
await handleLanguageSelect(code, () => {
|
|
45
45
|
if (__DEV__) {
|
|
46
|
-
console.log('[LanguageSelectionScreen] Navigating back using
|
|
46
|
+
console.log('[LanguageSelectionScreen] Navigating back using standard navigation');
|
|
47
47
|
}
|
|
48
48
|
navigation.goBack();
|
|
49
49
|
});
|
|
@@ -110,7 +110,7 @@ export { ReminderItem } from './reminders/presentation/components/ReminderItem';
|
|
|
110
110
|
export type { ReminderItemProps, ReminderItemTranslations } from './reminders/presentation/components/ReminderItem';
|
|
111
111
|
|
|
112
112
|
export { ReminderForm } from './reminders/presentation/components/ReminderForm';
|
|
113
|
-
export type { ReminderFormProps, ReminderFormTranslations } from './reminders/presentation/components/ReminderForm';
|
|
113
|
+
export type { ReminderFormProps, ReminderFormTranslations } from './reminders/presentation/components/ReminderForm.constants';
|
|
114
114
|
|
|
115
115
|
export { FormButton } from './reminders/presentation/components/FormButton';
|
|
116
116
|
export type { FormButtonProps } from './reminders/presentation/components/FormButton';
|