@umituz/react-native-settings 4.20.57 → 4.20.59

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 (65) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +51 -0
  2. package/.github/ISSUE_TEMPLATE/documentation.md +52 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +63 -0
  4. package/.github/PULL_REQUEST_TEMPLATE.md +84 -0
  5. package/AI_AGENT_GUIDELINES.md +367 -0
  6. package/ARCHITECTURE.md +246 -0
  7. package/CHANGELOG.md +67 -0
  8. package/CODE_OF_CONDUCT.md +75 -0
  9. package/CONTRIBUTING.md +107 -0
  10. package/DOCUMENTATION_MIGRATION.md +319 -0
  11. package/DOCUMENTATION_TEMPLATE.md +155 -0
  12. package/LICENSE +21 -0
  13. package/README.md +321 -498
  14. package/SECURITY.md +98 -0
  15. package/SETTINGS_SCREEN_GUIDE.md +185 -0
  16. package/TESTING.md +358 -0
  17. package/package.json +13 -2
  18. package/src/__tests__/setup.ts +1 -4
  19. package/src/application/README.md +85 -271
  20. package/src/domains/about/README.md +85 -440
  21. package/src/domains/about/presentation/hooks/README.md +93 -348
  22. package/src/domains/appearance/README.md +95 -584
  23. package/src/domains/appearance/hooks/README.md +95 -303
  24. package/src/domains/appearance/infrastructure/services/README.md +83 -397
  25. package/src/domains/appearance/presentation/components/README.md +99 -0
  26. package/src/domains/cloud-sync/README.md +73 -439
  27. package/src/domains/cloud-sync/presentation/components/README.md +95 -493
  28. package/src/domains/dev/README.md +71 -457
  29. package/src/domains/disclaimer/README.md +77 -411
  30. package/src/domains/disclaimer/presentation/components/README.md +95 -392
  31. package/src/domains/faqs/README.md +86 -574
  32. package/src/domains/feedback/README.md +79 -553
  33. package/src/domains/feedback/presentation/hooks/README.md +93 -426
  34. package/src/domains/legal/README.md +88 -537
  35. package/src/domains/rating/README.md +73 -440
  36. package/src/domains/rating/presentation/components/README.md +95 -475
  37. package/src/domains/video-tutorials/README.md +77 -470
  38. package/src/domains/video-tutorials/presentation/components/README.md +95 -431
  39. package/src/infrastructure/README.md +78 -425
  40. package/src/infrastructure/repositories/README.md +88 -420
  41. package/src/infrastructure/services/README.md +74 -460
  42. package/src/presentation/components/README.md +97 -480
  43. package/src/presentation/components/SettingsErrorBoundary/README.md +48 -442
  44. package/src/presentation/components/SettingsFooter/README.md +48 -427
  45. package/src/presentation/components/SettingsItemCard/README.md +153 -392
  46. package/src/presentation/components/SettingsItemCard/STRATEGY.md +164 -0
  47. package/src/presentation/components/SettingsSection/README.md +47 -401
  48. package/src/presentation/hooks/README.md +95 -389
  49. package/src/presentation/hooks/mutations/README.md +99 -376
  50. package/src/presentation/hooks/queries/README.md +111 -353
  51. package/src/presentation/navigation/README.md +70 -502
  52. package/src/presentation/navigation/components/README.md +70 -295
  53. package/src/presentation/navigation/hooks/README.md +75 -367
  54. package/src/presentation/navigation/utils/README.md +100 -380
  55. package/src/presentation/screens/README.md +53 -504
  56. package/src/presentation/screens/components/SettingsContent/README.md +53 -382
  57. package/src/presentation/screens/components/SettingsHeader/README.md +48 -303
  58. package/src/presentation/screens/components/sections/CustomSettingsList/README.md +47 -359
  59. package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +81 -176
  60. package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +40 -297
  61. package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +47 -451
  62. package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +45 -361
  63. package/src/presentation/screens/hooks/README.md +64 -354
  64. package/src/presentation/screens/types/README.md +79 -409
  65. package/src/presentation/screens/utils/README.md +65 -255
@@ -2,479 +2,75 @@
2
2
 
3
3
  Dynamic loader component that fetches and displays user profile information in the settings screen header.
4
4
 
5
- ## Features
5
+ ## Purpose
6
6
 
