@umituz/react-native-settings 1.11.4 → 2.4.0

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 (167) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +129 -3
  3. package/lib/__tests__/setup.d.ts +5 -0
  4. package/lib/__tests__/setup.d.ts.map +1 -0
  5. package/lib/__tests__/setup.js +143 -0
  6. package/lib/__tests__/setup.js.map +1 -0
  7. package/lib/domain/repositories/ISettingsRepository.d.ts +51 -0
  8. package/lib/domain/repositories/ISettingsRepository.d.ts.map +1 -0
  9. package/lib/domain/repositories/ISettingsRepository.js +8 -0
  10. package/lib/domain/repositories/ISettingsRepository.js.map +1 -0
  11. package/lib/index.d.ts +35 -0
  12. package/lib/index.d.ts.map +1 -0
  13. package/lib/index.js +32 -0
  14. package/lib/index.js.map +1 -0
  15. package/lib/infrastructure/storage/SettingsStore.d.ts +36 -0
  16. package/lib/infrastructure/storage/SettingsStore.d.ts.map +1 -0
  17. package/lib/infrastructure/storage/SettingsStore.js +144 -0
  18. package/lib/infrastructure/storage/SettingsStore.js.map +1 -0
  19. package/lib/presentation/components/CloudSyncSetting.d.ts +16 -0
  20. package/lib/presentation/components/CloudSyncSetting.d.ts.map +1 -0
  21. package/lib/presentation/components/CloudSyncSetting.js +30 -0
  22. package/lib/presentation/components/CloudSyncSetting.js.map +1 -0
  23. package/lib/presentation/components/DisclaimerCard.d.ts +15 -0
  24. package/lib/presentation/components/DisclaimerCard.d.ts.map +1 -0
  25. package/lib/presentation/components/DisclaimerCard.js +73 -0
  26. package/lib/presentation/components/DisclaimerCard.js.map +1 -0
  27. package/lib/presentation/components/DisclaimerModal.d.ts +13 -0
  28. package/lib/presentation/components/DisclaimerModal.d.ts.map +1 -0
  29. package/lib/presentation/components/DisclaimerModal.js +62 -0
  30. package/lib/presentation/components/DisclaimerModal.js.map +1 -0
  31. package/lib/presentation/components/DisclaimerSetting.d.ts +39 -0
  32. package/lib/presentation/components/DisclaimerSetting.d.ts.map +1 -0
  33. package/lib/presentation/components/DisclaimerSetting.js +59 -0
  34. package/lib/presentation/components/DisclaimerSetting.js.map +1 -0
  35. package/lib/presentation/components/SettingItem.d.ts +45 -0
  36. package/lib/presentation/components/SettingItem.d.ts.map +1 -0
  37. package/lib/presentation/components/SettingItem.js +113 -0
  38. package/lib/presentation/components/SettingItem.js.map +1 -0
  39. package/lib/presentation/components/SettingsErrorBoundary.d.ts +23 -0
  40. package/lib/presentation/components/SettingsErrorBoundary.d.ts.map +1 -0
  41. package/lib/presentation/components/SettingsErrorBoundary.js +73 -0
  42. package/lib/presentation/components/SettingsErrorBoundary.js.map +1 -0
  43. package/lib/presentation/components/SettingsFooter.d.ts +11 -0
  44. package/lib/presentation/components/SettingsFooter.d.ts.map +1 -0
  45. package/lib/presentation/components/SettingsFooter.js +31 -0
  46. package/lib/presentation/components/SettingsFooter.js.map +1 -0
  47. package/lib/presentation/components/SettingsSection.d.ts +13 -0
  48. package/lib/presentation/components/SettingsSection.d.ts.map +1 -0
  49. package/lib/presentation/components/SettingsSection.js +37 -0
  50. package/lib/presentation/components/SettingsSection.js.map +1 -0
  51. package/lib/presentation/components/StorageClearSetting.d.ts +16 -0
  52. package/lib/presentation/components/StorageClearSetting.d.ts.map +1 -0
  53. package/lib/presentation/components/StorageClearSetting.js +21 -0
  54. package/lib/presentation/components/StorageClearSetting.js.map +1 -0
  55. package/lib/presentation/components/UserProfileHeader.d.ts +30 -0
  56. package/lib/presentation/components/UserProfileHeader.d.ts.map +1 -0
  57. package/lib/presentation/components/UserProfileHeader.js +119 -0
  58. package/lib/presentation/components/UserProfileHeader.js.map +1 -0
  59. package/lib/presentation/screens/AppearanceScreen.d.ts +8 -0
  60. package/lib/presentation/screens/AppearanceScreen.d.ts.map +1 -0
  61. package/lib/presentation/screens/AppearanceScreen.js +8 -0
  62. package/lib/presentation/screens/AppearanceScreen.js.map +1 -0
  63. package/lib/presentation/screens/SettingsScreen.d.ts +38 -0
  64. package/lib/presentation/screens/SettingsScreen.d.ts.map +1 -0
  65. package/lib/presentation/screens/SettingsScreen.js +37 -0
  66. package/lib/presentation/screens/SettingsScreen.js.map +1 -0
  67. package/lib/presentation/screens/components/AboutLegalSection.d.ts +15 -0
  68. package/lib/presentation/screens/components/AboutLegalSection.d.ts.map +1 -0
  69. package/lib/presentation/screens/components/AboutLegalSection.js +28 -0
  70. package/lib/presentation/screens/components/AboutLegalSection.js.map +1 -0
  71. package/lib/presentation/screens/components/AppearanceSection.d.ts +12 -0
  72. package/lib/presentation/screens/components/AppearanceSection.d.ts.map +1 -0
  73. package/lib/presentation/screens/components/AppearanceSection.js +21 -0
  74. package/lib/presentation/screens/components/AppearanceSection.js.map +1 -0
  75. package/lib/presentation/screens/components/LanguageSection.d.ts +12 -0
  76. package/lib/presentation/screens/components/LanguageSection.d.ts.map +1 -0
  77. package/lib/presentation/screens/components/LanguageSection.js +26 -0
  78. package/lib/presentation/screens/components/LanguageSection.js.map +1 -0
  79. package/lib/presentation/screens/components/NotificationsSection.d.ts +12 -0
  80. package/lib/presentation/screens/components/NotificationsSection.d.ts.map +1 -0
  81. package/lib/presentation/screens/components/NotificationsSection.js +58 -0
  82. package/lib/presentation/screens/components/NotificationsSection.js.map +1 -0
  83. package/lib/presentation/screens/components/SettingsContent.d.ts +36 -0
  84. package/lib/presentation/screens/components/SettingsContent.d.ts.map +1 -0
  85. package/lib/presentation/screens/components/SettingsContent.js +81 -0
  86. package/lib/presentation/screens/components/SettingsContent.js.map +1 -0
  87. package/lib/presentation/screens/components/SettingsHeader.d.ts +12 -0
  88. package/lib/presentation/screens/components/SettingsHeader.d.ts.map +1 -0
  89. package/lib/presentation/screens/components/SettingsHeader.js +59 -0
  90. package/lib/presentation/screens/components/SettingsHeader.js.map +1 -0
  91. package/lib/presentation/screens/components/index.d.ts +9 -0
  92. package/lib/presentation/screens/components/index.d.ts.map +1 -0
  93. package/lib/presentation/screens/components/index.js +9 -0
  94. package/lib/presentation/screens/components/index.js.map +1 -0
  95. package/lib/presentation/screens/hooks/useFeatureDetection.d.ts +21 -0
  96. package/lib/presentation/screens/hooks/useFeatureDetection.d.ts.map +1 -0
  97. package/lib/presentation/screens/hooks/useFeatureDetection.js +82 -0
  98. package/lib/presentation/screens/hooks/useFeatureDetection.js.map +1 -0
  99. package/lib/presentation/screens/types/CustomSection.d.ts +19 -0
  100. package/lib/presentation/screens/types/CustomSection.d.ts.map +1 -0
  101. package/lib/presentation/screens/types/CustomSection.js +6 -0
  102. package/lib/presentation/screens/types/CustomSection.js.map +1 -0
  103. package/lib/presentation/screens/types/ExtendedConfig.d.ts +68 -0
  104. package/lib/presentation/screens/types/ExtendedConfig.d.ts.map +1 -0
  105. package/lib/presentation/screens/types/ExtendedConfig.js +6 -0
  106. package/lib/presentation/screens/types/ExtendedConfig.js.map +1 -0
  107. package/lib/presentation/screens/types/FeatureConfig.d.ts +95 -0
  108. package/lib/presentation/screens/types/FeatureConfig.d.ts.map +1 -0
  109. package/lib/presentation/screens/types/FeatureConfig.js +6 -0
  110. package/lib/presentation/screens/types/FeatureConfig.js.map +1 -0
  111. package/lib/presentation/screens/types/SettingsConfig.d.ts +97 -0
  112. package/lib/presentation/screens/types/SettingsConfig.d.ts.map +1 -0
  113. package/lib/presentation/screens/types/SettingsConfig.js +6 -0
  114. package/lib/presentation/screens/types/SettingsConfig.js.map +1 -0
  115. package/lib/presentation/screens/types/index.d.ts +10 -0
  116. package/lib/presentation/screens/types/index.d.ts.map +1 -0
  117. package/lib/presentation/screens/types/index.js +6 -0
  118. package/lib/presentation/screens/types/index.js.map +1 -0
  119. package/lib/presentation/screens/utils/normalizeConfig.d.ts +44 -0
  120. package/lib/presentation/screens/utils/normalizeConfig.d.ts.map +1 -0
  121. package/lib/presentation/screens/utils/normalizeConfig.js +38 -0
  122. package/lib/presentation/screens/utils/normalizeConfig.js.map +1 -0
  123. package/package.json +46 -11
  124. package/src/__tests__/integration.test.tsx +371 -0
  125. package/src/__tests__/performance.test.tsx +369 -0
  126. package/src/__tests__/setup.test.tsx +20 -0
  127. package/src/__tests__/setup.ts +157 -0
  128. package/src/domain/repositories/ISettingsRepository.ts +0 -0
  129. package/src/index.ts +9 -1
  130. package/src/infrastructure/storage/SettingsStore.ts +90 -45
  131. package/src/infrastructure/storage/__tests__/SettingsStore.test.tsx +302 -0
  132. package/src/presentation/components/CloudSyncSetting.tsx +11 -17
  133. package/src/presentation/components/DisclaimerCard.tsx +115 -0
  134. package/src/presentation/components/DisclaimerModal.tsx +104 -0
  135. package/src/presentation/components/DisclaimerSetting.tsx +77 -159
  136. package/src/presentation/components/SettingItem.tsx +11 -2
  137. package/src/presentation/components/SettingsErrorBoundary.tsx +126 -0
  138. package/src/presentation/components/SettingsFooter.tsx +0 -0
  139. package/src/presentation/components/SettingsSection.tsx +0 -0
  140. package/src/presentation/components/StorageClearSetting.tsx +13 -8
  141. package/src/presentation/components/UserProfileHeader.tsx +48 -11
  142. package/src/presentation/components/__tests__/CloudSyncSetting.test.tsx +78 -0
  143. package/src/presentation/components/__tests__/DisclaimerCard.test.tsx +208 -0
  144. package/src/presentation/components/__tests__/DisclaimerModal.test.tsx +236 -0
  145. package/src/presentation/components/__tests__/DisclaimerSetting.test.tsx +74 -0
  146. package/src/presentation/components/__tests__/SettingItem.test.tsx +189 -0
  147. package/src/presentation/components/__tests__/SettingsErrorBoundary.test.tsx +186 -0
  148. package/src/presentation/screens/AppearanceScreen.tsx +0 -0
  149. package/src/presentation/screens/SettingsScreen.tsx +29 -159
  150. package/src/presentation/screens/__tests__/SettingsScreen.test.tsx +322 -0
  151. package/src/presentation/screens/components/AboutLegalSection.tsx +14 -5
  152. package/src/presentation/screens/components/AppearanceSection.tsx +1 -1
  153. package/src/presentation/screens/components/LanguageSection.tsx +2 -1
  154. package/src/presentation/screens/components/NotificationsSection.tsx +19 -14
  155. package/src/presentation/screens/components/SettingsContent.tsx +167 -0
  156. package/src/presentation/screens/components/SettingsHeader.tsx +79 -0
  157. package/src/presentation/screens/components/index.ts +0 -0
  158. package/src/presentation/screens/hooks/__tests__/useFeatureDetection.test.tsx +261 -0
  159. package/src/presentation/screens/hooks/useFeatureDetection.ts +15 -5
  160. package/src/presentation/screens/types/CustomSection.ts +20 -0
  161. package/src/presentation/screens/types/ExtendedConfig.ts +68 -0
  162. package/src/presentation/screens/types/FeatureConfig.ts +102 -0
  163. package/src/presentation/screens/types/SettingsConfig.ts +116 -0
  164. package/src/presentation/screens/types/index.ts +20 -0
  165. package/src/presentation/screens/utils/normalizeConfig.ts +2 -1
  166. package/src/presentation/screens/LanguageSelectionScreen.tsx +0 -204
  167. package/src/presentation/screens/types.ts +0 -263
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -20,7 +20,7 @@ npm install @umituz/react-native-settings
20
20
  ## Peer Dependencies
