@truworth/twc-auth 1.2.4 → 1.2.6

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 (116) hide show
  1. package/README.md +1 -4
  2. package/build/assets/email_icon.svg +6 -0
  3. package/build/src/api/axiosClient/index.js +1 -1
  4. package/build/src/api/axiosClient/index.native.js +1 -1
  5. package/build/src/components/VerifyMobileOTP/index.js +8 -6
  6. package/build/src/components/VerifyMobileOTP/index.native.js +6 -11
  7. package/build/src/constants/base-url/index.js +5 -0
  8. package/build/src/constants/base-url/index.native.js +1 -0
  9. package/build/src/constants/cdn-url/index.js +2 -1
  10. package/build/src/constants/social-login-options.js +16 -0
  11. package/build/src/contexts/AuthContext.js +6 -2
  12. package/build/src/enums/index.js +1 -0
  13. package/build/src/enums/loginMethod.enum.js +1 -1
  14. package/build/src/enums/socialLogins.enum.js +6 -0
  15. package/build/src/helpers/{Network.js → network.js} +1 -1
  16. package/build/src/hooks/useRequest.js +1 -1
  17. package/build/src/navigator/index.native.js +5 -1
  18. package/build/src/screens/EnterEmail/hooks/internal/useEnterEmail.js +50 -41
  19. package/build/src/screens/EnterEmail/index.js +37 -11
  20. package/build/src/screens/EnterEmail/index.native.js +6 -9
  21. package/build/src/screens/EnterMobile/components/ExistingAccountsSheet/hooks/internal/useExistingAccountsSheet.js +36 -0
  22. package/build/src/screens/EnterMobile/components/ExistingAccountsSheet/index.js +33 -0
  23. package/build/src/screens/EnterMobile/components/ExistingAccountsSheet/index.native.js +73 -0
  24. package/build/src/screens/EnterMobile/components/ExistingAccountsSheet/types.js +1 -0
  25. package/build/src/screens/EnterMobile/hooks/internal/useEnterMobile.js +67 -0
  26. package/build/src/screens/EnterMobile/index.js +82 -0
  27. package/build/src/screens/EnterMobile/index.native.js +56 -0
  28. package/build/src/screens/EnterMobile/types.js +1 -0
  29. package/build/src/screens/EnterPassword/hooks/internal/useEnterPassword.js +42 -31
  30. package/build/src/screens/EnterPassword/index.js +6 -6
  31. package/build/src/screens/EnterPassword/index.native.js +5 -10
  32. package/build/src/screens/Login/components/LoginWebComponent/index.js +4 -1
  33. package/build/src/screens/LoginWithEmailOTP/hooks/internal/useLoginWithEmailOTP.js +8 -5
  34. package/build/src/screens/LoginWithMobileOTP/hooks/internal/useLoginWithMobileOTP.js +71 -0
  35. package/build/src/screens/LoginWithMobileOTP/index.js +8 -0
  36. package/build/src/screens/LoginWithMobileOTP/index.native.js +10 -0
  37. package/build/src/screens/SSOLogin/AuthenticationMethods/index.js +9 -8
  38. package/build/src/screens/SSOLogin/AuthenticationMethods/index.native.js +2 -6
  39. package/build/src/screens/SignUp/components/SignUpForm/index.js +20 -5
  40. package/build/src/screens/SignUp/components/SignUpWebComponent/index.js +12 -2
  41. package/build/src/screens/SignUp/hooks/internal/useSignUp.js +1 -1
  42. package/build/src/screens/SignUp/index.native.js +17 -13
  43. package/build/src/screens/UserConsent/hooks/internal/useConsent.js +10 -1
  44. package/build/src/screens/UserConsent/index.js +1 -1
  45. package/build/src/screens/VerifyLinkPrimaryAccountEmailOTP/hooks/internal/useVerifyLinkPrimaryAccountEmailOTP.js +73 -0
  46. package/build/src/screens/VerifyLinkPrimaryAccountEmailOTP/index.js +8 -0
  47. package/build/src/screens/VerifyLinkPrimaryAccountEmailOTP/index.native.js +14 -0
  48. package/build/src/screens/VerifyLinkPrimaryAccountEmailOTP/types.js +1 -0
  49. package/build/src/screens/VerifyLinkPrimaryAccountMobileOTP/hooks/internal/useVerifyLinkPrimaryAccountMobileOTP.js +82 -0
  50. package/build/src/screens/VerifyLinkPrimaryAccountMobileOTP/index.js +8 -0
  51. package/build/src/screens/VerifyLinkPrimaryAccountMobileOTP/index.native.js +10 -0
  52. package/build/src/screens/VerifyLinkPrimaryAccountMobileOTP/types.js +1 -0
  53. package/build/src/screens/Welcome/SocialAuth/commonSocialAuth.js +127 -0
  54. package/build/src/screens/Welcome/SocialAuth/hooks/useSocialAuth.native.js +192 -0
  55. package/build/src/screens/Welcome/SocialAuth/hooks/useSocialAuth.web.js +13 -0
  56. package/build/src/screens/Welcome/SocialAuth/hooks/web/useFacebookAuth.web.js +118 -0
  57. package/build/src/screens/Welcome/SocialAuth/hooks/web/useGoogleAuth.web.js +75 -0
  58. package/build/src/screens/Welcome/components/SocialLoginModal/index.js +9 -0
  59. package/build/src/screens/Welcome/components/SocialLoginModal/index.native.js +21 -0
  60. package/build/src/screens/Welcome/components/SocialLoginModal/types.js +1 -0
  61. package/build/src/screens/Welcome/hooks/internal/useWelcome.js +10 -5
  62. package/build/src/screens/Welcome/index.js +3 -2
  63. package/build/src/screens/Welcome/index.native.js +41 -4
  64. package/build/types/components/VerifyMobileOTP/index.d.ts +1 -1
  65. package/build/types/components/VerifyMobileOTP/types.d.ts +0 -1
  66. package/build/types/constants/base-url/index.d.ts +1 -0
  67. package/build/types/constants/base-url/index.native.d.ts +1 -0
  68. package/build/types/constants/cdn-url/index.d.ts +2 -1
  69. package/build/types/constants/social-login-options.d.ts +3 -0
  70. package/build/types/contexts/AuthContext.d.ts +3 -1
  71. package/build/types/contexts/type.d.ts +12 -0
  72. package/build/types/enums/index.d.ts +1 -0
  73. package/build/types/enums/loginMethod.enum.d.ts +1 -1
  74. package/build/types/enums/socialLogins.enum.d.ts +5 -0
  75. package/build/types/helpers/types.d.ts +7 -1
  76. package/build/types/navigator/index.native.d.ts +17 -0
  77. package/build/types/screens/EnterEmail/hooks/internal/useEnterEmail.d.ts +11 -15
  78. package/build/types/screens/EnterEmail/types.d.ts +6 -1
  79. package/build/types/screens/EnterMobile/components/ExistingAccountsSheet/hooks/internal/useExistingAccountsSheet.d.ts +13 -0
  80. package/build/types/screens/EnterMobile/components/ExistingAccountsSheet/index.d.ts +3 -0
  81. package/build/types/screens/EnterMobile/components/ExistingAccountsSheet/index.native.d.ts +3 -0
  82. package/build/types/screens/EnterMobile/components/ExistingAccountsSheet/types.d.ts +28 -0
  83. package/build/types/screens/EnterMobile/hooks/internal/useEnterMobile.d.ts +15 -0
  84. package/build/types/screens/EnterMobile/index.d.ts +4 -0
  85. package/build/types/screens/EnterMobile/index.native.d.ts +4 -0
  86. package/build/types/screens/EnterMobile/types.d.ts +44 -0
  87. package/build/types/screens/EnterPassword/hooks/internal/useEnterPassword.d.ts +8 -8
  88. package/build/types/screens/LoginWithEmailOTP/hooks/internal/useLoginWithEmailOTP.d.ts +1 -1
  89. package/build/types/screens/LoginWithMobileOTP/hooks/internal/useLoginWithMobileOTP.d.ts +11 -0
  90. package/build/types/screens/LoginWithMobileOTP/index.d.ts +5 -0
  91. package/build/types/screens/LoginWithMobileOTP/index.native.d.ts +4 -0
  92. package/build/types/screens/SSOLogin/AuthenticationMethods/index.d.ts +1 -1
  93. package/build/types/screens/SSOLogin/AuthenticationMethods/types.d.ts +1 -0
  94. package/build/types/screens/VerifyLinkPrimaryAccountEmailOTP/hooks/internal/useVerifyLinkPrimaryAccountEmailOTP.d.ts +15 -0
  95. package/build/types/screens/VerifyLinkPrimaryAccountEmailOTP/index.d.ts +3 -0
  96. package/build/types/screens/VerifyLinkPrimaryAccountEmailOTP/index.native.d.ts +4 -0
  97. package/build/types/screens/VerifyLinkPrimaryAccountEmailOTP/types.d.ts +14 -0
  98. package/build/types/screens/VerifyLinkPrimaryAccountMobileOTP/hooks/internal/useVerifyLinkPrimaryAccountMobileOTP.d.ts +17 -0
  99. package/build/types/screens/VerifyLinkPrimaryAccountMobileOTP/index.d.ts +3 -0
  100. package/build/types/screens/VerifyLinkPrimaryAccountMobileOTP/index.native.d.ts +4 -0
  101. package/build/types/screens/VerifyLinkPrimaryAccountMobileOTP/types.d.ts +5 -0
  102. package/build/types/screens/Welcome/SocialAuth/commonSocialAuth.d.ts +50 -0
  103. package/build/types/screens/Welcome/SocialAuth/hooks/useSocialAuth.native.d.ts +7 -0
  104. package/build/types/screens/Welcome/SocialAuth/hooks/useSocialAuth.web.d.ts +7 -0
  105. package/build/types/screens/Welcome/SocialAuth/hooks/web/useFacebookAuth.web.d.ts +5 -0
  106. package/build/types/screens/Welcome/SocialAuth/hooks/web/useGoogleAuth.web.d.ts +4 -0
  107. package/build/types/screens/Welcome/components/SocialLoginModal/index.d.ts +3 -0
  108. package/build/types/screens/Welcome/components/SocialLoginModal/index.native.d.ts +3 -0
  109. package/build/types/screens/Welcome/components/SocialLoginModal/types.d.ts +8 -0
  110. package/build/types/screens/Welcome/hooks/internal/useWelcome.d.ts +8 -0
  111. package/build/types/types/types.d.ts +3 -0
  112. package/package.json +3 -5
  113. package/build/assets/okay_icon copy.svg +0 -3
  114. /package/build/src/helpers/{Validation.js → validation.js} +0 -0
  115. /package/build/types/helpers/{Network.d.ts → network.d.ts} +0 -0
  116. /package/build/types/helpers/{Validation.d.ts → validation.d.ts} +0 -0
