@umituz/react-native-auth 2.5.7 → 2.5.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-auth",
3
- "version": "2.5.7",
3
+ "version": "2.5.10",
4
4
  "description": "Authentication service for React Native apps - Secure, type-safe, and production-ready. Provider-agnostic design with dependency injection, configurable validation, and comprehensive error handling.",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Anonymous User Name Generator
3
+ * Generates friendly, random names for anonymous users
4
+ * Fully generic - no app-specific content
5
+ */
6
+
7
+ const DEFAULT_NAMES = [
8
+ 'Alex',
9
+ 'Sam',
10
+ 'Jordan',
11
+ 'Taylor',
12
+ 'Morgan',
13
+ 'Casey',
14
+ 'Riley',
15
+ 'Avery',
16
+ 'Quinn',
17
+ 'Blake',
18
+ 'Charlie',
19
+ 'Dakota',
20
+ 'Eden',
21
+ 'Finley',
22
+ 'Harper',
23
+ 'Sage',
24
+ 'River',
25
+ 'Skylar',
26
+ 'Rowan',
27
+ 'Phoenix',
28
+ ];
29
+
30
+ export interface GuestNameConfig {
31
+ names?: string[];
32
+ prefixes?: string[];
33
+ usePrefixes?: boolean;
34
+ }
35
+
36
+ /**
37
+ * Generate a random guest name
38
+ * Uses userId to ensure consistency per user
39
+ */
40
+ export function generateGuestName(
41
+ userId?: string,
42
+ config?: GuestNameConfig,
43
+ ): string {
44
+ const names = config?.names || DEFAULT_NAMES;
45
+ const prefixes = config?.prefixes || [];
46
+ const usePrefixes = config?.usePrefixes ?? false;
47
+
48
+ if (!userId) {
49
+ const randomIndex = Math.floor(Math.random() * names.length);
50
+ return names[randomIndex];
51
+ }
52
+
53
+ // Use userId hash for consistent name per user
54
+ const hash = userId.split('').reduce((acc, char) => {
55
+ return ((acc << 5) - acc + char.charCodeAt(0)) | 0;
56
+ }, 0);
57
+
58
+ const nameIndex = Math.abs(hash) % names.length;
59
+ const name = names[nameIndex];
60
+
61
+ if (usePrefixes && prefixes.length > 0) {
62
+ const prefixIndex = Math.abs(hash >> 8) % prefixes.length;
63
+ return `${prefixes[prefixIndex]} ${name}`;
64
+ }
65
+
66
+ return name;
67
+ }
68
+
69
+ /**
70
+ * Get guest display name with fallback
71
+ */
72
+ export function getGuestDisplayName(
73
+ userId?: string,
74
+ fallback = 'Guest',
75
+ config?: GuestNameConfig,
76
+ ): string {
77
+ if (!userId) return fallback;
78
+ return generateGuestName(userId, config);
79
+ }
package/src/index.ts CHANGED
@@ -113,6 +113,10 @@ export type { UseProfileEditReturn, ProfileEditFormState } from './presentation/
113
113
 
114
114
  export type { UserProfile, UpdateProfileParams } from './domain/entities/UserProfile';
115
115
 
116
+ // Domain Utils - Guest Names
117
+ export { generateGuestName, getGuestDisplayName } from './domain/utils/guestNameGenerator';
118
+ export type { GuestNameConfig } from './domain/utils/guestNameGenerator';
119
+
116
120
  // =============================================================================
117
121
  // PRESENTATION LAYER - Screens & Navigation
118
122
  // =============================================================================
@@ -13,7 +13,6 @@ import {
13
13
  } from "@gorhom/bottom-sheet";
14
14
  import { useAppDesignTokens } from "@umituz/react-native-design-system-theme";
15
15
  import { useLocalization } from "@umituz/react-native-localization";
16
- import { X } from "lucide-react-native";
17
16
  import { useAuthModalStore } from "../stores/authModalStore";
18
17
  import { useAuth } from "../hooks/useAuth";
19
18
  import { LoginForm } from "./LoginForm";
