@umituz/react-native-settings 4.20.55 → 4.20.57

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 (47) hide show
  1. package/README.md +145 -3
  2. package/package.json +1 -2
  3. package/src/application/README.md +322 -0
  4. package/src/domains/about/README.md +452 -0
  5. package/src/domains/about/presentation/hooks/README.md +350 -0
  6. package/src/domains/appearance/README.md +596 -0
  7. package/src/domains/appearance/hooks/README.md +366 -0
  8. package/src/domains/appearance/infrastructure/services/README.md +455 -0
  9. package/src/domains/cloud-sync/README.md +451 -0
  10. package/src/domains/cloud-sync/presentation/components/README.md +493 -0
  11. package/src/domains/dev/README.md +477 -0
  12. package/src/domains/disclaimer/README.md +421 -0
  13. package/src/domains/disclaimer/presentation/components/README.md +394 -0
  14. package/src/domains/faqs/README.md +586 -0
  15. package/src/domains/feedback/README.md +565 -0
  16. package/src/domains/feedback/presentation/hooks/README.md +428 -0
  17. package/src/domains/legal/README.md +549 -0
  18. package/src/domains/rating/README.md +452 -0
  19. package/src/domains/rating/presentation/components/README.md +475 -0
  20. package/src/domains/video-tutorials/README.md +482 -0
  21. package/src/domains/video-tutorials/presentation/components/README.md +433 -0
  22. package/src/infrastructure/README.md +509 -0
  23. package/src/infrastructure/repositories/README.md +475 -0
  24. package/src/infrastructure/services/README.md +510 -0
  25. package/src/presentation/components/README.md +482 -0
  26. package/src/presentation/components/SettingsErrorBoundary/README.md +461 -0
  27. package/src/presentation/components/SettingsFooter/README.md +446 -0
  28. package/src/presentation/components/SettingsItemCard/README.md +457 -0
  29. package/src/presentation/components/SettingsSection/README.md +421 -0
  30. package/src/presentation/hooks/README.md +413 -0
  31. package/src/presentation/hooks/mutations/README.md +430 -0
  32. package/src/presentation/hooks/queries/README.md +441 -0
  33. package/src/presentation/navigation/README.md +532 -0
  34. package/src/presentation/navigation/components/README.md +330 -0
  35. package/src/presentation/navigation/hooks/README.md +399 -0
  36. package/src/presentation/navigation/utils/README.md +442 -0
  37. package/src/presentation/screens/README.md +525 -0
  38. package/src/presentation/screens/components/SettingsContent/README.md +404 -0
  39. package/src/presentation/screens/components/SettingsHeader/README.md +322 -0
  40. package/src/presentation/screens/components/sections/CustomSettingsList/README.md +388 -0
  41. package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +232 -0
  42. package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +325 -0
  43. package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +480 -0
  44. package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +391 -0
  45. package/src/presentation/screens/hooks/README.md +383 -0
  46. package/src/presentation/screens/types/README.md +439 -0
  47. package/src/presentation/screens/utils/README.md +288 -0
@@ -0,0 +1,480 @@
1
+ # ProfileSectionLoader
2
+
3
+ Dynamic loader component that fetches and displays user profile information in the settings screen header.
4
+
5
+ ## Features
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
13
+
14
+ ## Installation
15
+
16
+ This component is part of `@umituz/react-native-settings`.
17
+
18
+ ## Usage
19
+
20
+ ### Basic Usage
21
+
22
+ ```tsx
23
+ import { ProfileSectionLoader } from '@umituz/react-native-settings';
24
+
25
+ function SettingsScreen() {
26
+ return (
27
+ <ProfileSectionLoader
28
+ userId="user123"
29
+ onPress={() => navigation.navigate('Account')}
30
+ />
31
+ );
32
+ }
33
+ ```
34
+
35
+ ### With Custom Profile Data
36
+
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
+ };
46
+
47
+ return (
48
+ <ProfileSectionLoader userProfile={userProfile} />
49
+ );
50
+ }
51
+ ```
52
+
53
+ ### With Anonymous User
54
+
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
+ };
64
+
65
+ return (
66
+ <ProfileSectionLoader userProfile={userProfile} />
67
+ );
68
+ }
69
+ ```
70
+
71
+ ## Props
72
+
73
+ ### ProfileSectionLoaderProps
74
+
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 |
85
+
86
+ ## Component Structure
87
+
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
+ ```
102
+
103
+ ## Examples
104
+
105
+ ### With Loading State
106
+
107
+ ```tsx
108
+ function ProfileWithLoading() {
109
+ const [profile, setProfile] = useState(null);
110
+ const [loading, setLoading] = useState(true);
111
+
112
+ useEffect(() => {
113
+ fetchProfile('user123').then(data => {
114
+ setProfile(data);
115
+ setLoading(false);
116
+ });
117
+ }, []);
118
+
119
+ if (loading) {
120
+ return <ProfileSectionLoader loadingComponent={<ProfileSkeleton />} />;
121
+ }
122
+
123
+ return <ProfileSectionLoader userProfile={profile} />;
124
+ }
125
+ ```
126
+
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