@umituz/react-native-auth 3.5.5 → 3.5.7

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": "3.5.5",
3
+ "version": "3.5.7",
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",
@@ -61,7 +61,7 @@
61
61
  "@types/react": "~19.1.0",
62
62
  "@typescript-eslint/eslint-plugin": "^7.0.0",
63
63
  "@typescript-eslint/parser": "^7.0.0",
64
- "@umituz/react-native-design-system": "^2.8.34",
64
+ "@umituz/react-native-design-system": "^2.8.39",
65
65
  "@umituz/react-native-design-system-theme": "*",
66
66
  "eslint": "^8.57.0",
67
67
  "expo-apple-authentication": "^6.0.0",
package/src/index.ts CHANGED
@@ -170,7 +170,6 @@ export type {
170
170
  // COMPONENTS
171
171
  export { AuthContainer } from './presentation/components/AuthContainer';
172
172
  export { AuthHeader } from './presentation/components/AuthHeader';
173
- export { AuthFormCard } from './presentation/components/AuthFormCard';
174
173
  export { LoginForm } from './presentation/components/LoginForm';
175
174
  export { RegisterForm } from './presentation/components/RegisterForm';
176
175
  export { AuthLegalLinks } from './presentation/components/AuthLegalLinks';
@@ -8,11 +8,8 @@ import {
8
8
  View,
9
9
  StyleSheet,
10
10
  ScrollView,
11
- KeyboardAvoidingView,
12
11
  } from "react-native";
13
- import { useSafeAreaInsets } from "react-native-safe-area-context";
14
- import { useResponsive } from "@umituz/react-native-design-system";
15
- import { AuthBackground } from "./AuthBackground";
12
+ import { useResponsive, useSafeAreaInsets, AtomicKeyboardAvoidingView, useAppDesignTokens } from "@umituz/react-native-design-system";
16
13
 
17
14
  /** Layout constants for auth screens */
18
15
  const AUTH_LAYOUT = {
@@ -29,17 +26,18 @@ export const AuthContainer: React.FC<AuthContainerProps> = ({ children }) => {
29
26
  const insets = useSafeAreaInsets();
30
27
  const { spacingMultiplier } = useResponsive();
31
28
 
29
+ const tokens = useAppDesignTokens();
30
+
32
31
  const dynamicStyles = useMemo(() => ({
33
32
  paddingTop: insets.top + (AUTH_LAYOUT.VERTICAL_PADDING * spacingMultiplier),
34
33
  paddingBottom: insets.bottom + (AUTH_LAYOUT.VERTICAL_PADDING * spacingMultiplier),
35
34
  }), [insets.top, insets.bottom, spacingMultiplier]);
36
35
 
37
36
  return (
38
- <KeyboardAvoidingView
39
- style={styles.container}
37
+ <AtomicKeyboardAvoidingView
38
+ style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}
40
39
  behavior="padding"
41
40
  >
42
- <AuthBackground />
43
41
  <ScrollView
44
42
  contentContainerStyle={[styles.scrollContent, dynamicStyles]}
45
43
  keyboardShouldPersistTaps="handled"
@@ -47,7 +45,7 @@ export const AuthContainer: React.FC<AuthContainerProps> = ({ children }) => {
47
45
  >
48
46
  <View style={styles.content}>{children}</View>
49
47
  </ScrollView>
50
- </KeyboardAvoidingView>
48
+ </AtomicKeyboardAvoidingView>
51
49
  );
52
50
  };
53
51
 
@@ -32,7 +32,8 @@ export const AuthErrorDisplay: React.FC<AuthErrorDisplayProps> = ({
32
32
  >
33
33
  <AtomicText
34
34
  type="bodyMedium"
35
- style={[styles.errorText, { color: tokens.colors.error }]}
35
+ color="error"
36
+ style={styles.errorText}
36
37
  >
37
38
  {error}
38
39
  </AtomicText>
@@ -48,7 +49,6 @@ const styles = StyleSheet.create({
48
49
  borderWidth: 1,
49
50
  },
50
51
  errorText: {
51
- fontSize: 14,
52
52
  textAlign: "center",
53
53
  fontWeight: "500",
54
54
  },
@@ -21,15 +21,16 @@ export const AuthHeader: React.FC<AuthHeaderProps> = ({ title, subtitle }) => {
21
21
  <View style={[styles.header, { marginBottom: tokens.spacing.xl, paddingHorizontal: tokens.spacing.md }]}>
22
22
  <AtomicText
23
23
  type="headlineLarge"
24
- style={{ color: tokens.colors.onPrimary, textAlign: "center" }}
24
+ color="onPrimary"
25
+ style={{ textAlign: "center" }}
25
26
  >
26
27
  {title}
27
28
  </AtomicText>
28
29
  {(subtitle || t("auth.subtitle")) && (
29
30
  <AtomicText
30
31
  type="bodyMedium"
32
+ color="textInverse"
31
33
  style={{
32
- color: tokens.colors.textInverse,
33
34
  textAlign: "center",
34
35
  marginTop: tokens.spacing.xs,
35
36
  }}
@@ -79,13 +79,11 @@ export const AuthLegalLinks: React.FC<AuthLegalLinksProps> = ({
79
79
  {hasTerms && (
80
80
  <AtomicButton
81
81
  variant="text"
82
+ size="sm"
82
83
  onPress={handleTermsPress}
83
84
  style={styles.linkButton}
84
- >
85
- <AtomicText type="bodySmall" color="primary">
86
- {t("auth.termsOfService")}
87
- </AtomicText>
88
- </AtomicButton>
85
+ title={t("auth.termsOfService")}
86
+ />
89
87
  )}
90
88
  {hasTerms && hasPrivacy && (
91
89
  <AtomicText type="bodySmall" color="secondary" style={styles.separator}>
@@ -95,13 +93,11 @@ export const AuthLegalLinks: React.FC<AuthLegalLinksProps> = ({
95
93
  {hasPrivacy && (
96
94
  <AtomicButton
97
95
  variant="text"
96
+ size="sm"
98
97
  onPress={handlePrivacyPress}
99
98
  style={styles.linkButton}
100
- >
101
- <AtomicText type="bodySmall" color="primary">
102
- {t("auth.privacyPolicy")}
103
- </AtomicText>
104
- </AtomicButton>
99
+ title={t("auth.privacyPolicy")}
100
+ />
105
101
  )}
106
102
  </View>
107
103
  </View>
@@ -49,54 +49,52 @@ export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) =>
49
49
 
50
50
  return (
51
51
  <>
52
- <View style={styles.inputContainer}>
53
- <AtomicInput
54
- label={t("auth.email")}
55
- value={email}
56
- onChangeText={handleEmailChange}
57
- placeholder={t("auth.emailPlaceholder")}
58
- keyboardType="email-address"
59
- autoCapitalize="none"
60
- disabled={loading}
61
- state={emailError ? "error" : "default"}
62
- helperText={emailError || undefined}
63
- returnKeyType="next"
64
- onSubmitEditing={() => passwordRef.current?.focus()}
65
- blurOnSubmit={false}
66
- />
67
- </View>
52
+ <AtomicInput
53
+ label={t("auth.email")}
54
+ value={email}
55
+ onChangeText={handleEmailChange}
56
+ placeholder={t("auth.emailPlaceholder")}
57
+ keyboardType="email-address"
58
+ autoCapitalize="none"
59
+ disabled={loading}
60
+ state={emailError ? "error" : "default"}
61
+ helperText={emailError || undefined}
62
+ returnKeyType="next"
63
+ onSubmitEditing={() => passwordRef.current?.focus()}
64
+ blurOnSubmit={false}
65
+ textContentType="emailAddress"
66
+ style={styles.input}
67
+ />
68
68
 
69
- <View style={styles.inputContainer}>
70
- <AtomicInput
71
- ref={passwordRef}
72
- label={t("auth.password")}
73
- value={password}
74
- onChangeText={handlePasswordChange}
75
- placeholder={t("auth.passwordPlaceholder")}
76
- secureTextEntry
77
- showPasswordToggle
78
- autoCapitalize="none"
79
- disabled={loading}
80
- state={passwordError ? "error" : "default"}
81
- helperText={passwordError || undefined}
82
- returnKeyType="done"
83
- onSubmitEditing={() => { void handleSignIn(); }}
84
- />
85
- </View>
69
+ <AtomicInput
70
+ ref={passwordRef}
71
+ label={t("auth.password")}
72
+ value={password}
73
+ onChangeText={handlePasswordChange}
74
+ placeholder={t("auth.passwordPlaceholder")}
75
+ secureTextEntry
76
+ showPasswordToggle
77
+ autoCapitalize="none"
78
+ disabled={loading}
79
+ state={passwordError ? "error" : "default"}
80
+ helperText={passwordError || undefined}
81
+ returnKeyType="done"
82
+ onSubmitEditing={() => { void handleSignIn(); }}
83
+ textContentType="password"
84
+ style={styles.input}
85
+ />
86
86
 
87
87
  <AuthErrorDisplay error={displayError} />
88
88
 
89
- <View style={styles.buttonContainer}>
90
- <AtomicButton
91
- variant="primary"
92
- onPress={() => { void handleSignIn(); }}
93
- disabled={loading || !email.trim() || !password.trim()}
94
- fullWidth
95
- style={styles.signInButton}
96
- >
97
- {t("auth.signIn")}
98
- </AtomicButton>
99
- </View>
89
+ <AtomicButton
90
+ variant="primary"
91
+ onPress={() => { void handleSignIn(); }}
92
+ disabled={loading || !email.trim() || !password.trim()}
93
+ fullWidth
94
+ style={styles.signInButton}
95
+ >
96
+ {t("auth.signIn")}
97
+ </AtomicButton>
100
98
 
101
99
  <AuthLink
102
100
  text={t("auth.dontHaveAccount")}
@@ -109,13 +107,11 @@ export const LoginForm: React.FC<LoginFormProps> = ({ onNavigateToRegister }) =>
109
107
  };
110
108
 
111
109
  const styles = StyleSheet.create({
112
- inputContainer: {
110
+ input: {
113
111
  marginBottom: 20,
114
112
  },
115
- buttonContainer: {
116
- marginBottom: 16,
117
- },
118
113
  signInButton: {
119
114
  minHeight: 52,
115
+ marginBottom: 16,
120
116
  },
121
117
  });
@@ -53,105 +53,102 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
53
53
 
54
54
  return (
55
55
  <>
56
- <View style={styles.inputContainer}>
57
- <AtomicInput
58
- label={t("auth.displayName")}
59
- value={displayName}
60
- onChangeText={handleDisplayNameChange}
61
- placeholder={
62
- t("auth.displayNamePlaceholder")
63
- }
64
- autoCapitalize="words"
65
- disabled={loading}
66
- state={fieldErrors.displayName ? "error" : "default"}
67
- helperText={fieldErrors.displayName || undefined}
68
- returnKeyType="next"
69
- onSubmitEditing={() => emailRef.current?.focus()}
70
- blurOnSubmit={false}
71
- />
72
- </View>
56
+ <AtomicInput
57
+ label={t("auth.displayName")}
58
+ value={displayName}
59
+ onChangeText={handleDisplayNameChange}
60
+ placeholder={
61
+ t("auth.displayNamePlaceholder")
62
+ }
63
+ autoCapitalize="words"
64
+ disabled={loading}
65
+ state={fieldErrors.displayName ? "error" : "default"}
66
+ helperText={fieldErrors.displayName || undefined}
67
+ returnKeyType="next"
68
+ onSubmitEditing={() => emailRef.current?.focus()}
69
+ blurOnSubmit={false}
70
+ style={styles.input}
71
+ />
73
72
 
74
- <View style={styles.inputContainer}>
75
- <AtomicInput
76
- ref={emailRef}
77
- label={t("auth.email")}
78
- value={email}
79
- onChangeText={handleEmailChange}
80
- placeholder={t("auth.emailPlaceholder")}
81
- keyboardType="email-address"
82
- autoCapitalize="none"
83
- disabled={loading}
84
- state={fieldErrors.email ? "error" : "default"}
85
- helperText={fieldErrors.email || undefined}
86
- returnKeyType="next"
87
- onSubmitEditing={() => passwordRef.current?.focus()}
88
- blurOnSubmit={false}
89
- />
90
- </View>
73
+ <AtomicInput
74
+ ref={emailRef}
75
+ label={t("auth.email")}
76
+ value={email}
77
+ onChangeText={handleEmailChange}
78
+ placeholder={t("auth.emailPlaceholder")}
79
+ keyboardType="email-address"
80
+ autoCapitalize="none"
81
+ disabled={loading}
82
+ state={fieldErrors.email ? "error" : "default"}
83
+ helperText={fieldErrors.email || undefined}
84
+ returnKeyType="next"
85
+ onSubmitEditing={() => passwordRef.current?.focus()}
86
+ blurOnSubmit={false}
87
+ textContentType="emailAddress"
88
+ style={styles.input}
89
+ />
91
90
 
92
- <View style={styles.inputContainer}>
93
- <AtomicInput
94
- ref={passwordRef}
95
- label={t("auth.password")}
96
- value={password}
97
- onChangeText={handlePasswordChange}
98
- placeholder={t("auth.passwordPlaceholder")}
99
- secureTextEntry
100
- showPasswordToggle
101
- autoCapitalize="none"
102
- disabled={loading}
103
- state={fieldErrors.password ? "error" : "default"}
104
- helperText={fieldErrors.password || undefined}
105
- returnKeyType="next"
106
- onSubmitEditing={() => confirmPasswordRef.current?.focus()}
107
- blurOnSubmit={false}
108
- />
109
- {password.length > 0 && (
110
- <PasswordStrengthIndicator requirements={passwordRequirements} />
111
- )}
112
- </View>
91
+ <AtomicInput
92
+ ref={passwordRef}
93
+ label={t("auth.password")}
94
+ value={password}
95
+ onChangeText={handlePasswordChange}
96
+ placeholder={t("auth.passwordPlaceholder")}
97
+ secureTextEntry
98
+ showPasswordToggle
99
+ autoCapitalize="none"
100
+ disabled={loading}
101
+ state={fieldErrors.password ? "error" : "default"}
102
+ helperText={fieldErrors.password || undefined}
103
+ returnKeyType="next"
104
+ onSubmitEditing={() => confirmPasswordRef.current?.focus()}
105
+ blurOnSubmit={false}
106
+ textContentType="newPassword"
107
+ style={styles.input}
108
+ />
109
+ {password.length > 0 && (
110
+ <PasswordStrengthIndicator requirements={passwordRequirements} />
111
+ )}
113
112
 
114
- <View style={styles.inputContainer}>
115
- <AtomicInput
116
- ref={confirmPasswordRef}
117
- label={t("auth.confirmPassword")}
118
- value={confirmPassword}
119
- onChangeText={handleConfirmPasswordChange}
120
- placeholder={
121
- t("auth.confirmPasswordPlaceholder")
122
- }
123
- secureTextEntry
124
- showPasswordToggle
125
- autoCapitalize="none"
126
- disabled={loading}
127
- state={fieldErrors.confirmPassword ? "error" : "default"}
128
- helperText={fieldErrors.confirmPassword || undefined}
129
- returnKeyType="done"
130
- onSubmitEditing={() => { void handleSignUp(); }}
131
- />
132
- {confirmPassword.length > 0 && (
133
- <PasswordMatchIndicator isMatch={passwordsMatch} />
134
- )}
135
- </View>
113
+ <AtomicInput
114
+ ref={confirmPasswordRef}
115
+ label={t("auth.confirmPassword")}
116
+ value={confirmPassword}
117
+ onChangeText={handleConfirmPasswordChange}
118
+ placeholder={
119
+ t("auth.confirmPasswordPlaceholder")
120
+ }
121
+ secureTextEntry
122
+ showPasswordToggle
123
+ autoCapitalize="none"
124
+ disabled={loading}
125
+ state={fieldErrors.confirmPassword ? "error" : "default"}
126
+ helperText={fieldErrors.confirmPassword || undefined}
127
+ returnKeyType="done"
128
+ onSubmitEditing={() => { void handleSignUp(); }}
129
+ textContentType="newPassword"
130
+ style={styles.input}
131
+ />
132
+ {confirmPassword.length > 0 && (
133
+ <PasswordMatchIndicator isMatch={passwordsMatch} />
134
+ )}
136
135
 
137
136
  <AuthErrorDisplay error={displayError} />
138
137
 
139
- <View style={styles.buttonContainer}>
140
- <AtomicButton
141
- variant="primary"
142
- onPress={() => { void handleSignUp(); }}
143
- disabled={
144
- loading ||
145
- !email.trim() ||
146
- !password.trim() ||
147
- !confirmPassword.trim()
148
- }
149
- fullWidth
150
- style={styles.signUpButton}
151
- >
152
- {t("auth.signUp")}
153
- </AtomicButton>
154
- </View>
138
+ <AtomicButton
139
+ variant="primary"
140
+ onPress={() => { void handleSignUp(); }}
141
+ disabled={
142
+ loading ||
143
+ !email.trim() ||
144
+ !password.trim() ||
145
+ !confirmPassword.trim()
146
+ }
147
+ fullWidth
148
+ style={styles.signUpButton}
149
+ >
150
+ {t("auth.signUp")}
151
+ </AtomicButton>
155
152
 
156
153
  <AuthLink
157
154
  text={t("auth.alreadyHaveAccount")}
@@ -172,15 +169,13 @@ export const RegisterForm: React.FC<RegisterFormProps> = ({
172
169
  };
173
170
 
174
171
  const styles = StyleSheet.create({
175
- inputContainer: {
172
+ input: {
176
173
  marginBottom: 20,
177
174
  },
178
- buttonContainer: {
179
- marginBottom: 16,
180
- marginTop: 8,
181
- },
182
175
  signUpButton: {
183
176
  minHeight: 52,
177
+ marginBottom: 16,
178
+ marginTop: 8,
184
179
  },
185
180
  });
186
181
 
@@ -1,11 +1,10 @@
1
1
  import React from "react";
2
2
  import {
3
3
  View,
4
- TouchableOpacity,
5
4
  StyleSheet,
6
5
  Platform,
7
6
  } from "react-native";
8
- import { useAppDesignTokens, AtomicText, AtomicIcon, AtomicSpinner } from "@umituz/react-native-design-system";
7
+ import { useAppDesignTokens, Divider, AtomicButton } from "@umituz/react-native-design-system";
9
8
  import { useLocalization } from "@umituz/react-native-localization";
10
9
  import type { SocialAuthProvider } from "../../domain/value-objects/AuthConfig";
11
10
 
@@ -45,61 +44,35 @@ export const SocialLoginButtons: React.FC<SocialLoginButtonsProps> = ({
45
44
 
46
45
  return (
47
46
  <View style={styles.container}>
48
- <View style={styles.dividerContainer}>
49
- <View style={[styles.divider, { backgroundColor: tokens.colors.border }]} />
50
- <AtomicText type="bodySmall" color="secondary" style={styles.dividerText}>
51
- {t("auth.orContinueWith")}
52
- </AtomicText>
53
- <View style={[styles.divider, { backgroundColor: tokens.colors.border }]} />
54
- </View>
47
+ <Divider text={t("auth.orContinueWith")} spacing="large" />
55
48
 
56
49
  <View style={styles.buttonsContainer}>
57
50
  {showGoogle && (
58
- <TouchableOpacity
59
- style={[
60
- styles.socialButton,
61
- { borderColor: tokens.colors.border },
62
- disabled && styles.disabledButton,
63
- ]}
64
- onPress={onGooglePress}
65
- disabled={disabled || googleLoading}
66
- activeOpacity={0.7}
51
+ <AtomicButton
52
+ variant="outline"
53
+ onPress={onGooglePress || (() => {})}
54
+ loading={googleLoading}
55
+ disabled={disabled}
56
+ icon="logo-google"
57
+ fullWidth
58
+ style={styles.socialButton}
67
59
  >
68
- {googleLoading ? (
69
- <AtomicSpinner size="sm" color={tokens.colors.textPrimary} />
70
- ) : (
71
- <>
72
- <AtomicIcon name="logo-google" size="sm" />
73
- <AtomicText style={[styles.buttonText, { color: tokens.colors.textPrimary }]}>
74
- {t("auth.google")}
75
- </AtomicText>
76
- </>
77
- )}
78
- </TouchableOpacity>
60
+ {t("auth.google")}
61
+ </AtomicButton>
79
62
  )}
80
63
 
81
64
  {showApple && (
82
- <TouchableOpacity
83
- style={[
84
- styles.socialButton,
85
- { borderColor: tokens.colors.border },
86
- disabled && styles.disabledButton,
87
- ]}
88
- onPress={onApplePress}
89
- disabled={disabled || appleLoading}
90
- activeOpacity={0.7}
65
+ <AtomicButton
66
+ variant="outline"
67
+ onPress={onApplePress || (() => {})}
68
+ loading={appleLoading}
69
+ disabled={disabled}
70
+ icon="logo-apple"
71
+ fullWidth
72
+ style={styles.socialButton}
91
73
  >
92
- {appleLoading ? (
93
- <AtomicSpinner size="sm" color={tokens.colors.textPrimary} />
94
- ) : (
95
- <>
96
- <AtomicIcon name="logo-apple" size="sm" color="onSurface" />
97
- <AtomicText style={[styles.buttonText, { color: tokens.colors.textPrimary }]}>
98
- {t("auth.apple")}
99
- </AtomicText>
100
- </>
101
- )}
102
- </TouchableOpacity>
74
+ {t("auth.apple")}
75
+ </AtomicButton>
103
76
  )}
104
77
  </View>
105
78
  </View>
@@ -110,38 +83,13 @@ const styles = StyleSheet.create({
110
83
  container: {
111
84
  marginTop: 24,
112
85
  },
113
- dividerContainer: {
114
- flexDirection: "row",
115
- alignItems: "center",
116
- marginBottom: 20,
117
- },
118
- divider: {
119
- flex: 1,
120
- height: 1,
121
- },
122
- dividerText: {
123
- marginHorizontal: 16,
124
- },
125
86
  buttonsContainer: {
126
- flexDirection: "row",
87
+ flexDirection: 'row',
88
+ marginTop: 8,
127
89
  gap: 12,
128
90
  },
129
91
  socialButton: {
130
92
  flex: 1,
131
- flexDirection: "row",
132
- alignItems: "center",
133
- justifyContent: "center",
134
- paddingVertical: 14,
135
- borderRadius: 12,
136
- borderWidth: 1,
137
- gap: 8,
138
- },
139
- disabledButton: {
140
- opacity: 0.5,
141
- },
142
- buttonText: {
143
- fontSize: 16,
144
- fontWeight: "600",
145
93
  },
146
94
  });
147
95
 
@@ -8,6 +8,7 @@ import { useLocalization } from "@umituz/react-native-localization";
8
8
  import { useAuth } from "./useAuth";
9
9
  import { getAuthErrorLocalizationKey } from "../utils/getAuthErrorMessage";
10
10
  import { validateEmail, validatePasswordForLogin } from "../../infrastructure/utils/AuthValidation";
11
+ import { AlertService, alertService } from "@umituz/react-native-design-system";
11
12
 
12
13
  export interface UseLoginFormResult {
13
14
  email: string;
@@ -74,6 +75,11 @@ export function useLoginForm(): UseLoginFormResult {
74
75
 
75
76
  try {
76
77
  await signIn(email.trim(), password);
78
+
79
+ alertService.success(
80
+ t("auth.successTitle"),
81
+ t("auth.signInSuccess")
82
+ );
77
83
  } catch (err: unknown) {
78
84
  const localizationKey = getAuthErrorLocalizationKey(err);
79
85
  const errorMessage = t(localizationKey);
@@ -14,6 +14,7 @@ import { DEFAULT_PASSWORD_CONFIG } from "../../domain/value-objects/AuthConfig";
14
14
  import { useAuth } from "./useAuth";
15
15
  import { getAuthErrorLocalizationKey } from "../utils/getAuthErrorMessage";
16
16
  import type { PasswordRequirements } from "../../infrastructure/utils/AuthValidation";
17
+ import { AlertService, alertService } from "@umituz/react-native-design-system";
17
18
 
18
19
  export interface UseRegisterFormResult {
19
20
  displayName: string;
@@ -154,6 +155,11 @@ export function useRegisterForm(): UseRegisterFormResult {
154
155
  password,
155
156
  displayName.trim() || undefined,
156
157
  );
158
+
159
+ alertService.success(
160
+ t("auth.successTitle"),
161
+ t("auth.signUpSuccess")
162
+ );
157
163
  } catch (err: unknown) {
158
164
  const localizationKey = getAuthErrorLocalizationKey(err);
159
165
  const errorMessage = t(localizationKey);
@@ -4,12 +4,11 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { useAppNavigation } from "@umituz/react-native-design-system";
7
+ import { useAppNavigation, AtomicCard } from "@umituz/react-native-design-system";
8
8
  import { useLocalization } from "@umituz/react-native-localization";
9
9
  import type { AuthStackParamList } from "../navigation/AuthNavigator";
10
10
  import { AuthContainer } from "../components/AuthContainer";
11
11
  import { AuthHeader } from "../components/AuthHeader";
12
- import { AuthFormCard } from "../components/AuthFormCard";
13
12
  import { LoginForm } from "../components/LoginForm";
14
13
 
15
14
  export const LoginScreen: React.FC = () => {
@@ -23,9 +22,9 @@ export const LoginScreen: React.FC = () => {
23
22
  return (
24
23
  <AuthContainer>
25
24
  <AuthHeader title={t("auth.title")} />
26
- <AuthFormCard>
25
+ <AtomicCard variant="elevated" padding="large">
27
26
  <LoginForm onNavigateToRegister={handleNavigateToRegister} />
28
- </AuthFormCard>
27
+ </AtomicCard>
29
28
  </AuthContainer>
30
29
  );
31
30
  };
@@ -4,12 +4,11 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { useAppNavigation } from "@umituz/react-native-design-system";
7
+ import { useAppNavigation, AtomicCard } from "@umituz/react-native-design-system";
8
8
  import { useLocalization } from "@umituz/react-native-localization";
9
9
  import type { AuthStackParamList } from "../navigation/AuthNavigator";
10
10
  import { AuthContainer } from "../components/AuthContainer";
11
11
  import { AuthHeader } from "../components/AuthHeader";
12
- import { AuthFormCard } from "../components/AuthFormCard";
13
12
  import { RegisterForm } from "../components/RegisterForm";
14
13
 
15
14
  export interface RegisterScreenProps {
@@ -35,7 +34,7 @@ export const RegisterScreen: React.FC<RegisterScreenProps> = ({
35
34
  return (
36
35
  <AuthContainer>
37
36
  <AuthHeader title={t("auth.createAccount")} />
38
- <AuthFormCard>
37
+ <AtomicCard variant="elevated" padding="large">
39
38
  <RegisterForm
40
39
  onNavigateToLogin={handleNavigateToLogin}
41
40
  termsUrl={termsUrl}
@@ -43,7 +42,7 @@ export const RegisterScreen: React.FC<RegisterScreenProps> = ({
43
42
  onTermsPress={onTermsPress}
44
43
  onPrivacyPress={onPrivacyPress}
45
44
  />
46
- </AuthFormCard>
45
+ </AtomicCard>
47
46
  </AuthContainer>
48
47
  );
49
48
  };
@@ -1,21 +0,0 @@
1
- /**
2
- * Auth Background Component
3
- * Standard background for auth screens
4
- */
5
-
6
- import React from "react";
7
- import { StyleSheet, View } from "react-native";
8
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
9
-
10
- export const AuthBackground: React.FC = () => {
11
- const tokens = useAppDesignTokens();
12
-
13
- return (
14
- <View
15
- style={[
16
- StyleSheet.absoluteFill,
17
- { backgroundColor: tokens.colors.backgroundPrimary }
18
- ]}
19
- />
20
- );
21
- };
@@ -1,51 +0,0 @@
1
- /**
2
- * Auth Form Card Component
3
- * Reusable card container for auth forms
4
- */
5
-
6
- import React from "react";
7
- import { View, StyleSheet } from "react-native";
8
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
9
-
10
- interface AuthFormCardProps {
11
- children: React.ReactNode;
12
- }
13
-
14
- export const AuthFormCard: React.FC<AuthFormCardProps> = ({ children }) => {
15
- const tokens = useAppDesignTokens();
16
-
17
- return (
18
- <View
19
- style={[
20
- styles.formCard,
21
- {
22
- backgroundColor: tokens.colors.surface,
23
- borderRadius: tokens.borders.radius.xl,
24
- padding: tokens.spacing.lg,
25
- },
26
- ]}
27
- >
28
- <View style={styles.form}>{children}</View>
29
- </View>
30
- );
31
- };
32
-
33
- const styles = StyleSheet.create({
34
- formCard: {
35
- width: "100%",
36
- },
37
- form: {
38
- width: "100%",
39
- },
40
- });
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
@@ -1,24 +0,0 @@
1
- /**
2
- * Apple Icon SVG
3
- * Dark mode compatible Apple logo
4
- */
5
-
6
- import React from "react";
7
- import Svg, { Path } from "react-native-svg";
8
-
9
- export interface AppleIconSvgProps {
10
- size?: number;
11
- color: string;
12
- }
13
-
14
- export const AppleIconSvg: React.FC<AppleIconSvgProps> = ({
15
- size = 20,
16
- color,
17
- }) => (
18
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
19
- <Path
20
- d="M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.53 4.09l-.02-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"
21
- fill={color}
22
- />
23
- </Svg>
24
- );
@@ -1,32 +0,0 @@
1
- /**
2
- * Google Icon SVG
3
- * Standard Google logo with color
4
- */
5
-
6
- import React from "react";
7
- import Svg, { Path } from "react-native-svg";
8
-
9
- export interface GoogleIconSvgProps {
10
- size?: number;
11
- }
12
-
13
- export const GoogleIconSvg: React.FC<GoogleIconSvgProps> = ({ size = 20 }) => (
14
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
15
- <Path
16
- d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
17
- fill="#4285F4"
18
- />
19
- <Path
20
- d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
21
- fill="#34A853"
22
- />
23
- <Path
24
- d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
25
- fill="#FBBC05"
26
- />
27
- <Path
28
- d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
29
- fill="#EA4335"
30
- />
31
- </Svg>
32
- );
@@ -1,6 +0,0 @@
1
- /**
2
- * Social Login Icons
3
- */
4
-
5
- export { AppleIconSvg } from "./AppleIconSvg";
6
- export { GoogleIconSvg } from "./GoogleIconSvg";