21
21
 
22
22
  ```bash
23
- npm install zustand lucide-react-native @umituz/react-native-storage @umituz/react-native-design-system @umituz/react-native-design-system-theme @umituz/react-native-localization @umituz/react-native-notifications react-native-paper expo-linear-gradient
23
+ npm install zustand lucide-react-native @umituz/react-native-storage @umituz/react-native-design-system @umituz/react-native-design-system-atoms @umituz/react-native-design-system-organisms @umituz/react-native-design-system-theme @umituz/react-native-localization @umituz/react-native-appearance @react-navigation/native react-native-safe-area-context expo-linear-gradient
24
24
  ```
25
25
 
26
26
  ## Usage
@@ -179,8 +179,51 @@ import { SettingsFooter } from '@umituz/react-native-settings';
179
179
  ```tsx
180
180
  import { DisclaimerSetting } from '@umituz/react-native-settings';
181
181
 
182
- // In AboutScreen
182
+ // Basic usage with translation keys
183
183
  <DisclaimerSetting />
184
+
185
+ // Custom props
186
+ <DisclaimerSetting
187
+ titleKey="custom.disclaimer.title"
188
+ messageKey="custom.disclaimer.message"
189
+ shortMessageKey="custom.disclaimer.shortMessage"
190
+ iconName="Info"
191
+ iconColor="#F59E0B"
192
+ modalTitle="Custom Disclaimer"
193
+ modalContent="This is a custom disclaimer message for your app."
194
+ />
195
+ ```
196
+
197
+ ### Cloud Sync Setting Component
198
+
199
+ ```tsx
200
+ import { CloudSyncSetting } from '@umituz/react-native-settings';
201
+
202
+ // Basic usage
203
+ <CloudSyncSetting />
204
+
205
+ // With custom props
206
+ <CloudSyncSetting
207
+ title="Cloud Sync"
208
+ description="Sync your data across devices"
209
+ isSyncing={false}
210
+ lastSynced={new Date()}
211
+ onPress={() => handleSync()}
212
+ iconColor="#3B82F6"
213
+ />
214
+ ```
215
+
216
+ ### Settings Error Boundary
217
+
218
+ ```tsx
219
+ import { SettingsErrorBoundary } from '@umituz/react-native-settings';
220
+
221
+ <SettingsErrorBoundary
222
+ fallbackTitle="custom.error.title"
223
+ fallbackMessage="custom.error.message"
224
+ >
225
+ <YourSettingsComponents />
226
+ </SettingsErrorBoundary>
184
227
  ```
