@umituz/react-native-auth 3.6.44 → 3.6.45

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.
@@ -1,103 +1,79 @@
1
- /**
2
- * Auth Legal Links Component
3
- * Display Terms of Service and Privacy Policy links
4
- */
5
-
6
1
  import React from "react";
7
2
  import { View, StyleSheet, Linking } from "react-native";
8
- import { AtomicButton, AtomicText } from "@umituz/react-native-design-system";
3
+ import { AtomicText, AtomicButton, useAppDesignTokens } from "@umituz/react-native-design-system";
9
4
 
10
- import { useLocalization } from "@umituz/react-native-localization";
5
+ export interface AuthLegalLinksTranslations {
6
+ termsOfService: string;
7
+ privacyPolicy: string;
8
+ }
11
9
 
12
10
  export interface AuthLegalLinksProps {
13
- /**
14
- * Terms of Service URL
15
- */
11
+ translations: AuthLegalLinksTranslations;
16
12
  termsUrl?: string;
17
- /**
18
- * Privacy Policy URL
19
- */
20
13
  privacyUrl?: string;
21
- /**
22
- * Callback when Terms of Service is pressed
23
- */
24
14
  onTermsPress?: () => void;
25
- /**
26
- * Callback when Privacy Policy is pressed
27
- */
28
15
  onPrivacyPress?: () => void;
29
- /**
30
- * Custom text before links
31
- */
32
16
  prefixText?: string;
33
17
  }
34
18
 
