@umituz/react-native-auth 3.4.30 → 3.4.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +426 -0
- package/package.json +1 -3
- package/src/application/README.md +513 -0
- package/src/domain/ConfigAndErrors.md +545 -0
- package/src/domain/README.md +293 -0
- package/src/domain/entities/AuthUser.md +377 -0
- package/src/domain/entities/UserProfile.md +443 -0
- package/src/infrastructure/README.md +576 -0
- package/src/infrastructure/services/README.md +417 -0
- package/src/presentation/README.md +770 -0
- package/src/presentation/components/AuthBackground.tsx +21 -0
- package/src/presentation/components/AuthContainer.tsx +3 -3
- package/src/presentation/components/LoginForm.md +331 -0
- package/src/presentation/components/PasswordIndicators.md +471 -0
- package/src/presentation/components/ProfileComponents.md +432 -0
- package/src/presentation/components/README.md +117 -0
- package/src/presentation/components/SocialLoginButtons.md +303 -0
- package/src/presentation/hooks/README.md +122 -0
- package/src/presentation/hooks/useAccountManagement.md +380 -0
- package/src/presentation/hooks/useAuth.md +255 -0
- package/src/presentation/hooks/useAuthBottomSheet.md +417 -0
- package/src/presentation/hooks/useAuthRequired.md +248 -0
- package/src/presentation/hooks/useProfileUpdate.md +327 -0
- package/src/presentation/hooks/useSocialLogin.md +411 -0
- package/src/presentation/hooks/useUserProfile.md +230 -0
- package/src/presentation/screens/README.md +198 -0
- package/src/presentation/components/AuthGradientBackground.tsx +0 -33
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# Social Login Hooks
|
|
2
|
+
|
|
3
|
+
Google ve Apple ile social authentication işlemleri için hooks.
|
|
4
|
+
|
|
5
|
+
## Hooks
|
|
6
|
+
|
|
7
|
+
- **[`useSocialLogin`](#usesociallogin)** - Genel social login yönetimi
|
|
8
|
+
- **[`useGoogleAuth`](#usegoogleauth)** - Google ile giriş (OAuth flow)
|
|
9
|
+
- **[`useAppleAuth`](#useappleauth)** - Apple ile giriş
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## useSocialLogin
|
|
14
|
+
|
|
15
|
+
Genel social login işlevselliği sağlar. `@umituz/react-native-firebase` paketinin `useSocialAuth` hook'unu wrap'ler.
|
|
16
|
+
|
|
17
|
+
### Kullanım
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { useSocialLogin } from '@umituz/react-native-auth';
|
|
21
|
+
|
|
22
|
+
function LoginScreen() {
|
|
23
|
+
const {
|
|
24
|
+
signInWithGoogle,
|
|
25
|
+
signInWithApple,
|
|
26
|
+
googleLoading,
|
|
27
|
+
appleLoading,
|
|
28
|
+
googleConfigured,
|
|
29
|
+
appleAvailable,
|
|
30
|
+
} = useSocialLogin({
|
|
31
|
+
google: {
|
|
32
|
+
webClientId: 'your-web-client-id.apps.googleusercontent.com',
|
|
33
|
+
iosClientId: 'your-ios-client-id.apps.googleusercontent.com',
|
|
34
|
+
},
|
|
35
|
+
apple: { enabled: true },
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<View>
|
|
40
|
+
<Button
|
|
41
|
+
onPress={signInWithGoogle}
|
|
42
|
+
disabled={googleLoading || !googleConfigured}
|
|
43
|
+
>
|
|
44
|
+
{googleLoading ? 'Giriş yapılıyor...' : 'Google ile Giriş'}
|
|
45
|
+
</Button>
|
|
46
|
+
|
|
47
|
+
<Button
|
|
48
|
+
onPress={signInWithApple}
|
|
49
|
+
disabled={appleLoading || !appleAvailable}
|
|
50
|
+
>
|
|
51
|
+
{appleLoading ? 'Giriş yapılıyor...' : 'Apple ile Giriş'}
|
|
52
|
+
</Button>
|
|
53
|
+
</View>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### API
|
|
59
|
+
|
|
60
|
+
#### Parameters
|
|
61
|
+
|
|
62
|
+
| Param | Tip | Açıklama |
|
|
63
|
+
|-------|------|----------|
|
|
64
|
+
| `config` | `UseSocialLoginConfig` | Social auth konfigürasyonu |
|
|
65
|
+
|
|
66
|
+
#### UseSocialLoginConfig
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
interface UseSocialLoginConfig {
|
|
70
|
+
google?: {
|
|
71
|
+
iosClientId?: string;
|
|
72
|
+
webClientId?: string;
|
|
73
|
+
androidClientId?: string;
|
|
74
|
+
};
|
|
75
|
+
apple?: {
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Return Value
|
|
82
|
+
|
|
83
|
+
| Prop | Tip | Açıklama |
|
|
84
|
+
|------|-----|----------|
|
|
85
|
+
| `signInWithGoogle` | `() => Promise<SocialAuthResult>` | Google ile giriş (Not: `useGoogleAuth` kullanın) |
|
|
86
|
+
| `signInWithApple` | `() => Promise<SocialAuthResult>` | Apple ile giriş |
|
|
87
|
+
| `googleLoading` | `boolean` | Google giriş loading durumu |
|
|
88
|
+
| `appleLoading` | `boolean` | Apple giriş loading durumu |
|
|
89
|
+
| `googleConfigured` | `boolean` | Google yapılandırılmış mı |
|
|
90
|
+
| `appleAvailable` | `boolean` | Apple mevcut mu (sadece iOS) |
|
|
91
|
+
|
|
92
|
+
**Not:** `signInWithGoogle` için tam OAuth flow'u `useGoogleAuth` hook'unu kullanın.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## useGoogleAuth
|
|
97
|
+
|
|
98
|
+
Google OAuth flow'unu `expo-auth-session` kullanarak yönetir ve Firebase authentication ile entegre eder.
|
|
99
|
+
|
|
100
|
+
### Kullanım
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { useGoogleAuth } from '@umituz/react-native-auth';
|
|
104
|
+
|
|
105
|
+
function LoginScreen() {
|
|
106
|
+
const { signInWithGoogle, googleLoading, googleConfigured } = useGoogleAuth({
|
|
107
|
+
iosClientId: 'your-ios-client-id.apps.googleusercontent.com',
|
|
108
|
+
webClientId: 'your-web-client-id.apps.googleusercontent.com',
|
|
109
|
+
androidClientId: 'your-android-client-id.apps.googleusercontent.com',
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const handleGoogleSignIn = async () => {
|
|
113
|
+
const result = await signInWithGoogle();
|
|
114
|
+
|
|
115
|
+
if (result.success) {
|
|
116
|
+
console.log('Google ile giriş başarılı');
|
|
117
|
+
} else {
|
|
118
|
+
Alert.alert('Hata', result.error || 'Giriş başarısız');
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<Button
|
|
124
|
+
onPress={handleGoogleSignIn}
|
|
125
|
+
disabled={googleLoading || !googleConfigured}
|
|
126
|
+
>
|
|
127
|
+
{googleLoading ? 'Giriş yapılıyor...' : 'Google ile Giriş'}
|
|
128
|
+
</Button>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### API
|
|
134
|
+
|
|
135
|
+
#### Parameters
|
|
136
|
+
|
|
137
|
+
| Param | Tip | Required | Açıklama |
|
|
138
|
+
|-------|------|----------|----------|
|
|
139
|
+
| `iosClientId` | `string` | No* | iOS için Google Client ID |
|
|
140
|
+
| `webClientId` | `string` | No* | Web için Google Client ID |
|
|
141
|
+
| `androidClientId` | `string` | No* | Android için Google Client ID |
|
|
142
|
+
|
|
143
|
+
*En az biri sağlanmalıdır.
|
|
144
|
+
|
|
145
|
+
#### Return Value
|
|
146
|
+
|
|
147
|
+
| Prop | Tip | Açıklama |
|
|
148
|
+
|------|-----|----------|
|
|
149
|
+
| `signInWithGoogle` | `() => Promise<SocialAuthResult>` | Google ile giriş fonksiyonu |
|
|
150
|
+
| `googleLoading` | `boolean` | Loading durumu |
|
|
151
|
+
| `googleConfigured` | `boolean` | Yapılandırılmış mı |
|
|
152
|
+
|
|
153
|
+
### Örnekler
|
|
154
|
+
|
|
155
|
+
#### Google ile Giriş Ekranı
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
function SocialLoginScreen() {
|
|
159
|
+
const { signInWithGoogle, googleLoading } = useGoogleAuth({
|
|
160
|
+
iosClientId: Config.GOOGLE_IOS_CLIENT_ID,
|
|
161
|
+
webClientId: Config.GOOGLE_WEB_CLIENT_ID,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const { signInWithApple, appleLoading, appleAvailable } = useAppleAuth();
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<View style={styles.container}>
|
|
168
|
+
<Text style={styles.title}>Giriş Yap</Text>
|
|
169
|
+
|
|
170
|
+
<TouchableOpacity
|
|
171
|
+
style={styles.googleButton}
|
|
172
|
+
onPress={signInWithGoogle}
|
|
173
|
+
disabled={googleLoading}
|
|
174
|
+
>
|
|
175
|
+
{googleLoading ? (
|
|
176
|
+
<ActivityIndicator />
|
|
177
|
+
) : (
|
|
178
|
+
<>
|
|
179
|
+
<GoogleIcon />
|
|
180
|
+
<Text>Google ile devam et</Text>
|
|
181
|
+
</>
|
|
182
|
+
)}
|
|
183
|
+
</TouchableOpacity>
|
|
184
|
+
|
|
185
|
+
{Platform.OS === 'ios' && appleAvailable && (
|
|
186
|
+
<TouchableOpacity
|
|
187
|
+
style={styles.appleButton}
|
|
188
|
+
onPress={signInWithApple}
|
|
189
|
+
disabled={appleLoading}
|
|
190
|
+
>
|
|
191
|
+
{appleLoading ? (
|
|
192
|
+
<ActivityIndicator />
|
|
193
|
+
) : (
|
|
194
|
+
<>
|
|
195
|
+
<AppleIcon />
|
|
196
|
+
<Text>Apple ile devam et</Text>
|
|
197
|
+
</>
|
|
198
|
+
)}
|
|
199
|
+
</TouchableOpacity>
|
|
200
|
+
)}
|
|
201
|
+
</View>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### Hata Yönetimi
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
function LoginWithErrorHandling() {
|
|
210
|
+
const { signInWithGoogle, googleLoading } = useGoogleAuth({
|
|
211
|
+
webClientId: Config.GOOGLE_WEB_CLIENT_ID,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const handleGoogleSignIn = async () => {
|
|
215
|
+
try {
|
|
216
|
+
const result = await signInWithGoogle();
|
|
217
|
+
|
|
218
|
+
if (result.success) {
|
|
219
|
+
// Başarılı giriş
|
|
220
|
+
navigation.navigate('Home');
|
|
221
|
+
} else {
|
|
222
|
+
// Hata durumunda
|
|
223
|
+
if (result.error?.includes('cancelled')) {
|
|
224
|
+
// Kullanıcı iptal etti
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
Alert.alert(
|
|
229
|
+
'Giriş Hatası',
|
|
230
|
+
result.error || 'Google ile giriş yapılamadı'
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
} catch (error) {
|
|
234
|
+
Alert.alert(
|
|
235
|
+
'Beklenmeyen Hata',
|
|
236
|
+
'Bir hata oluştu. Lütfen daha sonra tekrar deneyin.'
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
return <Button onPress={handleGoogleSignIn} />;
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## useAppleAuth
|
|
248
|
+
|
|
249
|
+
Apple Sign-In işlevselliği sağlar. Sadece iOS'ta mevcuttur.
|
|
250
|
+
|
|
251
|
+
### Kullanım
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { useAppleAuth } from '@umituz/react-native-auth';
|
|
255
|
+
import { Platform } from 'react-native';
|
|
256
|
+
|
|
257
|
+
function LoginScreen() {
|
|
258
|
+
const { signInWithApple, appleLoading, appleAvailable } = useAppleAuth();
|
|
259
|
+
|
|
260
|
+
if (Platform.OS !== 'ios' || !appleAvailable) {
|
|
261
|
+
return null; // Apple sadece iOS'ta çalışır
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return (
|
|
265
|
+
<TouchableOpacity
|
|
266
|
+
onPress={signInWithApple}
|
|
267
|
+
disabled={appleLoading}
|
|
268
|
+
style={styles.appleButton}
|
|
269
|
+
>
|
|
270
|
+
{appleLoading ? (
|
|
271
|
+
<ActivityIndicator />
|
|
272
|
+
) : (
|
|
273
|
+
<>
|
|
274
|
+
<AppleIcon />
|
|
275
|
+
<Text>Apple ile Giriş</Text>
|
|
276
|
+
</>
|
|
277
|
+
)}
|
|
278
|
+
</TouchableOpacity>
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### API
|
|
284
|
+
|
|
285
|
+
#### Return Value
|
|
286
|
+
|
|
287
|
+
| Prop | Tip | Açıklama |
|
|
288
|
+
|------|-----|----------|
|
|
289
|
+
| `signInWithApple` | `() => Promise<SocialAuthResult>` | Apple ile giriş fonksiyonu |
|
|
290
|
+
| `appleLoading` | `boolean` | Loading durumu |
|
|
291
|
+
| `appleAvailable` | `boolean` | Apple Sign-In mevcut mu (iOS only) |
|
|
292
|
+
|
|
293
|
+
### Örnekler
|
|
294
|
+
|
|
295
|
+
#### Platform-Specific Apple Button
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
function SocialLoginButtons() {
|
|
299
|
+
const { signInWithApple, appleLoading, appleAvailable } = useAppleAuth();
|
|
300
|
+
const { signInWithGoogle, googleLoading } = useGoogleAuth({
|
|
301
|
+
webClientId: Config.GOOGLE_WEB_CLIENT_ID,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
return (
|
|
305
|
+
<View>
|
|
306
|
+
{/* Google - tüm platformlar */}
|
|
307
|
+
<SocialButton
|
|
308
|
+
provider="google"
|
|
309
|
+
onPress={signInWithGoogle}
|
|
310
|
+
loading={googleLoading}
|
|
311
|
+
/>
|
|
312
|
+
|
|
313
|
+
{/* Apple - sadece iOS */}
|
|
314
|
+
{Platform.OS === 'ios' && appleAvailable && (
|
|
315
|
+
<SocialButton
|
|
316
|
+
provider="apple"
|
|
317
|
+
onPress={signInWithApple}
|
|
318
|
+
loading={appleLoading}
|
|
319
|
+
/>
|
|
320
|
+
)}
|
|
321
|
+
</View>
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
#### Apple ile Giriş ve Hata Yönetimi
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
function AppleLoginButton() {
|
|
330
|
+
const { signInWithApple, appleLoading, appleAvailable } = useAppleAuth();
|
|
331
|
+
|
|
332
|
+
const handleAppleSignIn = async () => {
|
|
333
|
+
const result = await signInWithApple();
|
|
334
|
+
|
|
335
|
+
if (result.success) {
|
|
336
|
+
console.log('Apple ile giriş başarılı');
|
|
337
|
+
// Kullanıcıyı ana ekrana yönlendir
|
|
338
|
+
} else {
|
|
339
|
+
// Hata yönetimi
|
|
340
|
+
if (result.error?.includes('cancelled')) {
|
|
341
|
+
console.log('Kullanıcı iptal etti');
|
|
342
|
+
} else {
|
|
343
|
+
Alert.alert('Hata', result.error || 'Apple ile giriş yapılamadı');
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
if (!appleAvailable) {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return (
|
|
353
|
+
<TouchableOpacity onPress={handleAppleSignIn} disabled={appleLoading}>
|
|
354
|
+
<Text>Apple ile Giriş</Text>
|
|
355
|
+
</TouchableOpacity>
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## SocialAuthResult
|
|
361
|
+
|
|
362
|
+
Tüm social login fonksiyonları aynı result tipini döner:
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
interface SocialAuthResult {
|
|
366
|
+
success: boolean;
|
|
367
|
+
error?: string;
|
|
368
|
+
user?: AuthUser;
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## Konfigürasyon
|
|
373
|
+
|
|
374
|
+
### Google Client ID Almak
|
|
375
|
+
|
|
376
|
+
1. [Google Cloud Console](https://console.cloud.google.com/)'a gidin
|
|
377
|
+
2. Yeni bir proje oluşturun veya mevcut projeyi seçin
|
|
378
|
+
3. "APIs & Services" > "Credentials" sayfasına gidin
|
|
379
|
+
4. "OAuth 2.0 Client IDs" oluşturun:
|
|
380
|
+
- **iOS**: iOS uygulamanız için
|
|
381
|
+
- **Android**: Android uygulamanız için
|
|
382
|
+
- **Web**: Expo/web için
|
|
383
|
+
|
|
384
|
+
### Apple Sign-In Konfigürasyonu
|
|
385
|
+
|
|
386
|
+
1. [Apple Developer](https://developer.apple.com/)'da gidin
|
|
387
|
+
2. "Certificates, Identifiers & Profiles" > "Identifiers"
|
|
388
|
+
3. App ID'nizi seçin ve "Sign In with Apple"ı enable edin
|
|
389
|
+
4. Firebase Console'da Apple Sign-In'i enable edin
|
|
390
|
+
|
|
391
|
+
## Önemli Notlar
|
|
392
|
+
|
|
393
|
+
### Google
|
|
394
|
+
- `expo-web-browser` kurulumu gerekir
|
|
395
|
+
- `WebBrowser.maybeCompleteAuthSession()` app root'ta çağrılmalı
|
|
396
|
+
- En az bir client ID sağlanmalıdır
|
|
397
|
+
|
|
398
|
+
### Apple
|
|
399
|
+
- Sadece iOS'ta mevcuttur
|
|
400
|
+
- `expo-apple-authentication` kurulumu gerekir
|
|
401
|
+
- Apple Developer hesabı gerekir
|
|
402
|
+
- Test için cihaz gereklidir (simulator'de çalışmayabilir)
|
|
403
|
+
|
|
404
|
+
## İlgili Hook'lar
|
|
405
|
+
|
|
406
|
+
- [`useAuth`](./useAuth.md) - Ana auth state yönetimi
|
|
407
|
+
- [`useSocialLogin`](#usesociallogin) - Genel social login yönetimi
|
|
408
|
+
|
|
409
|
+
## İlgili Component'ler
|
|
410
|
+
|
|
411
|
+
- [`SocialLoginButtons`](../components/SocialLoginButtons.md) - Social login button component'i
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# useUserProfile
|
|
2
|
+
|
|
3
|
+
Hook for fetching user profile data for display in settings or profile screens.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Returns profile data based on auth state
|
|
8
|
+
- Generates anonymous names for anonymous users
|
|
9
|
+
- Memoized for performance
|
|
10
|
+
- Type-safe profile data
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { useUserProfile } from '@umituz/react-native-auth';
|
|
16
|
+
|
|
17
|
+
function ProfileHeader() {
|
|
18
|
+
const profile = useUserProfile({
|
|
19
|
+
accountRoute: '/account',
|
|
20
|
+
anonymousDisplayName: 'Guest User',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (!profile) {
|
|
24
|
+
return <LoadingSpinner />;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<View>
|
|
29
|
+
<Avatar source={{ uri: profile.avatarUrl }} />
|
|
30
|
+
<Text>{profile.displayName}</Text>
|
|
31
|
+
{profile.isAnonymous && <Text>Guest</Text>}
|
|
32
|
+
</View>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
### Parameters
|
|
40
|
+
|
|
41
|
+
| Param | Type | Default | Description |
|
|
42
|
+
|-------|------|---------|-------------|
|
|
43
|
+
| `anonymousDisplayName` | `string` | `undefined` | Default name for anonymous users |
|
|
44
|
+
| `accountRoute` | `string` | `undefined` | Account settings route |
|
|
45
|
+
| `anonymousNameConfig` | `AnonymousNameConfig` | `undefined` | Anonymous name generation config |
|
|
46
|
+
|
|
47
|
+
### Return Value
|
|
48
|
+
|
|
49
|
+
`UserProfileData | undefined` - `undefined` if no user, otherwise:
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Description |
|
|
52
|
+
|------|------|-------------|
|
|
53
|
+
| `displayName` | `string` | User's display name |
|
|
54
|
+
| `userId` | `string` | User ID |
|
|
55
|
+
| `isAnonymous` | `boolean` | Is anonymous user |
|
|
56
|
+
| `avatarUrl` | `string \| undefined` | Profile photo URL |
|
|
57
|
+
| `accountSettingsRoute` | `string \| undefined` | Account settings route |
|
|
58
|
+
|
|
59
|
+
## Examples
|
|
60
|
+
|
|
61
|
+
### Simple Profile Header
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
function ProfileHeader() {
|
|
65
|
+
const profile = useUserProfile();
|
|
66
|
+
|
|
67
|
+
if (!profile) return null;
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<View style={styles.header}>
|
|
71
|
+
{profile.avatarUrl ? (
|
|
72
|
+
<Image source={{ uri: profile.avatarUrl }} style={styles.avatar} />
|
|
73
|
+
) : (
|
|
74
|
+
<View style={styles.placeholderAvatar}>
|
|
75
|
+
<Text>{profile.displayName?.[0]}</Text>
|
|
76
|
+
</View>
|
|
77
|
+
)}
|
|
78
|
+
<View>
|
|
79
|
+
<Text style={styles.name}>{profile.displayName}</Text>
|
|
80
|
+
{profile.isAnonymous && (
|
|
81
|
+
<Badge style={styles.badge}>Guest</Badge>
|
|
82
|
+
)}
|
|
83
|
+
</View>
|
|
84
|
+
</View>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Profile Settings Link
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
function SettingsLink() {
|
|
93
|
+
const profile = useUserProfile({
|
|
94
|
+
accountRoute: '/settings/account',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
if (!profile || profile.isAnonymous) {
|
|
98
|
+
return null; // Don't show for anonymous users
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<TouchableOpacity
|
|
103
|
+
onPress={() => navigation.navigate(profile.accountSettingsRoute)}
|
|
104
|
+
>
|
|
105
|
+
<Text>Account Settings</Text>
|
|
106
|
+
</TouchableOpacity>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Anonymous User with Custom Name
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
function UserProfileCard() {
|
|
115
|
+
const profile = useUserProfile({
|
|
116
|
+
anonymousDisplayName: 'Guest User',
|
|
117
|
+
anonymousNameConfig: {
|
|
118
|
+
prefix: 'User',
|
|
119
|
+
adjectiveCount: 1,
|
|
120
|
+
nounCount: 1,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (!profile) return <Skeleton />;
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<Card>
|
|
128
|
+
<Card.Title>{profile.displayName}</Card.Title>
|
|
129
|
+
{profile.isAnonymous && (
|
|
130
|
+
<Card.Description>
|
|
131
|
+
<Link href="/register">Create an account</Link> for more features
|
|
132
|
+
</Card.Description>
|
|
133
|
+
)}
|
|
134
|
+
</Card>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Navigation Integration
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
function ProfileTab() {
|
|
143
|
+
const profile = useUserProfile({
|
|
144
|
+
accountRoute: 'Account',
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const navigation = useNavigation();
|
|
148
|
+
|
|
149
|
+
const handleProfilePress = () => {
|
|
150
|
+
if (profile?.isAnonymous) {
|
|
151
|
+
navigation.navigate('Register');
|
|
152
|
+
} else if (profile?.accountSettingsRoute) {
|
|
153
|
+
navigation.navigate(profile.accountSettingsRoute);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<TouchableOpacity onPress={handleProfilePress}>
|
|
159
|
+
<Text>{profile?.displayName || 'Profile'}</Text>
|
|
160
|
+
</TouchableOpacity>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Conditional Content Based on Auth
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
function WelcomeBanner() {
|
|
169
|
+
const profile = useUserProfile();
|
|
170
|
+
|
|
171
|
+
if (!profile) return <LoadingBanner />;
|
|
172
|
+
|
|
173
|
+
if (profile.isAnonymous) {
|
|
174
|
+
return (
|
|
175
|
+
<Banner>
|
|
176
|
+
<Text>Welcome, {profile.displayName}!</Text>
|
|
177
|
+
<Button onPress={() => navigation.navigate('Register')}>
|
|
178
|
+
Create Account
|
|
179
|
+
</Button>
|
|
180
|
+
</Banner>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<Banner>
|
|
186
|
+
<Text>Welcome, {profile.displayName}!</Text>
|
|
187
|
+
<Text>Complete your profile to get the most out of the app.</Text>
|
|
188
|
+
</Banner>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Anonymous Name Generation
|
|
194
|
+
|
|
195
|
+
Anonymous users automatically get random names generated:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { generateAnonymousName } from '@umituz/react-native-auth';
|
|
199
|
+
|
|
200
|
+
// Default: "User_Witty_Badger_1234"
|
|
201
|
+
const name1 = generateAnonymousName('user-123');
|
|
202
|
+
|
|
203
|
+
// Custom config
|
|
204
|
+
const name2 = generateAnonymousName('user-123', {
|
|
205
|
+
prefix: 'Guest',
|
|
206
|
+
adjectiveCount: 1,
|
|
207
|
+
nounCount: 1,
|
|
208
|
+
});
|
|
209
|
+
// "Guest_Clever_Fox_1234"
|
|
210
|
+
|
|
211
|
+
// ID only
|
|
212
|
+
const name3 = generateAnonymousName('user-123', {
|
|
213
|
+
prefix: '',
|
|
214
|
+
adjectiveCount: 0,
|
|
215
|
+
nounCount: 0,
|
|
216
|
+
});
|
|
217
|
+
// "user-123"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Performance Notes
|
|
221
|
+
|
|
222
|
+
- Hook uses `useMemo` for performance
|
|
223
|
+
- Only recalculates when dependencies change
|
|
224
|
+
- Automatically updates on user sign-in/sign-out
|
|
225
|
+
|
|
226
|
+
## Related Hooks
|
|
227
|
+
|
|
228
|
+
- [`useAuth`](./useAuth.md) - Main auth state management
|
|
229
|
+
- [`useProfileUpdate`](./useProfileUpdate.md) - Profile updates
|
|
230
|
+
- [`useProfileEdit`](./useProfileEdit.md) - Profile editing form
|