@umituz/react-native-settings 4.17.15 → 4.17.16

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.
Files changed (94) hide show
  1. package/package.json +11 -13
  2. package/src/domains/about/__tests__/integration.test.tsx +328 -0
  3. package/src/domains/about/__tests__/types.d.ts +5 -0
  4. package/src/domains/about/domain/entities/AppInfo.ts +74 -0
  5. package/src/domains/about/domain/entities/__tests__/AppInfo.test.ts +93 -0
  6. package/src/domains/about/domain/repositories/IAboutRepository.ts +22 -0
  7. package/src/domains/about/index.ts +10 -0
  8. package/src/domains/about/infrastructure/repositories/AboutRepository.ts +68 -0
  9. package/src/domains/about/infrastructure/repositories/__tests__/AboutRepository.test.ts +153 -0
  10. package/src/domains/about/presentation/components/AboutContent.tsx +104 -0
  11. package/src/domains/about/presentation/components/AboutHeader.tsx +79 -0
  12. package/src/domains/about/presentation/components/AboutSection.tsx +134 -0
  13. package/src/domains/about/presentation/components/AboutSettingItem.tsx +208 -0
  14. package/src/domains/about/presentation/components/__tests__/AboutContent.simple.test.tsx +178 -0
  15. package/src/domains/about/presentation/components/__tests__/AboutContent.test.tsx +293 -0
  16. package/src/domains/about/presentation/components/__tests__/AboutHeader.test.tsx +201 -0
  17. package/src/domains/about/presentation/components/__tests__/AboutSettingItem.test.tsx +71 -0
  18. package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.simple.test.tsx +229 -0
  19. package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.test.tsx +240 -0
  20. package/src/domains/about/presentation/hooks/useAboutInfo.ts +262 -0
  21. package/src/domains/about/presentation/screens/AboutScreen.tsx +195 -0
  22. package/src/domains/about/presentation/screens/__tests__/AboutScreen.simple.test.tsx +199 -0
  23. package/src/domains/about/presentation/screens/__tests__/AboutScreen.test.tsx +366 -0
  24. package/src/domains/about/types/global.d.ts +15 -0
  25. package/src/domains/about/utils/__tests__/index.test.ts +408 -0
  26. package/src/domains/about/utils/index.ts +160 -0
  27. package/src/domains/appearance/__tests__/components/AppearanceScreen.test.tsx +195 -0
  28. package/src/domains/appearance/__tests__/hooks/index.test.tsx +232 -0
  29. package/src/domains/appearance/__tests__/integration/index.test.tsx +207 -0
  30. package/src/domains/appearance/__tests__/services/appearanceService.test.ts +299 -0
  31. package/src/domains/appearance/__tests__/setup.ts +96 -0
  32. package/src/domains/appearance/__tests__/stores/appearanceStore.test.tsx +175 -0
  33. package/src/domains/appearance/data/colorPalettes.ts +94 -0
  34. package/src/domains/appearance/hooks/index.ts +6 -0
  35. package/src/domains/appearance/hooks/useAppearance.ts +61 -0
  36. package/src/domains/appearance/hooks/useAppearanceActions.ts +144 -0
  37. package/src/domains/appearance/index.ts +7 -0
  38. package/src/domains/appearance/infrastructure/services/appearanceService.ts +301 -0
  39. package/src/domains/appearance/infrastructure/services/systemThemeDetection.ts +79 -0
  40. package/src/domains/appearance/infrastructure/services/validation.ts +91 -0
  41. package/src/domains/appearance/infrastructure/storage/appearanceStorage.ts +120 -0
  42. package/src/domains/appearance/infrastructure/stores/appearanceStore.ts +132 -0
  43. package/src/domains/appearance/presentation/components/AppearanceHeader.tsx +67 -0
  44. package/src/domains/appearance/presentation/components/AppearancePreview.tsx +141 -0
  45. package/src/domains/appearance/presentation/components/AppearanceSection.tsx +139 -0
  46. package/src/domains/appearance/presentation/components/ColorPicker.tsx +113 -0
  47. package/src/domains/appearance/presentation/components/CustomColorsSection.tsx +186 -0
  48. package/src/domains/appearance/presentation/components/ThemeModeSection.tsx +110 -0
  49. package/src/domains/appearance/presentation/components/ThemeOption.tsx +138 -0
  50. package/src/domains/appearance/presentation/components/index.ts +6 -0
  51. package/src/domains/appearance/presentation/screens/AppearanceScreen.tsx +226 -0
  52. package/src/domains/appearance/presentation/screens/index.ts +2 -0
  53. package/src/domains/appearance/types/index.ts +54 -0
  54. package/src/domains/faqs/domain/entities/FAQEntity.ts +16 -0
  55. package/src/domains/faqs/domain/services/FAQSearchService.ts +36 -0
  56. package/src/domains/faqs/domain/services/index.ts +1 -0
  57. package/src/domains/faqs/index.ts +7 -0
  58. package/src/domains/faqs/presentation/components/FAQCategory.tsx +71 -0
  59. package/src/domains/faqs/presentation/components/FAQEmptyState.tsx +75 -0
  60. package/src/domains/faqs/presentation/components/FAQItem.tsx +103 -0
  61. package/src/domains/faqs/presentation/components/FAQSearchBar.tsx +70 -0
  62. package/src/domains/faqs/presentation/components/FAQSection.tsx +50 -0
  63. package/src/domains/faqs/presentation/components/index.ts +18 -0
  64. package/src/domains/faqs/presentation/hooks/index.ts +6 -0
  65. package/src/domains/faqs/presentation/hooks/useFAQExpansion.ts +51 -0
  66. package/src/domains/faqs/presentation/hooks/useFAQSearch.ts +33 -0
  67. package/src/domains/faqs/presentation/screens/FAQScreen.tsx +129 -0
  68. package/src/domains/faqs/presentation/screens/index.ts +2 -0
  69. package/src/domains/feedback/domain/entities/FeedbackEntity.ts +92 -0
  70. package/src/domains/feedback/domain/repositories/IFeedbackRepository.ts +28 -0
  71. package/src/domains/feedback/index.ts +6 -0
  72. package/src/domains/feedback/presentation/components/FeedbackForm.tsx +189 -0
  73. package/src/domains/feedback/presentation/components/FeedbackModal.tsx +111 -0
  74. package/src/domains/feedback/presentation/components/SupportSection.tsx +160 -0
  75. package/src/domains/feedback/presentation/hooks/useDeleteFeedback.ts +25 -0
  76. package/src/domains/feedback/presentation/hooks/useFeedbackForm.ts +59 -0
  77. package/src/domains/feedback/presentation/hooks/useSubmitFeedback.ts +55 -0
  78. package/src/domains/feedback/presentation/hooks/useUserFeedback.ts +29 -0
  79. package/src/domains/legal/__tests__/ContentValidationService.test.ts +195 -0
  80. package/src/domains/legal/__tests__/StyleCacheService.test.ts +110 -0
  81. package/src/domains/legal/__tests__/UrlHandlerService.test.ts +71 -0
  82. package/src/domains/legal/__tests__/setup.ts +82 -0
  83. package/src/domains/legal/domain/entities/LegalConfig.ts +26 -0
  84. package/src/domains/legal/domain/services/ContentValidationService.ts +89 -0
  85. package/src/domains/legal/domain/services/StyleCacheService.ts +97 -0
  86. package/src/domains/legal/domain/services/UrlHandlerService.ts +128 -0
  87. package/src/domains/legal/index.ts +8 -0
  88. package/src/domains/legal/presentation/components/LegalItem.tsx +177 -0
  89. package/src/domains/legal/presentation/components/LegalLinks.tsx +154 -0
  90. package/src/domains/legal/presentation/components/LegalSection.tsx +134 -0
  91. package/src/domains/legal/presentation/screens/LegalScreen.tsx +237 -0
  92. package/src/domains/legal/presentation/screens/PrivacyPolicyScreen.tsx +214 -0
  93. package/src/domains/legal/presentation/screens/TermsOfServiceScreen.tsx +214 -0
  94. package/src/index.ts +19 -0
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Privacy Policy Screen Component
3
+ * Display Privacy Policy content
4
+ */
5
+
6
+ import React from "react";
7
+ import { View, ScrollView, StyleSheet } from "react-native";
8
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
9
+ import { useResponsiveDesignTokens } from "@umituz/react-native-design-system";
10
+ import { AtomicText, AtomicButton } from "@umituz/react-native-design-system";
11
+ import { UrlHandlerService } from "../../domain/services/UrlHandlerService";
12
+ import { ContentValidationService } from "../../domain/services/ContentValidationService";
13
+ import { StyleCacheService } from "../../domain/services/StyleCacheService";
14
+
15
+ export interface PrivacyPolicyScreenProps {
16
+ /**
17
+ * Privacy Policy content (HTML or plain text)
18
+ * Either content or url must be provided
19
+ */
20
+ content?: string;
21
+ /**
22
+ * Privacy Policy URL (if content is not provided, will open URL)
23
+ * Either content or url must be provided
24
+ */
25
+ url?: string;
26
+ /**
27
+ * Custom title
28
+ */
29
+ title: string;
30
+ /**
31
+ * Text for viewing online button (required when url is provided)
32
+ */
33
+ viewOnlineText?: string;
34
+ /**
35
+ * Text for open button (required when url is provided)
36
+ */
37
+ openText?: string;
38
+ /**
39
+ * Callback when URL is pressed (if content is not provided)
40
+ */
41
+ onUrlPress?: () => void;
42
+ /**
43
+ * Test ID for E2E testing
44
+ */
45
+ testID?: string;
46
+ }
47
+
48
+ export const PrivacyPolicyScreen: React.FC<PrivacyPolicyScreenProps> = React.memo(({
49
+ content,
50
+ url,
51
+ title,
52
+ viewOnlineText,
53
+ openText,
54
+ onUrlPress,
55
+ testID = "privacy-policy-screen",
56
+ }) => {
57
+ const tokens = useResponsiveDesignTokens();
58
+ const insets = useSafeAreaInsets();
59
+
60
+ // Validate required props
61
+ React.useEffect(() => {
62
+ ContentValidationService.validateScreenContent(
63
+ content,
64
+ url,
65
+ title,
66
+ viewOnlineText,
67
+ openText,
68
+ 'PrivacyPolicyScreen'
69
+ );
70
+ }, [content, url, title, viewOnlineText, openText]);
71
+
72
+ // Use cached styles
73
+ const styles = React.useMemo(() => {
74
+ return StyleCacheService.getCachedStyles(
75
+ 'PrivacyPolicyScreen',
76
+ 'privacy-policy-styles',
77
+ createPrivacyPolicyStyles
78
+ );
79
+ }, []);
80
+
81
+ // Memoize URL press handler to prevent child re-renders
82
+ const handleUrlPress = React.useCallback(async () => {
83
+ if (__DEV__) {
84
+ console.log('PrivacyPolicyScreen: URL pressed', { url });
85
+ }
86
+
87
+ if (onUrlPress) {
88
+ onUrlPress();
89
+ } else if (url) {
90
+ try {
91
+ await UrlHandlerService.openUrl(url);
92
+ } catch (error) {
93
+ if (__DEV__) {
94
+ console.error('PrivacyPolicyScreen: Error opening URL', error);
95
+ }
96
+ }
97
+ }
98
+ }, [onUrlPress, url]);
99
+
100
+ // Memoize container style to prevent object creation
101
+ const containerStyle = React.useMemo(() => [
102
+ styles.container,
103
+ {
104
+ backgroundColor: tokens.colors.backgroundPrimary,
105
+ paddingTop: insets.top,
106
+ },
107
+ ], [styles.container, tokens.colors.backgroundPrimary, insets.top]);
108
+
109
+ // Memoize conditional rendering
110
+ const showContent = React.useMemo(() => !!(content), [content]);
111
+ const showUrlSection = React.useMemo(() =>
112
+ ContentValidationService.shouldShowUrlSection(url, onUrlPress),
113
+ [url, onUrlPress]
114
+ );
115
+
116
+ // Memoize content section
117
+ const contentSection = React.useMemo(() => {
118
+ if (showContent) {
119
+ return (
120
+ <AtomicText type="bodyMedium" color="onSurface" style={styles.text}>
121
+ {content}
122
+ </AtomicText>
123
+ );
124
+ }
125
+
126
+ if (showUrlSection) {
127
+ return (
128
+ <View style={styles.urlContainer}>
129
+ <AtomicText
130
+ type="bodyMedium"
131
+ color="secondary"
132
+ style={styles.urlText}
133
+ >
134
+ {viewOnlineText}
135
+ </AtomicText>
136
+ <AtomicButton
137
+ variant="primary"
138
+ onPress={handleUrlPress}
139
+ fullWidth
140
+ style={styles.urlButton}
141
+ >
142
+ {openText}
143
+ </AtomicButton>
144
+ </View>
145
+ );
146
+ }
147
+
148
+ return null;
149
+ }, [showContent, showUrlSection, styles.text, styles.urlContainer, styles.urlText, styles.urlButton, content, viewOnlineText, openText, handleUrlPress]);
150
+
151
+ return (
152
+ <View style={containerStyle} testID={testID}>
153
+ <ScrollView
154
+ contentContainerStyle={styles.scrollContent}
155
+ showsVerticalScrollIndicator={false}
156
+ >
157
+ <View style={styles.content}>
158
+ <AtomicText
159
+ type="headlineLarge"
160
+ color="primary"
161
+ style={styles.title}
162
+ >
163
+ {title}
164
+ </AtomicText>
165
+
166
+ {contentSection}
167
+ </View>
168
+ </ScrollView>
169
+ </View>
170
+ );
171
+ });
172
+
173
+ const createPrivacyPolicyStyles = () => {
174
+ return StyleSheet.create({
175
+ container: {
176
+ flex: 1,
177
+ },
178
+ scrollContent: {
179
+ flexGrow: 1,
180
+ padding: 20,
181
+ },
182
+ content: {
183
+ flex: 1,
184
+ },
185
+ title: {
186
+ marginBottom: 24,
187
+ },
188
+ text: {
189
+ lineHeight: 24,
190
+ },
191
+ urlContainer: {
192
+ marginTop: 32,
193
+ alignItems: "center",
194
+ },
195
+ urlText: {
196
+ marginBottom: 16,
197
+ textAlign: "center",
198
+ },
199
+ urlButton: {
200
+ marginTop: 8,
201
+ },
202
+ });
203
+ };
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Terms of Service Screen Component
3
+ * Display Terms of Service content
4
+ */
5
+
6
+ import React from "react";
7
+ import { View, ScrollView, StyleSheet } from "react-native";
8
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
9
+ import { useResponsiveDesignTokens } from "@umituz/react-native-design-system";
10
+ import { AtomicText, AtomicButton } from "@umituz/react-native-design-system";
11
+ import { UrlHandlerService } from "../../domain/services/UrlHandlerService";
12
+ import { ContentValidationService } from "../../domain/services/ContentValidationService";
13
+ import { StyleCacheService } from "../../domain/services/StyleCacheService";
14
+
15
+ export interface TermsOfServiceScreenProps {
16
+ /**
17
+ * Terms of Service content (HTML or plain text)
18
+ * Either content or url must be provided
19
+ */
20
+ content?: string;
21
+ /**
22
+ * Terms of Service URL (if content is not provided, will open URL)
23
+ * Either content or url must be provided
24
+ */
25
+ url?: string;
26
+ /**
27
+ * Custom title
28
+ */
29
+ title: string;
30
+ /**
31
+ * Text for viewing online button (required when url is provided)
32
+ */
33
+ viewOnlineText?: string;
34
+ /**
35
+ * Text for open button (required when url is provided)
36
+ */
37
+ openText?: string;
38
+ /**
39
+ * Callback when URL is pressed (if content is not provided)
40
+ */
41
+ onUrlPress?: () => void;
42
+ /**
43
+ * Test ID for E2E testing
44
+ */
45
+ testID?: string;
46
+ }
47
+
48
+ export const TermsOfServiceScreen: React.FC<TermsOfServiceScreenProps> = React.memo(({
49
+ content,
50
+ url,
51
+ title,
52
+ viewOnlineText,
53
+ openText,
54
+ onUrlPress,
55
+ testID = "terms-of-service-screen",
56
+ }) => {
57
+ const tokens = useResponsiveDesignTokens();
58
+ const insets = useSafeAreaInsets();
59
+
60
+ // Validate required props
61
+ React.useEffect(() => {
62
+ ContentValidationService.validateScreenContent(
63
+ content,
64
+ url,
65
+ title,
66
+ viewOnlineText,
67
+ openText,
68
+ 'TermsOfServiceScreen'
69
+ );
70
+ }, [content, url, title, viewOnlineText, openText]);
71
+
72
+ // Use cached styles
73
+ const styles = React.useMemo(() => {
74
+ return StyleCacheService.getCachedStyles(
75
+ 'TermsOfServiceScreen',
76
+ 'terms-of-service-styles',
77
+ createTermsOfServiceStyles
78
+ );
79
+ }, []);
80
+
81
+ // Memoize URL press handler to prevent child re-renders
82
+ const handleUrlPress = React.useCallback(async () => {
83
+ if (__DEV__) {
84
+ console.log('TermsOfServiceScreen: URL pressed', { url });
85
+ }
86
+
87
+ if (onUrlPress) {
88
+ onUrlPress();
89
+ } else if (url) {
90
+ try {
91
+ await UrlHandlerService.openUrl(url);
92
+ } catch (error) {
93
+ if (__DEV__) {
94
+ console.error('TermsOfServiceScreen: Error opening URL', error);
95
+ }
96
+ }
97
+ }
98
+ }, [onUrlPress, url]);
99
+
100
+ // Memoize container style to prevent object creation
101
+ const containerStyle = React.useMemo(() => [
102
+ styles.container,
103
+ {
104
+ backgroundColor: tokens.colors.backgroundPrimary,
105
+ paddingTop: insets.top,
106
+ },
107
+ ], [styles.container, tokens.colors.backgroundPrimary, insets.top]);
108
+
109
+ // Memoize conditional rendering
110
+ const showContent = React.useMemo(() => !!(content), [content]);
111
+ const showUrlSection = React.useMemo(() =>
112
+ ContentValidationService.shouldShowUrlSection(url, onUrlPress),
113
+ [url, onUrlPress]
114
+ );
115
+
116
+ // Memoize content section
117
+ const contentSection = React.useMemo(() => {
118
+ if (showContent) {
119
+ return (
120
+ <AtomicText type="bodyMedium" color="onSurface" style={styles.text}>
121
+ {content}
122
+ </AtomicText>
123
+ );
124
+ }
125
+
126
+ if (showUrlSection) {
127
+ return (
128
+ <View style={styles.urlContainer}>
129
+ <AtomicText
130
+ type="bodyMedium"
131
+ color="secondary"
132
+ style={styles.urlText}
133
+ >
134
+ {viewOnlineText}
135
+ </AtomicText>
136
+ <AtomicButton
137
+ variant="primary"
138
+ onPress={handleUrlPress}
139
+ fullWidth
140
+ style={styles.urlButton}
141
+ >
142
+ {openText}
143
+ </AtomicButton>
144
+ </View>
145
+ );
146
+ }
147
+
148
+ return null;
149
+ }, [showContent, showUrlSection, styles.text, styles.urlContainer, styles.urlText, styles.urlButton, content, viewOnlineText, openText, handleUrlPress]);
150
+
151
+ return (
152
+ <View style={containerStyle} testID={testID}>
153
+ <ScrollView
154
+ contentContainerStyle={styles.scrollContent}
155
+ showsVerticalScrollIndicator={false}
156
+ >
157
+ <View style={styles.content}>
158
+ <AtomicText
159
+ type="headlineLarge"
160
+ color="primary"
161
+ style={styles.title}
162
+ >
163
+ {title}
164
+ </AtomicText>
165
+
166
+ {contentSection}
167
+ </View>
168
+ </ScrollView>
169
+ </View>
170
+ );
171
+ });
172
+
173
+ const createTermsOfServiceStyles = () => {
174
+ return StyleSheet.create({
175
+ container: {
176
+ flex: 1,
177
+ },
178
+ scrollContent: {
179
+ flexGrow: 1,
180
+ padding: 20,
181
+ },
182
+ content: {
183
+ flex: 1,
184
+ },
185
+ title: {
186
+ marginBottom: 24,
187
+ },
188
+ text: {
189
+ lineHeight: 24,
190
+ },
191
+ urlContainer: {
192
+ marginTop: 32,
193
+ alignItems: "center",
194
+ },
195
+ urlText: {
196
+ marginBottom: 16,
197
+ textAlign: "center",
198
+ },
199
+ urlButton: {
200
+ marginTop: 8,
201
+ },
202
+ });
203
+ };
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
package/src/index.ts CHANGED
@@ -80,6 +80,25 @@ export type { StorageClearSettingProps } from './presentation/components/Storage
80
80
  export { DevSettingsSection } from './presentation/components/DevSettingsSection';
81
81
  export type { DevSettingsProps } from './presentation/components/DevSettingsSection';
82
82
 
83
+ // =============================================================================
84
+ // DOMAIN EXPORTS - Consolidated Features
85
+ // =============================================================================
86
+
87
+ // About Domain - User info, app details, version
88
+ export * from './domains/about';
89
+
90
+ // Legal Domain - Terms, privacy, licenses
91
+ export * from './domains/legal';
92
+
93
+ // Appearance Domain - Theme, dark mode
94
+ export * from './domains/appearance';
95
+
96
+ // Feedback Domain - User feedback, bug reports
97
+ export * from './domains/feedback';
98
+
99
+ // FAQs Domain - Frequently asked questions
100
+ export * from './domains/faqs';
101
+
83
102
  // =============================================================================
84
103
  // PRESENTATION LAYER - Re-exports from Dependencies
85
104
  // =============================================================================