35
19
  export const AuthLegalLinks: React.FC<AuthLegalLinksProps> = ({
20
+ translations,
36
21
  termsUrl,
37
22
  privacyUrl,
38
23
  onTermsPress,
39
24
  onPrivacyPress,
40
25
  prefixText,
41
26
  }) => {
42
- const { t } = useLocalization();
27
+ const tokens = useAppDesignTokens();
43
28
 
44
- const handleTermsPress = () => {
29
+ const handleTermsPress = async () => {
45
30
  if (onTermsPress) {
46
31
  onTermsPress();
47
32
  } else if (termsUrl) {
48
- void Linking.openURL(termsUrl);
33
+ await Linking.openURL(termsUrl);
49
34
  }
50
35
  };
51
36
 
52
- const handlePrivacyPress = () => {
37
+ const handlePrivacyPress = async () => {
53
38
  if (onPrivacyPress) {
54
39
  onPrivacyPress();
55
40
  } else if (privacyUrl) {
56
- void Linking.openURL(privacyUrl);
41
+ await Linking.openURL(privacyUrl);
57
42
  }
58
43
  };
59
44
 
60
- const hasTerms = termsUrl || onTermsPress;
61
- const hasPrivacy = privacyUrl || onPrivacyPress;
62
-
63
- if (!hasTerms && !hasPrivacy) {
45
+ if (!termsUrl && !privacyUrl && !onTermsPress && !onPrivacyPress) {
64
46
  return null;
65
47
  }
66
48
 
67
49
  return (
68
- <View style={styles.container}>
50
+ <View style={[styles.container, { marginTop: tokens.spacing.lg }]}>
69
51
  {prefixText && (
70
- <AtomicText
71
- type="bodySmall"
72
- color="textSecondary"
73
- style={styles.prefixText}
74
- >
52
+ <AtomicText type="bodySmall" color="textSecondary" style={styles.prefix}>
75
53
  {prefixText}
76
54
  </AtomicText>
77
55
  )}
78
- <View style={styles.linksContainer}>
79
- {hasTerms && (
56
+ <View style={styles.linksRow}>
57
+ {(termsUrl || onTermsPress) && (
80
58
  <AtomicButton
81
59
  variant="text"
82
60
  size="sm"
83
- onPress={handleTermsPress}
84
- style={styles.linkButton}
85
- title={t("auth.termsOfService")}
86
- />
61
+ onPress={() => { void handleTermsPress(); }}
62
+ >
63
+ {translations.termsOfService}
64
+ </AtomicButton>
87
65
  )}
88
- {hasTerms && hasPrivacy && (
89
- <AtomicText type="bodySmall" color="textSecondary" style={styles.separator}>
90
- {" • "}
91
- </AtomicText>
66
+ {(termsUrl || onTermsPress) && (privacyUrl || onPrivacyPress) && (
67
+ <AtomicText type="bodySmall" color="textSecondary"> & </AtomicText>
92
68
  )}
93
- {hasPrivacy && (
69
+ {(privacyUrl || onPrivacyPress) && (
94
70
  <AtomicButton
95
71
  variant="text"
96
72
  size="sm"
97
- onPress={handlePrivacyPress}
98
- style={styles.linkButton}
99
- title={t("auth.privacyPolicy")}
100
- />
73
+ onPress={() => { void handlePrivacyPress(); }}
74
+ >
75
+ {translations.privacyPolicy}
76
+ </AtomicButton>
101
77
  )}
102
78
  </View>
103
79
  </View>
@@ -106,35 +82,13 @@ export const AuthLegalLinks: React.FC<AuthLegalLinksProps> = ({
106
82
 
107
83
  const styles = StyleSheet.create({
108
84
  container: {
109
- marginTop: 16,
110
85
  alignItems: "center",
111
86
  },
112
- prefixText: {
113
- marginBottom: 8,
114
- textAlign: "center",
87
+ prefix: {
88
+ marginBottom: 4,
115
89
  },
116
- linksContainer: {
90
+ linksRow: {
117
91
  flexDirection: "row",
118
92
  alignItems: "center",
119
- justifyContent: "center",
120
- flexWrap: "wrap",
121
- },
122
- linkButton: {
123
- paddingHorizontal: 4,
124
- paddingVertical: 4,
125
- },
126
- separator: {
127
- marginHorizontal: 4,
128
93
  },
129
94
  });
130
-
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
@@ -1,24 +1,29 @@
1
- /**
2
- * Login Form Component
3
- * Single Responsibility: Render login form UI
4
- */
5
-
6
- import React, { useRef, useEffect } from "react";
1
+ import React, { useRef } from "react";
7
2
  import { StyleSheet, TextInput } from "react-native";
8
3
  import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system";
9
- import { useLocalization } from "@umituz/react-native-localization";
10
4
  import { useLoginForm } from "../hooks/useLoginForm";
11
5
  import { AuthErrorDisplay } from "./AuthErrorDisplay";
12
6
  import { AuthLink } from "./AuthLink";
13
7
 
14
- declare const __DEV__: boolean;
8
+ export interface LoginFormTranslations {
9
+ email: string;
10
+ emailPlaceholder: string;
11
+ password: string;
12
+ passwordPlaceholder: string;
13
+ signIn: string;
14
+ dontHaveAccount: string;
15
+ createAccount: string;
16
+ }
15
17
 
16
- interface LoginFormProps {
18
+ export interface LoginFormProps {
19
+ translations: LoginFormTranslations;
17
20
  onNavigateToRegister: () => void;
18
21
  }
19
22
 
20
- export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) => {
21
- const { t } = useLocalization();
23
+ export const LoginForm: React.FC<LoginFormProps> = ({
24
+ translations,
25
+ onNavigateToRegister,
26
+ }) => {
22
27
  const passwordRef = useRef<React.ElementRef<typeof TextInput>>(null);
23
28
  const {
24
29
  email,
@@ -32,28 +37,13 @@ export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) =>
32
37
  displayError,
33
38
  } = useLoginForm();
34
39
 
35
- useEffect(() => {
36
- if (__DEV__) {
37
- console.log("[LoginForm] Mounted/Updated:", {
38
- hasEmail: !!email,
39
- hasPassword: !!password,
40
- loading,
41
- hasError: !!displayError,
42
- });
43
- }
44
- }, [email, password, loading, displayError]);
45
-
46
- if (__DEV__) {
47
- console.log("[LoginForm] Rendering...");
48
- }
49
-
50
40
  return (
51
41
  <>
52
42
  <AtomicInput
53
- label={t("auth.email")}
43
+ label={translations.email}
54
44
  value={email}
55
45
  onChangeText={handleEmailChange}
56
- placeholder={t("auth.emailPlaceholder")}
46
+ placeholder={translations.emailPlaceholder}
57
47
  keyboardType="email-address"
58
48
  autoCapitalize="none"
59
49
  disabled={loading}
@@ -68,10 +58,10 @@ export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) =>
68
58
 
69
59
  <AtomicInput
70
60
  ref={passwordRef}
71
- label={t("auth.password")}
61
+ label={translations.password}
72
62
  value={password}
73
63
  onChangeText={handlePasswordChange}
74
- placeholder={t("auth.passwordPlaceholder")}
64
+ placeholder={translations.passwordPlaceholder}
75
65
  secureTextEntry
76
66
  showPasswordToggle
77
67
  autoCapitalize="none"
@@ -94,12 +84,12 @@ export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) =>
94
84
  fullWidth
95
85
  style={styles.signInButton}
96
86
  >
97
- {t("auth.signIn")}
87
+ {translations.signIn}
98
88
  </AtomicButton>
99
89
 
100
90
  <AuthLink
101
- text={t("auth.dontHaveAccount")}
102
- linkText={t("auth.createAccount")}
91
+ text={translations.dontHaveAccount}
92
+ linkText={translations.createAccount}
103
93
  onPress={onNavigateToRegister}
104
94
  disabled={loading}
105
95
  />
@@ -1,22 +1,24 @@
1
1
  import React from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
3
  import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
4
- import { useLocalization } from "@umituz/react-native-localization";
4
+
5
+ export interface PasswordMatchTranslations {
6
+ match: string;
7
+ noMatch: string;
8
+ }
5
9
 
6
10
  export interface PasswordMatchIndicatorProps {
11
+ translations: PasswordMatchTranslations;
7
12
  isMatch: boolean;
8
13
  }
9
14
 
10
15
  export const PasswordMatchIndicator: React.FC<PasswordMatchIndicatorProps> = ({
16
+ translations,
11
17
  isMatch,
12
18
  }) => {
13
19
  const tokens = useAppDesignTokens();
14
- const { t } = useLocalization();
15
-
16
20
  const color = isMatch ? tokens.colors.success : tokens.colors.error;
17
- const text = isMatch
18
- ? t("auth.passwordsMatch")
19
- : t("auth.passwordsDontMatch");
21
+ const text = isMatch ? translations.match : translations.noMatch;
20
22
 
21
23
  return (
22
24
  <View style={styles.container}>
@@ -39,4 +41,3 @@ const styles = StyleSheet.create({
39
41
  borderRadius: 3,
40
42
  },
41
43
  });
42
-
@@ -1,10 +1,14 @@
1
1
  import React from "react";
2
2
  import { View, StyleSheet } from "react-native";
3
3
  import { useAppDesignTokens, AtomicText, type ColorVariant } from "@umituz/react-native-design-system";
4
- import { useLocalization } from "@umituz/react-native-localization";
5
4
  import type { PasswordRequirements } from "../../infrastructure/utils/AuthValidation";
6
5
 
6
+ export interface PasswordStrengthTranslations {
7
+ minLength: string;
8
+ }
9
+
7
10
  export interface PasswordStrengthIndicatorProps {
11
+ translations: PasswordStrengthTranslations;
8
12
  requirements: PasswordRequirements;
9
13
  showLabels?: boolean;
10
14
  }
@@ -24,10 +28,6 @@ const RequirementDot: React.FC<RequirementDotProps> = ({
24
28
  }) => {
25
29
  const tokens = useAppDesignTokens();
26
30
  const colorKey = isValid ? successColor : pendingColor;
27
-
28
- // Resolve the color value from the token key for the View background
29
- // We use type assertion since we know these are valid specific keys passed from parent
30
- // but tokens.colors index signature might be limited
31
31
  const dotColor = (tokens.colors as Record<string, string>)[colorKey] || tokens.colors.textTertiary;
32
32
 
33
33
  return (
@@ -40,33 +40,30 @@ const RequirementDot: React.FC<RequirementDotProps> = ({
40
40
  );
41
41
  };
42
42
 
43
- export const PasswordStrengthIndicator: React.FC<
44
- PasswordStrengthIndicatorProps
45
- > = ({ requirements, showLabels = true }) => {
43
+ export const PasswordStrengthIndicator: React.FC<PasswordStrengthIndicatorProps> = ({
44
+ translations,
45
+ requirements,
46
+ showLabels = true,
47
+ }) => {
46
48
  const tokens = useAppDesignTokens();
47
- const { t } = useLocalization();
48
-
49
49
  const successColor: ColorVariant = "success";
50
50
  const pendingColor: ColorVariant = "textTertiary";
51
51
 
52
52
  const items = [
53
- { key: "minLength", label: t("auth.passwordReq.minLength"), isValid: requirements.hasMinLength },
53
+ { key: "minLength", label: translations.minLength, isValid: requirements.hasMinLength },
54
54
  ];
55
55
 
56
56
  if (!showLabels) {
57
57
  return (
58
58
  <View style={styles.dotsOnly}>
59
59
  {items.map((item) => {
60
- const colorKey = item.isValid ? successColor : pendingColor;
61
- const dotColor = (tokens.colors as Record<string, string>)[colorKey] || tokens.colors.textTertiary;
62
-
63
- return (
60
+ const colorKey = item.isValid ? successColor : pendingColor;
61
+ const dotColor = (tokens.colors as Record<string, string>)[colorKey] || tokens.colors.textTertiary;
62
+
63
+ return (
64
64
  <View
65
65
  key={item.key}
66
- style={[
67
- styles.dotOnly,
68
- { backgroundColor: dotColor },
69
- ]}
66
+ style={[styles.dotOnly, { backgroundColor: dotColor }]}
70
67
  />
71
68
  );
72
69
  })}
@@ -116,4 +113,3 @@ const styles = StyleSheet.create({
116
113
  borderRadius: 4,
117
114
  },
118
115
  });
119
-
@@ -1,20 +1,33 @@
1
- /**
2
- * Register Form Component
3
- * Single Responsibility: Render register form UI
4
- */
5
-
6
1
  import React, { useRef } from "react";
7
2
  import { StyleSheet, TextInput } from "react-native";
8
3
  import { AtomicInput, AtomicButton } from "@umituz/react-native-design-system";
9
- import { useLocalization } from "@umituz/react-native-localization";
10
4
  import { useRegisterForm } from "../hooks/useRegisterForm";
11
5
  import { AuthErrorDisplay } from "./AuthErrorDisplay";
12
6
  import { AuthLink } from "./AuthLink";
13
- import { AuthLegalLinks } from "./AuthLegalLinks";
14
- import { PasswordStrengthIndicator } from "./PasswordStrengthIndicator";
15
- import { PasswordMatchIndicator } from "./PasswordMatchIndicator";
7
+ import { AuthLegalLinks, type AuthLegalLinksTranslations } from "./AuthLegalLinks";
8
+ import { PasswordStrengthIndicator, type PasswordStrengthTranslations } from "./PasswordStrengthIndicator";
9
+ import { PasswordMatchIndicator, type PasswordMatchTranslations } from "./PasswordMatchIndicator";
10
+
11
+ export interface RegisterFormTranslations {
12
+ displayName: string;
13
+ displayNamePlaceholder: string;
14
+ email: string;
15
+ emailPlaceholder: string;
16
+ password: string;
17
+ passwordPlaceholder: string;
18
+ confirmPassword: string;
19
+ confirmPasswordPlaceholder: string;
20
+ signUp: string;
21
+ alreadyHaveAccount: string;
22
+ signIn: string;
23
+ bySigningUp: string;
24
+ legal: AuthLegalLinksTranslations;
25
+ passwordStrength: PasswordStrengthTranslations;
26
+ passwordMatch: PasswordMatchTranslations;
27
+ }
16
28
 
17
- interface RegisterFormProps {
29
+ export interface RegisterFormProps {
30
+ translations: RegisterFormTranslations;
18
31
  onNavigateToLogin: () => void;
19
32
  termsUrl?: string;
20
33
  privacyUrl?: string;
@@ -23,13 +36,13 @@ interface RegisterFormProps {
23
36
  }
24
37
 
25
38
  export const RegisterForm: React.FC<RegisterFormProps> = ({
39
+ translations,
26
40
  onNavigateToLogin,
27
41
  termsUrl,
28
42
  privacyUrl,
29
43
  onTermsPress,
30
44
  onPrivacyPress,
31
45
  }) => {
32
- const { t } = useLocalization();
33
46
  const emailRef = useRef<React.ElementRef<typeof TextInput>>(null);
34
47
  const passwordRef = useRef<React.ElementRef<typeof TextInput>>(null);
35
48
  const confirmPasswordRef = useRef<React.ElementRef<typeof TextInput>>(null);
@@ -54,12 +67,10 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
54
67
  return (
55
68
  <>
56
69
  <AtomicInput
57
- label={t("auth.displayName")}
70
+ label={translations.displayName}
58
71
  value={displayName}
59
72
  onChangeText={handleDisplayNameChange}
60
- placeholder={
61
- t("auth.displayNamePlaceholder")
62
- }
73
+ placeholder={translations.displayNamePlaceholder}
63
74
  autoCapitalize="words"
64
75
  disabled={loading}
65
76
  state={fieldErrors.displayName ? "error" : "default"}
@@ -72,10 +83,10 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
72
83
 
73
84
  <AtomicInput
74
85
  ref={emailRef}
75
- label={t("auth.email")}
86
+ label={translations.email}
76
87
  value={email}
77
88
  onChangeText={handleEmailChange}
78
- placeholder={t("auth.emailPlaceholder")}
89
+ placeholder={translations.emailPlaceholder}
79
90
  keyboardType="email-address"
80
91
  autoCapitalize="none"
81
92
  disabled={loading}
@@ -90,10 +101,10 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
90
101
 
91
102
  <AtomicInput
92
103
  ref={passwordRef}
93
- label={t("auth.password")}
104
+ label={translations.password}
94
105
  value={password}
95
106
  onChangeText={handlePasswordChange}
96
- placeholder={t("auth.passwordPlaceholder")}
107
+ placeholder={translations.passwordPlaceholder}
97
108
  secureTextEntry
98
109
  showPasswordToggle
99
110
  autoCapitalize="none"
@@ -108,15 +119,18 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
108
119
  style={styles.input}
109
120
  />
110
121
  {password.length > 0 && (
111
- <PasswordStrengthIndicator requirements={passwordRequirements} />
122
+ <PasswordStrengthIndicator
123
+ translations={translations.passwordStrength}
124
+ requirements={passwordRequirements}
125
+ />
112
126
  )}
113
127
 
114
128
  <AtomicInput
115
129
  ref={confirmPasswordRef}
116
- label={t("auth.confirmPassword")}
130
+ label={translations.confirmPassword}
117
131
  value={confirmPassword}
118
132
  onChangeText={handleConfirmPasswordChange}
119
- placeholder={t("auth.confirmPasswordPlaceholder")}
133
+ placeholder={translations.confirmPasswordPlaceholder}
120
134
  secureTextEntry
121
135
  showPasswordToggle
122
136
  autoCapitalize="none"
@@ -130,7 +144,10 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
130
144
  style={styles.input}
131
145
  />
132
146
  {confirmPassword.length > 0 && (
133
- <PasswordMatchIndicator isMatch={passwordsMatch} />
147
+ <PasswordMatchIndicator
148
+ translations={translations.passwordMatch}
149
+ isMatch={passwordsMatch}
150
+ />
134
151
  )}
135
152
 
136
153
  <AuthErrorDisplay error={displayError} />
@@ -147,22 +164,23 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
147
164
  fullWidth
148
165
  style={styles.signUpButton}
149
166
  >
150
- {t("auth.signUp")}
167
+ {translations.signUp}
151
168
  </AtomicButton>
152
169
 
153
170
  <AuthLink
154
- text={t("auth.alreadyHaveAccount")}
155
- linkText={t("auth.signIn")}
171
+ text={translations.alreadyHaveAccount}
172
+ linkText={translations.signIn}
156
173
  onPress={onNavigateToLogin}
157
174
  disabled={loading}
158
175
  />
159
176
 
160
177
  <AuthLegalLinks
178
+ translations={translations.legal}
161
179
  termsUrl={termsUrl}
162
180
  privacyUrl={privacyUrl}
163
181
  onTermsPress={onTermsPress}
164
182
  onPrivacyPress={onPrivacyPress}
165
- prefixText={t("auth.bySigningUp")}
183
+ prefixText={translations.bySigningUp}
166
184
  />
167
185
  </>
168
186
  );
@@ -178,4 +196,3 @@ const styles = StyleSheet.create({
178
196
  marginTop: 8,
179
197
  },
180
198
  });
181
-
@@ -1,76 +1,75 @@
1
1
  import React from "react";
2
- import {
3
- View,
4
- StyleSheet,
5
- Platform,
6
- } from "react-native";
7
- import { Divider, AtomicButton } from "@umituz/react-native-design-system";
8
- import { useLocalization } from "@umituz/react-native-localization";
2
+ import { View, StyleSheet } from "react-native";
3
+ import { AtomicText, AtomicButton, useAppDesignTokens } from "@umituz/react-native-design-system";
9
4
  import type { SocialAuthProvider } from "../../domain/value-objects/AuthConfig";
10
5
 
6
+ export interface SocialLoginButtonsTranslations {
7
+ orContinueWith: string;
8
+ google: string;
9
+ apple: string;
10
+ }
11
+
11
12
  export interface SocialLoginButtonsProps {
12
- /** Enabled providers to display */
13
+ translations: SocialLoginButtonsTranslations;
13
14
  enabledProviders: SocialAuthProvider[];
14
- /** Called when Google sign-in is pressed */
15
15
  onGooglePress?: () => void;
16
- /** Called when Apple sign-in is pressed */
17
16
  onApplePress?: () => void;
18
- /** Loading state for Google button */
19
17
  googleLoading?: boolean;
20
- /** Loading state for Apple button */
21
18
  appleLoading?: boolean;
22
- /** Disable all buttons */
23
- disabled?: boolean;
24
19
  }
25
20
 
26
21
  export const SocialLoginButtons: React.FC<SocialLoginButtonsProps> = ({
22
+ translations,
27
23
  enabledProviders,
28
24
  onGooglePress,
29
25
  onApplePress,
30
26
  googleLoading = false,
31
27
  appleLoading = false,
32
- disabled = false,
33
28
  }) => {
34
- const { t } = useLocalization();
35
-
36
- const safeEnabledProviders = enabledProviders ?? [];
37
- const showGoogle = safeEnabledProviders.includes("google");
38
- const showApple = safeEnabledProviders.includes("apple") && Platform.OS === "ios";
29
+ const tokens = useAppDesignTokens();
30
+ const hasGoogle = enabledProviders.includes("google");
31
+ const hasApple = enabledProviders.includes("apple");
39
32
 
40
- if (!showGoogle && !showApple) {
33
+ if (!hasGoogle && !hasApple) {
41
34
  return null;
42
35
  }
43
36
 
44
37
  return (
45
- <View style={styles.container}>
46
- <Divider text={t("auth.orContinueWith")} spacing="large" />
38
+ <View style={[styles.container, { marginTop: tokens.spacing.lg }]}>
39
+ <View style={styles.dividerContainer}>
40
+ <View style={[styles.divider, { backgroundColor: tokens.colors.border }]} />
41
+ <AtomicText type="bodySmall" color="textSecondary" style={styles.dividerText}>
42
+ {translations.orContinueWith}
43
+ </AtomicText>
44
+ <View style={[styles.divider, { backgroundColor: tokens.colors.border }]} />
45
+ </View>
47
46
 
48
47
  <View style={styles.buttonsContainer}>
49
- {showGoogle && (
48
+ {hasGoogle && onGooglePress && (
50
49
  <AtomicButton
51
50
  variant="outline"
52
- onPress={onGooglePress || (() => {})}
51
+ onPress={onGooglePress}
52
+ disabled={googleLoading || appleLoading}
53
53
  loading={googleLoading}
54
- disabled={disabled}
55
- icon="logo-google"
56
54
  fullWidth
57
55
  style={styles.socialButton}
56
+ leftIcon="logo-google"
58
57
  >
59
- {t("auth.google")}
58
+ {translations.google}
60
59
  </AtomicButton>
61
60
  )}
62
61
 
63
- {showApple && (
62
+ {hasApple && onApplePress && (
64
63
  <AtomicButton
65
64
  variant="outline"
66
- onPress={onApplePress || (() => {})}
65
+ onPress={onApplePress}
66
+ disabled={googleLoading || appleLoading}
67
67
  loading={appleLoading}
68
- disabled={disabled}
69
- icon="logo-apple"
70
68
  fullWidth
71
69
  style={styles.socialButton}
70
+ leftIcon="logo-apple"
72
71
  >
73
- {t("auth.apple")}
72
+ {translations.apple}
74
73
  </AtomicButton>
75
74
  )}
76
75
  </View>
@@ -79,16 +78,23 @@ export const SocialLoginButtons: React.FC<SocialLoginButtonsProps> = ({
79
78
  };
80
79
 
81
80
  const styles = StyleSheet.create({
82
- container: {
83
- marginTop: 24,
81
+ container: {},
82
+ dividerContainer: {
83
+ flexDirection: "row",
84
+ alignItems: "center",
85
+ marginBottom: 16,
86
+ },
87
+ divider: {
88
+ flex: 1,
89
+ height: 1,
90
+ },
91
+ dividerText: {
92
+ marginHorizontal: 16,
84
93
  },
85
94
  buttonsContainer: {
86
- flexDirection: 'row',
87
- marginTop: 8,
88
95
  gap: 12,
89
96
  },
90
97
  socialButton: {
91
- flex: 1,
98
+ minHeight: 48,
92
99
  },
93
100
  });
94
-