@truworth/twc-auth 1.1.0 → 1.2.1

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 (202) hide show
  1. package/README.md +239 -306
  2. package/build/assets/animation/redirect-home.json +1101 -0
  3. package/build/assets/cross_icon copy.svg +5 -0
  4. package/build/assets/cross_icon.svg +5 -0
  5. package/build/assets/gender-diversity.svg +22 -0
  6. package/build/assets/logo.svg +55 -0
  7. package/build/assets/okay_icon copy.svg +3 -0
  8. package/build/assets/okay_icon.svg +3 -0
  9. package/build/src/api/axiosClient/index.js +5 -0
  10. package/build/src/api/axiosClient/index.native.js +5 -0
  11. package/build/src/components/AdvancedTransitionWrapper/index.js +380 -0
  12. package/build/src/components/AdvancedTransitionWrapper/index.native.js +10 -0
  13. package/build/src/components/AdvancedTransitionWrapper/types.js +1 -0
  14. package/build/src/components/ConfirmationModal/index.js +11 -0
  15. package/build/src/components/ConfirmationModal/index.native.js +15 -0
  16. package/build/src/components/ConfirmationModal/types.js +1 -0
  17. package/build/src/components/EmailOTPVerify/index.js +20 -0
  18. package/build/src/components/EmailOTPVerify/index.native.js +26 -0
  19. package/build/src/components/EmailOTPVerify/type.js +1 -0
  20. package/build/src/components/IonIcon/index.js +11 -0
  21. package/build/src/components/IonIcon/index.native.js +9 -0
  22. package/build/src/components/IonIcon/types.js +1 -0
  23. package/build/src/components/OTPStatusLabel/index.js +10 -0
  24. package/build/src/components/OTPStatusLabel/index.native.js +21 -0
  25. package/build/src/components/OTPStatusLabel/types.js +1 -0
  26. package/build/src/components/PasswordCriteria/hooks/usePasswordCriteria.js +78 -0
  27. package/build/src/components/PasswordCriteria/index.js +47 -0
  28. package/build/src/components/PasswordCriteria/index.native.js +19 -0
  29. package/build/src/components/PasswordCriteria/types.js +1 -0
  30. package/build/src/components/ScreenLayout/index.js +12 -0
  31. package/build/src/components/ScreenLayout/index.native.js +18 -0
  32. package/build/src/components/ScreenLayout/types.js +1 -0
  33. package/build/src/components/SupportDetails/index.js +9 -0
  34. package/build/src/components/SupportDetails/index.native.js +6 -0
  35. package/build/src/components/VerifyOTP/index.js +23 -0
  36. package/build/src/components/VerifyOTP/index.native.js +38 -0
  37. package/build/src/components/VerifyOTP/types.js +1 -0
  38. package/build/src/constants/cdn-url/index.js +1 -0
  39. package/build/src/constants/cdn-url/index.native.js +5 -0
  40. package/build/src/contexts/AuthContext.js +184 -0
  41. package/build/src/contexts/type.js +1 -0
  42. package/build/src/helpers/Network.js +93 -0
  43. package/build/src/helpers/Validation.js +12 -0
  44. package/build/src/helpers/show-message/index.js +19 -0
  45. package/build/src/helpers/show-message/index.native.js +14 -0
  46. package/build/src/helpers/show-message/types.js +1 -0
  47. package/build/src/helpers/types.js +1 -0
  48. package/build/src/hooks/internal/useAuthPackageContext.js +9 -0
  49. package/build/src/hooks/internal/useTimer.js +40 -0
  50. package/build/src/hooks/useAuthContext.js +10 -0
  51. package/build/src/hooks/useRequest.js +38 -0
  52. package/build/src/index.js +12 -0
  53. package/build/src/navigator/index.js +10 -0
  54. package/build/src/navigator/index.native.js +16 -0
  55. package/build/src/screens/CountryCode/components/CountryCodeDropdown/index.js +38 -0
  56. package/build/src/screens/CountryCode/components/CountryCodeDropdown/index.native.js +6 -0
  57. package/build/src/screens/CountryCode/components/CountryCodeDropdown/types.js +1 -0
  58. package/build/src/screens/CountryCode/hooks/internal/useCountryCode.js +38 -0
  59. package/build/src/screens/CountryCode/index.js +10 -0
  60. package/build/src/screens/CountryCode/index.native.js +37 -0
  61. package/build/src/screens/CountryCode/type.js +1 -0
  62. package/build/src/screens/CreatePassword/hooks/internal/useCreatePassword.js +52 -0
  63. package/build/src/screens/CreatePassword/index.js +43 -0
  64. package/build/src/screens/CreatePassword/index.native.js +32 -0
  65. package/build/src/screens/CreatePassword/type.js +1 -0
  66. package/build/src/screens/EnterEmail/hooks/internal/useEnterEmail.js +86 -0
  67. package/build/src/screens/EnterEmail/index.js +30 -0
  68. package/build/src/screens/EnterEmail/index.native.js +34 -0
  69. package/build/src/screens/EnterPassword/hooks/internal/useEnterPassword.js +47 -0
  70. package/build/src/screens/EnterPassword/index.js +22 -0
  71. package/build/src/screens/EnterPassword/index.native.js +23 -0
  72. package/build/src/screens/EnterPassword/types.js +1 -0
  73. package/build/src/screens/Login/components/LoginWebComponent/index.js +44 -0
  74. package/build/src/screens/Login/components/LoginWebComponent/index.native.js +6 -0
  75. package/build/src/screens/Login/index.js +10 -0
  76. package/build/src/screens/Login/index.native.js +6 -0
  77. package/build/src/screens/SignUp/components/SignUpForm/index.js +181 -0
  78. package/build/src/screens/SignUp/components/SignUpForm/index.native.js +6 -0
  79. package/build/src/screens/SignUp/components/SignUpForm/type.js +1 -0
  80. package/build/src/screens/SignUp/components/SignUpWebComponent/index.js +82 -0
  81. package/build/src/screens/SignUp/components/SignUpWebComponent/index.native.js +6 -0
  82. package/build/src/screens/SignUp/components/SignUpWebComponent/types.js +1 -0
  83. package/build/src/screens/SignUp/hooks/internal/useSignUp.js +138 -0
  84. package/build/src/screens/SignUp/index.js +6 -0
  85. package/build/src/screens/SignUp/index.native.js +185 -0
  86. package/build/src/screens/SignUp/types.js +1 -0
  87. package/build/src/screens/UserConsent/hooks/internal/useConsent.js +48 -0
  88. package/build/src/screens/UserConsent/index.js +69 -0
  89. package/build/src/screens/UserConsent/index.native.js +46 -0
  90. package/build/src/screens/UserConsent/types.js +1 -0
  91. package/build/src/screens/VerifyEmail/hooks/internal/useVerifyEmail.js +69 -0
  92. package/build/src/screens/VerifyEmail/index.js +8 -0
  93. package/build/src/screens/VerifyEmail/index.native.js +14 -0
  94. package/build/src/screens/VerifyEmail/types.js +1 -0
  95. package/build/src/screens/VerifyMobile/hooks/internal/useVerifyMobile.js +73 -0
  96. package/build/src/screens/VerifyMobile/index.js +8 -0
  97. package/build/src/screens/VerifyMobile/index.native.js +9 -0
  98. package/build/src/screens/VerifyMobile/types.js +1 -0
  99. package/build/src/screens/Welcome/hooks/internal/useWelcome.js +21 -0
  100. package/build/src/screens/Welcome/index.js +28 -0
  101. package/build/src/screens/Welcome/index.native.js +41 -0
  102. package/build/src/types/types.js +1 -0
  103. package/build/types/api/axiosClient/index.d.ts +1 -0
  104. package/build/types/api/axiosClient/index.native.d.ts +1 -0
  105. package/build/types/components/AdvancedTransitionWrapper/index.d.ts +3 -0
  106. package/build/types/components/AdvancedTransitionWrapper/index.native.d.ts +5 -0
  107. package/build/types/components/AdvancedTransitionWrapper/types.d.ts +25 -0
  108. package/build/types/components/ConfirmationModal/index.d.ts +3 -0
  109. package/build/types/components/ConfirmationModal/index.native.d.ts +3 -0
  110. package/build/types/components/ConfirmationModal/types.d.ts +13 -0
  111. package/build/types/components/EmailOTPVerify/index.d.ts +3 -0
  112. package/build/types/components/EmailOTPVerify/index.native.d.ts +3 -0
  113. package/build/types/components/EmailOTPVerify/type.d.ts +9 -0
  114. package/build/types/components/IonIcon/index.d.ts +3 -0
  115. package/build/types/components/IonIcon/index.native.d.ts +4 -0
  116. package/build/types/components/IonIcon/types.d.ts +6 -0
  117. package/build/types/components/OTPStatusLabel/index.d.ts +2 -0
  118. package/build/types/components/OTPStatusLabel/index.native.d.ts +3 -0
  119. package/build/types/components/OTPStatusLabel/types.d.ts +6 -0
  120. package/build/types/components/PasswordCriteria/hooks/usePasswordCriteria.d.ts +13 -0
  121. package/build/types/components/PasswordCriteria/index.d.ts +3 -0
  122. package/build/types/components/PasswordCriteria/index.native.d.ts +3 -0
  123. package/build/types/components/PasswordCriteria/types.d.ts +15 -0
  124. package/build/types/components/ScreenLayout/index.d.ts +3 -0
  125. package/build/types/components/ScreenLayout/index.native.d.ts +3 -0
  126. package/build/types/components/ScreenLayout/types.d.ts +12 -0
  127. package/build/types/components/SupportDetails/index.d.ts +2 -0
  128. package/build/types/components/SupportDetails/index.native.d.ts +2 -0
  129. package/build/types/components/VerifyOTP/index.d.ts +3 -0
  130. package/build/types/components/VerifyOTP/index.native.d.ts +3 -0
  131. package/build/types/components/VerifyOTP/types.d.ts +10 -0
  132. package/build/types/constants/cdn-url/index.d.ts +1 -0
  133. package/build/types/constants/cdn-url/index.native.d.ts +3 -0
  134. package/build/types/contexts/AuthContext.d.ts +36 -0
  135. package/build/types/contexts/type.d.ts +58 -0
  136. package/build/types/helpers/Network.d.ts +5 -0
  137. package/build/types/helpers/Validation.d.ts +2 -0
  138. package/build/types/helpers/show-message/index.d.ts +3 -0
  139. package/build/types/helpers/show-message/index.native.d.ts +3 -0
  140. package/build/types/helpers/show-message/types.d.ts +2 -0
  141. package/build/types/helpers/types.d.ts +13 -0
  142. package/build/types/hooks/internal/useAuthPackageContext.d.ts +1 -0
  143. package/build/types/hooks/internal/useTimer.d.ts +3 -0
  144. package/build/types/hooks/useAuthContext.d.ts +2 -0
  145. package/build/types/hooks/useRequest.d.ts +5 -0
  146. package/build/types/index.d.ts +8 -0
  147. package/build/types/navigator/index.d.ts +2 -0
  148. package/build/types/navigator/index.native.d.ts +36 -0
  149. package/build/types/screens/CountryCode/components/CountryCodeDropdown/index.d.ts +3 -0
  150. package/build/types/screens/CountryCode/components/CountryCodeDropdown/index.native.d.ts +2 -0
  151. package/build/types/screens/CountryCode/components/CountryCodeDropdown/types.d.ts +17 -0
  152. package/build/types/screens/CountryCode/hooks/internal/useCountryCode.d.ts +12 -0
  153. package/build/types/screens/CountryCode/index.d.ts +2 -0
  154. package/build/types/screens/CountryCode/index.native.d.ts +2 -0
  155. package/build/types/screens/CountryCode/type.d.ts +11 -0
  156. package/build/types/screens/CreatePassword/hooks/internal/useCreatePassword.d.ts +26 -0
  157. package/build/types/screens/CreatePassword/index.d.ts +3 -0
  158. package/build/types/screens/CreatePassword/index.native.d.ts +4 -0
  159. package/build/types/screens/CreatePassword/type.d.ts +43 -0
  160. package/build/types/screens/EnterEmail/hooks/internal/useEnterEmail.d.ts +24 -0
  161. package/build/types/screens/EnterEmail/index.d.ts +7 -0
  162. package/build/types/screens/EnterEmail/index.native.d.ts +4 -0
  163. package/build/types/screens/EnterPassword/hooks/internal/useEnterPassword.d.ts +20 -0
  164. package/build/types/screens/EnterPassword/index.d.ts +3 -0
  165. package/build/types/screens/EnterPassword/index.native.d.ts +4 -0
  166. package/build/types/screens/EnterPassword/types.d.ts +5 -0
  167. package/build/types/screens/Login/components/LoginWebComponent/index.d.ts +2 -0
  168. package/build/types/screens/Login/components/LoginWebComponent/index.native.d.ts +2 -0
  169. package/build/types/screens/Login/index.d.ts +2 -0
  170. package/build/types/screens/Login/index.native.d.ts +2 -0
  171. package/build/types/screens/SignUp/components/SignUpForm/index.d.ts +3 -0
  172. package/build/types/screens/SignUp/components/SignUpForm/index.native.d.ts +2 -0
  173. package/build/types/screens/SignUp/components/SignUpForm/type.d.ts +9 -0
  174. package/build/types/screens/SignUp/components/SignUpWebComponent/index.d.ts +2 -0
  175. package/build/types/screens/SignUp/components/SignUpWebComponent/index.native.d.ts +2 -0
  176. package/build/types/screens/SignUp/components/SignUpWebComponent/types.d.ts +24 -0
  177. package/build/types/screens/SignUp/hooks/internal/useSignUp.d.ts +50 -0
  178. package/build/types/screens/SignUp/index.d.ts +2 -0
  179. package/build/types/screens/SignUp/index.native.d.ts +4 -0
  180. package/build/types/screens/SignUp/types.d.ts +18 -0
  181. package/build/types/screens/UserConsent/hooks/internal/useConsent.d.ts +10 -0
  182. package/build/types/screens/UserConsent/index.d.ts +3 -0
  183. package/build/types/screens/UserConsent/index.native.d.ts +4 -0
  184. package/build/types/screens/UserConsent/types.d.ts +27 -0
  185. package/build/types/screens/VerifyEmail/hooks/internal/useVerifyEmail.d.ts +19 -0
  186. package/build/types/screens/VerifyEmail/index.d.ts +3 -0
  187. package/build/types/screens/VerifyEmail/index.native.d.ts +4 -0
  188. package/build/types/screens/VerifyEmail/types.d.ts +8 -0
  189. package/build/types/screens/VerifyMobile/hooks/internal/useVerifyMobile.d.ts +14 -0
  190. package/build/types/screens/VerifyMobile/index.d.ts +3 -0
  191. package/build/types/screens/VerifyMobile/index.native.d.ts +4 -0
  192. package/build/types/screens/VerifyMobile/types.d.ts +5 -0
  193. package/build/types/screens/Welcome/hooks/internal/useWelcome.d.ts +14 -0
  194. package/build/types/screens/Welcome/index.d.ts +4 -0
  195. package/build/types/screens/Welcome/index.native.d.ts +4 -0
  196. package/build/types/types/types.d.ts +90 -0
  197. package/get-metro-config.js +40 -0
  198. package/get-next-config.js +26 -0
  199. package/package.json +86 -38
  200. package/dist/index.esm.js +0 -2028
  201. package/dist/index.umd.js +0 -70
  202. package/dist/vite.svg +0 -1