7
- - **Dynamic Loading**: Fetches user profile data on mount
8
- - **Loading States**: Shows skeleton while loading
9
- - **Error Handling**: Graceful error display with retry
10
- - **Customizable**: Custom profile data injection
11
- - **Action Handler**: Configurable press handler
12
- - **Avatar Support**: Display user avatar with fallback
7
+ Provides a reusable component for displaying user profile information at the top of the settings screen. Handles loading states, error states, and supports both authenticated and anonymous user profiles with customizable display options.
13
8
 
14
- ## Installation
9
+ ## File Paths
15
10
 
16
- This component is part of `@umituz/react-native-settings`.
11
+ - **Component**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/screens/components/sections/ProfileSectionLoader/ProfileSectionLoader.tsx`
12
+ - **Use Profile Info Hook**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/domain/profile/hooks/useAboutInfo.ts`
17
13
 
18
- ## Usage
14
+ ## Strategy
19
15
 
20
- ### Basic Usage
16
+ 1. **Data Fetching**: Use useAboutInfo hook to dynamically fetch user profile information when userId is provided
17
+ 2. **State Management**: Handle loading, error, and success states with appropriate UI feedback
18
+ 3. **Profile Injection**: Support pre-loaded profile data via userProfile prop to bypass fetching
19
+ 4. **Avatar Handling**: Display user avatars with fallback options for missing or failed loads
20
+ 5. **Anonymous Support**: Clearly distinguish between authenticated and anonymous user profiles
21
21
 
22
- ```tsx
23
- import { ProfileSectionLoader } from '@umituz/react-native-settings';
22
+ ## Restrictions
24
23
 
25
- function SettingsScreen() {
26
- return (
27
- <ProfileSectionLoader
28
- userId="user123"
29
- onPress={() => navigation.navigate('Account')}
30
- />
31
- );
32
- }
33
- ```
24
+ - DO NOT make API calls directly; always use useAboutInfo hook for data fetching
25
+ - ❌ DO NOT hardcode profile data; always use provided props or fetched data
26
+ - ❌ NEVER ignore error states; always provide error feedback
27
+ - ❌ AVOID bypassing loading states when data is being fetched
28
+ - DO NOT mix profile display logic with authentication logic
29
+ - ❌ NEVER assume profile data exists; always handle undefined/null cases
30
+ - ❌ AVOID adding authentication actions (sign in/out) within this component
34
31
 
35
- ### With Custom Profile Data
32
+ ## Rules
36
33
 
37
- ```tsx
38
- function SettingsScreen() {
39
- const userProfile = {
40
- displayName: 'John Doe',
41
- userId: 'user123',
42
- avatarUrl: 'https://example.com/avatar.jpg',
43
- isAnonymous: false,
44
- onPress: () => navigation.navigate('Account'),
45
- };
34
+ - ✅ MUST accept either userProfile or userId prop (not both)
35
+ - MUST display loading state when fetching profile data
36
+ - MUST display error state when fetch fails
37
+ - MUST support anonymous user profiles with distinct visual treatment
38
+ - ✅ MUST provide onPress handler for profile interaction
39
+ - ✅ SHOULD show avatar when available and showAvatar is true
40
+ - ✅ MUST handle missing avatarUrl gracefully
41
+ - SHOULD use custom loading/error components when provided
46
42
 
47
- return (
48
- <ProfileSectionLoader userProfile={userProfile} />
49
- );
50
- }
51
- ```
43
+ ## AI Agent Guidelines
52
44
 
53
- ### With Anonymous User
45
+ When working with ProfileSectionLoader:
54
46
 
55
- ```tsx
56
- function SettingsScreen() {
57
- const userProfile = {
58
- displayName: 'Guest',
59
- userId: 'guest-123',
60
- isAnonymous: true,
61
- anonymousDisplayName: 'Guest User',
62
- onPress: () => navigation.navigate('Auth'),
63
- };
47
+ 1. **Data Source Priority**: Use userProfile prop when data is already available. Use userId prop only when fetching is needed. Never provide both props simultaneously.
64
48
 
65
- return (
66
- <ProfileSectionLoader userProfile={userProfile} />
67
- );
68
- }
69
- ```
49
+ 2. **Loading States**: Always provide visual feedback during data fetching. Use skeleton loaders or spinner components for better UX.
70
50
 
71
- ## Props
51
+ 3. **Error Handling**: Implement retry mechanisms for failed profile fetches. Provide clear error messages to users.
72
52
 
73
- ### ProfileSectionLoaderProps
53
+ 4. **Avatar Management**: Handle avatar loading failures. Implement fallback to initials or default avatar when image fails to load.
74
54
 