185
228
 
186
229
  ## API Reference
@@ -266,7 +309,48 @@ Footer component displaying app version.
266
309
 
267
310
  ### `DisclaimerSetting`
268
311
 
269
- Disclaimer component for health/wellness apps with modal display.
312
+ Disclaimer component with modal display for legal notices.
313
+
314
+ **Props:**
315
+ - `titleKey?: string` - Translation key for title (default: "settings.disclaimer.title")
316
+ - `messageKey?: string` - Translation key for message (default: "settings.disclaimer.message")
317
+ - `shortMessageKey?: string` - Translation key for short message (default: "settings.disclaimer.shortMessage")
318
+ - `iconName?: string` - Icon name (default: "AlertTriangle")
319
+ - `iconColor?: string` - Custom icon color
320
+ - `backgroundColor?: string` - Custom background color
321
+ - `modalTitle?: string` - Custom modal title (overrides translation)
322
+ - `modalContent?: string` - Custom modal content (overrides translation)
323
+
324
+ ### `CloudSyncSetting`
325
+
326
+ Cloud sync setting component with status display.
327
+
328
+ **Props:**
329
+ - `title?: string` - Custom title (default: "cloud_sync" translation key)
330
+ - `description?: string` - Custom description
331
+ - `isSyncing?: boolean` - Whether currently syncing
332
+ - `lastSynced?: Date | null` - Last sync time
333
+ - `onPress?: () => void` - Press handler
334
+ - `iconColor?: string` - Custom icon color
335
+ - `titleColor?: string` - Custom title color
336
+
337
+ ### `DisclaimerCard`
338
+
339
+ Card component for disclaimer display (used internally by DisclaimerSetting).
340
+
341
+ ### `DisclaimerModal`
342
+
343
+ Modal component for full disclaimer display (used internally by DisclaimerSetting).
344
+
345
+ ### `SettingsErrorBoundary`
346
+
347
+ Error boundary component for settings screens.
348
+
349
+ **Props:**
350
+ - `children: ReactNode` - Child components
351
+ - `fallback?: ReactNode` - Custom fallback component
352
+ - `fallbackTitle?: string` - Custom error title translation key
353
+ - `fallbackMessage?: string` - Custom error message translation key
270
354
 
