@umituz/react-native-auth 2.7.3 → 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.
- package/package.json +33 -9
- package/src/application/ports/IAuthRepository.ts +11 -0
- package/src/infrastructure/adapters/StorageProviderAdapter.ts +26 -10
- package/src/infrastructure/adapters/UIProviderAdapter.ts +20 -9
- package/src/infrastructure/providers/FirebaseAuthProvider.ts +3 -2
- package/src/infrastructure/repositories/AuthRepository.ts +91 -0
- package/src/infrastructure/services/AuthPackage.ts +14 -6
- package/src/infrastructure/services/AuthService.ts +67 -119
- package/src/infrastructure/services/GuestModeService.ts +1 -6
- package/src/infrastructure/utils/AuthValidation.ts +15 -14
- package/src/infrastructure/utils/auth-tracker.util.ts +28 -0
- package/src/presentation/components/AccountActions.tsx +38 -50
- package/src/presentation/components/AuthBottomSheet.tsx +4 -4
- package/src/presentation/components/AuthDivider.tsx +0 -1
- package/src/presentation/components/AuthGradientBackground.tsx +1 -1
- package/src/presentation/components/AuthLegalLinks.tsx +7 -8
- package/src/presentation/components/EditProfileActions.tsx +53 -0
- package/src/presentation/components/EditProfileAvatar.tsx +33 -0
- package/src/presentation/components/EditProfileForm.tsx +55 -0
- package/src/presentation/components/LoginForm.tsx +1 -1
- package/src/presentation/components/PasswordMatchIndicator.tsx +6 -14
- package/src/presentation/components/PasswordStrengthIndicator.tsx +11 -17
- package/src/presentation/components/ProfileBenefitsList.tsx +47 -0
- package/src/presentation/components/ProfileSection.tsx +20 -85
- package/src/presentation/components/RegisterForm.tsx +6 -6
- package/src/presentation/components/SocialLoginButtons.tsx +11 -15
- package/src/presentation/hooks/mutations/useAuthMutations.ts +50 -0
- package/src/presentation/hooks/useAccountManagement.ts +2 -0
- package/src/presentation/hooks/useAuthActions.ts +19 -35
- package/src/presentation/hooks/useAuthState.ts +4 -1
- package/src/presentation/hooks/useLoginForm.ts +6 -8
- package/src/presentation/hooks/useProfileUpdate.ts +7 -7
- package/src/presentation/hooks/useRegisterForm.ts +16 -17
- package/src/presentation/hooks/useUserProfile.ts +3 -3
- package/src/presentation/navigation/AuthNavigator.tsx +10 -6
- package/src/presentation/screens/AccountScreen.tsx +9 -1
- package/src/presentation/screens/EditProfileScreen.tsx +40 -185
- package/src/presentation/screens/LoginScreen.tsx +4 -6
- package/src/presentation/screens/RegisterScreen.tsx +4 -6
- package/src/presentation/stores/authModalStore.ts +2 -1
- package/src/types/external.d.ts +31 -45
- package/src/infrastructure/services/AuthCoreService.ts +0 -138
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Mutations
|
|
3
|
+
* TanStack Query mutations for auth operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useMutation } from "@umituz/react-native-tanstack";
|
|
7
|
+
import { getAuthService } from "../../../infrastructure/services/AuthService";
|
|
8
|
+
import type { SignUpParams, SignInParams } from "../../../application/ports/IAuthService";
|
|
9
|
+
import type { AuthUser } from "../../../domain/entities/AuthUser";
|
|
10
|
+
|
|
11
|
+
export const useSignUpMutation = () => {
|
|
12
|
+
return useMutation({
|
|
13
|
+
mutationFn: async (params: SignUpParams): Promise<AuthUser> => {
|
|
14
|
+
const service = getAuthService();
|
|
15
|
+
if (!service) throw new Error("Auth Service not initialized");
|
|
16
|
+
// Access repository directly
|
|
17
|
+
return service.getRepository().signUp(params);
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const useSignInMutation = () => {
|
|
23
|
+
return useMutation({
|
|
24
|
+
mutationFn: async (params: SignInParams): Promise<AuthUser> => {
|
|
25
|
+
const service = getAuthService();
|
|
26
|
+
if (!service) throw new Error("Auth Service not initialized");
|
|
27
|
+
return service.getRepository().signIn(params);
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const useSignOutMutation = () => {
|
|
33
|
+
return useMutation({
|
|
34
|
+
mutationFn: async (): Promise<void> => {
|
|
35
|
+
const service = getAuthService();
|
|
36
|
+
if (!service) throw new Error("Auth Service not initialized");
|
|
37
|
+
return service.getRepository().signOut();
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const useGuestModeMutation = () => {
|
|
43
|
+
return useMutation({
|
|
44
|
+
mutationFn: async (): Promise<void> => {
|
|
45
|
+
const service = getAuthService();
|
|
46
|
+
if (!service) throw new Error("Auth Service not initialized");
|
|
47
|
+
return service.setGuestMode();
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
};
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* Generic hook - reauthentication is handled via callback from calling app
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument */
|
|
7
8
|
import { useCallback, useState } from "react";
|
|
8
9
|
import { useAuth } from "./useAuth";
|
|
10
|
+
// @ts-expect-error - Module def issue in node_modules vs types
|
|
9
11
|
import { deleteCurrentUser } from "@umituz/react-native-firebase";
|
|
10
12
|
|
|
11
13
|
export interface UseAccountManagementOptions {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useAuthActions Hook
|
|
3
|
-
* Single Responsibility: Handle authentication actions
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
1
|
import { useCallback } from "react";
|
|
7
|
-
import { getAuthService } from "../../infrastructure/services/AuthService";
|
|
8
2
|
import type { UseAuthStateResult } from "./useAuthState";
|
|
3
|
+
import {
|
|
4
|
+
useSignInMutation,
|
|
5
|
+
useSignUpMutation,
|
|
6
|
+
useSignOutMutation,
|
|
7
|
+
useGuestModeMutation,
|
|
8
|
+
} from "./mutations/useAuthMutations";
|
|
9
9
|
|
|
10
10
|
export interface UseAuthActionsResult {
|
|
11
11
|
signUp: (email: string, password: string, displayName?: string) => Promise<void>;
|
|
@@ -17,18 +17,17 @@ export interface UseAuthActionsResult {
|
|
|
17
17
|
export function useAuthActions(state: UseAuthStateResult): UseAuthActionsResult {
|
|
18
18
|
const { isGuest, setIsGuest, setLoading, setError } = state;
|
|
19
19
|
|
|
20
|
+
const signInMutation = useSignInMutation();
|
|
21
|
+
const signUpMutation = useSignUpMutation();
|
|
22
|
+
const signOutMutation = useSignOutMutation();
|
|
23
|
+
const guestModeMutation = useGuestModeMutation();
|
|
24
|
+
|
|
20
25
|
const signUp = useCallback(
|
|
21
26
|
async (email: string, password: string, displayName?: string) => {
|
|
22
|
-
const service = getAuthService();
|
|
23
|
-
if (!service) {
|
|
24
|
-
const err = "Auth service is not initialized";
|
|
25
|
-
setError(err);
|
|
26
|
-
throw new Error(err);
|
|
27
|
-
}
|
|
28
27
|
try {
|
|
29
28
|
setLoading(true);
|
|
30
29
|
setError(null);
|
|
31
|
-
await
|
|
30
|
+
await signUpMutation.mutateAsync({ email, password, displayName });
|
|
32
31
|
if (isGuest) {
|
|
33
32
|
setIsGuest(false);
|
|
34
33
|
}
|
|
@@ -40,21 +39,15 @@ export function useAuthActions(state: UseAuthStateResult): UseAuthActionsResult
|
|
|
40
39
|
setLoading(false);
|
|
41
40
|
}
|
|
42
41
|
},
|
|
43
|
-
[isGuest, setIsGuest, setLoading, setError],
|
|
42
|
+
[isGuest, setIsGuest, setLoading, setError, signUpMutation],
|
|
44
43
|
);
|
|
45
44
|
|
|
46
45
|
const signIn = useCallback(
|
|
47
46
|
async (email: string, password: string) => {
|
|
48
|
-
const service = getAuthService();
|
|
49
|
-
if (!service) {
|
|
50
|
-
const err = "Auth service is not initialized";
|
|
51
|
-
setError(err);
|
|
52
|
-
throw new Error(err);
|
|
53
|
-
}
|
|
54
47
|
try {
|
|
55
48
|
setLoading(true);
|
|
56
49
|
setError(null);
|
|
57
|
-
await
|
|
50
|
+
await signInMutation.mutateAsync({ email, password });
|
|
58
51
|
if (isGuest) {
|
|
59
52
|
setIsGuest(false);
|
|
60
53
|
}
|
|
@@ -66,38 +59,29 @@ export function useAuthActions(state: UseAuthStateResult): UseAuthActionsResult
|
|
|
66
59
|
setLoading(false);
|
|
67
60
|
}
|
|
68
61
|
},
|
|
69
|
-
[isGuest, setIsGuest, setLoading, setError],
|
|
62
|
+
[isGuest, setIsGuest, setLoading, setError, signInMutation],
|
|
70
63
|
);
|
|
71
64
|
|
|
72
65
|
const signOut = useCallback(async () => {
|
|
73
|
-
const service = getAuthService();
|
|
74
|
-
if (!service) return;
|
|
75
|
-
|
|
76
66
|
try {
|
|
77
67
|
setLoading(true);
|
|
78
|
-
await
|
|
68
|
+
await signOutMutation.mutateAsync();
|
|
79
69
|
} finally {
|
|
80
70
|
setLoading(false);
|
|
81
71
|
}
|
|
82
|
-
}, [setLoading]);
|
|
72
|
+
}, [setLoading, signOutMutation]);
|
|
83
73
|
|
|
84
74
|
const continueAsGuest = useCallback(async () => {
|
|
85
|
-
const service = getAuthService();
|
|
86
|
-
if (!service) {
|
|
87
|
-
setIsGuest(true);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
75
|
try {
|
|
92
76
|
setLoading(true);
|
|
93
|
-
await
|
|
77
|
+
await guestModeMutation.mutateAsync();
|
|
94
78
|
setIsGuest(true);
|
|
95
79
|
} catch {
|
|
96
80
|
setIsGuest(true);
|
|
97
81
|
} finally {
|
|
98
82
|
setLoading(false);
|
|
99
83
|
}
|
|
100
|
-
}, [setIsGuest, setLoading]);
|
|
84
|
+
}, [setIsGuest, setLoading, guestModeMutation]);
|
|
101
85
|
|
|
102
86
|
return {
|
|
103
87
|
signUp,
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
* Single Responsibility: Manage authentication state
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument */
|
|
6
7
|
import { useState, useEffect, useRef, useMemo } from "react";
|
|
7
8
|
import { DeviceEventEmitter } from "react-native";
|
|
8
9
|
import { getAuthService } from "../../infrastructure/services/AuthService";
|
|
10
|
+
// @ts-expect-error - Module def issue in node_modules vs types
|
|
9
11
|
import { useFirebaseAuth } from "@umituz/react-native-firebase";
|
|
10
12
|
import { mapToAuthUser } from "../../infrastructure/utils/UserMapper";
|
|
11
13
|
import type { AuthUser } from "../../domain/entities/AuthUser";
|
|
@@ -101,13 +103,14 @@ export function useAuthState(): UseAuthStateResult {
|
|
|
101
103
|
|
|
102
104
|
const errorSubscription = DeviceEventEmitter.addListener(
|
|
103
105
|
"auth-error",
|
|
104
|
-
(payload:
|
|
106
|
+
(payload: { error?: string }) => {
|
|
105
107
|
if (payload?.error) {
|
|
106
108
|
setError(payload.error);
|
|
107
109
|
}
|
|
108
110
|
}
|
|
109
111
|
);
|
|
110
112
|
|
|
113
|
+
|
|
111
114
|
return () => {
|
|
112
115
|
guestSubscription.remove();
|
|
113
116
|
authSubscription.remove();
|
|
@@ -7,7 +7,7 @@ import { useState, useCallback } from "react";
|
|
|
7
7
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
8
8
|
import { useAuth } from "./useAuth";
|
|
9
9
|
import { getAuthErrorLocalizationKey } from "../utils/getAuthErrorMessage";
|
|
10
|
-
import { validateEmail } from "../../infrastructure/utils/AuthValidation";
|
|
10
|
+
import { validateEmail, validatePasswordForLogin } from "../../infrastructure/utils/AuthValidation";
|
|
11
11
|
|
|
12
12
|
export interface UseLoginFormResult {
|
|
13
13
|
email: string;
|
|
@@ -59,16 +59,14 @@ export function useLoginForm(): UseLoginFormResult {
|
|
|
59
59
|
let hasError = false;
|
|
60
60
|
|
|
61
61
|
const emailResult = validateEmail(email.trim());
|
|
62
|
-
if (!emailResult.isValid) {
|
|
63
|
-
setEmailError(t(
|
|
62
|
+
if (!emailResult.isValid && emailResult.error) {
|
|
63
|
+
setEmailError(t(emailResult.error));
|
|
64
64
|
hasError = true;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
} else if (password.length < 6) {
|
|
71
|
-
setPasswordError(t("auth.errors.weakPassword"));
|
|
67
|
+
const passwordResult = validatePasswordForLogin(password);
|
|
68
|
+
if (!passwordResult.isValid && passwordResult.error) {
|
|
69
|
+
setPasswordError(t(passwordResult.error));
|
|
72
70
|
hasError = true;
|
|
73
71
|
}
|
|
74
72
|
|
|
@@ -16,22 +16,21 @@ export interface UseProfileUpdateReturn {
|
|
|
16
16
|
|
|
17
17
|
export const useProfileUpdate = (): UseProfileUpdateReturn => {
|
|
18
18
|
const { user } = useAuth();
|
|
19
|
-
const [isUpdating
|
|
20
|
-
const [error
|
|
19
|
+
const [isUpdating] = useState(false);
|
|
20
|
+
const [error] = useState<string | null>(null);
|
|
21
21
|
|
|
22
22
|
const updateProfile = useCallback(
|
|
23
|
-
|
|
23
|
+
(_params: UpdateProfileParams) => {
|
|
24
24
|
if (!user) {
|
|
25
|
-
|
|
25
|
+
return Promise.reject(new Error("No user logged in"));
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
if (user.isAnonymous) {
|
|
29
|
-
|
|
29
|
+
return Promise.reject(new Error("Anonymous users cannot update profile"));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
// Note: App should implement this via Firebase SDK
|
|
33
|
-
|
|
34
|
-
throw new Error("Profile update should be implemented by app");
|
|
33
|
+
return Promise.reject(new Error("Profile update should be implemented by app"));
|
|
35
34
|
},
|
|
36
35
|
[user],
|
|
37
36
|
);
|
|
@@ -42,3 +41,4 @@ export const useProfileUpdate = (): UseProfileUpdateReturn => {
|
|
|
42
41
|
error,
|
|
43
42
|
};
|
|
44
43
|
};
|
|
44
|
+
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
import { useState, useCallback, useMemo } from "react";
|
|
7
7
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
8
|
-
import { batchValidate } from "@umituz/react-native-validation";
|
|
9
8
|
import {
|
|
10
9
|
validateEmail,
|
|
11
10
|
validatePasswordForRegister,
|
|
@@ -85,8 +84,8 @@ export function useRegisterForm(): UseRegisterFormResult {
|
|
|
85
84
|
}
|
|
86
85
|
return next;
|
|
87
86
|
});
|
|
88
|
-
|
|
89
|
-
}, [
|
|
87
|
+
setLocalError(null);
|
|
88
|
+
}, []);
|
|
90
89
|
|
|
91
90
|
const handleEmailChange = useCallback((text: string) => {
|
|
92
91
|
setEmail(text);
|
|
@@ -97,8 +96,8 @@ export function useRegisterForm(): UseRegisterFormResult {
|
|
|
97
96
|
}
|
|
98
97
|
return next;
|
|
99
98
|
});
|
|
100
|
-
|
|
101
|
-
}, [
|
|
99
|
+
setLocalError(null);
|
|
100
|
+
}, []);
|
|
102
101
|
|
|
103
102
|
const handlePasswordChange = useCallback((text: string) => {
|
|
104
103
|
setPassword(text);
|
|
@@ -112,8 +111,8 @@ export function useRegisterForm(): UseRegisterFormResult {
|
|
|
112
111
|
}
|
|
113
112
|
return next;
|
|
114
113
|
});
|
|
115
|
-
|
|
116
|
-
}, [
|
|
114
|
+
setLocalError(null);
|
|
115
|
+
}, []);
|
|
117
116
|
|
|
118
117
|
const handleConfirmPasswordChange = useCallback((text: string) => {
|
|
119
118
|
setConfirmPassword(text);
|
|
@@ -124,29 +123,28 @@ export function useRegisterForm(): UseRegisterFormResult {
|
|
|
124
123
|
}
|
|
125
124
|
return next;
|
|
126
125
|
});
|
|
127
|
-
|
|
128
|
-
}, [
|
|
126
|
+
setLocalError(null);
|
|
127
|
+
}, []);
|
|
129
128
|
|
|
130
129
|
const handleSignUp = useCallback(async () => {
|
|
131
130
|
setLocalError(null);
|
|
132
131
|
setFieldErrors({});
|
|
133
132
|
|
|
134
|
-
// Manual validation since batchValidate is not available
|
|
135
133
|
const emailResult = validateEmail(email.trim());
|
|
136
|
-
if (!emailResult.isValid) {
|
|
137
|
-
setFieldErrors((prev) => ({ ...prev, email: emailResult.error }));
|
|
134
|
+
if (!emailResult.isValid && emailResult.error) {
|
|
135
|
+
setFieldErrors((prev) => ({ ...prev, email: t(emailResult.error as string) }));
|
|
138
136
|
return;
|
|
139
137
|
}
|
|
140
138
|
|
|
141
139
|
const passwordResult = validatePasswordForRegister(password, DEFAULT_PASSWORD_CONFIG);
|
|
142
|
-
if (!passwordResult.isValid) {
|
|
143
|
-
setFieldErrors((prev) => ({ ...prev, password: passwordResult.error }));
|
|
140
|
+
if (!passwordResult.isValid && passwordResult.error) {
|
|
141
|
+
setFieldErrors((prev) => ({ ...prev, password: t(passwordResult.error as string) }));
|
|
144
142
|
return;
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
const confirmResult = validatePasswordConfirmation(password, confirmPassword);
|
|
148
|
-
if (!confirmResult.isValid) {
|
|
149
|
-
setFieldErrors((prev) => ({ ...prev, confirmPassword: confirmResult.error }));
|
|
146
|
+
if (!confirmResult.isValid && confirmResult.error) {
|
|
147
|
+
setFieldErrors((prev) => ({ ...prev, confirmPassword: t(confirmResult.error as string) }));
|
|
150
148
|
return;
|
|
151
149
|
}
|
|
152
150
|
|
|
@@ -156,7 +154,7 @@ export function useRegisterForm(): UseRegisterFormResult {
|
|
|
156
154
|
password,
|
|
157
155
|
displayName.trim() || undefined,
|
|
158
156
|
);
|
|
159
|
-
} catch (err:
|
|
157
|
+
} catch (err: unknown) {
|
|
160
158
|
const localizationKey = getAuthErrorLocalizationKey(err);
|
|
161
159
|
const errorMessage = t(localizationKey);
|
|
162
160
|
setLocalError(errorMessage);
|
|
@@ -184,3 +182,4 @@ export function useRegisterForm(): UseRegisterFormResult {
|
|
|
184
182
|
};
|
|
185
183
|
}
|
|
186
184
|
|
|
185
|
+
|
|
@@ -9,7 +9,7 @@ import { useAuth } from "./useAuth";
|
|
|
9
9
|
import { generateGuestName, type GuestNameConfig } from "../../domain/utils/guestNameGenerator";
|
|
10
10
|
|
|
11
11
|
export interface UserProfileData {
|
|
12
|
-
displayName
|
|
12
|
+
displayName?: string;
|
|
13
13
|
userId?: string;
|
|
14
14
|
isAnonymous: boolean;
|
|
15
15
|
avatarUrl?: string;
|
|
@@ -27,8 +27,8 @@ export const useUserProfile = (
|
|
|
27
27
|
): UserProfileData | undefined => {
|
|
28
28
|
const { user } = useAuth();
|
|
29
29
|
|
|
30
|
-
const guestName = params?.guestDisplayName
|
|
31
|
-
const accountRoute = params?.accountRoute
|
|
30
|
+
const guestName = params?.guestDisplayName;
|
|
31
|
+
const accountRoute = params?.accountRoute;
|
|
32
32
|
const nameConfig = params?.guestNameConfig;
|
|
33
33
|
|
|
34
34
|
return useMemo(() => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import React, { useEffect, useState } from "react";
|
|
7
|
-
import { createStackNavigator } from "@react-navigation/stack";
|
|
7
|
+
import { createStackNavigator, StackScreenProps } from "@react-navigation/stack";
|
|
8
8
|
import { useAppDesignTokens } from "@umituz/react-native-design-system";
|
|
9
9
|
import { storageRepository } from "@umituz/react-native-storage";
|
|
10
10
|
import { unwrap } from "@umituz/react-native-storage";
|
|
@@ -16,7 +16,7 @@ export type AuthStackParamList = {
|
|
|
16
16
|
Register: undefined;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const AuthStack = createStackNavigator();
|
|
19
|
+
const AuthStack = createStackNavigator<AuthStackParamList>();
|
|
20
20
|
|
|
21
21
|
const SHOW_REGISTER_KEY = "auth_show_register";
|
|
22
22
|
|
|
@@ -51,15 +51,18 @@ export const AuthNavigator: React.FC<AuthNavigatorProps> = ({
|
|
|
51
51
|
>(undefined);
|
|
52
52
|
|
|
53
53
|
useEffect(() => {
|
|
54
|
-
|
|
54
|
+
const checkInitialRoute = async () => {
|
|
55
|
+
const result = await storageRepository.getString(SHOW_REGISTER_KEY, "false");
|
|
55
56
|
const value = unwrap(result, "false");
|
|
56
57
|
if (value === "true") {
|
|
57
58
|
setInitialRouteName("Register");
|
|
58
|
-
storageRepository.removeItem(SHOW_REGISTER_KEY);
|
|
59
|
+
void storageRepository.removeItem(SHOW_REGISTER_KEY);
|
|
59
60
|
} else {
|
|
60
61
|
setInitialRouteName("Login");
|
|
61
62
|
}
|
|
62
|
-
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
void checkInitialRoute();
|
|
63
66
|
}, []);
|
|
64
67
|
|
|
65
68
|
if (initialRouteName === undefined) {
|
|
@@ -76,7 +79,7 @@ export const AuthNavigator: React.FC<AuthNavigatorProps> = ({
|
|
|
76
79
|
>
|
|
77
80
|
<AuthStack.Screen name="Login" component={LoginScreen} />
|
|
78
81
|
<AuthStack.Screen name="Register">
|
|
79
|
-
{(props:
|
|
82
|
+
{(props: StackScreenProps<AuthStackParamList, "Register">) => (
|
|
80
83
|
<RegisterScreen
|
|
81
84
|
{...props}
|
|
82
85
|
termsUrl={termsUrl}
|
|
@@ -90,3 +93,4 @@ export const AuthNavigator: React.FC<AuthNavigatorProps> = ({
|
|
|
90
93
|
);
|
|
91
94
|
};
|
|
92
95
|
|
|
96
|
+
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import React from "react";
|
|
8
8
|
import { View, ScrollView, StyleSheet } from "react-native";
|
|
9
9
|
import { useAppDesignTokens } from "@umituz/react-native-design-system";
|
|
10
|
+
|
|
10
11
|
import { ProfileSection, type ProfileSectionConfig } from "../components/ProfileSection";
|
|
11
12
|
import { AccountActions, type AccountActionsConfig } from "../components/AccountActions";
|
|
12
13
|
|
|
@@ -23,6 +24,12 @@ export interface AccountScreenProps {
|
|
|
23
24
|
export const AccountScreen: React.FC<AccountScreenProps> = ({ config }) => {
|
|
24
25
|
const tokens = useAppDesignTokens();
|
|
25
26
|
|
|
27
|
+
const handleLogout = () => {
|
|
28
|
+
if (config.accountActions?.onLogout) {
|
|
29
|
+
void config.accountActions.onLogout();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
26
33
|
return (
|
|
27
34
|
<ScrollView
|
|
28
35
|
style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}
|
|
@@ -30,7 +37,7 @@ export const AccountScreen: React.FC<AccountScreenProps> = ({ config }) => {
|
|
|
30
37
|
>
|
|
31
38
|
<ProfileSection
|
|
32
39
|
profile={config.profile}
|
|
33
|
-
onSignIn={config.profile.isAnonymous ?
|
|
40
|
+
onSignIn={config.profile.isAnonymous ? handleLogout : undefined}
|
|
34
41
|
/>
|
|
35
42
|
|
|
36
43
|
{!config.isAnonymous && config.accountActions && (
|
|
@@ -54,3 +61,4 @@ const styles = StyleSheet.create({
|
|
|
54
61
|
height: 24,
|
|
55
62
|
},
|
|
56
63
|
});
|
|
64
|
+
|