75
- | Prop | Type | Default | Description |
76
- |------|------|---------|-------------|
77
- | `userProfile` | `UserProfile` | `undefined` | Pre-loaded profile data |
78
- | `userId` | `string` | `undefined` | User ID for fetching profile |
79
- | `showAvatar` | `boolean` | `true` | Show user avatar |
80
- | `showEmail` | `boolean` | `true` | Show email address |
81
- | `onPress` | `() => void` | `undefined` | Press handler |
82
- | `loadingComponent` | `ReactNode` | `undefined` | Custom loading component |
83
- | `errorComponent` | `ReactNode` | `undefined` | Custom error component |
84
- | `style` | `ViewStyle` | `undefined` | Custom container style |
55
+ 5. **Anonymous Users**: Clearly distinguish anonymous users from authenticated users. Use different visual treatments (badges, labels, etc.).
85
56
 
86
- ## Component Structure
57
+ 6. **Privacy Considerations**: For anonymous users, display minimal information. Do not expose sensitive profile details.
87
58
 
88
- ```
89
- ProfileSectionLoader
90
- ├── Loading State (if loading)
91
- │ └── Skeleton / LoadingSpinner
92
- ├── Error State (if error)
93
- │ └── Error message with retry
94
- └── Profile Content (when loaded)
95
- ├── Avatar
96
- ├── User Info
97
- │ ├── Display Name
98
- │ ├── Email (optional)
99
- │ └── Anonymous badge (if applicable)
100
- └── Chevron/Arrow
101
- ```
59
+ 7. **Customization**: Use custom loading and error components to match app design system. Maintain consistent styling.
102
60
 
103
- ## Examples
61
+ 8. **Action Handling**: The onPress handler should navigate to account settings or profile edit screen. Do not handle authentication (sign in/out) within this component.
104
62
 
105
- ### With Loading State
63
+ 9. **Performance**: Profile data fetching should be efficient. Implement caching strategies to avoid unnecessary refetches.
106
64
 
107
- ```tsx
108
- function ProfileWithLoading() {
109
- const [profile, setProfile] = useState(null);
110
- const [loading, setLoading] = useState(true);
65
+ 10. **Accessibility**: Add proper accessibility labels for profile elements. Ensure screen readers can announce profile information correctly.
111
66
 
112
- useEffect(() => {
113
- fetchProfile('user123').then(data => {
114
- setProfile(data);
115
- setLoading(false);
116
- });
117
- }, []);
67
+ 11. **Responsive Design**: Ensure profile section displays correctly on different screen sizes and orientations.
118
68
 
119
- if (loading) {
120
- return <ProfileSectionLoader loadingComponent={<ProfileSkeleton />} />;
121
- }
69
+ 12. **Integration**: This component should be placed at the top of SettingsContent, before all other sections.
122
70
 
123
- return <ProfileSectionLoader userProfile={profile} />;
124
- }
125
- ```
71
+ ## Related Components
126
72
 