@@ -0,0 +1,192 @@
1
+ import { useCallback, useState } from "react";
2
+ import { Alert, Linking, Platform } from "react-native";
3
+ import { useAuthPackageContext } from "../../../../hooks/internal/useAuthPackageContext";
4
+ import { useNavigation } from "@react-navigation/native";
5
+ import { GoogleSignin } from "@react-native-google-signin/google-signin";
6
+ import { handleAppleAuth, handleFacebookAuth, handleGoogleAuth, SocialAuthStatus } from "../commonSocialAuth";
7
+ import { RegistrationMethod, SocialLoginsEnum } from "../../../../enums";
8
+ import { showMessage } from "../../../../helpers/show-message";
9
+ import { AccessToken, GraphRequest, GraphRequestManager, LoginManager } from "react-native-fbsdk-next";
10
+ import AppleAuth, { AppleAuthRequestOperation, AppleAuthRequestScope, AppleAuthCredentialState } from '@invertase/react-native-apple-authentication';
11
+ import { axiosClient } from "../../../../api/axiosClient";
12
+ const useSocialAuth = () => {
13
+ const [loading, setLoading] = useState(false);
14
+ const { onLogin, socialLoginConfig, onRegistrationMethodChange } = useAuthPackageContext();
15
+ const navigation = useNavigation();
16
+ const googleAppId = socialLoginConfig?.google?.webClientId;
17
+ const loginWithGoogle = useCallback(async () => {
18
+ try {
19
+ setLoading(true);
20
+ GoogleSignin.configure({ webClientId: googleAppId });
21
+ await GoogleSignin.hasPlayServices();
22
+ const googleResponse = await GoogleSignin.signIn();
23
+ const { user, idToken } = googleResponse.data || {};
24
+ if (!user || !idToken) {
25
+ return showMessage({
26
+ message: "Google login failed",
27
+ type: "error"
28
+ });
29
+ }
30
+ const result = await handleGoogleAuth({
31
+ email: user.email,
32
+ googleIdentityToken: idToken,
33
+ platform: Platform.OS === "ios" ? "ios" : "android",
34
+ });
35
+ return handleSocialAuthResult(result, {
36
+ email: user.email,
37
+ firstName: user.givenName ?? '',
38
+ lastName: user.familyName ?? '',
39
+ googleUserId: user.id,
40
+ }, SocialLoginsEnum.Google);
41
+ }
42
+ catch (err) {
43
+ console.error("Google login failed:", err);
44
+ return { error: err };
45
+ }
46
+ finally {
47
+ setLoading(false);
48
+ }
49
+ }, [googleAppId]);
50
+ const loginWithFacebook = useCallback(async () => {
51
+ try {
52
+ const facebookResponse = await LoginManager.logInWithPermissions(['public_profile', 'email']);
53
+ if (facebookResponse.isCancelled) {
54
+ return;
55
+ }
56
+ setLoading(true);
57
+ const fbAccessToken = await AccessToken.getCurrentAccessToken();
58
+ const profile = await new Promise((resolve, reject) => {
59
+ new GraphRequestManager().addRequest(new GraphRequest('/me', {
60
+ accessToken: fbAccessToken?.accessToken,
61
+ parameters: { fields: { string: 'email,name' } },
62
+ }, (err, res) => (err ? reject(err) : resolve(res)))).start();
63
+ });
64
+ if (!profile.email || !profile.id) {
65
+ return showMessage({
66
+ message: "Facebook login failed",
67
+ type: "error"
68
+ });
69
+ }
70
+ const nameParts = profile.name?.split(' ') || [];
71
+ const firstName = nameParts[0] || undefined;
72
+ const lastName = nameParts.slice(1).join(' ') || undefined;
73
+ const result = await handleFacebookAuth({
74
+ email: profile.email,
75
+ facebookIdentityToken: fbAccessToken?.accessToken ?? '',
76
+ platform: Platform.OS === "ios" ? "ios" : "android",
77
+ });
78
+ return handleSocialAuthResult(result, {
79
+ email: profile.email,
80
+ firstName,
81
+ lastName,
82
+ fbUserId: profile.id
83
+ }, SocialLoginsEnum.Facebook);
84
+ }
85
+ catch (err) {
86
+ console.error("Facebook login failed:", err);
87
+ return { error: err };
88
+ }
89
+ finally {
90
+ setLoading(false);
91
+ }
92
+ }, []);
93
+ const loginWithApple = useCallback(async () => {
94
+ try {
95
+ const appleAuthResponse = await AppleAuth.performRequest({
96
+ requestedOperation: AppleAuthRequestOperation.LOGIN,
97
+ requestedScopes: [AppleAuthRequestScope.EMAIL,
98
+ AppleAuthRequestScope.FULL_NAME],
99
+ });
100
+ const credentialState = await AppleAuth.getCredentialStateForUser(appleAuthResponse.user);
101
+ if (credentialState !== AppleAuthCredentialState.AUTHORIZED) {
102
+ return;
103
+ }
104
+ setLoading(true);
105
+ if (!appleAuthResponse.email) {
106
+ try {
107
+ const { data } = await axiosClient.post('/auth/apple', {
108
+ token: appleAuthResponse.identityToken,
109
+ source: Platform.OS,
110
+ });
111
+ onLogin({
112
+ token: data.token,
113
+ member: data.member
114
+ });
115
+ return;
116
+ }
117
+ catch (error) {
118
+ return Alert.alert('Account Not Found!', "The Wellness Corner account linked with this Apple ID was not found. Please unlink this Apple ID from The Wellness Corner app and try again. To stop using this Apple ID with The Wellness Corner, tap on 'Know More' below.", [
119
+ {
120
+ text: 'Know More',
121
+ style: 'default',
122
+ onPress: () => Linking.openURL('https://support.apple.com/en-in/HT210426')
123
+ },
124
+ {
125
+ text: 'Cancel',
126
+ style: 'cancel'
127
+ }
128
+ ], { cancelable: true });
129
+ }
130
+ finally {
131
+ setLoading(false);
132
+ }
133
+ }
134
+ if (!appleAuthResponse.identityToken || !appleAuthResponse.email) {
135
+ return showMessage({
136
+ message: "Apple login failed",
137
+ type: "error"
138
+ });
139
+ }
140
+ const result = await handleAppleAuth({
141
+ email: appleAuthResponse.email,
142
+ appleIdentityToken: appleAuthResponse.identityToken,
143
+ platform: Platform.OS === "ios" ? "ios" : "android",
144
+ });
145
+ return handleSocialAuthResult(result, {
146
+ email: appleAuthResponse.email,
147
+ firstName: appleAuthResponse.fullName?.givenName ?? '',
148
+ lastName: appleAuthResponse.fullName?.familyName ?? '',
149
+ appleUserId: appleAuthResponse.user
150
+ }, SocialLoginsEnum.Apple);
151
+ }
152
+ catch (error) {
153
+ console.error("Apple login failed:", error);
154
+ return { error: error };
155
+ }
156
+ finally {
157
+ setLoading(false);
158
+ }
159
+ }, []);
160
+ const providerCleanup = {
161
+ google: () => GoogleSignin.signOut(),
162
+ facebook: () => LoginManager.logOut(),
163
+ apple: () => Promise.resolve(), // Apple doesn't need explicit cleanup
164
+ };
165
+ const handleSocialAuthResult = async (result, userData, providerName) => {
166
+ switch (result.status) {
167
+ case SocialAuthStatus.REGISTER:
168
+ onRegistrationMethodChange(RegistrationMethod.SOCIAL);
169
+ return navigation.navigate('SignUp', userData);
170
+ case SocialAuthStatus.INVALID:
171
+ // Clean up provider session
172
+ await providerCleanup[providerName]();
173
+ return showMessage({
174
+ message: `You have previously registered using your ${result.data.existingLoginType}. Please use your ${result.data.existingLoginType} to login.`,
175
+ type: 'error'
176
+ });
177
+ case SocialAuthStatus.SUCCESS:
178
+ onLogin({
179
+ token: result.data.token,
180
+ member: result.data.member
181
+ });
182
+ break;
183
+ }
184
+ };
185
+ return {
186
+ loading,
187
+ loginWithGoogle,
188
+ loginWithFacebook,
189
+ loginWithApple
190
+ };
191
+ };
192
+ export { useSocialAuth };
@@ -0,0 +1,13 @@
1
+ import { useFacebookAuth } from "./web/useFacebookAuth.web";
2
+ import { useGoogleAuth } from "./web/useGoogleAuth.web";
3
+ const useSocialAuth = () => {
4
+ const { loginWithGoogle, googleSignOut } = useGoogleAuth();
5
+ const { loginWithFacebook, facebookSignOut } = useFacebookAuth();
6
+ return {
7
+ loginWithGoogle,
8
+ googleSignOut,
9
+ loginWithFacebook,
10
+ facebookSignOut
11
+ };
12
+ };
13
+ export { useSocialAuth };
@@ -0,0 +1,118 @@
1
+ import { useEffect, useCallback, useState } from "react";
2
+ import { useRouter } from "next/router";
3
+ import { useAuthPackageContext } from "../../../../../hooks/internal/useAuthPackageContext";
4
+ import { RegistrationMethod } from "../../../../../enums";
5
+ import { handleFacebookAuth } from "../../commonSocialAuth";
6
+ import { showMessage } from "../../../../../helpers/show-message";
7
+ export const useFacebookAuth = () => {
8
+ const [error, setError] = useState(null);
9
+ const { onLogin, socialLoginConfig, onRegistrationMethodChange } = useAuthPackageContext();
10
+ const router = useRouter();
11
+ const facebookAppId = socialLoginConfig?.facebook?.webClientId;
12
+ // Load Facebook SDK once
13
+ useEffect(() => {
14
+ if (!facebookAppId) {
15
+ return;
16
+ }
17
+ (function (d, s, id) {
18
+ var js, fjs = d.getElementsByTagName(s)[0];
19
+ if (d.getElementById(id)) {
20
+ return;
21
+ }
22
+ js = d.createElement(s);
23
+ js.id = id;
24
+ js.src = "https://connect.facebook.net/en_US/sdk.js";
25
+ if (fjs && fjs.parentNode) {
26
+ fjs.parentNode.insertBefore(js, fjs);
27
+ }
28
+ }(document, 'script', 'facebook-jssdk'));
29
+ initFacebookSdk();
30
+ }, [facebookAppId]);
31
+ const initFacebookSdk = () => {
32
+ window.fbAsyncInit = () => {
33
+ window.FB.init({
34
+ appId: facebookAppId,
35
+ cookie: true,
36
+ xfbml: true,
37
+ version: 'v16.0'
38
+ });
39
+ };
40
+ };
41
+ const loginWithFacebook = () => {
42
+ if (!window.FB) {
43
+ showMessage({
44
+ message: "Facebook login is still initialising. Please try again in a moment.",
45
+ type: "warning",
46
+ });
47
+ return;
48
+ }
49
+ window.FB.login(() => checkLoginState(), {
50
+ scope: "public_profile,email",
51
+ return_scopes: true,
52
+ });
53
+ };
54
+ const checkLoginState = () => window.FB.getLoginStatus((response) => {
55
+ statusChangeCallback(response);
56
+ });
57
+ // ✅ Handle status
58
+ const statusChangeCallback = useCallback(async (response) => {
59
+ try {
60
+ if (response.status === "connected") {
61
+ const accessToken = response.authResponse.accessToken;
62
+ window.FB.api("/me", { fields: "name,email" }, async (userResponse) => {
63
+ const { email, name, id: fbUserId } = userResponse;
64
+ if (!email) {
65
+ facebookSignOut();
66
+ showMessage({
67
+ message: "We couldn’t retrieve your Facebook email. Please use another login method or update your Facebook permissions.",
68
+ type: "error",
69
+ });
70
+ return;
71
+ }
72
+ const nameParts = name.split(" ");
73
+ //{ error, isValid, loginType } = await verifyLoginType(email, LoginMethodCode.Facebook);
74
+ const result = await handleFacebookAuth({
75
+ email,
76
+ facebookIdentityToken: accessToken,
77
+ platform: "web",
78
+ });
79
+ switch (result.status) {
80
+ case "REGISTER":
81
+ onRegistrationMethodChange(RegistrationMethod.SOCIAL);
82
+ return router.push({
83
+ pathname: "/registration",
84
+ query: {
85
+ email,
86
+ firstName: nameParts[0],
87
+ lastName: nameParts[1] || "",
88
+ fbUserId,
89
+ },
90
+ });
91
+ case "INVALID":
92
+ facebookSignOut();
93
+ return showMessage({
94
+ message: `You have previously registered using your ${result.data.existingLoginType}. Please use your ${result.data.existingLoginType} to login method.`,
95
+ type: "error",
96
+ });
97
+ case "SUCCESS":
98
+ onLogin({
99
+ token: result.data.token,
100
+ member: result.data.member
101
+ });
102
+ break;
103
+ }
104
+ });
105
+ }
106
+ }
107
+ catch (error) {
108
+ console.error("Google login failed:", error);
109
+ setError(error);
110
+ return { error };
111
+ }
112
+ }, []);
113
+ // ✅ Logout
114
+ const facebookSignOut = useCallback(() => {
115
+ window.FB.api("/me/permissions", "delete", null, () => window.FB.logout((res) => statusChangeCallback(res)));
116
+ }, [statusChangeCallback]);
117
+ return { loginWithFacebook, facebookSignOut, error };
118
+ };
@@ -0,0 +1,75 @@
1
+ import { useCallback } from "react";
2
+ import { useGoogleLogin } from "react-google-login";
3
+ import { useAuthPackageContext } from "../../../../../hooks/internal/useAuthPackageContext";
4
+ import { showMessage } from "../../../../../helpers/show-message";
5
+ import { RegistrationMethod } from "../../../../../enums";
6
+ import { useRouter } from "next/router";
7
+ import { handleGoogleAuth } from "../../commonSocialAuth";
8
+ export const useGoogleAuth = () => {
9
+ const router = useRouter();
10
+ const { onLogin, socialLoginConfig, onRegistrationMethodChange } = useAuthPackageContext();
11
+ const googleAppId = socialLoginConfig?.google?.webClientId;
12
+ const onSuccess = async (response) => {
13
+ const { tokenId, profileObj, googleId } = response;
14
+ const { email, givenName, familyName } = profileObj;
15
+ const result = await handleGoogleAuth({
16
+ email,
17
+ googleIdentityToken: tokenId,
18
+ platform: "web",
19
+ });
20
+ switch (result.status) {
21
+ case "REGISTER":
22
+ onRegistrationMethodChange(RegistrationMethod.SOCIAL);
23
+ return router.push({
24
+ pathname: "/registration",
25
+ query: {
26
+ email,
27
+ firstName: givenName,
28
+ lastName: familyName,
29
+ googleUserId: googleId,
30
+ },
31
+ });
32
+ case "INVALID":
33
+ googleSignOut();
34
+ return showMessage({
35
+ message: `You have previously registered using your ${result.data.existingLoginType}. Please use your ${result.data.existingLoginType} to login method.`,
36
+ type: "error",
37
+ });
38
+ case "SUCCESS":
39
+ onLogin({
40
+ token: result.data.token,
41
+ member: result.data.member
42
+ });
43
+ break;
44
+ }
45
+ };
46
+ const onFailure = (response) => {
47
+ if (response.error === "popup_closed_by_user") {
48
+ showMessage({
49
+ message: "If you tried logging in with Google and seeing this error then please enable third-party cookies and try again.",
50
+ type: "warning"
51
+ });
52
+ }
53
+ };
54
+ const { signIn } = useGoogleLogin({
55
+ clientId: googleAppId || "",
56
+ onSuccess,
57
+ onFailure,
58
+ isSignedIn: false,
59
+ accessType: "offline",
60
+ cookiePolicy: "single_host_origin",
61
+ });
62
+ const loginWithGoogle = useCallback(() => {
63
+ if (!googleAppId) {
64
+ return;
65
+ }
66
+ return signIn();
67
+ }, [googleAppId, signIn]);
68
+ const googleSignOut = useCallback(() => {
69
+ const auth2 = window.gapi?.auth2?.getAuthInstance?.();
70
+ if (auth2) {
71
+ auth2.signOut().then(() => auth2.disconnect());
72
+ }
73
+ }, []);
74
+ return { loginWithGoogle, googleSignOut };
75
+ };
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Flex, ResponsiveModal, Typography } from "@truworth/twc-web-design";
3
+ const SocialLoginModal = ({ visible, hide, socialLoginType, onClick }) => {
4
+ return (_jsxs(ResponsiveModal, { title: _jsx(Typography, { type: "heading", size: "h6", className: "text-center mb-0", children: "Corporate Users" }), open: visible, onClose: hide, showCloseButton: false, children: [_jsxs(Typography, { type: "body", size: "small", children: ["If you are a corporate user, you will", ' ', _jsx("span", { style: { textDecoration: 'underline' }, children: "NOT" }), ' ', "be able to avail all the health benefits offered on The Wellness Corner by your employer if you login through ", socialLoginType, ".", _jsxs(Flex, { direction: "column", className: "mt-3", children: ["In that case you will have to go back ", '&', " register using your official Email Address."] })] }), _jsx(Button, { label: "I understand, I'm NOT a corporate user", className: "mt-4", onClick: (e) => {
5
+ e.preventDefault();
6
+ onClick();
7
+ } })] }));
8
+ };
9
+ export { SocialLoginModal };
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect } from 'react';
3
+ import { Text } from 'react-native';
4
+ import { BottomSheet, RoundedButton } from '@truworth/twc-rn-common';
5
+ import { useModalize } from 'react-native-modalize';
6
+ const SocialLoginModal = ({ visible, hide, socialLoginType, onClick }) => {
7
+ const { ref: socialSheetRef, open: openSheet, close: closeSheet } = useModalize();
8
+ useEffect(() => {
9
+ if (visible) {
10
+ openSheet();
11
+ }
12
+ else {
13
+ closeSheet();
14
+ }
15
+ }, [visible]);
16
+ return (_jsxs(BottomSheet, { title: 'Corporate Users', sheetRef: socialSheetRef, childrenStyle: { padding: 16 }, onClose: hide, children: [_jsxs(Text, { style: {
17
+ fontSize: 12, fontWeight: '600', color: '#000',
18
+ lineHeight: 16, marginBottom: 30,
19
+ }, children: ["If you are a corporate user, you will", ' ', _jsx(Text, { style: { textDecorationLine: 'underline' }, children: "NOT" }), ' ', "be able to avail all the health benefits offered on The Wellness Corner by your employer if you login through ", socialLoginType, ".", '\n', '\n', "In that case you will have to go back ", '&', " register using your official Email Address."] }), _jsx(RoundedButton, { label: "I understand, I'm NOT a corporate user", onPress: onClick })] }));
20
+ };
21
+ export { SocialLoginModal };
@@ -1,6 +1,7 @@
1
1
  import { useState } from "react";