271
355
  ## Types
272
356
 
@@ -300,6 +384,48 @@ interface UserSettings {
300
384
 
301
385
  ⚠️ **Translations**: Settings screens require i18n translations. Make sure to provide translations for settings keys.
302
386
 
387
+ ⚠️ **Dynamic Text**: All text in this package uses translation keys to be app-agnostic. Provide translations like:
388
+ - `cloud_sync`, `syncing`, `sync_to_cloud`, `never_synced`, `just_now`, `Xm_ago`, `Xh_ago`, `Xd_ago`
389
+ - `error_boundary.title`, `error_boundary.message`, `error_boundary.dev_title`, `error_boundary.dev_message`
390
+ - `settings.disclaimer.title`, `settings.disclaimer.message`, `settings.disclaimer.shortMessage`
391
+
392
+ ⚠️ **Design System**: Uses @umituz/react-native-design-system packages for consistent styling across apps.
393
+
394
+ ⚠️ **Development Logs**: All console logs are wrapped in `__DEV__` checks for production safety.
395
+
396
+ ## Architecture
397
+
398
+ This package follows **Domain-Driven Design (DDD)** principles:
399
+
400
+ - **Domain Layer**: Repository interfaces and business entities
401
+ - **Infrastructure Layer**: Storage implementation with Zustand
402
+ - **Presentation Layer**: UI components and screens
403
+
404
+ ### Key Principles
405
+
406
+ ✅ **SOLID**: Single responsibility, open/closed, Liskov substitution, interface segregation, dependency inversion
407
+ ✅ **DRY**: No code duplication, reusable components
408
+ ✅ **KISS**: Simple, maintainable code
409
+ ✅ **200-line limit**: All files under 200 lines for maintainability
410
+ ✅ **TypeScript**: Full type safety
411
+ ✅ **Memory Leak Prevention**: Proper cleanup and error handling
412
+ ✅ **App-Agnostic**: No hardcoded app-specific text or logic
413
+ ✅ **Test Coverage**: Comprehensive test suite
414
+
415
+ ## Performance
416
+
417
+ - ✅ **Optimized Rendering**: React.memo and useMemo where appropriate
418
+ - ✅ **Memory Management**: Proper cleanup in useEffect hooks
419
+ - ✅ **Error Boundaries**: Prevent crashes and provide graceful fallbacks
420
+ - ✅ **Development Logs**: __DEV__ only logging for production safety
421
+
422
+ ## Version History
423
+
424
+ - **v2.2.0**: Major refactor - removed hardcoded text, improved architecture, added comprehensive tests
425
+ - **v2.1.0**: Enhanced component structure and TypeScript support
426
+ - **v2.0.0**: Breaking changes - removed LanguageSelectionScreen, improved API
427
+ - **v1.x.x**: Initial releases with basic settings functionality
428
+
303
429
  ## License
304
430
 
305
431
  MIT
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Jest Test Setup
3
+ * Mock all external dependencies
4
+ */
5
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Jest Test Setup
3
+ * Mock all external dependencies
4
+ */
5
+ // Mock React Native modules
6
+ jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
7
+ // Mock design system packages
8
+ jest.mock('@umituz/react-native-design-system-theme', () => ({
9
+ useDesignSystemTheme: () => ({
10
+ themeMode: 'light',
11
+ }),
12
+ useAppDesignTokens: () => ({
13
+ colors: {
14
+ backgroundPrimary: '#ffffff',
15
+ primary: '#007AFF',
16
+ textPrimary: '#000000',
17
+ textSecondary: '#666666',
18
+ surface: '#f5f5f5',
19
+ borderLight: '#e0e0e0',
20
+ warning: '#FF9800',
21
+ },
22
+ spacing: {
23
+ md: 16,
24
+ },
25
+ typography: {
26
+ labelLarge: {
27
+ fontWeight: '500',
28
+ fontSize: 14,
29
+ },
30
+ },
31
+ }),
32
+ withAlpha: jest.fn((color, alpha) => `${color}${alpha}`),
33
+ }));
34
+ jest.mock('@umituz/react-native-design-system-atoms', () => ({
35
+ AtomicText: ({ children, type, color, style, testID }) => {
36
+ const React = require('react');
37
+ const { Text } = require('react-native');
38
+ return React.createElement(Text, {
39
+ style,
40
+ testID: testID || `atomic-text-${type}-${color}`
41
+ }, children);
42
+ },
43
+ AtomicIcon: ({ name, color, size, style, testID }) => {
44
+ const React = require('react');
45
+ const { Text } = require('react-native');
46
+ return React.createElement(Text, {
47
+ style,
48
+ testID: testID || `atomic-icon-${name}-${color}-${size}`
49
+ }, `Icon: ${name}`);
50
+ },
51
+ }));
52
+ // Mock localization
53
+ jest.mock('@umituz/react-native-localization', () => ({
54
+ useLocalization: () => ({
55
+ t: (key) => key,
56
+ changeLanguage: jest.fn(),
57
+ currentLanguage: 'en-US',
58
+ }),
59
+ }));
60
+ // Mock storage
61
+ jest.mock('@umituz/react-native-storage', () => ({
62
+ storageRepository: {
63
+ getItem: jest.fn(),
64
+ setItem: jest.fn(),
65
+ removeItem: jest.fn(),
66
+ clear: jest.fn(),
67
+ },
68
+ StorageKey: {
69
+ SETTINGS: 'settings',
70
+ },
71
+ createUserKey: (key, userId) => `${key}_${userId}`,
72
+ unwrap: (result, defaultValue) => result.success ? result.data : defaultValue,
73
+ }));
74
+ // Mock lucide-react-native
75
+ jest.mock('lucide-react-native', () => ({
76
+ Cloud: 'Cloud',
77
+ Bell: 'Bell',
78
+ Palette: 'Palette',
79
+ ChevronRight: 'ChevronRight',
80
+ AlertTriangle: 'AlertTriangle',
81
+ Info: 'Info',
82
+ X: 'X',
83
+ ArrowRight: 'ArrowRight',
84
+ Settings: 'Settings',
85
+ }));
86
+ // Mock navigation
87
+ jest.mock('@react-navigation/native', () => ({
88
+ useNavigation: () => ({
89
+ navigate: jest.fn(),
90
+ goBack: jest.fn(),
91
+ getState: jest.fn(() => ({
92
+ routes: [{ name: 'Settings' }],
93
+ })),
94
+ setOptions: jest.fn(),
95
+ isFocused: jest.fn(() => true),
96
+ addListener: jest.fn(() => jest.fn()),
97
+ removeListener: jest.fn(),
98
+ }),
99
+ useFocusEffect: jest.fn(),
100
+ useIsFocused: jest.fn(() => true),
101
+ NavigationContainer: ({ children }) => children,
102
+ }));
103
+ // Mock safe area context
104
+ jest.mock('react-native-safe-area-context', () => ({
105
+ SafeAreaProvider: ({ children }) => children,
106
+ SafeAreaView: ({ children }) => children,
107
+ useSafeAreaInsets: () => ({
108
+ top: 0,
109
+ bottom: 0,
110
+ left: 0,
111
+ right: 0,
112
+ }),
113
+ }));
114
+ // Mock linear gradient
115
+ jest.mock('expo-linear-gradient', () => ({
116
+ LinearGradient: ({ children }) => children,
117
+ }));
118
+ // Mock notification service
119
+ jest.mock('@umituz/react-native-notifications', () => ({
120
+ notificationService: {
121
+ hasPermissions: jest.fn(() => Promise.resolve(true)),
122
+ requestPermissions: jest.fn(() => Promise.resolve()),
123
+ },
124
+ }));
125
+ // Mock appearance
126
+ jest.mock('@umituz/react-native-appearance', () => ({
127
+ useAppearance: () => ({
128
+ colorScheme: 'light',
129
+ setColorScheme: jest.fn(),
130
+ }),
131
+ }));
132
+ // Mock console methods in tests
133
+ global.console = {
134
+ ...console,
135
+ warn: jest.fn(),
136
+ error: jest.fn(),
137
+ };
138
+ // Set up __DEV__ mock
139
+ Object.defineProperty(global, '__DEV__', {
140
+ value: true,
141
+ writable: true,
142
+ });
143
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Settings Repository Interface
3
+ *
4
+ * Defines contracts for settings persistence and retrieval
5
+ * Pure business logic - no dependencies on external frameworks
6
+ */
7
+ export interface UserSettings {
8
+ userId: string;
9
+ theme: 'light' | 'dark' | 'auto';
10
+ language: string;
11
+ notificationsEnabled: boolean;
12
+ emailNotifications: boolean;
13
+ pushNotifications: boolean;
14
+ soundEnabled: boolean;
15
+ vibrationEnabled: boolean;
16
+ privacyMode: boolean;
17
+ updatedAt: Date;
18
+ }
19
+ export interface SettingsError extends Error {
20
+ code: 'LOAD_FAILED' | 'SAVE_FAILED' | 'NOT_FOUND' | 'INVALID_DATA';
21
+ }
22
+ export type SettingsResult<T> = {
23
+ success: true;
24
+ data: T;
25
+ } | {
26
+ success: false;
27
+ error: SettingsError;
28
+ };
29
+ /**
30
+ * Settings Repository Interface
31
+ * Repository pattern for settings management
32
+ */
33
+ export interface ISettingsRepository {
34
+ /**
35
+ * Load user settings from persistent storage
36
+ */
37
+ loadSettings(userId: string): Promise<SettingsResult<UserSettings>>;
38
+ /**
39
+ * Save user settings to persistent storage
40
+ */
41
+ saveSettings(settings: Partial<UserSettings>): Promise<SettingsResult<UserSettings>>;
42
+ /**
43
+ * Reset settings to default values
44
+ */
45
+ resetSettings(userId: string): Promise<SettingsResult<UserSettings>>;
46
+ /**
47
+ * Get default settings for a user
48
+ */
49
+ getDefaultSettings(userId: string): UserSettings;
50
+ }
51
+ //# sourceMappingURL=ISettingsRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISettingsRepository.d.ts","sourceRoot":"","sources":["../../../src/domain/repositories/ISettingsRepository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,aAAc,SAAQ,KAAK;IAC1C,IAAI,EAAE,aAAa,GAAG,aAAa,GAAG,WAAW,GAAG,cAAc,CAAC;CACpE;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;CACT,GAAG;IACF,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAEpE;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAErF;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAErE;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAAC;CAClD"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Settings Repository Interface
3
+ *
4
+ * Defines contracts for settings persistence and retrieval
5
+ * Pure business logic - no dependencies on external frameworks
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=ISettingsRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ISettingsRepository.js","sourceRoot":"","sources":["../../../src/domain/repositories/ISettingsRepository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @umituz/react-native-settings - Public API
3
+ *
4
+ * Settings management for React Native apps
5
+ * User preferences, theme, language, notifications
6
+ *
7
+ * Usage:
8
+ * import { useSettings, useSettingsStore, SettingsScreen, AppearanceScreen, LanguageSelectionScreen, SettingItem, DisclaimerSetting } from '@umituz/react-native-settings';
9
+ */
10
+ export type { ISettingsRepository, UserSettings, SettingsError, SettingsResult, } from './domain/repositories/ISettingsRepository';
11
+ export { useSettingsStore, useSettings, } from './infrastructure/storage/SettingsStore';
12
+ export { SettingsScreen } from './presentation/screens/SettingsScreen';
13
+ export type { SettingsScreenProps } from './presentation/screens/SettingsScreen';
14
+ export { AppearanceScreen } from './presentation/screens/AppearanceScreen';
15
+ export type { SettingsConfig, CustomSettingsSection } from './presentation/screens/types';
16
+ export { SettingItem } from './presentation/components/SettingItem';
17
+ export type { SettingItemProps } from './presentation/components/SettingItem';
18
+ export { SettingsSection } from './presentation/components/SettingsSection';
19
+ export type { SettingsSectionProps } from './presentation/components/SettingsSection';
20
+ export { SettingsFooter } from './presentation/components/SettingsFooter';
21
+ export type { SettingsFooterProps } from './presentation/components/SettingsFooter';
22
+ export { UserProfileHeader } from './presentation/components/UserProfileHeader';
23
+ export type { UserProfileHeaderProps } from './presentation/components/UserProfileHeader';
24
+ export { DisclaimerSetting } from './presentation/components/DisclaimerSetting';
25
+ export type { DisclaimerSettingProps } from './presentation/components/DisclaimerSetting';
26
+ export { DisclaimerCard } from './presentation/components/DisclaimerCard';
27
+ export type { DisclaimerCardProps } from './presentation/components/DisclaimerCard';
28
+ export { DisclaimerModal } from './presentation/components/DisclaimerModal';
29
+ export type { DisclaimerModalProps } from './presentation/components/DisclaimerModal';
30
+ export { SettingsErrorBoundary } from './presentation/components/SettingsErrorBoundary';
31
+ export { CloudSyncSetting } from './presentation/components/CloudSyncSetting';
32
+ export type { CloudSyncSettingProps } from './presentation/components/CloudSyncSetting';
33
+ export { StorageClearSetting } from './presentation/components/StorageClearSetting';
34
+ export type { StorageClearSettingProps } from './presentation/components/StorageClearSetting';
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,2CAA2C,CAAC;AAMnD,OAAO,EACL,gBAAgB,EAChB,WAAW,GACZ,MAAM,wCAAwC,CAAC;AAMhD,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAM3E,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAM1F,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACpE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,YAAY,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC1E,YAAY,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,YAAY,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAE1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,YAAY,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAE1F,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC1E,YAAY,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,YAAY,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,iDAAiD,CAAC;AAExF,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAC9E,YAAY,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AAExF,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AACpF,YAAY,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @umituz/react-native-settings - Public API
3
+ *
4
+ * Settings management for React Native apps
5
+ * User preferences, theme, language, notifications
6
+ *
7
+ * Usage:
8
+ * import { useSettings, useSettingsStore, SettingsScreen, AppearanceScreen, LanguageSelectionScreen, SettingItem, DisclaimerSetting } from '@umituz/react-native-settings';
9
+ */
10
+ // =============================================================================
11
+ // INFRASTRUCTURE LAYER - Storage
12
+ // =============================================================================
13
+ export { useSettingsStore, useSettings, } from './infrastructure/storage/SettingsStore';
14
+ // =============================================================================
15
+ // PRESENTATION LAYER - Screens
16
+ // =============================================================================
17
+ export { SettingsScreen } from './presentation/screens/SettingsScreen';
18
+ export { AppearanceScreen } from './presentation/screens/AppearanceScreen';
19
+ // =============================================================================
20
+ // PRESENTATION LAYER - Components
21
+ // =============================================================================
22
+ export { SettingItem } from './presentation/components/SettingItem';
23
+ export { SettingsSection } from './presentation/components/SettingsSection';
24
+ export { SettingsFooter } from './presentation/components/SettingsFooter';
25
+ export { UserProfileHeader } from './presentation/components/UserProfileHeader';
26
+ export { DisclaimerSetting } from './presentation/components/DisclaimerSetting';
27
+ export { DisclaimerCard } from './presentation/components/DisclaimerCard';
28
+ export { DisclaimerModal } from './presentation/components/DisclaimerModal';
29
+ export { SettingsErrorBoundary } from './presentation/components/SettingsErrorBoundary';
30
+ export { CloudSyncSetting } from './presentation/components/CloudSyncSetting';
31
+ export { StorageClearSetting } from './presentation/components/StorageClearSetting';
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,gFAAgF;AAChF,iCAAiC;AACjC,gFAAgF;AAEhF,OAAO,EACL,gBAAgB,EAChB,WAAW,GACZ,MAAM,wCAAwC,CAAC;AAEhD,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAQ3E,gFAAgF;AAChF,kCAAkC;AAClC,gFAAgF;AAEhF,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAG5E,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAG1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAGhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAGhF,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAG5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,iDAAiD,CAAC;AAExF,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAG9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Settings Store - Zustand State Management
3
+ *
4
+ * Global settings state for app preferences
5
+ * Manages theme, language, notifications, and privacy settings
6
+ *
7
+ * DDD ARCHITECTURE: Uses @umituz/react-native-storage for all storage operations
8
+ * - Type-safe storage with StorageKey enum
9
+ * - Result pattern for error handling
10
+ * - Single source of truth for all storage
11
+ */
12
+ import type { UserSettings } from '../../domain/repositories/ISettingsRepository';
13
+ interface SettingsStore {
14
+ settings: UserSettings | null;
15
+ loading: boolean;
16
+ error: string | null;
17
+ loadSettings: (userId: string) => Promise<void>;
18
+ updateSettings: (updates: Partial<UserSettings>) => Promise<void>;
19
+ resetSettings: (userId: string) => Promise<void>;
20
+ clearError: () => void;
21
+ }
22
+ export declare const useSettingsStore: import("zustand").UseBoundStore<import("zustand").StoreApi<SettingsStore>>;
23
+ /**
24
+ * Hook for accessing settings state
25
+ */
26
+ export declare const useSettings: () => {
27
+ settings: UserSettings | null;
28
+ loading: boolean;
29
+ error: string | null;
30
+ loadSettings: (userId: string) => Promise<void>;
31
+ updateSettings: (updates: Partial<UserSettings>) => Promise<void>;
32
+ resetSettings: (userId: string) => Promise<void>;
33
+ clearError: () => void;
34
+ };
35
+ export {};
36
+ //# sourceMappingURL=SettingsStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsStore.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/storage/SettingsStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAElF,UAAU,aAAa;IAErB,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AA4BD,eAAO,MAAM,gBAAgB,4EAiH1B,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,WAAW;;;;2BAtJC,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;8BACrB,OAAO,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC;4BACzC,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;sBAC9B,IAAI;CAgKvB,CAAC"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Settings Store - Zustand State Management
3
+ *
4
+ * Global settings state for app preferences
5
+ * Manages theme, language, notifications, and privacy settings
6
+ *
7
+ * DDD ARCHITECTURE: Uses @umituz/react-native-storage for all storage operations
8
+ * - Type-safe storage with StorageKey enum
9
+ * - Result pattern for error handling
10
+ * - Single source of truth for all storage
11
+ */
12
+ import { create } from 'zustand';
13
+ import { storageRepository, StorageKey, createUserKey, unwrap } from '@umituz/react-native-storage';
14
+ const DEFAULT_OFFLINE_USER_ID = 'offline_user';
15
+ const DEFAULT_SETTINGS_CACHE = new Map();
16
+ const getDefaultSettings = (userId) => {
17
+ if (DEFAULT_SETTINGS_CACHE.has(userId)) {
18
+ return DEFAULT_SETTINGS_CACHE.get(userId);
19
+ }
20
+ const settings = {
21
+ userId,
22
+ theme: 'auto',
23
+ language: 'en-US',
24
+ notificationsEnabled: true,
25
+ emailNotifications: true,
26
+ pushNotifications: true,
27
+ soundEnabled: true,
28
+ vibrationEnabled: true,
29
+ privacyMode: false,
30
+ updatedAt: new Date(),
31
+ };
32
+ DEFAULT_SETTINGS_CACHE.set(userId, settings);
33
+ return settings;
34
+ };
35
+ export const useSettingsStore = create((set, get) => ({
36
+ settings: null,
37
+ loading: false,
38
+ error: null,
39
+ loadSettings: async (userId) => {
40
+ if (__DEV__) {
41
+ console.log('SettingsStore: Loading settings for user:', userId);
42
+ }
43
+ set({ loading: true, error: null });
44
+ try {
45
+ const defaultSettings = getDefaultSettings(userId);
46
+ const storageKey = createUserKey(StorageKey.SETTINGS, userId);
47
+ // ✅ DRY: Storage domain handles JSON parse, error handling
48
+ const result = await storageRepository.getItem(storageKey, defaultSettings);
49
+ const data = unwrap(result, defaultSettings);
50
+ // ✅ CLEAN CODE: Auto-save defaults if not exists
51
+ if (!result.success) {
52
+ await storageRepository.setItem(storageKey, defaultSettings);
53
+ }
54
+ set({
55
+ settings: data,
56
+ loading: false,
57
+ error: null,
58
+ });
59
+ if (__DEV__) {
60
+ console.log('SettingsStore: Settings loaded successfully');
61
+ }
62
+ }
63
+ catch (error) {
64
+ if (__DEV__) {
65
+ console.error('SettingsStore: Failed to load settings:', error);
66
+ }
67
+ set({ loading: false, error: 'Failed to load settings' });
68
+ }
69
+ },
70
+ updateSettings: async (updates) => {
71
+ if (__DEV__) {
72
+ console.log('SettingsStore: Updating settings with:', updates);
73
+ }
74
+ const { settings } = get();
75
+ // ✅ CLEAN CODE: Auto-initialize if settings not loaded
76
+ if (!settings) {
77
+ await get().loadSettings(DEFAULT_OFFLINE_USER_ID);
78
+ }
79
+ // ✅ DEFENSIVE: Verify settings loaded successfully
80
+ const currentSettings = get().settings;
81
+ if (!currentSettings) {
82
+ const errorMsg = 'Failed to initialize settings';
83
+ if (__DEV__) {
84
+ console.error('SettingsStore:', errorMsg);
85
+ }
86
+ set({ error: errorMsg });
87
+ return;
88
+ }
89
+ set({ loading: true, error: null });
90
+ try {
91
+ const updatedSettings = {
92
+ ...currentSettings,
93
+ ...updates,
94
+ updatedAt: new Date(),
95
+ };
96
+ const storageKey = createUserKey(StorageKey.SETTINGS, currentSettings.userId);
97
+ // ✅ DRY: Storage domain replaces JSON.stringify + AsyncStorage + try/catch
98
+ const result = await storageRepository.setItem(storageKey, updatedSettings);
99
+ set({
100
+ settings: result.success ? updatedSettings : currentSettings,
101
+ loading: false,
102
+ error: null,
103
+ });
104
+ if (__DEV__) {
105
+ console.log('SettingsStore: Settings updated successfully');
106
+ }
107
+ }
108
+ catch (error) {
109
+ if (__DEV__) {
110
+ console.error('SettingsStore: Failed to update settings:', error);
111
+ }
112
+ set({ loading: false, error: 'Failed to update settings' });
113
+ }
114
+ },
115
+ resetSettings: async (userId) => {
116
+ set({ loading: true, error: null });
117
+ const defaultSettings = getDefaultSettings(userId);
118
+ const storageKey = createUserKey(StorageKey.SETTINGS, userId);
119
+ // ✅ DRY: Storage domain replaces JSON.stringify + AsyncStorage + try/catch
120
+ const result = await storageRepository.setItem(storageKey, defaultSettings);
121
+ set({
122
+ settings: result.success ? defaultSettings : get().settings,
123
+ loading: false,
124
+ error: null,
125
+ });
126
+ },
127
+ clearError: () => set({ error: null }),
128
+ }));
129
+ /**
130
+ * Hook for accessing settings state
131
+ */
132
+ export const useSettings = () => {
133
+ const { settings, loading, error, loadSettings, updateSettings, resetSettings, clearError } = useSettingsStore();
134
+ return {
135
+ settings,
136
+ loading,
137
+ error,
138
+ loadSettings,
139
+ updateSettings,
140
+ resetSettings,
141
+ clearError,
142
+ };
143
+ };
144
+ //# sourceMappingURL=SettingsStore.js.map