@umituz/react-native-auth 2.7.2 → 2.7.5

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 (44) hide show
  1. package/package.json +33 -9
  2. package/src/application/ports/IAuthRepository.ts +11 -0
  3. package/src/infrastructure/adapters/StorageProviderAdapter.ts +26 -10
  4. package/src/infrastructure/adapters/UIProviderAdapter.ts +20 -9
  5. package/src/infrastructure/providers/FirebaseAuthProvider.ts +3 -2
  6. package/src/infrastructure/repositories/AuthRepository.ts +91 -0
  7. package/src/infrastructure/services/AuthPackage.ts +14 -6
  8. package/src/infrastructure/services/AuthService.ts +67 -119
  9. package/src/infrastructure/services/GuestModeService.ts +1 -6
  10. package/src/infrastructure/utils/AuthValidation.ts +15 -14
  11. package/src/infrastructure/utils/auth-tracker.util.ts +28 -0
  12. package/src/presentation/components/AccountActions.tsx +38 -50
  13. package/src/presentation/components/AuthBottomSheet.tsx +4 -4
  14. package/src/presentation/components/AuthDivider.tsx +0 -1
  15. package/src/presentation/components/AuthGradientBackground.tsx +1 -1
  16. package/src/presentation/components/AuthHeader.tsx +1 -1
  17. package/src/presentation/components/AuthLegalLinks.tsx +7 -8
  18. package/src/presentation/components/AuthLink.tsx +1 -1
  19. package/src/presentation/components/EditProfileActions.tsx +53 -0
  20. package/src/presentation/components/EditProfileAvatar.tsx +33 -0
  21. package/src/presentation/components/EditProfileForm.tsx +55 -0
  22. package/src/presentation/components/LoginForm.tsx +1 -1
  23. package/src/presentation/components/PasswordMatchIndicator.tsx +6 -14
  24. package/src/presentation/components/PasswordStrengthIndicator.tsx +11 -17
  25. package/src/presentation/components/ProfileBenefitsList.tsx +47 -0
  26. package/src/presentation/components/ProfileSection.tsx +20 -85
  27. package/src/presentation/components/RegisterForm.tsx +6 -6
  28. package/src/presentation/components/SocialLoginButtons.tsx +11 -15
  29. package/src/presentation/hooks/mutations/useAuthMutations.ts +50 -0
  30. package/src/presentation/hooks/useAccountManagement.ts +2 -0
  31. package/src/presentation/hooks/useAuthActions.ts +19 -35
  32. package/src/presentation/hooks/useAuthState.ts +4 -1
  33. package/src/presentation/hooks/useLoginForm.ts +6 -8
  34. package/src/presentation/hooks/useProfileUpdate.ts +7 -7
  35. package/src/presentation/hooks/useRegisterForm.ts +16 -17
  36. package/src/presentation/hooks/useUserProfile.ts +3 -3
  37. package/src/presentation/navigation/AuthNavigator.tsx +10 -6
  38. package/src/presentation/screens/AccountScreen.tsx +9 -1
  39. package/src/presentation/screens/EditProfileScreen.tsx +40 -185
  40. package/src/presentation/screens/LoginScreen.tsx +4 -6
  41. package/src/presentation/screens/RegisterScreen.tsx +4 -6
  42. package/src/presentation/stores/authModalStore.ts +2 -1
  43. package/src/types/external.d.ts +31 -45
  44. package/src/infrastructure/services/AuthCoreService.ts +0 -138
@@ -6,7 +6,7 @@
6
6
  import React from "react";
7
7
  import { View, StyleSheet, Linking } from "react-native";
8
8
  import { AtomicButton, AtomicText } from "@umituz/react-native-design-system";
9
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
9
+
10
10
  import { useLocalization } from "@umituz/react-native-localization";
11
11
 