2
- import { useAuthContext } from "../../../../hooks/useAuthContext";
3
2
  import { useAuthPackageContext } from "../../../../hooks/internal/useAuthPackageContext";
3
+ import { SocialLoginsEnum } from "../../../../enums";
4
+ import { socialLoginOptions } from "../../../../constants/social-login-options";
4
5
  /**
5
6
  * @internal
6
7
  * Hook for managing Welcome screen state and auth context integration.
@@ -9,13 +10,17 @@ import { useAuthPackageContext } from "../../../../hooks/internal/useAuthPackage
9
10
  const useWelcome = () => {
10
11
  const [loading, setLoading] = useState(false);
11
12
  const [showSocialLoginModal, setShowSocialLoginModal] = useState(false);
12
- const { LogoComponent, onLaunchAuthSession } = useAuthPackageContext();
13
+ const [socialLoginType, setSocialLoginType] = useState();
14
+ const { LogoComponent, socialLoginConfig, onLaunchAuthSession } = useAuthPackageContext();
15
+ const isSocialLoginEnabled = socialLoginOptions.some(({ type }) => socialLoginConfig?.[type]?.enabled);
13
16
  return {
14
- loading,
15
- setLoading,
17
+ loading, setLoading,
16
18
  showSocialLoginModal, setShowSocialLoginModal,
19
+ socialLoginType, setSocialLoginType,
17
20
  LogoComponent,
18
- onLaunchAuthSession
21
+ onLaunchAuthSession,
22
+ socialLoginConfig,
23
+ isSocialLoginEnabled,
19
24
  };
20
25
  };
21
26
  export { useWelcome };
@@ -1,9 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
- import { CDN_IMAGES_URL, IonIcon } from "@truworth/twc-web-common";
3
+ import { CDN_IMAGES_URL } from "../../constants/cdn-url";
4
4
  import { Button, Flex, Typography } from "@truworth/twc-web-design";
5
5
  import { AdvancedTransitionWrapper } from "../../components/AdvancedTransitionWrapper";
6
6
  import { useWelcome } from "./hooks/internal/useWelcome";
7
+ import { Mail } from "lucide-react";
7
8
  const Welcome = ({ onClickEnterEmail }) => {
8
9
  const { LogoComponent } = useWelcome();
9
10
  const renderLogo = () => {
@@ -22,6 +23,6 @@ const Welcome = ({ onClickEnterEmail }) => {
22
23
  // Fallback to default logo
23
24
  return (_jsx("img", { width: 160, height: 35, className: 'md:mt-0 mt-6 md:h-[40px] h-[30px]', src: `${CDN_IMAGES_URL}/new-twc_logo.svg` }));
24
25
  };
25
- return (_jsx(AdvancedTransitionWrapper, { type: 'slide', duration: 0.3, children: _jsxs(Flex, { justify: 'center', align: "center", direction: 'column', className: 'h-screen w-[80%] mx-auto gap-6', children: [renderLogo(), _jsxs(Flex, { justify: "center", align: "center", direction: "column", className: 'gap-2', children: [_jsx(Typography, { type: 'heading', size: 'h5', className: 'text-center text-[#1A1A1A] font-semibold', children: "Welcome!" }), _jsx(Typography, { type: 'utility', size: 'large', color: "gray-400", className: 'text-center font-semibold', children: "Select an option to proceed" })] }), _jsx(Button, { label: "Enter Your Email", variant: "secondary", onClick: onClickEnterEmail, leftIcon: _jsx(IonIcon, { name: "mail", style: { fontSize: 20 } }), isFullWidth: true })] }) }));
26
+ return (_jsx(AdvancedTransitionWrapper, { type: 'slide', duration: 0.3, children: _jsxs(Flex, { justify: 'center', align: "center", direction: 'column', className: 'h-screen w-[80%] mx-auto gap-6', children: [renderLogo(), _jsxs(Flex, { justify: "center", align: "center", direction: "column", className: 'gap-2', children: [_jsx(Typography, { type: 'heading', size: 'h5', className: 'text-center text-[#1A1A1A] font-semibold', children: "Welcome!" }), _jsx(Typography, { type: 'utility', size: 'large', color: "gray-400", className: 'text-center font-semibold', children: "Select an option to proceed" })] }), _jsx(Button, { label: "Enter Your Email", variant: "secondary", onClick: onClickEnterEmail, leftIcon: _jsx(Mail, { size: 20 }), isFullWidth: true })] }) }));
26
27
  };
27
28
  export default Welcome;
@@ -1,14 +1,20 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React, { useCallback } from 'react';
3
3
  import { useFocusEffect } from '@react-navigation/native';
4
- import { View, Text, BackHandler, ScrollView } from 'react-native';
4
+ import { View, Text, BackHandler, ScrollView, TouchableOpacity, Platform } from 'react-native';
5
5
  import { Colors, LoadingModal, RoundedButton } from '@truworth/twc-rn-common';
6
6
  import { Layout } from '@ui-kitten/components';
7
7
  import { useWelcome } from './hooks/internal/useWelcome';
8
+ import { SocialLoginModal } from './components/SocialLoginModal';
9
+ import { socialLoginOptions } from '../../constants/social-login-options';
8
10
  import Logo from '../../../assets/logo.svg';
11
+ import { useSocialAuth } from './SocialAuth/hooks/useSocialAuth.native';
12
+ import { SocialLoginsEnum } from '../../enums';
13
+ import FastImage from 'react-native-fast-image';
9
14
  const { gray } = Colors;
10
15
  const Welcome = ({ navigation }) => {
11
- const { loading, LogoComponent, onLaunchAuthSession } = useWelcome();
16
+ const { loading, loginWithFacebook, loginWithGoogle, loginWithApple } = useSocialAuth();
17
+ const { LogoComponent, isSocialLoginEnabled, showSocialLoginModal, setShowSocialLoginModal, socialLoginType, setSocialLoginType, socialLoginConfig, onLaunchAuthSession, } = useWelcome();
12
18
  useFocusEffect(useCallback(() => {
13
19
  onLaunchAuthSession?.();
14
20
  const backHandler = BackHandler.addEventListener('hardwareBackPress', () => true);
@@ -30,12 +36,43 @@ const Welcome = ({ navigation }) => {
30
36
  // Fallback to default logo
31
37
  return (_jsx(View, { style: { marginTop: 70, alignSelf: 'center' }, children: _jsx(Logo, {}) }));
32
38
  };
39
+ const handleLogin = () => {
40
+ setShowSocialLoginModal(false);
41
+ switch (socialLoginType) {
42
+ case SocialLoginsEnum.Google:
43
+ return loginWithGoogle();
44
+ case SocialLoginsEnum.Facebook:
45
+ return loginWithFacebook();
46
+ case SocialLoginsEnum.Apple:
47
+ return loginWithApple();
48
+ default:
49
+ return;
50
+ }
51
+ };
33
52
  return (_jsxs(Layout, { style: { flex: 1, backgroundColor: '#FFFFFF' }, children: [_jsx(ScrollView, { showsVerticalScrollIndicator: false, children: _jsxs(View, { style: { padding: 16 }, children: [renderLogo(), _jsx(Text, { style: {
34
53
  fontSize: 32, fontWeight: '600', color: gray.gray_900,
35
54
  marginTop: 56, textAlign: 'center', lineHeight: 48,
36
55
  }, children: "Welcome!" }), _jsx(Text, { style: {
37
56
  fontSize: 16, fontWeight: '500', color: gray.gray_400,
38
57
  marginTop: 4, lineHeight: 24, textAlign: 'center',
39
- }, children: "Select an option to proceed" }), _jsxs(View, { style: { marginTop: 48 }, children: [_jsx(RoundedButton, { type: "secondary", label: "Enter Your Email", leftIcon: "mail", size: "large", onPress: () => navigation.navigate('EnterEmail') }), _jsx(RoundedButton, { type: "outline", label: "Search Your Organization", leftIcon: "key", containerStyle: { marginTop: 24 }, size: "large", onPress: () => navigation.navigate('SSOSearchOrganization') })] })] }) }), _jsx(LoadingModal, { loading: loading })] }));
58
+ }, children: "Select an option to proceed" }), _jsxs(View, { style: { marginTop: 48 }, children: [_jsx(RoundedButton, { type: "secondary", label: "Enter Your Email", leftIcon: "mail", size: "large", onPress: () => navigation.navigate('EnterEmail') }), _jsx(RoundedButton, { type: "outline", label: "Search Your Organization", leftIcon: "key", containerStyle: { marginTop: 24 }, size: "large", onPress: () => navigation.navigate('SSOSearchOrganization') })] }), isSocialLoginEnabled && (_jsxs(_Fragment, { children: [_jsxs(View, { style: {
59
+ flexDirection: 'row', alignItems: 'center',
60
+ justifyContent: 'center', marginVertical: 40
61
+ }, children: [_jsx(View, { style: { height: 1, width: 20, backgroundColor: gray.gray_600 } }), _jsx(Text, { style: { fontSize: 14, color: gray.gray_600, paddingHorizontal: 3, fontWeight: '500' }, children: ` or continue with ` }), _jsx(View, { style: { height: 1, width: 20, backgroundColor: gray.gray_600 } })] }), _jsx(View, { style: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }, children: socialLoginOptions.map(({ type, iconImageUrl }) => {
62
+ if (Platform.OS === 'android' && type === SocialLoginsEnum.Apple) {
63
+ return null;
64
+ }
65
+ return (socialLoginConfig?.[type]?.enabled &&
66
+ _jsx(TouchableOpacity, { activeOpacity: 0.8, onPress: () => {
67
+ setSocialLoginType(type);
68
+ setShowSocialLoginModal(true);
69
+ }, style: {
70
+ height: 56, backgroundColor: '#FFFFFF', width: 56,
71
+ flexDirection: 'row', alignItems: 'center',
72
+ justifyContent: 'center', marginHorizontal: 12,
73
+ borderWidth: 1, borderColor: gray.gray_200, borderRadius: 28,
74
+ }, children: _jsx(FastImage, { source: { uri: iconImageUrl }, style: { width: 24, height: 24 } }) }, type));
75
+ }) })] }))] }) }), showSocialLoginModal &&
76
+ _jsx(SocialLoginModal, { visible: showSocialLoginModal, hide: () => setShowSocialLoginModal(false), socialLoginType: socialLoginType, onClick: handleLogin }), _jsx(LoadingModal, { loading: loading })] }));
40
77
  };
41
78
  export default Welcome;
@@ -1,3 +1,3 @@
1
1
  import type { OTPVerifyProps } from "./types";
2
- declare const VerifyMobileOTP: ({ validateOTP, timer, resendOTP, phone, status, resendTextClassName }: OTPVerifyProps) => import("react/jsx-runtime").JSX.Element;
2
+ declare const VerifyMobileOTP: ({ validateOTP, timer, resendOTP, phone, status }: OTPVerifyProps) => import("react/jsx-runtime").JSX.Element;
3
3
  export { VerifyMobileOTP };
@@ -5,6 +5,5 @@ interface OTPVerifyProps {
5
5
  status: OTPStatus | string;
6
6
  resendOTP: () => void;
7
7
  phone?: string;
8
- resendTextClassName?: string;
9
8
  }
10
9
  export type { OTPVerifyProps };
@@ -0,0 +1 @@
1
+ export declare const BASE_URL: string;
@@ -0,0 +1 @@
1
+ export declare const BASE_URL: string | undefined;
@@ -1 +1,2 @@
1
- export { MEMBER_IMAGES_URL } from "@truworth/twc-web-common";
1
+ export declare const MEMBER_IMAGES_URL: string;
2
+ export declare const CDN_IMAGES_URL: string;
@@ -0,0 +1,3 @@
1
+ import type { SocialLoginOptions } from "../helpers/types";
2
+ declare const socialLoginOptions: SocialLoginOptions[];
3
+ export { socialLoginOptions };
@@ -29,8 +29,10 @@ declare const AuthPackageContext: React.Context<AuthPackageContextValue | null>;
29
29
  * @param onLogout - Optional callback after successful logout
30
30
  * @param onLaunchAuthSession - Optional callback after successfully launching the auth session. For example, it can be used to set the Firebase notification token or request Android permissions.
31
31
  * @param onRefreshSession - Optional handler for refreshing user session
32
+ * @param openChatSupport - Optional callback to open chat support
33
+ * @param socialLoginConfig - Optional social login configuration
32
34
  */
33
- declare const AuthProvider: ({ children, LogoComponent, session, appConfig, onLogin, onLogout, onLaunchAuthSession, onRefreshSession }: AuthContextProps) => import("react/jsx-runtime").JSX.Element;
35
+ declare const AuthProvider: ({ children, LogoComponent, session, appConfig, onLogin, onLogout, onLaunchAuthSession, onRefreshSession, openChatSupport, socialLoginConfig }: AuthContextProps) => import("react/jsx-runtime").JSX.Element;
34
36
  export { AuthProvider };
35
37
  export default AuthContext;
36
38
  export { AuthPackageContext };