127
- ### With Error Handling
128
-
129
- ```tsx
130
- function ProfileWithError() {
131
- const [error, setError] = useState(null);
132
- const [profile, setProfile] = useState(null);
133
-
134
- useEffect(() => {
135
- fetchProfile('user123')
136
- .then(setProfile)
137
- .catch(setError);
138
- }, []);
139
-
140
- if (error) {
141
- return (
142
- <ProfileSectionLoader
143
- errorComponent={
144
- <ProfileError
145
- message="Failed to load profile"
146
- onRetry={() => window.location.reload()}
147
- />
148
- }
149
- />
150
- );
151
- }
152
-
153
- return <ProfileSectionLoader userProfile={profile} />;
154
- }
155
- ```
156
-
157
- ### Custom Avatar Service
158
-
159
- ```tsx
160
- function CustomAvatarProfile() {
161
- const profile = {
162
- displayName: 'John Doe',
163
- userId: 'user123',
164
- avatarUrl: 'https://ui-avatars.com/api/?name=John+Doe&background=2196F3&color=fff',
165
- onPress: () => navigation.navigate('Account'),
166
- };
167
-
168
- return <ProfileSectionLoader userProfile={profile} />;
169
- }
170
- ```
171
-
172
- ### With Sign Out Action
173
-
174
- ```tsx
175
- function ProfileWithSignOut() {
176
- const [profile, setProfile] = useState(null);
177
- const navigation = useNavigation();
178
-
179
- const handleSignOut = async () => {
180
- await signOut();
181
- navigation.reset({ index: 0, routes: [{ name: 'Login' }] });
182
- };
183
-
184
- return (
185
- <View>
186
- <ProfileSectionLoader userProfile={profile} />
187
-
188
- <TouchableOpacity onPress={handleSignOut} style={styles.signOut}>
189
- <Text>Sign Out</Text>
190
- </TouchableOpacity>
191
- </View>
192
- );
193
- }
194
- ```
195
-
196
- ### Anonymous vs Authenticated
197
-
198
- ```tsx
199
- function AdaptiveProfile() {
200
- const user = useAuth();
201
-
202
- if (user?.isAnonymous) {
203
- return (
204
- <ProfileSectionLoader
205
- userProfile={{
206
- displayName: 'Guest',
207
- isAnonymous: true,
208
- anonymousDisplayName: 'Guest User',
209
- onPress: () => navigation.navigate('SignIn'),
210
- }}
211
- />
212
- );
213
- }
214
-
215
- return (
216
- <ProfileSectionLoader
217
- userProfile={{
218
- displayName: user.displayName,
219
- userId: user.uid,
220
- avatarUrl: user.photoURL,
221
- isAnonymous: false,
222
- onPress: () => navigation.navigate('Account'),
223
- }}
224
- />
225
- );
226
- }
227
- ```
228
-
229
- ## Data Types
230
-
231
- ### UserProfile
232
-
233
- ```typescript
234
- interface UserProfile {
235
- displayName: string; // Display name
236
- userId: string; // User ID
237
- avatarUrl?: string; // Avatar URL
238
- isAnonymous?: boolean; // Anonymous user flag
239
- anonymousDisplayName?: string; // Anonymous display name
240
- avatarServiceUrl?: string; // Avatar service URL
241
- accountSettingsRoute?: string; // Account settings route
242
- onPress?: () => void; // Press handler
243
- }
244
- ```
245
-
246
- ## Styling
247
-
248
- ### Default Styles
249
-
250
- ```typescript
251
- const styles = StyleSheet.create({
252
- container: {
253
- flexDirection: 'row',
254
- alignItems: 'center',
255
- padding: tokens.spacing.lg,
256
- backgroundColor: tokens.colors.surface,
257
- },
258
- avatar: {
259
- width: 60,
260
- height: 60,
261
- borderRadius: 30,
262
- marginRight: tokens.spacing.md,
263
- },
264
- content: {
265
- flex: 1,
266
- },
267
- displayName: {
268
- fontSize: tokens.typography.fontSize.lg,
269
- fontWeight: '600',
270
- color: tokens.colors.textPrimary,
271
- },
272
- email: {
273
- fontSize: tokens.typography.fontSize.sm,
274
- color: tokens.colors.textSecondary,
275
- marginTop: 2,
276
- },
277
- anonymousBadge: {
278
- backgroundColor: tokens.colors.warning,
279
- paddingHorizontal: 8,
280
- paddingVertical: 2,
281
- borderRadius: 4,
282
- marginTop: 4,
283
- alignSelf: 'flex-start',
284
- },
285
- anonymousText: {
286
- fontSize: tokens.typography.fontSize.xs,
287
- color: tokens.colors.surface,
288
- fontWeight: '600',
289
- },
290
- chevron: {
291
- marginLeft: tokens.spacing.sm,
292
- },
293
- });
294
- ```
295
-
296
- ### Custom Styling
297
-
298
- ```tsx
299
- <ProfileSectionLoader
300
- userProfile={profile}
301
- style={{
302
- backgroundColor: '#f5f5f5',
303
- paddingVertical: 20,
304
- borderBottomWidth: 1,
305
- borderBottomColor: '#e0e0e0',
306
- }}
307
- />
308
- ```
309
-
310
- ### Avatar Styling
311
-
312
- ```tsx
313
- function CustomAvatarProfile() {
314
- return (
315
- <ProfileSectionLoader
316
- userProfile={profile}
317
- avatarStyle={{
318
- borderWidth: 2,
319
- borderColor: '#2196F3',
320
- }}
321
- />
322
- );
323
- }
324
- ```
325
-
326
- ## Loading States
327
-
328
- ### Skeleton Loader
329
-
330
- ```tsx
331
- function ProfileSkeleton() {
332
- return (
333
- <View style={styles.container}>
334
- <View style={[styles.avatar, styles.skeleton]} />
335
- <View style={styles.content}>
336
- <View style={[styles.text, styles.skeleton]} />
337
- <View style={[styles.textSm, styles.skeleton]} />
338
- </View>
339
- </View>
340
- );
341
- }
342
-
343
- const skeletonStyles = StyleSheet.create({
344
- skeleton: {
345
- backgroundColor: '#e0e0e0',
346
- },
347
- text: {
348
- height: 20,
349
- width: 150,
350
- borderRadius: 4,
351
- },
352
- textSm: {
353
- height: 16,
354
- width: 200,
355
- borderRadius: 4,
356
- marginTop: 8,
357
- },
358
- });
359
- ```
360
-
361
- ### Spinner Loader
362
-
363
- ```tsx
364
- function SpinnerLoader() {
365
- return (
366
- <View style={styles.loaderContainer}>
367
- <ActivityIndicator size="large" color="#2196F3" />
368
- <Text style={styles.loadingText}>Loading profile...</Text>
369
- </View>
370
- );
371
- }
372
- ```
373
-
374
- ## Error States
375
-
376
- ### Error Message with Retry
377
-
378
- ```tsx
379
- function ProfileError({ message, onRetry }) {
380
- return (
381
- <View style={styles.errorContainer}>
382
- <Ionicons name="person-outline" size={48} color="#ccc" />
383
- <Text style={styles.errorTitle}>Profile Error</Text>
384
- <Text style={styles.errorMessage}>{message}</Text>
385
- <Button onPress={onRetry} title="Retry" />
386
- </View>
387
- );
388
- }
389
- ```
390
-
391
- ### Fallback Display
392
-
393
- ```tsx
394
- function ProfileFallback({ onPress }) {
395
- return (
396
- <TouchableOpacity onPress={onPress} style={styles.container}>
397
- <View style={styles.avatarPlaceholder}>
398
- <Ionicons name="person-outline" size={32} color="#999" />
399
- </View>
400
- <View style={styles.content}>
401
- <Text style={styles.name}>Sign In</Text>
402
- <Text style={styles.description}>Access your profile</Text>
403
- </View>
404
- <Ionicons name="chevron-forward" size={24} color="#999" />
405
- </TouchableOpacity>
406
- );
407
- }
408
- ```
409
-
410
- ## Avatar Sources
411
-
412
- ### From URL
413
-
414
- ```tsx
415
- const profile = {
416
- displayName: 'John Doe',
417
- avatarUrl: 'https://example.com/avatar.jpg',
418
- };
419
- ```
420
-
421
- ### From Avatar Service
422
-
423
- ```tsx
424
- const profile = {
425
- displayName: 'John Doe',
426
- avatarServiceUrl: 'https://ui-avatars.com/api/?name=John+Doe',
427
- };
428
- ```
429
-
430
- ### From Local Storage
431
-
432
- ```tsx
433
- const profile = {
434
- displayName: 'John Doe',
435
- avatarUrl: require('../../assets/images/default-avatar.png'),
436
- };
437
- ```
438
-
439
- ### Initials Fallback
440
-
441
- ```tsx
442
- function AvatarWithInitials({ displayName }) {
443
- const initials = displayName
444
- .split(' ')
445
- .map(name => name[0])
446
- .join('')
447
- .toUpperCase()
448
- .slice(0, 2);
449
-
450
- return (
451
- <View style={styles.avatar}>
452
- {avatarUrl ? (
453
- <Image source={{ uri: avatarUrl }} style={styles.image} />
454
- ) : (
455
- <Text style={styles.initials}>{initials}</Text>
456
- )}
457
- </View>
458
- );
459
- }
460
- ```
461
-
462
- ## Best Practices
463
-
464
- 1. **Loading States**: Always show loading indicator
465
- 2. **Error Handling**: Provide retry options on error
466
- 3. **Avatar Fallbacks**: Use initials or default avatar
467
- 4. **Anonymous Users**: Clearly indicate anonymous status
468
- 5. **Press Handler**: Always provide press handler
469
- 6. **Privacy**: Show minimal info for anonymous users
470
- 7. **Accessibility**: Add proper accessibility labels
471
-
472
- ## Related
473
-
474
- - **SettingsContent**: Content component
475
- - **SettingsScreen**: Main screen component
476
- - **UserProfile**: Profile type definition
477
-
478
- ## License
479
-
480
- MIT
73
+ - **Settings Content**: Content component that uses ProfileSectionLoader
74
+ - **Settings Screen**: Main screen component
75
+ - **User Profile**: Profile type definition
76
+ - **Use About Info**: Hook for fetching profile information