12
12
  export interface AuthLegalLinksProps {
@@ -39,22 +39,21 @@ export const AuthLegalLinks: React.FC<AuthLegalLinksProps> = ({
39
39
  onPrivacyPress,
40
40
  prefixText,
41
41
  }) => {
42
- const tokens = useAppDesignTokens();
43
42
  const { t } = useLocalization();
44
43
 
45
- const handleTermsPress = async () => {
44
+ const handleTermsPress = () => {
46
45
  if (onTermsPress) {
47
46
  onTermsPress();
48
47
  } else if (termsUrl) {
49
- await Linking.openURL(termsUrl);
48
+ void Linking.openURL(termsUrl);
50
49
  }
51
50
  };
52
51
 
53
- const handlePrivacyPress = async () => {
52
+ const handlePrivacyPress = () => {
54
53
  if (onPrivacyPress) {
55
54
  onPrivacyPress();
56
55
  } else if (privacyUrl) {
57
- await Linking.openURL(privacyUrl);
56
+ void Linking.openURL(privacyUrl);
58
57
  }
59
58
  };
60
59
 
@@ -84,7 +83,7 @@ export const AuthLegalLinks: React.FC<AuthLegalLinksProps> = ({
84
83
  style={styles.linkButton}
85
84
  >
86
85
  <AtomicText type="bodySmall" color="primary">
87
- {t("auth.termsOfService") || "Terms of Service"}
86
+ {t("auth.termsOfService")}
88
87
  </AtomicText>
89
88
  </AtomicButton>
90
89
  )}
@@ -100,7 +99,7 @@ export const AuthLegalLinks: React.FC<AuthLegalLinksProps> = ({
100
99
  style={styles.linkButton}
101
100
  >
102
101
  <AtomicText type="bodySmall" color="primary">
103
- {t("auth.privacyPolicy") || "Privacy Policy"}
102
+ {t("auth.privacyPolicy")}
104
103
  </AtomicText>
105
104
  </AtomicButton>
106
105
  )}
@@ -35,7 +35,7 @@ export const AuthLink: React.FC<AuthLinkProps> = ({
35
35
  variant="text"
36
36
  onPress={onPress}
37
37
  disabled={disabled}
38
- style={{ paddingHorizontal: tokens.spacing.xxs }}
38
+ style={{ paddingHorizontal: tokens.spacing.xs }}
39
39
  >
40
40
  {linkText}
41
41
  </AtomicButton>
@@ -0,0 +1,53 @@
1
+ import React from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { AtomicButton } from "@umituz/react-native-design-system";
4
+
5
+ export interface EditProfileActionsProps {
6
+ isSaving?: boolean;
7
+ onSave: () => void;
8
+ onCancel?: () => void;
9
+ labels: {
10
+ saveButton: string;
11
+ cancelButton: string;
12
+ };
13
+ }
14
+
15
+ export const EditProfileActions: React.FC<EditProfileActionsProps> = ({
16
+ isSaving,
17
+ onSave,
18
+ onCancel,
19
+ labels,
20
+ }) => {
21
+ return (
22
+ <View style={styles.actions}>
23
+ <AtomicButton
24
+ variant="primary"
25
+ onPress={onSave}
26
+ disabled={isSaving}
27
+ fullWidth
28
+ >
29
+ {labels.saveButton}
30
+ </AtomicButton>
31
+
32
+ {onCancel && (
33
+ <AtomicButton
34
+ variant="outline"
35
+ onPress={onCancel}
36
+ disabled={isSaving}
37
+ fullWidth
38
+ >
39
+ {labels.cancelButton}
40
+ </AtomicButton>
41
+ )}
42
+ </View>
43
+ );
44
+
45
+ };
46
+
47
+ const styles = StyleSheet.create({
48
+ actions: {
49
+ marginTop: 32,
50
+ gap: 12,
51
+ },
52
+ });
53
+
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { AtomicAvatar } from "@umituz/react-native-design-system";
4
+
5
+ export interface EditProfileAvatarProps {
6
+ photoURL: string | null;
7
+ displayName: string;
8
+ onPress?: () => void;
9
+ }
10
+
11
+ export const EditProfileAvatar: React.FC<EditProfileAvatarProps> = ({
12
+ photoURL,
13
+ displayName,
14
+ }) => {
15
+ return (
16
+ <View style={styles.avatarContainer}>
17
+ <AtomicAvatar
18
+ source={photoURL ? { uri: photoURL } : undefined}
19
+ name={displayName}
20
+ size="xl"
21
+ />
22
+
23
+ </View>
24
+ );
25
+ };
26
+
27
+ const styles = StyleSheet.create({
28
+ avatarContainer: {
29
+ alignItems: "center",
30
+ marginBottom: 24,
31
+ },
32
+ });
33
+
@@ -0,0 +1,55 @@
1
+ import React from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { AtomicInput } from "@umituz/react-native-design-system";
4
+
5
+ export interface EditProfileFormProps {
6
+ displayName: string;
7
+ email: string;
8
+ onChangeDisplayName: (value: string) => void;
9
+ onChangeEmail: (value: string) => void;
10
+ labels: {
11
+ displayNameLabel: string;
12
+ displayNamePlaceholder: string;
13
+ emailLabel: string;
14
+ emailPlaceholder: string;
15
+ };
16
+ }
17
+
18
+ export const EditProfileForm: React.FC<EditProfileFormProps> = ({
19
+ displayName,
20
+ email,
21
+ onChangeDisplayName,
22
+ onChangeEmail,
23
+ labels,
24
+ }) => {
25
+ return (
26
+ <View>
27
+ <View style={styles.field}>
28
+ <AtomicInput
29
+ label={labels.displayNameLabel}
30
+ value={displayName}
31
+ onChangeText={onChangeDisplayName}
32
+ placeholder={labels.displayNamePlaceholder}
33
+ />
34
+ </View>
35
+
36
+ <View style={styles.field}>
37
+ <AtomicInput
38
+ label={labels.emailLabel}
39
+ value={email}
40
+ onChangeText={onChangeEmail}
41
+ placeholder={labels.emailPlaceholder}
42
+ keyboardType="email-address"
43
+ autoCapitalize="none"
44
+ />
45
+ </View>
46
+ </View>
47
+ );
48
+ };
49
+
50
+ const styles = StyleSheet.create({
51
+ field: {
52
+ marginBottom: 20,
53
+ },
54
+ });
55
+
@@ -64,7 +64,7 @@ export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) =>
64
64
  <View style={styles.buttonContainer}>
65
65
  <AtomicButton
66
66
  variant="primary"
67
- onPress={handleSignIn}
67
+ onPress={() => { void handleSignIn(); }}
68
68
  disabled={loading || !email.trim() || !password.trim()}
69
69
  fullWidth
70
70
  style={styles.signInButton}
@@ -1,11 +1,6 @@
1
- /**
2
- * Password Match Indicator Component
3
- * Shows whether passwords match
4
- */
5
-
6
1
  import React from "react";
7
- import { View, Text, StyleSheet } from "react-native";
8
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
9
4
  import { useLocalization } from "@umituz/react-native-localization";
10
5
 
11
6
  export interface PasswordMatchIndicatorProps {
@@ -20,13 +15,13 @@ export const PasswordMatchIndicator: React.FC<PasswordMatchIndicatorProps> = ({
20
15
 
21
16
  const color = isMatch ? tokens.colors.success : tokens.colors.error;
22
17
  const text = isMatch
23
- ? t("auth.passwordsMatch", { defaultValue: "Passwords match" })
24
- : t("auth.passwordsDontMatch", { defaultValue: "Passwords don't match" });
18
+ ? t("auth.passwordsMatch")
19
+ : t("auth.passwordsDontMatch");
25
20
 
26
21
  return (
27
22
  <View style={styles.container}>
28
23
  <View style={[styles.dot, { backgroundColor: color }]} />
29
- <Text style={[styles.text, { color }]}>{text}</Text>
24
+ <AtomicText type="labelSmall" style={{ color }}>{text}</AtomicText>
30
25
  </View>
31
26
  );
32
27
  };
@@ -43,8 +38,5 @@ const styles = StyleSheet.create({
43
38
  height: 6,
44
39
  borderRadius: 3,
45
40
  },
46
- text: {
47
- fontSize: 12,
48
- fontWeight: "500",
49
- },
50
41
  });
42
+
@@ -1,11 +1,7 @@
1
- /**
2
- * Password Strength Indicator Component
3
- * Shows password requirements with visual feedback
4
- */
5
-
6
1
  import React from "react";
7
- import { View, Text, StyleSheet } from "react-native";
8
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
4
+ import { useLocalization } from "@umituz/react-native-localization";
9
5
  import type { PasswordRequirements } from "../../infrastructure/utils/AuthValidation";
10
6
 
11
7
  export interface PasswordStrengthIndicatorProps {
@@ -31,7 +27,7 @@ const RequirementDot: React.FC<RequirementDotProps> = ({
31
27
  return (
32
28
  <View style={styles.requirement}>
33
29
  <View style={[styles.dot, { backgroundColor: color }]} />
34
- <Text style={[styles.label, { color }]}>{label}</Text>
30
+ <AtomicText type="labelSmall" style={{ color }}>{label}</AtomicText>
35
31
  </View>
36
32
  );
37
33
  };
@@ -40,15 +36,16 @@ export const PasswordStrengthIndicator: React.FC<
40
36
  PasswordStrengthIndicatorProps
41
37
  > = ({ requirements, showLabels = true }) => {
42
38
  const tokens = useAppDesignTokens();
39
+ const { t } = useLocalization();
43
40
  const successColor = tokens.colors.success;
44
41
  const pendingColor = tokens.colors.textTertiary;
45
42
 
46
43
  const items = [
47
- { key: "minLength", label: "8+", isValid: requirements.hasMinLength },
48
- { key: "uppercase", label: "A-Z", isValid: requirements.hasUppercase },
49
- { key: "lowercase", label: "a-z", isValid: requirements.hasLowercase },
50
- { key: "number", label: "0-9", isValid: requirements.hasNumber },
51
- { key: "special", label: "!@#", isValid: requirements.hasSpecialChar },
44
+ { key: "minLength", label: t("auth.passwordReq.minLength"), isValid: requirements.hasMinLength },
45
+ { key: "uppercase", label: t("auth.passwordReq.uppercase"), isValid: requirements.hasUppercase },
46
+ { key: "lowercase", label: t("auth.passwordReq.lowercase"), isValid: requirements.hasLowercase },
47
+ { key: "number", label: t("auth.passwordReq.number"), isValid: requirements.hasNumber },
48
+ { key: "special", label: t("auth.passwordReq.special"), isValid: requirements.hasSpecialChar },
52
49
  ];
53
50
 
54
51
  if (!showLabels) {
@@ -111,8 +108,5 @@ const styles = StyleSheet.create({
111
108
  height: 8,
112
109
  borderRadius: 4,
113
110
  },
114
- label: {
115
- fontSize: 11,
116
- fontWeight: "500",
117
- },
118
111
  });
112
+
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Profile Benefits List Component
3
+ * Shows a list of benefits for anonymous users
4
+ */
5
+
6
+ import React from "react";
7
+ import { View, StyleSheet } from "react-native";
8
+ import { AtomicText, AtomicIcon } from "@umituz/react-native-design-system";
9
+
10
+ export interface ProfileBenefitsListProps {
11
+ benefits: string[];
12
+ }
13
+
14
+ export const ProfileBenefitsList: React.FC<ProfileBenefitsListProps> = ({ benefits }) => {
15
+
16
+ return (
17
+ <View style={styles.benefitsContainer}>
18
+ {benefits.map((benefit, index) => (
19
+ <View key={index} style={styles.benefitItem}>
20
+ <AtomicIcon name="check" size="sm" color="primary" />
21
+ <AtomicText
22
+ type="bodyMedium"
23
+ color="secondary"
24
+ style={styles.benefitText}
25
+ >
26
+ {benefit}
27
+ </AtomicText>
28
+ </View>
29
+ ))}
30
+ </View>
31
+ );
32
+ };
33
+
34
+ const styles = StyleSheet.create({
35
+ benefitsContainer: {
36
+ marginBottom: 16,
37
+ gap: 8,
38
+ },
39
+ benefitItem: {
40
+ flexDirection: "row",
41
+ alignItems: "flex-start",
42
+ gap: 8,
43
+ },
44
+ benefitText: {
45
+ flex: 1,
46
+ },
47
+ });
@@ -1,21 +1,20 @@
1
1
  /**
2
2
  * Profile Section Component
3
3
  * Generic user profile section for settings screens
4
- * Shows user info, sign in CTA for anonymous, or account navigation for signed in users
5
4
  */
6
5
 
7
6
  import React from "react";
8
- import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
9
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
10
- import { Avatar } from "@umituz/react-native-design-system";
7
+ import { View, TouchableOpacity, StyleSheet } from "react-native";
8
+ import { useAppDesignTokens, AtomicText, AtomicIcon, Avatar } from "@umituz/react-native-design-system";
9
+ import { ProfileBenefitsList } from "./ProfileBenefitsList";
11
10
 
12
11
  export interface ProfileSectionConfig {
13
- displayName: string;
12
+ displayName?: string;
14
13
  userId?: string;
15
14
  isAnonymous: boolean;
16
15
  avatarUrl?: string;
17
16
  accountSettingsRoute?: string;
18
- benefits?: string[]; // App-specific benefits for anonymous users to encourage sign-in
17
+ benefits?: string[];
19
18
  }
20
19
 
21
20
  export interface ProfileSectionProps {
@@ -43,8 +42,6 @@ export const ProfileSection: React.FC<ProfileSectionProps> = ({
43
42
  }
44
43
  };
45
44
 
46
-
47
-
48
45
  return (
49
46
  <TouchableOpacity
50
47
  style={[styles.container, { backgroundColor: tokens.colors.surface }]}
@@ -53,7 +50,6 @@ export const ProfileSection: React.FC<ProfileSectionProps> = ({
53
50
  disabled={!onPress && !onSignIn}
54
51
  >
55
52
  <View style={styles.content}>
56
- {/* Avatar */}
57
53
  <View style={styles.avatarContainer}>
58
54
  <Avatar
59
55
  uri={profile.avatarUrl}
@@ -63,72 +59,43 @@ export const ProfileSection: React.FC<ProfileSectionProps> = ({
63
59
  />
64
60
  </View>
65
61
 
66
- {/* User Info */}
67
62
  <View style={styles.info}>
68
- <Text
69
- style={[styles.displayName, { color: tokens.colors.textPrimary }]}
63
+ <AtomicText
64
+ type="titleMedium"
65
+ color="textPrimary"
70
66
  numberOfLines={1}
67
+ style={styles.displayName}
71
68
  >
72
69
  {profile.displayName}
73
- </Text>
70
+ </AtomicText>
74
71
  {profile.userId && (
75
- <Text
76
- style={[styles.userId, { color: tokens.colors.textSecondary }]}
72
+ <AtomicText
73
+ type="bodySmall"
74
+ color="secondary"
77
75
  numberOfLines={1}
78
76
  >
79
77
  {profile.userId}
80
- </Text>
78
+ </AtomicText>
81
79
  )}
82
80
  </View>
83
81
 
84
- {/* Action Icon - only for authenticated users */}
85
82
  {onPress && !profile.isAnonymous && (
86
- <Text style={[styles.chevron, { color: tokens.colors.textTertiary }]}>
87
-
88
- </Text>
83
+ <AtomicIcon name="chevron-right" size="sm" color="secondary" />
89
84
  )}
90
85
  </View>
91
86
 
92
- {/* Sign In CTA for Anonymous Users */}
93
87
  {profile.isAnonymous && onSignIn && (
94
- <View
95
- style={[
96
- styles.ctaContainer,
97
- { borderTopColor: tokens.colors.border },
98
- ]}
99
- >
100
- {/* Benefits List */}
101
- {profile.benefits && profile.benefits.length > 0 && (
102
- <View style={styles.benefitsContainer}>
103
- {profile.benefits.map((benefit, index) => (
104
- <View key={index} style={styles.benefitItem}>
105
- <Text style={[styles.benefitBullet, { color: tokens.colors.primary }]}>
106
-
107
- </Text>
108
- <Text style={[styles.benefitText, { color: tokens.colors.textSecondary }]}>
109
- {benefit}
110
- </Text>
111
- </View>
112
- ))}
113
- </View>
114
- )}
88
+ <View style={[styles.ctaContainer, { borderTopColor: tokens.colors.border }]}>
89
+ {profile.benefits && <ProfileBenefitsList benefits={profile.benefits} />}
115
90
 
116
91
  <TouchableOpacity
117
- style={[
118
- styles.ctaButton,
119
- { backgroundColor: tokens.colors.primary },
120
- ]}
92
+ style={[styles.ctaButton, { backgroundColor: tokens.colors.primary }]}
121
93
  onPress={onSignIn}
122
94
  activeOpacity={0.8}
123
95
  >
124
- <Text
125
- style={[
126
- styles.ctaText,
127
- { color: tokens.colors.onPrimary },
128
- ]}
129
- >
96
+ <AtomicText type="labelLarge" style={{ color: tokens.colors.onPrimary }}>
130
97
  {signInText}
131
- </Text>
98
+ </AtomicText>
132
99
  </TouchableOpacity>
133
100
  </View>
134
101
  )}
@@ -153,48 +120,16 @@ const styles = StyleSheet.create({
153
120
  flex: 1,
154
121
  },
155
122
  displayName: {
156
- fontSize: 18,
157
- fontWeight: "600",
158
123
  marginBottom: 2,
159
124
  },
160
- userId: {
161
- fontSize: 13,
162
- },
163
- chevron: {
164
- fontSize: 24,
165
- fontWeight: "400",
166
- },
167
125
  ctaContainer: {
168
126
  marginTop: 12,
169
127
  paddingTop: 12,
170
128
  borderTopWidth: 1,
171
129
  },
172
- benefitsContainer: {
173
- marginBottom: 16,
174
- gap: 8,
175
- },
176
- benefitItem: {
177
- flexDirection: "row",
178
- alignItems: "flex-start",
179
- gap: 8,
180
- },
181
- benefitBullet: {
182
- fontSize: 16,
183
- fontWeight: "600",
184
- marginTop: 2,
185
- },
186
- benefitText: {
187
- flex: 1,
188
- fontSize: 14,
189
- lineHeight: 20,
190
- },
191
130
  ctaButton: {
192
131
  paddingVertical: 12,
193
132
  borderRadius: 8,
194
133
  alignItems: "center",
195
134
  },
196
- ctaText: {
197
- fontSize: 15,
198
- fontWeight: "600",
199
- },
200
135
  });
@@ -51,11 +51,11 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
51
51
  <>
52
52
  <View style={styles.inputContainer}>
53
53
  <AtomicInput
54
- label={t("auth.displayName") || "Full Name"}
54
+ label={t("auth.displayName")}
55
55
  value={displayName}
56
56
  onChangeText={handleDisplayNameChange}
57
57
  placeholder={
58
- t("auth.displayNamePlaceholder") || "Enter your full name"
58
+ t("auth.displayNamePlaceholder")
59
59
  }
60
60
  autoCapitalize="words"
61
61
  disabled={loading}
@@ -97,11 +97,11 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
97
97
 
98
98
  <View style={styles.inputContainer}>
99
99
  <AtomicInput
100
- label={t("auth.confirmPassword") || "Confirm Password"}
100
+ label={t("auth.confirmPassword")}
101
101
  value={confirmPassword}
102
102
  onChangeText={handleConfirmPasswordChange}
103
103
  placeholder={
104
- t("auth.confirmPasswordPlaceholder") || "Confirm your password"
104
+ t("auth.confirmPasswordPlaceholder")
105
105
  }
106
106
  secureTextEntry
107
107
  autoCapitalize="none"
@@ -119,7 +119,7 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
119
119
  <View style={styles.buttonContainer}>
120
120
  <AtomicButton
121
121
  variant="primary"
122
- onPress={handleSignUp}
122
+ onPress={() => { void handleSignUp(); }}
123
123
  disabled={
124
124
  loading ||
125
125
  !email.trim() ||
@@ -145,7 +145,7 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
145
145
  privacyUrl={privacyUrl}
146
146
  onTermsPress={onTermsPress}
147
147
  onPrivacyPress={onPrivacyPress}
148
- prefixText={t("auth.bySigningUp") || "By signing up, you agree to our"}
148
+ prefixText={t("auth.bySigningUp")}
149
149
  />
150
150
  </>
151
151
  );
@@ -1,16 +1,14 @@
1
1
  import React from "react";
2
2
  import {
3
3
  View,
4
- Text,
5
4
  TouchableOpacity,
6
5
  StyleSheet,
7
6
  Platform,
8
7
  ActivityIndicator,
9
8
  } from "react-native";
10
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
9
+ import { useAppDesignTokens, AtomicText, AtomicIcon } from "@umituz/react-native-design-system";
11
10
  import { useLocalization } from "@umituz/react-native-localization";
12
11
  import type { SocialAuthProvider } from "../../domain/value-objects/AuthConfig";
13
- import { AppleIconSvg, GoogleIconSvg } from "./icons";
14
12
 
15
13
  export interface SocialLoginButtonsProps {
16
14
  /** Enabled providers to display */
@@ -49,9 +47,9 @@ export const SocialLoginButtons: React.FC<SocialLoginButtonsProps> = ({
49
47
  <View style={styles.container}>
50
48
  <View style={styles.dividerContainer}>
51
49
  <View style={[styles.divider, { backgroundColor: tokens.colors.border }]} />
52
- <Text style={[styles.dividerText, { color: tokens.colors.textSecondary }]}>
50
+ <AtomicText type="bodySmall" color="secondary" style={styles.dividerText}>
53
51
  {t("auth.orContinueWith")}
54
- </Text>
52
+ </AtomicText>
55
53
  <View style={[styles.divider, { backgroundColor: tokens.colors.border }]} />
56
54
  </View>
57
55
 
@@ -71,10 +69,10 @@ export const SocialLoginButtons: React.FC<SocialLoginButtonsProps> = ({
71
69
  <ActivityIndicator size="small" color={tokens.colors.textPrimary} />
72
70
  ) : (
73
71
  <>
74
- <GoogleIconSvg size={20} />
75
- <Text style={[styles.buttonText, { color: tokens.colors.textPrimary }]}>
76
- Google
77
- </Text>
72
+ <AtomicIcon name="google" size="sm" />
73
+ <AtomicText style={[styles.buttonText, { color: tokens.colors.textPrimary }]}>
74
+ {t("auth.google")}
75
+ </AtomicText>
78
76
  </>
79
77
  )}
80
78
  </TouchableOpacity>
@@ -95,10 +93,10 @@ export const SocialLoginButtons: React.FC<SocialLoginButtonsProps> = ({
95
93
  <ActivityIndicator size="small" color={tokens.colors.textPrimary} />
96
94
  ) : (
97
95
  <>
98
- <AppleIconSvg size={20} color={tokens.colors.textPrimary} />
99
- <Text style={[styles.buttonText, { color: tokens.colors.textPrimary }]}>
100
- Apple
101
- </Text>
96
+ <AtomicIcon name="apple" size="sm" color="primary" />
97
+ <AtomicText style={[styles.buttonText, { color: tokens.colors.textPrimary }]}>
98
+ {t("auth.apple")}
99
+ </AtomicText>
102
100
  </>
103
101
  )}
104
102
  </TouchableOpacity>
@@ -108,7 +106,6 @@ export const SocialLoginButtons: React.FC<SocialLoginButtonsProps> = ({
108
106
  );
109
107
  };
110
108
 
111
-
112
109
  const styles = StyleSheet.create({
113
110
  container: {
114
111
  marginTop: 24,
@@ -124,7 +121,6 @@ const styles = StyleSheet.create({
124
121
  },
125
122
  dividerText: {
126
123
  marginHorizontal: 16,
127
- fontSize: 14,
128
124
  },
129
125
  buttonsContainer: {
130
126
  flexDirection: "row",