@@ -0,0 +1,86 @@
1
+ import { useCallback, useState } from "react";
2
+ import { showMessage } from "../../../../helpers/show-message";
3
+ import { useAuthPackageContext } from "../../../../hooks/internal/useAuthPackageContext";
4
+ import { axiosClient } from "../../../../api/axiosClient";
5
+ const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
6
+ /**
7
+ * @internal
8
+ * Internal hook for managing EnterEmail screen state and auth context integration. Not exposed to package consumers.
9
+ */
10
+ const useEnterEmail = () => {
11
+ const [loading, setLoading] = useState(false);
12
+ const [isInvalidEmail, setInvalidEmail] = useState(true);
13
+ const [loginConflictModalVisible, setLoginConflictModalVisible] = useState(false);
14
+ const [loginType, setLoginType] = useState('');
15
+ const [email, setEmail] = useState('');
16
+ const { appConfig, onRegistrationMethodChange } = useAuthPackageContext();
17
+ const enterEmail = useCallback((text) => {
18
+ const value = text.toLowerCase().trim();
19
+ setInvalidEmail(!emailRegex.test(value));
20
+ setEmail(value);
21
+ }, [emailRegex]);
22
+ const handleValidateEmail = ({ onResult }) => {
23
+ if (loading || isInvalidEmail || !email)
24
+ return;
25
+ setLoading(true);
26
+ axiosClient({
27
+ url: '/auth/email-exists',
28
+ method: 'post',
29
+ data: { email }
30
+ }).then((res) => {
31
+ setLoading(false);
32
+ const code = Number(res.data.loginType);
33
+ const isKnown = code === 1 || code === 2 || code === 3 || code === 4;
34
+ if (!isKnown) {
35
+ showMessage('Unsupported login method. Please try again later.');
36
+ return;
37
+ }
38
+ if (code !== 1) {
39
+ let providerName = 'your social account';
40
+ switch (code) {
41
+ case 2:
42
+ providerName = 'Facebook';
43
+ break;
44
+ case 3:
45
+ providerName = 'Google';
46
+ break;
47
+ case 4:
48
+ providerName = 'Apple';
49
+ break;
50
+ }
51
+ setLoginType(providerName);
52
+ setLoginConflictModalVisible(true);
53
+ return;
54
+ }
55
+ onResult({ email, emailExist: true });
56
+ }).catch(err => {
57
+ console.log(err);
58
+ setLoading(false);
59
+ if (err?.response?.status === 404) {
60
+ onResult({ email, emailExist: false });
61
+ }
62
+ if (err?.response?.status >= 500) {
63
+ showMessage('Something went wrong');
64
+ }
65
+ });
66
+ };
67
+ const clearText = useCallback(() => {
68
+ setEmail('');
69
+ setInvalidEmail(true);
70
+ }, []);
71
+ return {
72
+ email,
73
+ appName: appConfig.appName,
74
+ isInvalidEmail,
75
+ loading,
76
+ enterEmail,
77
+ handleValidateEmail,
78
+ clearText,
79
+ loginConflictModalVisible,
80
+ setLoginConflictModalVisible,
81
+ onRegistrationMethodChange,
82
+ loginConflictErrorTitle: `Sign in with ${loginType}`,
83
+ loginConflictErrorDescription: `Looks like you previously registered using ${loginType}. Please go back and sign in with ${loginType}.`,
84
+ };
85
+ };
86
+ export { useEnterEmail };
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Form, TextInput, useForm } from '@truworth/twc-web-design';
3
+ import { ConfirmationModal as LoginConflictModal } from '../../components/ConfirmationModal';
4
+ import { ScreenLayout } from "../../components/ScreenLayout";
5
+ import { useEnterEmail } from "./hooks/internal/useEnterEmail";
6
+ import { SupportDetails } from '../../components/SupportDetails';
7
+ const EnterEmail = ({ onResult }) => {
8
+ const { loading, email, isInvalidEmail, loginConflictModalVisible, loginConflictErrorTitle, loginConflictErrorDescription, enterEmail, appName, handleValidateEmail, setLoginConflictModalVisible, } = useEnterEmail();
9
+ const form = useForm({ defaultValues: { email } });
10
+ return (_jsxs(_Fragment, { children: [_jsxs(ScreenLayout, { title: `Hi, Welcome To ${appName}!`, subTitle: "Please enter email to get started.", buttonProps: {
11
+ loading,
12
+ label: 'Continue',
13
+ onClick: () => {
14
+ if (!loading && !isInvalidEmail) {
15
+ handleValidateEmail({ onResult });
16
+ }
17
+ },
18
+ disabled: isInvalidEmail || loading,
19
+ }, children: [_jsx(Form, { className: "w-full", form: form, onSubmit: () => {
20
+ if (!loading && !isInvalidEmail) {
21
+ handleValidateEmail({ onResult });
22
+ }
23
+ }, children: _jsx(Form.Item, { name: "email", label: "Email", children: _jsx(TextInput, { type: "email", value: email, size: "medium", placeholder: "example@domain", ...form.register('email', {
24
+ onChange: (e) => {
25
+ enterEmail(e.target.value);
26
+ }
27
+ }) }) }) }), loginConflictModalVisible &&
28
+ _jsx(LoginConflictModal, { title: loginConflictErrorTitle, primaryLabel: 'Okay', description: loginConflictErrorDescription, visible: loginConflictModalVisible, onProceed: () => setLoginConflictModalVisible(false), onClose: () => setLoginConflictModalVisible(false) })] }), _jsx(SupportDetails, {})] }));
29
+ };
30
+ export default EnterEmail;
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Keyboard } from 'react-native';
3
+ import { Layout } from '@ui-kitten/components';
4
+ import { Colors, TextInputField } from '@truworth/twc-rn-common';
5
+ import { useEnterEmail } from './hooks/internal/useEnterEmail';
6
+ import { ScreenLayout } from '../../components/ScreenLayout/index.native';
7
+ import { ConfirmationModal as LoginConflictModal } from '../../components/ConfirmationModal';
8
+ const { utility } = Colors;
9
+ const EnterEmail = ({ navigation }) => {
10
+ const { loading, email, isInvalidEmail, loginConflictModalVisible, loginConflictErrorTitle, loginConflictErrorDescription, enterEmail, clearText, handleValidateEmail, onRegistrationMethodChange, setLoginConflictModalVisible, } = useEnterEmail();
11
+ return (_jsxs(Layout, { style: { flex: 1, backgroundColor: '#FFFFFF' }, children: [_jsx(ScreenLayout, { title: "Enter Your Email", buttonProps: {
12
+ loading,
13
+ label: 'Continue',
14
+ onPress: () => {
15
+ Keyboard.dismiss();
16
+ if (!loading && !isInvalidEmail) {
17
+ handleValidateEmail({
18
+ onResult: (params) => {
19
+ if (params.emailExist) {
20
+ navigation.navigate('EnterPassword', { email });
21
+ }
22
+ else {
23
+ onRegistrationMethodChange('email');
24
+ navigation.navigate('SignUp', { email });
25
+ }
26
+ }
27
+ });
28
+ }
29
+ },
30
+ disabled: isInvalidEmail || loading,
31
+ }, children: _jsx(TextInputField, { value: email, placeholder: 'Enter here...', onChangeValue: text => enterEmail(text), rightIcon2: email.length > 0 ? 'close' : '', onPressRightIcon2: clearText, autoFocus: true, autoCapitalize: 'none', keyboardType: 'email-address' }) }), loginConflictModalVisible &&
32
+ _jsx(LoginConflictModal, { title: loginConflictErrorTitle, description: loginConflictErrorDescription, visible: loginConflictModalVisible, onProceed: () => setLoginConflictModalVisible(false), onClose: () => setLoginConflictModalVisible(false), iconColor: utility.warning_main, primaryLabel: 'Okay' })] }));
33
+ };
34
+ export default EnterEmail;
@@ -0,0 +1,47 @@
1
+ import { useCallback, useState } from "react";
2
+ import { useAuthPackageContext } from "../../../../hooks/internal/useAuthPackageContext";
3
+ import { axiosClient } from "../../../../api/axiosClient";
4
+ /**
5
+ * @internal
6
+ * Internal hook for managing EnterPassword screen state and auth context integration. Not exposed to package consumers.
7
+ */
8
+ const useEnterPassword = () => {
9
+ const [password, setPassword] = useState('');
10
+ const [isPasswordVisible, setPasswordVisible] = useState(false);
11
+ const [isInvalidPassword, setInvalidPassword] = useState(false);
12
+ const [loading, setLoading] = useState(false);
13
+ const { onTokenChange, onLogin, appConfig } = useAuthPackageContext();
14
+ const togglePasswordVisibility = useCallback(() => setPasswordVisible(v => !v), []);
15
+ const handleSubmit = async ({ email, source }) => {
16
+ setLoading(true);
17
+ setInvalidPassword(false);
18
+ axiosClient({
19
+ url: '/auth/login',
20
+ method: 'POST',
21
+ data: { email, password, source },
22
+ }).then(res => {
23
+ onTokenChange(res.data.token);
24
+ onLogin(res.data);
25
+ }).catch(err => {
26
+ if (err?.response?.status === 400) {
27
+ setInvalidPassword(true);
28
+ }
29
+ }).finally(() => {
30
+ setLoading(false);
31
+ });
32
+ };
33
+ const onPassword = useCallback((text) => {
34
+ setPassword(text);
35
+ if (isInvalidPassword)
36
+ setInvalidPassword(false);
37
+ }, [isInvalidPassword]);
38
+ return {
39
+ loading,
40
+ password, setPassword,
41
+ isPasswordVisible, togglePasswordVisibility,
42
+ isInvalidPassword, setInvalidPassword,
43
+ handleSubmit, onPassword,
44
+ appName: appConfig.appName,
45
+ };
46
+ };
47
+ export { useEnterPassword };
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Form, PasswordInput, Typography, useForm } from '@truworth/twc-web-design';
3
+ import { ScreenLayout } from "../../components/ScreenLayout";
4
+ import { useEnterPassword } from './hooks/internal/useEnterPassword';
5
+ import { SupportDetails } from '../../components/SupportDetails';
6
+ const EnterPassword = ({ email, onPressBack }) => {
7
+ const { loading, password, isInvalidPassword, handleSubmit, onPassword, appName } = useEnterPassword();
8
+ const form = useForm({ defaultValues: { password } });
9
+ return (_jsxs(_Fragment, { children: [_jsx(ScreenLayout, { title: `Hi, Welcome To ${appName}!`, subTitle: email, buttonProps: {
10
+ loading,
11
+ label: 'Continue',
12
+ onClick: () => { if (email)
13
+ handleSubmit({ email, source: 'web' }); },
14
+ disabled: !password || !email || loading,
15
+ }, onPressBack: onPressBack, children: _jsx(Form, { className: "w-full", form: form, onSubmit: () => { if (email)
16
+ handleSubmit({ email, source: 'web' }); }, children: _jsx(Form.Item, { name: "password", label: "Password", description: isInvalidPassword &&
17
+ _jsx(Typography, { type: "body", size: "small", className: "h-1", color: "text-utility-danger-main", children: "Email and password do not match!" }), children: _jsx(PasswordInput, { placeholder: "Enter your password", value: password, showStrengthIndicator: false, className: `border rounded-md px-3 py-2
18
+ ${isInvalidPassword ? "border-red-500" : "border-gray-300"}`, ...form.register('password', {
19
+ onChange: (e) => onPassword(e.target.value)
20
+ }) }) }) }) }), _jsx(SupportDetails, {})] }));
21
+ };
22
+ export default EnterPassword;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { View } from 'react-native';
3
+ import { TextInputField } from '@truworth/twc-rn-common';
4
+ import { Layout } from '@ui-kitten/components';
5
+ import { ScreenLayout } from '../../components/ScreenLayout/index.native';
6
+ import { useEnterPassword } from './hooks/internal/useEnterPassword';
7
+ const EnterPassword = ({ route }) => {
8
+ const { email } = route.params;
9
+ const { loading, password, isPasswordVisible, togglePasswordVisibility, isInvalidPassword, handleSubmit, onPassword } = useEnterPassword();
10
+ return (_jsx(Layout, { style: { flex: 1, backgroundColor: '#FFFFFF' }, children: _jsx(ScreenLayout, { title: "Enter Your Password", buttonProps: {
11
+ loading,
12
+ label: 'Continue',
13
+ onPress: () => { if (email)
14
+ handleSubmit({ email, source: 'web' }); },
15
+ disabled: password.length == 0 || isInvalidPassword || loading,
16
+ }, children: _jsx(View, { style: { position: 'relative' }, children: _jsx(TextInputField, { placeholder: 'Enter password...', onChangeValue: onPassword, secureTextEntry: !isPasswordVisible, value: password, rightIcon2: isPasswordVisible
17
+ ? 'eye-outline'
18
+ : 'eye-off-outline', onPressRightIcon2: () => togglePasswordVisibility(), error: {
19
+ show: isInvalidPassword,
20
+ message: isInvalidPassword ? 'Email and password do not match!' : ''
21
+ }, autoFocus: true }) }) }) }));
22
+ };
23
+ export default EnterPassword;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useState } from 'react';
3
+ import { Flex } from '@truworth/twc-web-design';
4
+ import { useRouter } from 'next/router';
5
+ import { AdvancedTransitionWrapper } from '../../../../components/AdvancedTransitionWrapper';
6
+ import { useAuthPackageContext } from '../../../../hooks/internal/useAuthPackageContext';
7
+ import EnterEmail from '../../../EnterEmail/index';
8
+ import EnterPassword from '../../../EnterPassword/index';
9
+ const LoginWebComponent = () => {
10
+ const [email, setEmail] = useState('');
11
+ const [loginState, setLoginState] = useState('EnterEmail');
12
+ const { LogoComponent } = useAuthPackageContext();
13
+ const router = useRouter();
14
+ const onRedirectToPassword = (email) => {
15
+ setEmail(email);
16
+ setLoginState('EnterPassword');
17
+ };
18
+ const onRedirectToSignUp = (email) => {
19
+ router.push({
20
+ pathname: '/registration',
21
+ query: { email, registrationMethod: 'email' }
22
+ });
23
+ };
24
+ const renderStep = () => {
25
+ switch (loginState) {
26
+ case 'EnterEmail':
27
+ return (_jsx(EnterEmail, { onResult: (params) => {
28
+ if (params.emailExist) {
29
+ onRedirectToPassword(params.email);
30
+ }
31
+ else {
32
+ onRedirectToSignUp(params.email);
33
+ }
34
+ } }));
35
+ case 'EnterPassword':
36
+ return (_jsx(EnterPassword, { email: email, onPressBack: () => setLoginState('EnterEmail') }));
37
+ default:
38
+ return null;
39
+ }
40
+ };
41
+ return (_jsx(AdvancedTransitionWrapper, { type: 'slide', duration: 0.5, children: _jsxs(Flex, { direction: 'column', justify: 'center', style: { width: '70%' }, className: `lg:w-[70%] lg:h-screen mx-auto h-full my-10`, children: [React.isValidElement(LogoComponent)
42
+ && LogoComponent, renderStep()] }) }));
43
+ };
44
+ export { LoginWebComponent };
@@ -0,0 +1,6 @@
1
+ const LoginWebComponent = () => {
2
+ if (__DEV__)
3
+ console.warn("[@truworth/twc-auth] LoginWebComponent is web-only");
4
+ return null;
5
+ };
6
+ export { LoginWebComponent };
@@ -0,0 +1,10 @@
1
+ 'use client';
2
+ const Login = () => {
3
+ if (process.env.NODE_ENV !== 'production') {
4
+ if (typeof window !== 'undefined') {
5
+ console.warn("[@truworth/twc-auth] We use only LoginWebComponent for login");
6
+ }
7
+ }
8
+ return null;
9
+ };
10
+ export default Login;
@@ -0,0 +1,6 @@
1
+ const Login = () => {
2
+ if (__DEV__)
3
+ console.warn("[@truworth/twc-auth] we use only LoginWebComponent for login");
4
+ return null;
5
+ };
6
+ export default Login;
@@ -0,0 +1,181 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import Image from "next/image";
3
+ import React, { useEffect, useState } from "react";
4
+ import { CDN_IMAGES_URL } from "@truworth/twc-web-common";
5
+ import { Button, Col, CustomCheckbox, DatePicker, Flex, Form, RadioGroup, ResponsiveModal, Row, TextInput, Typography, useForm, validationPatterns } from "@truworth/twc-web-design";
6
+ import { CalendarDays } from "lucide-react";
7
+ import { SupportDetails } from "../../../../components/SupportDetails";
8
+ import { ScreenLayout } from "../../../../components/ScreenLayout";
9
+ import { CountryCodeDropdown } from "../../../CountryCode/components/CountryCodeDropdown";
10
+ import { useSignUp } from "../../hooks/internal/useSignUp";
11
+ import ReCAPTCHA from 'react-google-recaptcha';
12
+ import moment from "moment";
13
+ import dayjs from 'dayjs';
14
+ const isProduction = process.env.NODE_ENV === 'production';
15
+ const SignUpFormComponent = ({ email, registrationMethod, userDetails, onContinue, onGoToLogin }) => {
16
+ const [isHuman, setIsHuman] = useState(isProduction ? false : true);
17
+ const [termsAndConditions, setTermsAndConditions] = useState(false);
18
+ const [selectedCountry, setSelectedCountry] = useState({
19
+ countryCode: "in",
20
+ phoneCode: "91",
21
+ name: "INDIA",
22
+ });
23
+ const form = useForm({
24
+ liveValidation: true,
25
+ defaultValues: {
26
+ firstName: userDetails.firstName ?? "",
27
+ lastName: userDetails.lastName ?? "",
28
+ dateOfBirth: userDetails.selectedDOB,
29
+ phone: userDetails.phone ?? "",
30
+ gender: userDetails.gender ?? "",
31
+ referralCode: userDetails.referralCode ?? "",
32
+ }
33
+ });
34
+ const values = form.watch();
35
+ const { loading, setGender, setSelectedDOB, phone, setPhone, setEmail, setReferralCode, setCountryCode, countryCode, setIsPhoneValid, existingAccounts, existingAccountModal, setExistingAccountModal, onFirstName, onLastName, handleSubmit, getLoginTypeText, appName, termsAndConditionsUrl, } = useSignUp();
36
+ useEffect(() => {
37
+ if (values.phone) {
38
+ setPhone(values.phone);
39
+ setEmail(email);
40
+ }
41
+ }, [values.phone]);
42
+ const disabledDate = (current) => {
43
+ const currentDate = dayjs(current);
44
+ if (!currentDate.isValid()) {
45
+ return false;
46
+ }
47
+ const thirteenYearsAgo = dayjs().subtract(13, 'years');
48
+ const oldestAllowedDate = dayjs('1900-01-01');
49
+ return currentDate.isAfter(thirteenYearsAgo) || currentDate.isBefore(oldestAllowedDate);
50
+ };
51
+ const handleCaptcha = (value) => {
52
+ setIsHuman(Boolean(value));
53
+ };
54
+ const enterMobile = (text) => {
55
+ const digits = String(text).replace(/\D/g, '');
56
+ setPhone(digits);
57
+ if (countryCode === "91") {
58
+ setIsPhoneValid(/^\d{10}$/.test(digits));
59
+ }
60
+ else {
61
+ setIsPhoneValid(digits.length > 5);
62
+ }
63
+ };
64
+ return (_jsxs(_Fragment, { children: [_jsx(ScreenLayout, { title: "Looks like you're new here!", subTitle: "Tell us more about you so we can set up your account.", buttonProps: {
65
+ loading,
66
+ label: 'Continue',
67
+ onClick: () => {
68
+ handleSubmit({
69
+ onResult: () => {
70
+ onContinue({
71
+ firstName: values.firstName,
72
+ lastName: values.lastName,
73
+ gender: values.gender,
74
+ selectedDOB: values.dateOfBirth,
75
+ referralCode: values.referralCode,
76
+ email: email,
77
+ phone,
78
+ countryCode,
79
+ registrationMethod,
80
+ });
81
+ }
82
+ });
83
+ },
84
+ disabled: !values.firstName || !values.lastName || !values.gender || !values.dateOfBirth || !values.phone || !termsAndConditions || !isHuman
85
+ }, onPressBack: onGoToLogin, children: _jsxs(Form, { form: form, className: "w-full", onSubmit: () => { }, children: [_jsxs(Row, { gutter: 18, className: "py-0 my-0", children: [_jsx(Col, { xs: 24, md: 12, children: _jsx(Form.Item, { name: "firstName", label: "First Name", className: 'mt-5', rules: [
86
+ {
87
+ required: true,
88
+ message: 'Please enter your first name'
89
+ },
90
+ {
91
+ pattern: validationPatterns.nameOnly,
92
+ message: 'Name can only contain letters'
93
+ },
94
+ {
95
+ validator: async (_, value) => {
96
+ if (value && value.length < 3) {
97
+ throw new Error('Name must be at least 3 characters');
98
+ }
99
+ },
100
+ },
101
+ ], normalize: (value) => (value ?? '').replace(/[^a-zA-Z]/g, ''), children: _jsx(TextInput, { placeholder: "Enter your first name", ...form.register('firstName', {
102
+ onChange: (e) => onFirstName(e.target.value)
103
+ }) }) }) }), _jsx(Col, { xs: 24, md: 12, children: _jsx(Form.Item, { name: "lastName", label: "Last Name", className: 'mt-5', rules: [
104
+ {
105
+ required: true,
106
+ message: 'Please enter your last name'
107
+ },
108
+ {
109
+ pattern: validationPatterns.nameOnly,
110
+ message: 'Name can only contain letters'
111
+ },
112
+ {
113
+ validator: async (_, value) => {
114
+ if (value && value.length < 3) {
115
+ throw new Error('Name must be at least 3 characters');
116
+ }
117
+ },
118
+ },
119
+ ], normalize: (value) => (value ?? '').replace(/[^a-zA-Z]/g, ''), children: _jsx(TextInput, { placeholder: "Enter your last name", ...form.register('lastName', {
120
+ onChange: (e) => onLastName(e.target.value)
121
+ }) }) }) })] }), _jsxs(Row, { gutter: 18, className: "py-0 mt-4 relative", children: [_jsx(Col, { xs: 18, md: 19, children: _jsx(Typography, { type: "body", size: "large", className: "text-gray-700", children: "Your biological sex at the time of birth" }) }), _jsxs(Col, { xs: 6, md: 5, className: "flex justify-end group", children: [_jsx(Typography, { type: "body", size: "large", className: "text-primary cursor-pointer whitespace-nowrap", children: "Know More" }), _jsxs(Flex, { className: "hidden group-hover:block w-full absolute left-2 top-6 rounded-md p-4 z-10 text-gray-950 bg-white shadow-[0_0_10px_0_rgba(0,0,0,0.3)]", children: [_jsxs(Flex, { className: "p-0 mb-3 gap-3", children: [_jsx(Image, { src: `${CDN_IMAGES_URL}/registration/gender-diversity.svg`, alt: "gender diversity", width: 44, height: 44, className: "h-auto" }), _jsxs(Typography, { type: "body", size: "large", className: "text-gray-800", children: ["The ", appName, " respects Gender Diversity & Inclusion!"] })] }), _jsxs(Typography, { type: "body", size: "small", className: "text-gray-500", children: [appName, " aims to provide you with a personalized wellness experience. This requires us to incorporate certain algorithms based on protocols provided by established health & medical institutions around the world. These protocols are based on your biological sex at birth."] })] })] })] }), _jsx(Row, { className: "py-0 mb-5", children: _jsx(Col, { children: _jsx(Form.Item, { name: "gender", className: "mt-4", rules: [
122
+ {
123
+ required: true,
124
+ message: 'Please select your biological sex'
125
+ }
126
+ ], children: _jsx(RadioGroup, { orientation: "horizontal", options: [
127
+ { label: 'Male', value: 'M' },
128
+ { label: 'Female', value: 'F' },
129
+ ], ...form.register('gender', {
130
+ onChange: (e) => setGender(e.target.value)
131
+ }) }) }) }) }), _jsxs(Row, { gutter: 18, className: "py-0 my-5", children: [_jsx(Col, { xs: 24, md: 24, lg: 12, children: _jsx(Form.Item, { name: "dateOfBirth", label: "Date of Birth", rules: [
132
+ {
133
+ required: true,
134
+ message: 'Please select your date of birth'
135
+ }
136
+ ], children: _jsx(DatePicker, { required: true, size: "middle", format: "dd/MM/yyyy", placeholder: "DD/MM/YYYY",
137
+ /* @ts-ignore */
138
+ disabledDate: disabledDate, iconPosition: "right", defaultPickerValue: dayjs('1990-01-01').toDate(), suffixIcon: _jsx(CalendarDays, { className: "-mt-2" }), ...form.register('dateOfBirth', {
139
+ onChange: (value, dateString) => setSelectedDOB(dateString ?? (value?.toISOString ? value.toISOString() : String(value)))
140
+ }) }) }) }), _jsx(Col, { xs: 24, md: 24, lg: 12, children: _jsx(Form.Item, { label: "Mobile Number", className: "mb-0", name: "phone", rules: [
141
+ {
142
+ required: true,
143
+ message: 'Please enter your mobile number'
144
+ }
145
+ ], children: _jsx(Flex, { className: "border border-gray-400 rounded-md", children: _jsx(TextInput, { type: "tel", value: values.phone, placeholder: "Mobile number", maxLength: countryCode === "91" ? 10 : 14, className: "py-4 border-0 md:text-base", addonBefore: _jsx(CountryCodeDropdown, { selectedCountry: selectedCountry, handleSelect: (country) => {
146
+ setCountryCode(country.phoneCode);
147
+ setSelectedCountry(country);
148
+ setIsPhoneValid(country.phoneCode === "91"
149
+ ? /^[0-9]+$/.test(phone) && phone.length >= 10
150
+ : phone.length > 5);
151
+ } }), ...form.register("phone", {
152
+ onChange: (e) => enterMobile(e.target.value)
153
+ }) }) }) }) })] }), _jsx(Col, { children: _jsx(Form.Item, { name: "referralCode", label: "Referral Code (Optional)", className: "mt-4", children: _jsx(TextInput, { placeholder: "Referral code", ...form.register('referralCode', {
154
+ onChange: (e) => setReferralCode(e.target.value)
155
+ }) }) }) }), isProduction && (process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY
156
+ ? _jsx(RecaptchaComponent, { onChange: handleCaptcha })
157
+ : _jsx(Typography, { type: "utility", size: "small", color: "red-600", children: "reCAPTCHA misconfigured. Set NEXT_PUBLIC_RECAPTCHA_SITE_KEY." })), _jsx(Row, { className: "py-0 my-5", children: _jsx(Col, { children: _jsx(Form.Item, { name: "termsAndConditions", rules: [
158
+ {
159
+ required: true,
160
+ message: 'Please accept the Terms & Conditions'
161
+ }
162
+ ],
163
+ /* @ts-ignore */
164
+ valuePropName: "checked", children: _jsx(CustomCheckbox, { checked: termsAndConditions, onClick: (e) => {
165
+ setTermsAndConditions(prev => !prev);
166
+ }, className: "mt-4", label: _jsxs(Typography, { type: "body", size: "medium", children: ["I accept the", _jsx("a", { target: "_blank", rel: "noopener noreferrer", href: termsAndConditionsUrl, className: "px-1 text-primary", children: "Terms & Conditions" }), "listed on ", appName] }) }) }) }) })] }) }), _jsxs(Flex, { align: 'center', className: 'p-0 mt-4', children: [_jsx(Typography, { type: "body", size: "large", className: "text-gray-700", children: "Already have an account?" }), _jsx(Button, { label: "Sign-In", variant: "link", size: "medium", className: "ml-2 h-auto px-0", onClick: onGoToLogin })] }), existingAccountModal &&
167
+ _jsx(ExistingAccountsModal, { phone: phone, countryCode: countryCode, visible: existingAccountModal, hide: () => setExistingAccountModal(false), existingAccounts: existingAccounts, getLoginTypeText: getLoginTypeText, onGoToLogin: onGoToLogin })] }));
168
+ };
169
+ const ExistingAccountsModal = ({ visible, hide, existingAccounts, countryCode, phone, getLoginTypeText, onGoToLogin }) => {
170
+ return (_jsxs(ResponsiveModal, { open: visible, onClose: hide, onOpenChange: hide, title: _jsxs(_Fragment, { children: [_jsx(Typography, { type: "heading", size: "h6", children: "Mobile Number Already Linked" }), _jsxs(Typography, { type: "utility", size: "medium", color: "gray-600", className: "mt-2 mb-3", children: ["The mobile number +", countryCode, " ", String(phone).replace(/\d(?=\d{2})/g, 'X'), " is linked to the following ", existingAccounts.length === 1 ? 'account' : `${existingAccounts.length} accounts`, "."] }), _jsx("hr", {})] }), centered: true, showCloseButton: false, className: "px-0", footer: _jsxs(Flex, { direction: "column", children: [_jsx(Button, { isFullWidth: true, variant: "primary", label: "Go to Login", onClick: () => {
171
+ onGoToLogin();
172
+ hide();
173
+ }, className: "!ml-0 mb-[-4px]" }), _jsx(SupportDetails, {})] }), children: [_jsx(Typography, { type: "utility", size: "medium", children: "Please login through any of the below account or contact our support team for assistance" }), existingAccounts.map((item) => {
174
+ const key = item.id ?? item.email ?? `${item.loginType}-${item.createdOn}`;
175
+ return (_jsxs(Flex, { direction: "column", className: "border border-gray-300 p-4 rounded-md mt-3", children: [_jsxs(Flex, { direction: "column", className: "border-b-2 pb-2", children: [_jsx(Typography, { type: "utility", size: "large", children: item.name }), _jsx(Typography, { type: "utility", size: "medium", color: "primary", children: item.email })] }), _jsxs(Flex, { justify: "between", className: "mt-3", children: [_jsx(Typography, { type: "utility", size: "medium", color: "gray-700", children: "Login Type" }), _jsx(Typography, { type: "utility", size: "medium", color: "gray-800", children: getLoginTypeText(item.loginType) })] }), _jsxs(Flex, { justify: "between", className: "mt-3", children: [_jsx(Typography, { type: "utility", size: "medium", color: "gray-700", children: "Registration Date" }), _jsx(Typography, { type: "utility", size: "medium", color: "gray-800", children: moment(item.createdOn).format('DD/MM/YYYY') })] })] }, key));
176
+ })] }));
177
+ };
178
+ const RecaptchaComponent = React.memo(({ onChange }) => {
179
+ return (_jsx(Row, { gutter: 10, children: _jsx(Col, { span: 24, children: _jsx(ReCAPTCHA, { className: "g-recaptcha", sitekey: process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY || '', onChange: (token) => onChange(token ?? ''), onExpired: () => onChange(''), onErrored: () => onChange(''), size: "normal" }) }) }));
180
+ });
181
+ export { SignUpFormComponent };
@@ -0,0 +1,6 @@
1
+ const SignUpForm = () => {
2
+ if (__DEV__)
3
+ console.warn("[@truworth/twc-auth] SignUpWebComponent is web-only");
4
+ return null;
5
+ };
6
+ export { SignUpForm };
@@ -0,0 +1,82 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Flex, ResponsiveModal } from "@truworth/twc-web-design";
3
+ import { useRouter } from "next/router";
4
+ import { useEffect, useState } from "react";
5
+ import { AdvancedTransitionWrapper } from "../../../../components/AdvancedTransitionWrapper";
6
+ import { useAuthPackageContext } from "../../../../hooks/internal/useAuthPackageContext";
7
+ import { SignUpFormComponent } from "../SignUpForm";
8
+ import CreatePassword from "../../../CreatePassword";
9
+ import UserConsent from "../../../UserConsent";
10
+ import VerifyMobile from "../../../VerifyMobile";
11
+ import VerifyEmail from "../../../VerifyEmail";
12
+ const SignUpWebComponent = () => {
13
+ const router = useRouter();
14
+ const [email, setEmail] = useState('');
15
+ const [signUpStep, setSignUpStep] = useState('registration');
16
+ const [userDetails, setUserDetails] = useState({});
17
+ const [registrationParams, setRegistrationParams] = useState({});
18
+ const [showVerifyMobileModal, setShowVerifyMobileModal] = useState(false);
19
+ const [showVerifyEmailModal, setShowVerifyEmailModal] = useState(false);
20
+ const { onRegistrationMethodChange, registrationMethod } = useAuthPackageContext();
21
+ useEffect(() => {
22
+ const rawEmail = router.query.email;
23
+ const rawMethod = router.query.registrationMethod;
24
+ const emailFromQuery = Array.isArray(rawEmail) ? rawEmail[0] : rawEmail;
25
+ const registrationMethodFromQuery = Array.isArray(rawMethod) ? rawMethod[0] : rawMethod;
26
+ const isValidEmail = (val) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val);
27
+ if (typeof emailFromQuery === 'string') {
28
+ if (isValidEmail(emailFromQuery)) {
29
+ setEmail(emailFromQuery);
30
+ }
31
+ else {
32
+ console.warn('Ignoring invalid email in query:', emailFromQuery);
33
+ }
34
+ }
35
+ if (typeof registrationMethodFromQuery === 'string') {
36
+ const method = registrationMethodFromQuery.toLowerCase();
37
+ if (method === 'email' || method === 'mobile') {
38
+ onRegistrationMethodChange(method);
39
+ }
40
+ }
41
+ }, [router.query.email, router.query.registrationMethod, onRegistrationMethodChange]);
42
+ const onGoToLogin = () => {
43
+ router.push('/login');
44
+ };
45
+ const renderStep = () => {
46
+ switch (signUpStep) {
47
+ case 'registration':
48
+ return (_jsx(SignUpFormComponent, { email: email, userDetails: userDetails, registrationMethod: registrationMethod, onContinue: (userDetails) => {
49
+ setUserDetails(userDetails);
50
+ setSignUpStep('create-password');
51
+ }, onGoToLogin: onGoToLogin }));
52
+ case 'create-password':
53
+ return userDetails && (_jsx(CreatePassword, { userDetails: userDetails, handleBack: () => setSignUpStep('registration'), onContinue: (password, confirmPassword) => {
54
+ setUserDetails({ ...userDetails, password, confirmPassword });
55
+ setSignUpStep('user-consent');
56
+ } }));
57
+ case 'user-consent':
58
+ return (_jsx(UserConsent, { routeParams: userDetails, onBackHandler: () => setSignUpStep('create-password'), onVerifyEmail: ({ email, phone, sessionToken }) => {
59
+ setRegistrationParams({ email, phone, sessionToken });
60
+ setShowVerifyEmailModal(true);
61
+ }, onVerifyMobile: ({ phone, sessionToken }) => {
62
+ setRegistrationParams({ phone, sessionToken });
63
+ setShowVerifyMobileModal(true);
64
+ } }));
65
+ default:
66
+ return null;
67
+ }
68
+ };
69
+ return (_jsxs(_Fragment, { children: [_jsx(AdvancedTransitionWrapper, { type: 'slide', duration: 0.5, children: _jsx(Flex, { direction: 'column', justify: 'center', style: { width: '70%' }, className: `lg:w-[70%] lg:h-screen mx-auto h-full my-10`, children: renderStep() }) }), showVerifyMobileModal &&
70
+ _jsx(VerifyMobileModal, { visible: showVerifyMobileModal, hide: () => setShowVerifyMobileModal(false), sessionToken: registrationParams?.sessionToken || '', phone: registrationParams?.phone || '' }), showVerifyEmailModal &&
71
+ _jsx(VerifyEmailModal, { email: email, visible: showVerifyEmailModal, hide: () => setShowVerifyEmailModal(false), sessionToken: registrationParams?.sessionToken || '', onVerifiedOTP: () => {
72
+ setShowVerifyEmailModal(false);
73
+ setShowVerifyMobileModal(true);
74
+ } })] }));
75
+ };
76
+ export { SignUpWebComponent };
77
+ const VerifyMobileModal = ({ visible, hide, sessionToken, phone }) => {
78
+ return (_jsx(ResponsiveModal, { title: 'Verify Mobile', open: visible, onClose: hide, onOpenChange: hide, maskClosable: false, showCloseButton: false, children: _jsx(VerifyMobile, { sessionToken: sessionToken, phone: phone }) }));
79
+ };
80
+ const VerifyEmailModal = ({ visible, hide, sessionToken, email, onVerifiedOTP }) => {
81
+ return (_jsx(ResponsiveModal, { title: 'Verify Email', open: visible, onOpenChange: hide, onClose: hide, maskClosable: false, showCloseButton: false, children: _jsx(VerifyEmail, { email: email, sessionToken: sessionToken, onVerifiedOTP: onVerifiedOTP }) }));
82
+ };
@@ -0,0 +1,6 @@
1
+ const SignUpWebComponent = () => {
2
+ if (__DEV__)
3
+ console.warn("[@truworth/twc-auth] SignUpWebComponent is web-only");
4
+ return null;
5
+ };
6
+ export { SignUpWebComponent };