@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.
- package/README.md +239 -306
- package/build/assets/animation/redirect-home.json +1101 -0
- package/build/assets/cross_icon copy.svg +5 -0
- package/build/assets/cross_icon.svg +5 -0
- package/build/assets/gender-diversity.svg +22 -0
- package/build/assets/logo.svg +55 -0
- package/build/assets/okay_icon copy.svg +3 -0
- package/build/assets/okay_icon.svg +3 -0
- package/build/src/api/axiosClient/index.js +5 -0
- package/build/src/api/axiosClient/index.native.js +5 -0
- package/build/src/components/AdvancedTransitionWrapper/index.js +380 -0
- package/build/src/components/AdvancedTransitionWrapper/index.native.js +10 -0
- package/build/src/components/AdvancedTransitionWrapper/types.js +1 -0
- package/build/src/components/ConfirmationModal/index.js +11 -0
- package/build/src/components/ConfirmationModal/index.native.js +15 -0
- package/build/src/components/ConfirmationModal/types.js +1 -0
- package/build/src/components/EmailOTPVerify/index.js +20 -0
- package/build/src/components/EmailOTPVerify/index.native.js +26 -0
- package/build/src/components/EmailOTPVerify/type.js +1 -0
- package/build/src/components/IonIcon/index.js +11 -0
- package/build/src/components/IonIcon/index.native.js +9 -0
- package/build/src/components/IonIcon/types.js +1 -0
- package/build/src/components/OTPStatusLabel/index.js +10 -0
- package/build/src/components/OTPStatusLabel/index.native.js +21 -0
- package/build/src/components/OTPStatusLabel/types.js +1 -0
- package/build/src/components/PasswordCriteria/hooks/usePasswordCriteria.js +78 -0
- package/build/src/components/PasswordCriteria/index.js +47 -0
- package/build/src/components/PasswordCriteria/index.native.js +19 -0
- package/build/src/components/PasswordCriteria/types.js +1 -0
- package/build/src/components/ScreenLayout/index.js +12 -0
- package/build/src/components/ScreenLayout/index.native.js +18 -0
- package/build/src/components/ScreenLayout/types.js +1 -0
- package/build/src/components/SupportDetails/index.js +9 -0
- package/build/src/components/SupportDetails/index.native.js +6 -0
- package/build/src/components/VerifyOTP/index.js +23 -0
- package/build/src/components/VerifyOTP/index.native.js +38 -0
- package/build/src/components/VerifyOTP/types.js +1 -0
- package/build/src/constants/cdn-url/index.js +1 -0
- package/build/src/constants/cdn-url/index.native.js +5 -0
- package/build/src/contexts/AuthContext.js +184 -0
- package/build/src/contexts/type.js +1 -0
- package/build/src/helpers/Network.js +93 -0
- package/build/src/helpers/Validation.js +12 -0
- package/build/src/helpers/show-message/index.js +19 -0
- package/build/src/helpers/show-message/index.native.js +14 -0
- package/build/src/helpers/show-message/types.js +1 -0
- package/build/src/helpers/types.js +1 -0
- package/build/src/hooks/internal/useAuthPackageContext.js +9 -0
- package/build/src/hooks/internal/useTimer.js +40 -0
- package/build/src/hooks/useAuthContext.js +10 -0
- package/build/src/hooks/useRequest.js +38 -0
- package/build/src/index.js +12 -0
- package/build/src/navigator/index.js +10 -0
- package/build/src/navigator/index.native.js +16 -0
- package/build/src/screens/CountryCode/components/CountryCodeDropdown/index.js +38 -0
- package/build/src/screens/CountryCode/components/CountryCodeDropdown/index.native.js +6 -0
- package/build/src/screens/CountryCode/components/CountryCodeDropdown/types.js +1 -0
- package/build/src/screens/CountryCode/hooks/internal/useCountryCode.js +38 -0
- package/build/src/screens/CountryCode/index.js +10 -0
- package/build/src/screens/CountryCode/index.native.js +37 -0
- package/build/src/screens/CountryCode/type.js +1 -0
- package/build/src/screens/CreatePassword/hooks/internal/useCreatePassword.js +52 -0
- package/build/src/screens/CreatePassword/index.js +43 -0
- package/build/src/screens/CreatePassword/index.native.js +32 -0
- package/build/src/screens/CreatePassword/type.js +1 -0
- package/build/src/screens/EnterEmail/hooks/internal/useEnterEmail.js +86 -0
- package/build/src/screens/EnterEmail/index.js +30 -0
- package/build/src/screens/EnterEmail/index.native.js +34 -0
- package/build/src/screens/EnterPassword/hooks/internal/useEnterPassword.js +47 -0
- package/build/src/screens/EnterPassword/index.js +22 -0
- package/build/src/screens/EnterPassword/index.native.js +23 -0
- package/build/src/screens/EnterPassword/types.js +1 -0
- package/build/src/screens/Login/components/LoginWebComponent/index.js +44 -0
- package/build/src/screens/Login/components/LoginWebComponent/index.native.js +6 -0
- package/build/src/screens/Login/index.js +10 -0
- package/build/src/screens/Login/index.native.js +6 -0
- package/build/src/screens/SignUp/components/SignUpForm/index.js +181 -0
- package/build/src/screens/SignUp/components/SignUpForm/index.native.js +6 -0
- package/build/src/screens/SignUp/components/SignUpForm/type.js +1 -0
- package/build/src/screens/SignUp/components/SignUpWebComponent/index.js +82 -0
- package/build/src/screens/SignUp/components/SignUpWebComponent/index.native.js +6 -0
- package/build/src/screens/SignUp/components/SignUpWebComponent/types.js +1 -0
- package/build/src/screens/SignUp/hooks/internal/useSignUp.js +138 -0
- package/build/src/screens/SignUp/index.js +6 -0
- package/build/src/screens/SignUp/index.native.js +185 -0
- package/build/src/screens/SignUp/types.js +1 -0
- package/build/src/screens/UserConsent/hooks/internal/useConsent.js +48 -0
- package/build/src/screens/UserConsent/index.js +69 -0
- package/build/src/screens/UserConsent/index.native.js +46 -0
- package/build/src/screens/UserConsent/types.js +1 -0
- package/build/src/screens/VerifyEmail/hooks/internal/useVerifyEmail.js +69 -0
- package/build/src/screens/VerifyEmail/index.js +8 -0
- package/build/src/screens/VerifyEmail/index.native.js +14 -0
- package/build/src/screens/VerifyEmail/types.js +1 -0
- package/build/src/screens/VerifyMobile/hooks/internal/useVerifyMobile.js +73 -0
- package/build/src/screens/VerifyMobile/index.js +8 -0
- package/build/src/screens/VerifyMobile/index.native.js +9 -0
- package/build/src/screens/VerifyMobile/types.js +1 -0
- package/build/src/screens/Welcome/hooks/internal/useWelcome.js +21 -0
- package/build/src/screens/Welcome/index.js +28 -0
- package/build/src/screens/Welcome/index.native.js +41 -0
- package/build/src/types/types.js +1 -0
- package/build/types/api/axiosClient/index.d.ts +1 -0
- package/build/types/api/axiosClient/index.native.d.ts +1 -0
- package/build/types/components/AdvancedTransitionWrapper/index.d.ts +3 -0
- package/build/types/components/AdvancedTransitionWrapper/index.native.d.ts +5 -0
- package/build/types/components/AdvancedTransitionWrapper/types.d.ts +25 -0
- package/build/types/components/ConfirmationModal/index.d.ts +3 -0
- package/build/types/components/ConfirmationModal/index.native.d.ts +3 -0
- package/build/types/components/ConfirmationModal/types.d.ts +13 -0
- package/build/types/components/EmailOTPVerify/index.d.ts +3 -0
- package/build/types/components/EmailOTPVerify/index.native.d.ts +3 -0
- package/build/types/components/EmailOTPVerify/type.d.ts +9 -0
- package/build/types/components/IonIcon/index.d.ts +3 -0
- package/build/types/components/IonIcon/index.native.d.ts +4 -0
- package/build/types/components/IonIcon/types.d.ts +6 -0
- package/build/types/components/OTPStatusLabel/index.d.ts +2 -0
- package/build/types/components/OTPStatusLabel/index.native.d.ts +3 -0
- package/build/types/components/OTPStatusLabel/types.d.ts +6 -0
- package/build/types/components/PasswordCriteria/hooks/usePasswordCriteria.d.ts +13 -0
- package/build/types/components/PasswordCriteria/index.d.ts +3 -0
- package/build/types/components/PasswordCriteria/index.native.d.ts +3 -0
- package/build/types/components/PasswordCriteria/types.d.ts +15 -0
- package/build/types/components/ScreenLayout/index.d.ts +3 -0
- package/build/types/components/ScreenLayout/index.native.d.ts +3 -0
- package/build/types/components/ScreenLayout/types.d.ts +12 -0
- package/build/types/components/SupportDetails/index.d.ts +2 -0
- package/build/types/components/SupportDetails/index.native.d.ts +2 -0
- package/build/types/components/VerifyOTP/index.d.ts +3 -0
- package/build/types/components/VerifyOTP/index.native.d.ts +3 -0
- package/build/types/components/VerifyOTP/types.d.ts +10 -0
- package/build/types/constants/cdn-url/index.d.ts +1 -0
- package/build/types/constants/cdn-url/index.native.d.ts +3 -0
- package/build/types/contexts/AuthContext.d.ts +36 -0
- package/build/types/contexts/type.d.ts +58 -0
- package/build/types/helpers/Network.d.ts +5 -0
- package/build/types/helpers/Validation.d.ts +2 -0
- package/build/types/helpers/show-message/index.d.ts +3 -0
- package/build/types/helpers/show-message/index.native.d.ts +3 -0
- package/build/types/helpers/show-message/types.d.ts +2 -0
- package/build/types/helpers/types.d.ts +13 -0
- package/build/types/hooks/internal/useAuthPackageContext.d.ts +1 -0
- package/build/types/hooks/internal/useTimer.d.ts +3 -0
- package/build/types/hooks/useAuthContext.d.ts +2 -0
- package/build/types/hooks/useRequest.d.ts +5 -0
- package/build/types/index.d.ts +8 -0
- package/build/types/navigator/index.d.ts +2 -0
- package/build/types/navigator/index.native.d.ts +36 -0
- package/build/types/screens/CountryCode/components/CountryCodeDropdown/index.d.ts +3 -0
- package/build/types/screens/CountryCode/components/CountryCodeDropdown/index.native.d.ts +2 -0
- package/build/types/screens/CountryCode/components/CountryCodeDropdown/types.d.ts +17 -0
- package/build/types/screens/CountryCode/hooks/internal/useCountryCode.d.ts +12 -0
- package/build/types/screens/CountryCode/index.d.ts +2 -0
- package/build/types/screens/CountryCode/index.native.d.ts +2 -0
- package/build/types/screens/CountryCode/type.d.ts +11 -0
- package/build/types/screens/CreatePassword/hooks/internal/useCreatePassword.d.ts +26 -0
- package/build/types/screens/CreatePassword/index.d.ts +3 -0
- package/build/types/screens/CreatePassword/index.native.d.ts +4 -0
- package/build/types/screens/CreatePassword/type.d.ts +43 -0
- package/build/types/screens/EnterEmail/hooks/internal/useEnterEmail.d.ts +24 -0
- package/build/types/screens/EnterEmail/index.d.ts +7 -0
- package/build/types/screens/EnterEmail/index.native.d.ts +4 -0
- package/build/types/screens/EnterPassword/hooks/internal/useEnterPassword.d.ts +20 -0
- package/build/types/screens/EnterPassword/index.d.ts +3 -0
- package/build/types/screens/EnterPassword/index.native.d.ts +4 -0
- package/build/types/screens/EnterPassword/types.d.ts +5 -0
- package/build/types/screens/Login/components/LoginWebComponent/index.d.ts +2 -0
- package/build/types/screens/Login/components/LoginWebComponent/index.native.d.ts +2 -0
- package/build/types/screens/Login/index.d.ts +2 -0
- package/build/types/screens/Login/index.native.d.ts +2 -0
- package/build/types/screens/SignUp/components/SignUpForm/index.d.ts +3 -0
- package/build/types/screens/SignUp/components/SignUpForm/index.native.d.ts +2 -0
- package/build/types/screens/SignUp/components/SignUpForm/type.d.ts +9 -0
- package/build/types/screens/SignUp/components/SignUpWebComponent/index.d.ts +2 -0
- package/build/types/screens/SignUp/components/SignUpWebComponent/index.native.d.ts +2 -0
- package/build/types/screens/SignUp/components/SignUpWebComponent/types.d.ts +24 -0
- package/build/types/screens/SignUp/hooks/internal/useSignUp.d.ts +50 -0
- package/build/types/screens/SignUp/index.d.ts +2 -0
- package/build/types/screens/SignUp/index.native.d.ts +4 -0
- package/build/types/screens/SignUp/types.d.ts +18 -0
- package/build/types/screens/UserConsent/hooks/internal/useConsent.d.ts +10 -0
- package/build/types/screens/UserConsent/index.d.ts +3 -0
- package/build/types/screens/UserConsent/index.native.d.ts +4 -0
- package/build/types/screens/UserConsent/types.d.ts +27 -0
- package/build/types/screens/VerifyEmail/hooks/internal/useVerifyEmail.d.ts +19 -0
- package/build/types/screens/VerifyEmail/index.d.ts +3 -0
- package/build/types/screens/VerifyEmail/index.native.d.ts +4 -0
- package/build/types/screens/VerifyEmail/types.d.ts +8 -0
- package/build/types/screens/VerifyMobile/hooks/internal/useVerifyMobile.d.ts +14 -0
- package/build/types/screens/VerifyMobile/index.d.ts +3 -0
- package/build/types/screens/VerifyMobile/index.native.d.ts +4 -0
- package/build/types/screens/VerifyMobile/types.d.ts +5 -0
- package/build/types/screens/Welcome/hooks/internal/useWelcome.d.ts +14 -0
- package/build/types/screens/Welcome/index.d.ts +4 -0
- package/build/types/screens/Welcome/index.native.d.ts +4 -0
- package/build/types/types/types.d.ts +90 -0
- package/get-metro-config.js +40 -0
- package/get-next-config.js +26 -0
- package/package.json +86 -38
- package/dist/index.esm.js +0 -2028
- package/dist/index.umd.js +0 -70
- 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,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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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 @@
|
|
|
1
|
+
export {};
|