@@ -105,7 +104,9 @@ export const AuthBottomSheet: React.FC<AuthBottomSheetProps> = ({
105
104
  onPress={handleClose}
106
105
  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
107
106
  >
108
- <X size={24} color={tokens.colors.textSecondary} />
107
+ <Text style={[styles.closeIcon, { color: tokens.colors.textSecondary }]}>
108
+
109
+ </Text>
109
110
  </TouchableOpacity>
110
111
 
111
112
  <View style={styles.header}>
@@ -156,6 +157,10 @@ const styles = StyleSheet.create({
156
157
  padding: 8,
157
158
  zIndex: 10,
158
159
  },
160
+ closeIcon: {
161
+ fontSize: 24,
162
+ fontWeight: "400",
163
+ },
159
164
  header: {
160
165
  alignItems: "center",
161
166
  marginBottom: 24,
@@ -14,6 +14,7 @@ export interface ProfileSectionConfig {
14
14
  isAnonymous: boolean;
15
15
  avatarUrl?: string;
16
16
  accountSettingsRoute?: string;
17
+ benefits?: string[]; // App-specific benefits for anonymous users to encourage sign-in
17
18
  }
18
19
 
19
20
  export interface ProfileSectionProps {
@@ -111,6 +112,22 @@ export const ProfileSection: React.FC<ProfileSectionProps> = ({
111
112
  { borderTopColor: tokens.colors.border },
112
113
  ]}
113
114
  >
115
+ {/* Benefits List */}
116
+ {profile.benefits && profile.benefits.length > 0 && (
117
+ <View style={styles.benefitsContainer}>
118
+ {profile.benefits.map((benefit, index) => (
119
+ <View key={index} style={styles.benefitItem}>
120
+ <Text style={[styles.benefitBullet, { color: tokens.colors.primary }]}>
121
+
122
+ </Text>
123
+ <Text style={[styles.benefitText, { color: tokens.colors.textSecondary }]}>
124
+ {benefit}
125
+ </Text>
126
+ </View>
127
+ ))}
128
+ </View>
129
+ )}
130
+
114
131
  <TouchableOpacity
115
132
  style={[
116
133
  styles.ctaButton,
@@ -176,6 +193,25 @@ const styles = StyleSheet.create({
176
193
  paddingTop: 12,
177
194
  borderTopWidth: 1,
178
195
  },
196
+ benefitsContainer: {
197
+ marginBottom: 16,
198
+ gap: 8,
199
+ },
200
+ benefitItem: {
201
+ flexDirection: "row",
202
+ alignItems: "flex-start",
203
+ gap: 8,
204
+ },
205
+ benefitBullet: {
206
+ fontSize: 16,
207
+ fontWeight: "600",
208
+ marginTop: 2,
209
+ },
210
+ benefitText: {
211
+ flex: 1,
212
+ fontSize: 14,
213
+ lineHeight: 20,
214
+ },
179
215
  ctaButton: {
180
216
  paddingVertical: 12,
181
217
  borderRadius: 8,
@@ -6,6 +6,7 @@
6
6
 
7
7
  import { useMemo } from "react";
8
8
  import { useAuth } from "./useAuth";
9
+ import { generateGuestName, type GuestNameConfig } from "../../domain/utils/guestNameGenerator";
9
10
 
10
11
  export interface UserProfileData {
11
12
  displayName: string;
@@ -16,9 +17,9 @@ export interface UserProfileData {
16
17
  }
17
18
 
18
19
  export interface UseUserProfileParams {
19
- anonymousDisplayName?: string;
20
20
  guestDisplayName?: string;
21
21
  accountRoute?: string;
22
+ guestNameConfig?: GuestNameConfig;
22
23
  }
23
24
 
24
25
  export const useUserProfile = (
@@ -26,9 +27,9 @@ export const useUserProfile = (
26
27
  ): UserProfileData | undefined => {
27
28
  const { user } = useAuth();
28
29
 
29
- const anonymousName = params?.anonymousDisplayName || "Anonymous User";
30
- const guestName = params?.guestDisplayName || "Guest User";
30
+ const guestName = params?.guestDisplayName || "Guest";
31
31
  const accountRoute = params?.accountRoute || "Account";
32
+ const nameConfig = params?.guestNameConfig;
32
33
 
33
34
  return useMemo(() => {
34
35
  if (!user) {
@@ -39,7 +40,7 @@ export const useUserProfile = (
39
40
 
40
41
  if (isAnonymous) {
41
42
  return {
42
- displayName: anonymousName,
43
+ displayName: generateGuestName(user.uid, nameConfig),
43
44
  userId: user.uid,
44
45
  isAnonymous: true,
45
46
  };
@@ -52,5 +53,5 @@ export const useUserProfile = (
52
53
  isAnonymous: false,
53
54
  avatarUrl: user.photoURL || undefined,
54
55
  };
55
- }, [user, anonymousName, guestName, accountRoute]);
56
+ }, [user, guestName, accountRoute, nameConfig]);
56
57
  };