@truworth/twc-auth 1.1.0 → 1.2.2

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 +22 -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 +185 -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 +41 -0
  52. package/build/src/index.js +14 -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 +174 -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 +59 -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 +9 -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,138 @@
1
+ import { useMemo, useState } from "react";
2
+ import { validateEmojiRegex } from "../../../../helpers/Validation";
3
+ import { axiosClient } from "../../../../api/axiosClient";
4
+ import { showMessage } from "../../../../helpers/show-message";
5
+ import { useAuthPackageContext } from "../../../../hooks/internal/useAuthPackageContext";
6
+ /**
7
+ * @internal
8
+ * Hook for managing SignUp screen state and auth context integration.
9
+ * This hook is not exposed to package consumers.
10
+ */
11
+ const useSignUp = () => {
12
+ const [loading, setLoading] = useState(false);
13
+ const [datePicker, showDatePicker] = useState(false);
14
+ const [isPhoneValid, setIsPhoneValid] = useState(false);
15
+ const [existingAccountModal, setExistingAccountModal] = useState(false);
16
+ const [firstName, setFirstName] = useState('');
17
+ const [lastName, setLastName] = useState('');
18
+ const [phone, setPhone] = useState('');
19
+ const [gender, setGender] = useState('');
20
+ const [referralCode, setReferralCode] = useState('');
21
+ const [selectedDOB, setSelectedDOB] = useState('');
22
+ const [countryCode, setCountryCode] = useState('91');
23
+ const [error, setError] = useState({});
24
+ const [phoneError, setPhoneError] = useState(false);
25
+ const [email, setEmail] = useState('');
26
+ const [emailLinkedError, setEmailLinkedError] = useState('');
27
+ const [existingAccounts, setExistingAccounts] = useState([]);
28
+ const { appConfig, registrationMethod } = useAuthPackageContext();
29
+ const onFirstName = (text) => {
30
+ text = validateEmojiRegex(text).replace(/[^A-Za-z]/g, '');
31
+ setFirstName(text);
32
+ };
33
+ const onLastName = (text) => {
34
+ text = validateEmojiRegex(text).replace(/[^A-Za-z]/g, '');
35
+ ;
36
+ setLastName(text);
37
+ };
38
+ const handleEmail = (text) => {
39
+ let reg = /^(([^<>()\[\]\\.,;:\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,}))$/;
40
+ if (text.length === 0) {
41
+ setEmailLinkedError('');
42
+ }
43
+ else if (reg.test(text) === false) {
44
+ setEmailLinkedError('Invalid email');
45
+ }
46
+ else {
47
+ setEmailLinkedError('');
48
+ }
49
+ setEmail(text);
50
+ };
51
+ const handleSubmit = ({ onResult }) => {
52
+ if (registrationMethod === 'email' && countryCode === '91') {
53
+ setLoading(true);
54
+ axiosClient({
55
+ url: '/auth/mobile-exists',
56
+ method: 'POST',
57
+ data: { phone }
58
+ }).then(res => {
59
+ setLoading(false);
60
+ if (res?.data?.exists) {
61
+ setExistingAccounts(res?.data?.memberDetails || []);
62
+ setExistingAccountModal(true);
63
+ return;
64
+ }
65
+ onResult();
66
+ }).catch(err => onHandleError(err, onResult));
67
+ }
68
+ else if (registrationMethod === 'mobile' && email) {
69
+ setLoading(true);
70
+ axiosClient({
71
+ url: '/auth/email-exists',
72
+ method: 'POST',
73
+ data: { email }
74
+ }).then(() => {
75
+ setLoading(false);
76
+ setEmailLinkedError('This email is already linked with another user.');
77
+ }).catch(err => onHandleError(err, onResult));
78
+ }
79
+ else {
80
+ onResult();
81
+ }
82
+ };
83
+ const onHandleError = (err, onResult) => {
84
+ setLoading(false);
85
+ const status = err?.response?.status;
86
+ if (!status) {
87
+ return showMessage('Network error. Please try again.', err?.response?.data?.message);
88
+ }
89
+ if (status === 404) {
90
+ return onResult();
91
+ }
92
+ if (status === 400) {
93
+ return showMessage(err?.response?.data?.errors?.[0]?.message ?? 'Something went wrong');
94
+ }
95
+ if (typeof status === 'number' && status >= 500) {
96
+ return showMessage('Something went wrong');
97
+ }
98
+ };
99
+ const getLoginTypeText = (loginType) => {
100
+ switch (loginType) {
101
+ case 1: return 'Email';
102
+ case 2: return 'Google';
103
+ case 3: return 'Facebook';
104
+ case 4: return 'Apple';
105
+ case 5: return 'Microsoft';
106
+ default: return 'Email';
107
+ }
108
+ };
109
+ const disabled = useMemo(() => {
110
+ return !firstName || firstName.length < 3 || !lastName || lastName.length < 3 || !selectedDOB || !gender
111
+ || (registrationMethod == "email" && (!phone || !isPhoneValid)) || emailLinkedError.length > 0;
112
+ }, [firstName, lastName, selectedDOB, gender, phone, isPhoneValid, emailLinkedError, registrationMethod]);
113
+ return {
114
+ loading,
115
+ firstName, lastName,
116
+ gender, setGender,
117
+ datePicker, showDatePicker,
118
+ selectedDOB, setSelectedDOB,
119
+ phone, setPhone,
120
+ referralCode, setReferralCode,
121
+ countryCode, setCountryCode,
122
+ error, setError,
123
+ email, setEmail,
124
+ phoneError, setPhoneError,
125
+ isPhoneValid, setIsPhoneValid,
126
+ emailLinkedError,
127
+ existingAccounts,
128
+ existingAccountModal, setExistingAccountModal,
129
+ onFirstName, onLastName,
130
+ handleEmail, handleSubmit,
131
+ getLoginTypeText,
132
+ disabled,
133
+ registrationMethod,
134
+ appName: appConfig.appName,
135
+ termsAndConditionsUrl: appConfig.termsAndConditionsUrl
136
+ };
137
+ };
138
+ export { useSignUp };
@@ -0,0 +1,6 @@
1
+ const SignUp = () => {
2
+ if (__DEV__)
3
+ console.warn("[@truworth/twc-auth] We use only SignUpWebComponent for login");
4
+ return null;
5
+ };
6
+ export default SignUp;
@@ -0,0 +1,185 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { View, Text, Platform, Keyboard, TouchableOpacity, ScrollView, TextInput } from 'react-native';
4
+ import { useNavigation, useRoute } from '@react-navigation/native';
5
+ import { useModalize } from 'react-native-modalize';
6
+ import { Freshchat } from 'react-native-freshchat-sdk';
7
+ import { Layout } from '@ui-kitten/components';
8
+ import DateTimePicker from '@react-native-community/datetimepicker';
9
+ import IonIcon from 'react-native-vector-icons/Ionicons';
10
+ import moment from 'moment';
11
+ import { BottomSheet, Chips, Colors, TextInputField, DateInputField, widthPercentageToDP as wp, isIphoneX, RoundedButton, CustomKeyboardAvoidingView } from '@truworth/twc-rn-common';
12
+ import { ScreenLayout } from '../../components/ScreenLayout';
13
+ import { useSignUp } from './hooks/internal/useSignUp';
14
+ import { useAuthPackageContext } from '../../hooks/internal/useAuthPackageContext';
15
+ import GenderDiversity from '../../../assets/gender-diversity.svg';
16
+ const { gray, primary, utility } = Colors;
17
+ const SignUp = ({ navigation, route }) => {
18
+ const [knowMoreModal, setKnowMoreModal] = useState(false);
19
+ const { loading, firstName, lastName, gender, setGender, datePicker, showDatePicker, selectedDOB, setSelectedDOB, phone, setPhone, referralCode, setReferralCode, countryCode, setCountryCode, error, setError, phoneError, setPhoneError, isPhoneValid, setIsPhoneValid, email, emailLinkedError, existingAccounts, existingAccountModal, setExistingAccountModal, onFirstName, onLastName, handleEmail, handleSubmit, getLoginTypeText, disabled, registrationMethod, } = useSignUp();
20
+ const onChange = (event, selectedDate) => {
21
+ showDatePicker(Platform.OS === 'ios');
22
+ if (selectedDate) {
23
+ setSelectedDOB(moment(selectedDate).format('YYYY-MM-DD'));
24
+ }
25
+ };
26
+ return (_jsxs(Layout, { style: { flex: 1, backgroundColor: primary.white }, children: [_jsx(CustomKeyboardAvoidingView, { keyboardVerticalOffset: Platform.OS == 'ios' ? 20 : 0, behavior: Platform.OS == 'ios' ? 'padding' : undefined, children: _jsx(ScrollView, { showsVerticalScrollIndicator: false, keyboardShouldPersistTaps: 'always', children: _jsxs(ScreenLayout, { title: "Looks like you're new here!", subTitle: "Tell us more about you so we can setup your account.", buttonProps: {
27
+ label: 'Register',
28
+ loading,
29
+ onPress: () => {
30
+ handleSubmit({
31
+ onResult: () => {
32
+ navigation.navigate('CreatePassword', {
33
+ email: email.length > 0 ? email : route.params?.email || '',
34
+ phone: phone.length > 0 ? phone : route.params?.phone || '',
35
+ firstName,
36
+ lastName,
37
+ gender,
38
+ selectedDOB,
39
+ countryCode,
40
+ referralCode,
41
+ registrationMethod
42
+ });
43
+ }
44
+ });
45
+ },
46
+ disabled: disabled
47
+ }, children: [_jsxs(View, { style: { flexDirection: 'row', justifyContent: 'space-between' }, children: [_jsx(View, { style: { width: '47%' }, children: _jsx(TextInputField, { label: "First Name", value: firstName, onChangeValue: text => {
48
+ onFirstName(text);
49
+ setError(prev => ({ ...prev, firstName: text.length < 3 }));
50
+ }, error: {
51
+ show: error.firstName ? 'At least 3 letters' : '',
52
+ message: 'Enter at least 3 letters'
53
+ }, autoFocus: true, autoCapitalize: "words", clearButtonMode: "always" }) }), _jsx(View, { style: { width: '47%' }, children: _jsx(TextInputField, { label: "Last Name", value: lastName, onChangeValue: text => {
54
+ onLastName(text);
55
+ setError(prev => ({ ...prev, lastName: text.length < 3 }));
56
+ }, error: {
57
+ show: error.lastName ? 'At least 3 letters' : '',
58
+ message: 'Enter at least 3 letters'
59
+ }, autoCapitalize: "words", clearButtonMode: "always" }) })] }), _jsxs(View, { style: { flexDirection: 'row', marginTop: 32, marginBottom: 16 }, children: [_jsx(Text, { style: {
60
+ fontSize: 14, fontWeight: '600',
61
+ color: gray.gray_900, lineHeight: 16, flex: 1,
62
+ }, children: "Your biological sex at the time of birth" }), _jsx(TouchableOpacity, { activeOpacity: 0.8, onPress: () => setKnowMoreModal(true), children: _jsx(Text, { style: {
63
+ fontSize: 14, fontWeight: '600',
64
+ color: primary.primary_main, lineHeight: 16,
65
+ }, children: "Know More" }) })] }), _jsxs(View, { style: { flexDirection: 'row', justifyContent: 'space-between' }, children: [_jsx(TouchableOpacity, { activeOpacity: 1, style: { width: '48%' }, onPress: () => setGender('F'), children: _jsx(Chips, { label: " Female", leftIcon: "female", size: "large", selected: gender === 'F', containerStyle: { width: wp(42) } }) }), _jsx(TouchableOpacity, { activeOpacity: 1, style: { width: '48%' }, onPress: () => setGender('M'), children: _jsx(Chips, { label: " Male", leftIcon: "male", size: "large", selected: gender === 'M', containerStyle: { width: wp(42) } }) })] }), _jsx(DateInputField, { containerStyle: { marginTop: 32 }, label: 'Date of Birth', value: selectedDOB ? moment(selectedDOB).format('DD/MM/YYYY') : '', onPress: () => {
66
+ Keyboard.dismiss();
67
+ showDatePicker(true);
68
+ } }), registrationMethod == 'email' &&
69
+ _jsx(MobileInput, { phone: phone, setPhone: setPhone, countryCode: countryCode, setCountryCode: setCountryCode, phoneError: phoneError, setPhoneError: setPhoneError, isValid: isPhoneValid, setIsValid: setIsPhoneValid }), registrationMethod == 'mobile' &&
70
+ _jsx(View, { style: { marginTop: 24, marginBottom: 20 }, children: _jsx(TextInputField, { label: "Enter Your Email (Optional)", onChangeValue: handleEmail, value: email, autoFocus: false, autoCapitalize: 'none', keyboardType: "email-address", error: {
71
+ show: Boolean(emailLinkedError),
72
+ message: emailLinkedError
73
+ } }) }), _jsx(TextInputField, { label: "Enter Referral Code (Optional)", onChangeValue: text => setReferralCode(text.toUpperCase()), value: referralCode, autoCapitalize: 'characters', containerStyle: { marginTop: 12 } })] }) }) }), datePicker &&
74
+ _jsxs(View, { style: { width: '100%', backgroundColor: 'white', position: 'absolute', bottom: 0 }, children: [Platform.OS === 'ios' && (_jsx(View, { style: { backgroundColor: '#333', justifyContent: 'flex-end', marginTop: 30, padding: 10, marginLeft: -20, marginRight: 0, flexDirection: 'row', zIndex: 1 }, children: _jsx(TouchableOpacity, { onPress: () => showDatePicker(false), children: _jsx(Text, { style: { textAlign: 'right', fontSize: 14, color: '#FFFFFF' }, children: "Done" }) }) })), _jsx(View, { children: _jsx(DateTimePicker, { minimumDate: new Date(1900, 0, 1), value: selectedDOB ? moment(selectedDOB).toDate() : new Date('1990-01-01'), mode: 'date', display: Platform.OS === 'android' ? 'default' : 'spinner', onChange: onChange, style: { marginTop: 10, flex: 1 }, maximumDate: new Date() }) })] }), knowMoreModal &&
75
+ _jsx(KnowMoreModal, { visible: knowMoreModal, hide: () => setKnowMoreModal(false) }), existingAccountModal &&
76
+ _jsx(ExistingAccountsModal, { phone: phone, countryCode: countryCode, visible: existingAccountModal, hide: () => setExistingAccountModal(false), existingAccounts: existingAccounts, getLoginTypeText: getLoginTypeText })] }));
77
+ };
78
+ const KnowMoreModal = ({ visible, hide }) => {
79
+ const { ref: knowMoreRef, open: openKnowMoreSheet, close: closeKnowMoreSheet } = useModalize();
80
+ const { appConfig } = useAuthPackageContext();
81
+ useEffect(() => {
82
+ if (visible) {
83
+ openKnowMoreSheet();
84
+ }
85
+ else {
86
+ closeKnowMoreSheet();
87
+ }
88
+ }, [visible]);
89
+ return (_jsxs(BottomSheet, { sheetRef: knowMoreRef, onClose: hide, childrenStyle: { padding: 16 }, children: [_jsx(View, { style: { height: 10 } }), _jsxs(View, { style: { flexDirection: 'row', alignItems: 'center' }, children: [_jsx(GenderDiversity, { height: 60, width: 60 }), _jsxs(Text, { style: { marginLeft: 15, flex: 1, fontSize: 18, fontWeight: 'bold', color: '#228186' }, children: ["The ", appConfig.appName, " respects Gender Diversity & Inclusion!"] })] }), _jsxs(Text, { style: { fontSize: 14, color: gray.gray_600, lineHeight: 20, marginTop: 20, }, children: ["The ", appConfig.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(View, { style: { height: 20 } })] }));
90
+ };
91
+ const ExistingAccountsModal = ({ visible, hide, existingAccounts, countryCode, phone, getLoginTypeText }) => {
92
+ const { ref: existingAccountsRef, open: openExistingAccountsSheet, close: closeExistingAccountsSheet } = useModalize();
93
+ const navigation = useNavigation();
94
+ useEffect(() => {
95
+ if (visible) {
96
+ openExistingAccountsSheet();
97
+ }
98
+ else {
99
+ closeExistingAccountsSheet();
100
+ }
101
+ }, [visible]);
102
+ return (_jsx(BottomSheet, { sheetRef: existingAccountsRef, title: 'Existing Accounts', onClose: hide, childrenStyle: { padding: 16 }, adjustToContentHeight: true, panGestureEnabled: false, HeaderComponent: _jsxs(_Fragment, { children: [_jsxs(View, { style: { paddingTop: 22, marginHorizontal: 22 }, children: [_jsx(Text, { style: { fontSize: 16, fontWeight: '600', color: gray.gray_900, textAlign: 'center' }, children: "Mobile Number Already Linked" }), _jsxs(Text, { style: { fontSize: 12, fontWeight: '500', color: gray.gray_500, lineHeight: 18, textAlign: 'center', marginHorizontal: 16, marginTop: 4 }, 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(View, { style: { backgroundColor: gray.gray_200, height: 2, marginVertical: 8 } })] }), flatListProps: {
103
+ showsVerticalScrollIndicator: false,
104
+ contentContainerStyle: { flexGrow: 1 },
105
+ data: existingAccounts,
106
+ keyExtractor: (item, index) => item.memberId || index.toString(),
107
+ ListHeaderComponent: _jsx(_Fragment, { children: _jsxs(Text, { style: { fontSize: 12, fontWeight: '600', color: gray.gray_900, marginHorizontal: 16, marginTop: 8, marginBottom: 8 }, children: ["Please login with any of the below ", existingAccounts.length === 1 ? 'account' : 'accounts', " or contact our support team for assistance."] }) }),
108
+ renderItem: ({ item }) => {
109
+ return (_jsxs(View, { style: {
110
+ padding: 16,
111
+ margin: 8,
112
+ borderWidth: 1,
113
+ borderRadius: 8,
114
+ borderColor: gray.gray_200
115
+ }, children: [_jsxs(View, { children: [_jsx(Text, { style: { fontSize: 14, fontWeight: '600', color: gray.gray_900 }, children: item.name }), _jsx(Text, { style: { fontSize: 12, fontWeight: '500', color: primary.primary_main, marginTop: 3 }, children: item.email })] }), _jsx(View, { style: { height: 1, backgroundColor: gray.gray_200, marginVertical: 8 } }), _jsxs(View, { style: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }, children: [_jsx(Text, { style: { fontSize: 12, fontWeight: '500', color: gray.gray_500 }, children: "Login Type" }), _jsx(Text, { style: { fontSize: 12, fontWeight: '600', color: gray.gray_800 }, children: getLoginTypeText(item.loginType) })] }), _jsxs(View, { style: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginTop: 8 }, children: [_jsx(Text, { style: { fontSize: 12, fontWeight: '500', color: gray.gray_500 }, children: "Registration Date" }), _jsx(Text, { style: { fontSize: 12, fontWeight: '600', color: gray.gray_800 }, children: moment(item.createdOn).format('DD/MM/YYYY') })] })] }, item.memberId));
116
+ }
117
+ }, FooterComponent: _jsxs(View, { style: {
118
+ width: '100%',
119
+ backgroundColor: primary.white,
120
+ marginTop: 8,
121
+ padding: 16,
122
+ paddingBottom: isIphoneX() ? 42 : 16,
123
+ borderTopWidth: Platform.OS == 'android' ? 1 : 0,
124
+ borderTopColor: gray.gray_300,
125
+ shadowColor: '#DDDDDD',
126
+ shadowOffset: { width: 0, height: -2 },
127
+ shadowOpacity: 0.5,
128
+ shadowRadius: 3,
129
+ elevation: 3
130
+ }, children: [_jsx(RoundedButton, { label: "Go to Login", size: "large", onPress: () => navigation.navigate('EnterEmail'), containerStyle: { marginBottom: 8 } }), _jsxs(TouchableOpacity, { activeOpacity: 0.8, onPress: () => Freshchat.showConversations(), style: {
131
+ flexDirection: 'row',
132
+ alignItems: 'center',
133
+ justifyContent: 'center',
134
+ padding: 8,
135
+ marginTop: 8
136
+ }, children: [_jsx(IonIcon, { name: 'headset', size: 12, color: primary.primary_main }), _jsx(Text, { style: {
137
+ fontSize: 14,
138
+ fontWeight: '600',
139
+ color: primary.primary_main,
140
+ marginStart: 8
141
+ }, children: "Contact Support" })] })] }) }));
142
+ };
143
+ const MobileInput = ({ phone, setPhone, countryCode, setCountryCode, phoneError, setPhoneError, setIsValid }) => {
144
+ const navigation = useNavigation();
145
+ const route = useRoute();
146
+ useEffect(() => {
147
+ if (route.params?.countryCode) {
148
+ const { countryCode } = route.params;
149
+ setCountryCode(countryCode);
150
+ }
151
+ }, [route.params?.countryCode]);
152
+ const changeCountryCode = () => {
153
+ setIsValid(false);
154
+ setPhone('');
155
+ navigation.navigate('CountryCode', { prevRoute: 'SignUp', ...route.params });
156
+ };
157
+ const onChangeMobile = (text) => {
158
+ setPhoneError(false);
159
+ setPhone(text);
160
+ if (countryCode === '91' && text.length > 9 && /^[0-9\b]+$/.test(text)) {
161
+ setIsValid(true);
162
+ }
163
+ else if (countryCode != '91' && text.length > 5) {
164
+ setIsValid(true);
165
+ }
166
+ else {
167
+ setIsValid(false);
168
+ }
169
+ };
170
+ return (_jsxs(View, { style: { marginTop: 16 }, children: [_jsx(Text, { style: { fontSize: 14, fontWeight: '600', color: gray.gray_900 }, children: "Enter Mobile Number" }), _jsxs(View, { style: {
171
+ flexDirection: 'row', borderWidth: 1, borderRadius: 8,
172
+ alignItems: 'center', paddingHorizontal: 12, height: 56,
173
+ backgroundColor: primary.white, marginTop: 12,
174
+ borderColor: phone.length > 0 ? gray.gray_500 : gray.gray_300,
175
+ }, children: [_jsxs(TouchableOpacity, { activeOpacity: 0.8, onPress: changeCountryCode, style: { flexDirection: 'row', alignItems: 'center' }, children: [_jsx(Text, { style: { fontSize: 14, color: primary.black, fontWeight: '500' }, children: `+${countryCode}` }), _jsx(IonIcon, { size: 14, name: 'caret-down', color: gray.gray_900 })] }), _jsx(TextInput, { style: {
176
+ flex: 1, fontSize: 14, fontWeight: '500',
177
+ color: primary.black, marginLeft: 2,
178
+ }, onChangeText: text => onChangeMobile(text), value: phone, keyboardType: "numeric", maxLength: countryCode === '91' ? 10 : 14 }), phone.length > 0 &&
179
+ _jsx(TouchableOpacity, { activeOpacity: 0.8, onPress: () => {
180
+ setPhone('');
181
+ setIsValid(false);
182
+ setPhoneError(false);
183
+ }, style: { position: 'absolute', right: 10 }, children: _jsx(IonIcon, { size: 24, name: 'close', color: gray.gray_900 }) })] }), _jsx(Text, { style: { fontSize: 12, fontWeight: '500', color: utility.danger_main, marginStart: 4, marginTop: 4 }, children: phoneError ? 'This mobile number is already linked with other user' : '' })] }));
184
+ };
185
+ export default SignUp;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
1
+ import { useState } from "react";
2
+ import { axiosClient } from "../../../../api/axiosClient";
3
+ import { showMessage } from "../../../../helpers/show-message";
4
+ /**
5
+ * @internal
6
+ * Internal hook for managing UserConsent screen state and auth context integration. Not exposed to package consumers.
7
+ */
8
+ const useConsent = () => {
9
+ const [loading, setLoading] = useState(false);
10
+ const onAgree = ({ registrationParams, source, onResult }) => {
11
+ const { firstName, lastName, selectedDOB, gender, referralCode, email, phone, countryCode, registrationMethod, password } = registrationParams || {};
12
+ const payload = {
13
+ firstName,
14
+ lastName,
15
+ dateOfBirth: selectedDOB,
16
+ gender,
17
+ countryCode,
18
+ source,
19
+ registrationMethod
20
+ };
21
+ if (referralCode) {
22
+ payload.referralCode = referralCode;
23
+ }
24
+ if (password) {
25
+ payload.password = password;
26
+ }
27
+ if (email) {
28
+ payload.email = email;
29
+ }
30
+ if (phone) {
31
+ payload.phone = phone;
32
+ }
33
+ setLoading(true);
34
+ axiosClient({
35
+ url: '/auth/registration/initiate',
36
+ method: 'POST',
37
+ data: payload,
38
+ })
39
+ .then((res) => onResult(res.data))
40
+ .catch((err) => {
41
+ console.log(err);
42
+ showMessage(err?.response?.data?.errors?.[0]);
43
+ })
44
+ .finally(() => setLoading(false));
45
+ };
46
+ return { loading, onAgree };
47
+ };
48
+ export { useConsent };
@@ -0,0 +1,69 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import dynamic from 'next/dynamic';
3
+ import React from 'react';
4
+ import Image from 'next/image';
5
+ import { useEffect, useState } from "react";
6
+ import { Info } from 'lucide-react';
7
+ import { useRouter } from "next/router";
8
+ import { Flex, Typography, ResponsiveModal as Modal, Button } from '@truworth/twc-web-design';
9
+ import { useAuthPackageContext } from '../../hooks/internal/useAuthPackageContext';
10
+ import { CDN_IMAGES_URL } from '@truworth/twc-web-common';
11
+ import { useConsent } from './hooks/internal/useConsent';
12
+ import { ScreenLayout } from "../../components/ScreenLayout";
13
+ import redirectHome from '../../../assets/animation/redirect-home.json';
14
+ const Lottie = dynamic(() => import('react-lottie'), { ssr: false });
15
+ const UserConsent = ({ routeParams, onVerifyEmail, onVerifyMobile, onBackHandler }) => {
16
+ const { email, phone } = routeParams || {};
17
+ const [redirectModal, setRedirectModal] = useState(false);
18
+ const { loading, onAgree } = useConsent();
19
+ const { onLogin, appConfig: { appName, privacyPolicyUrl }, LogoComponent } = useAuthPackageContext();
20
+ const onAgreeHandler = (res) => {
21
+ const { token, member, emailVerificationRequired, mobileVerificationRequired, sessionToken } = res;
22
+ if (token && member) {
23
+ return onLogin({ token, member });
24
+ }
25
+ if (emailVerificationRequired) {
26
+ if (!sessionToken || !email) {
27
+ console.warn('UserConsent: missing sessionToken/email for VerifyEmail');
28
+ return;
29
+ }
30
+ return onVerifyEmail({ email, phone, sessionToken });
31
+ }
32
+ if (mobileVerificationRequired) {
33
+ if (!sessionToken || !phone) {
34
+ console.warn('UserConsent: missing sessionToken/phone for VerifyMobile');
35
+ return;
36
+ }
37
+ return onVerifyMobile({ phone, sessionToken });
38
+ }
39
+ // Fallback to avoid silent no-op
40
+ console.warn('onAgree returned no actionable flags. Please retry or contact support.');
41
+ };
42
+ return (_jsx(ScreenLayout, { title: _jsxs(Flex, { direction: 'column', className: 'h-full lg:justify-center', children: [React.isValidElement(LogoComponent)
43
+ ? LogoComponent
44
+ : typeof LogoComponent === 'function'
45
+ ? React.createElement(LogoComponent)
46
+ :
47
+ _jsx(Image, { src: `${CDN_IMAGES_URL ?? ''}/new-twc_logo.svg`, alt: "logo", priority: true, width: 176, height: 40, className: "mb-9 h-auto" }), _jsx(Flex, { className: 'p-0 lg:gap-8 flex-col-reverse lg:flex-row', children: _jsxs(Flex, { direction: 'column', className: 'p-0', children: [_jsx(Typography, { type: 'heading', size: 'h5', className: 'mb-3 text-gray-900', children: "Thank you for your trust & sharing your personal information with us." }), _jsx(Typography, { type: 'heading', size: 'h6', className: "mb-6 text-gray-600", children: "User Consent" }), _jsxs(Typography, { type: 'body', size: 'medium', className: 'lg:text-sm text-gray-800', children: ["I provide ", appName, " with the consent to collect, use, store, share, and/or otherwise process my personal information including but not limited to Name, Gender (biological sex at the time of birth), Date of Birth and Email Address, Mobile Number, and other health vital & lifestyle information). The information is collected for the specified, explicit and legitimate purposes only - which is to assess me or my family's Health Risk, schedule Investigations, Health Check-ups, Doctor Consultations, Procedure, Treatment, provide Health & Wellness Coaching and Payments and ensure that the same is not excessive in relation to the purposes for which it is being collected, and also ensure that such personal information is retained only as long as the user is registered on the platform. I, also agree to receive Email / SMS/WhatsApp alerts and calls in connection with me or my family's health & wellness services."] }), _jsxs(Typography, { type: 'body', size: 'medium', className: "lg:text-sm mt-5 text-gray-800", children: ["Please refer to the 'Terms & Conditions', Privacy & Data Protection Policy listed on ", _jsxs("a", { href: privacyPolicyUrl, target: '_blank', rel: "noopener noreferrer", className: "text-primary block font-semibold", children: [appName, "'s Privacy & Data Protection Policy"] })] }), _jsxs(Flex, { className: '!px-0 flex-col lg:flex-row mt-8', children: [_jsx(Button, { label: "Yes, I Agree", variant: "primary", loading: loading, onClick: () => onAgree({
48
+ registrationParams: routeParams,
49
+ source: 'web',
50
+ onResult: onAgreeHandler
51
+ }), className: "w-full lg:!w-auto lg:!mt-0" }), _jsx(Button, { label: "Not Now, I Will Register Later", variant: "link", onClick: () => setRedirectModal(true), className: "w-full lg:!w-auto lg:!mt-0" })] })] }) })] }), subTitle: "", onPressBack: onBackHandler, children: redirectModal &&
52
+ _jsx(RedirectToHomeModal, { redirectModal: redirectModal }) }));
53
+ };
54
+ const RedirectToHomeModal = ({ redirectModal }) => {
55
+ const router = useRouter();
56
+ useEffect(() => {
57
+ router.push('/login');
58
+ }, []);
59
+ return (_jsxs(Modal, { title: "", open: redirectModal, showCloseButton: false, footer: null, children: [_jsx(Lottie
60
+ /* @ts-ignore */
61
+ , {
62
+ /* @ts-ignore */
63
+ options: {
64
+ animationData: redirectHome,
65
+ loop: true,
66
+ autoplay: true
67
+ }, height: 150, width: 250 }), _jsxs(Flex, { direction: 'column', style: { marginTop: "-30px" }, children: [_jsx(Typography, { type: 'heading', size: 'h5', className: 'text-center mb-6', color: "text-gray-800", children: "Redirecting to the website homepage" }), _jsxs(Flex, { children: [_jsx(Info, { color: 'blue' }), _jsx(Typography, { type: 'body', size: 'small', className: 'text-center mb-6', color: "text-gray-800", children: "We have not stored any information you shared during registration." })] })] })] }));
68
+ };
69
+ export default UserConsent;
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ScrollView, Text, TouchableOpacity, Linking, View, Platform } from 'react-native';
3
+ import { Layout } from '@ui-kitten/components';
4
+ import { Colors, Header } from '@truworth/twc-rn-common';
5
+ import { ScreenLayout } from '../../components/ScreenLayout';
6
+ import { useAuthPackageContext } from '../../hooks/internal/useAuthPackageContext';
7
+ import { useConsent } from './hooks/internal/useConsent';
8
+ const { primary, gray } = Colors;
9
+ const UserConsent = ({ navigation, route }) => {
10
+ const { email, phone } = route.params || {};
11
+ const { onLogin, appConfig: { appName, privacyPolicyUrl } } = useAuthPackageContext();
12
+ const { loading, onAgree } = useConsent();
13
+ const onAgreeHandler = (res) => {
14
+ const { token, member, emailVerificationRequired, mobileVerificationRequired, sessionToken } = res;
15
+ if (token && member) {
16
+ return onLogin({ token, member });
17
+ }
18
+ if (emailVerificationRequired) {
19
+ if (!sessionToken || !email) {
20
+ console.warn('UserConsent: missing sessionToken/email for VerifyEmail');
21
+ return;
22
+ }
23
+ return navigation.navigate('VerifyEmail', { email, phone, sessionToken });
24
+ }
25
+ if (mobileVerificationRequired) {
26
+ if (!sessionToken || !phone) {
27
+ console.warn('UserConsent: missing sessionToken/phone for VerifyMobile');
28
+ return;
29
+ }
30
+ return navigation.navigate('VerifyMobile', { phone, sessionToken });
31
+ }
32
+ console.warn('onAgree returned no actionable flags. Please retry or contact support.');
33
+ };
34
+ return (_jsxs(Layout, { style: { flex: 1, backgroundColor: primary.white }, children: [_jsx(Header, {}), _jsx(ScrollView, { children: _jsx(ScreenLayout, { hideHeader: true, title: "", subTitle: "", buttonProps: {
35
+ loading,
36
+ type: 'secondary',
37
+ label: 'I agree, Register me.',
38
+ onPress: () => onAgree({
39
+ registrationParams: route.params,
40
+ source: Platform.OS,
41
+ onResult: onAgreeHandler
42
+ }),
43
+ disabled: loading,
44
+ }, children: _jsxs(View, { style: { paddingHorizontal: 8 }, children: [_jsxs(Text, { style: { color: gray.gray_600, fontWeight: '400', lineHeight: 24 }, children: ["I provide ", appName, ", with the consent to collect, use, store, share, and / or otherwise process my personal information including but not limited to Name, Gender (biological sex at the time of birth), Date of Birth and Email Address, Mobile Number, and other health vital & lifestyle information).", ' ', "The information is collected for the specified, explicit and legitimate purposes only \u2013 which is to assess me or my family\u2019s Health Risk, schedule Investigations, Health Check-ups, Doctor Consultations, Procedure, Treatment, provide Health & Wellness Coaching and Payments and ensure that the same is not excessive in relation to the purposes for which it is being collected, and also ensure that such personal information is retained only as long as the user is registered on the platform.", ' ', "I, also agree to receive Email / SMS / WhatsApp alerts and calls in connection with me or my family\u2019s health & wellness services.", ' ', "Please refer to the Terms & Conditions, Privacy & Data Protection Policy listed on", ' '] }), _jsx(TouchableOpacity, { style: { marginTop: 16, marginBottom: -12 }, activeOpacity: 0.8, onPress: () => privacyPolicyUrl && Linking.openURL(privacyPolicyUrl), children: _jsxs(Text, { style: { fontSize: 16, fontWeight: '600', color: primary.primary_main, lineHeight: 24 }, children: [appName, "'s Privacy & Data Protection Policy"] }) })] }) }) })] }));
45
+ };
46
+ export default UserConsent;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { showMessage } from "../../../../helpers/show-message";
3
+ import { axiosClient } from "../../../../api/axiosClient";
4
+ /**
5
+ * @internal
6
+ * Hook for managing VerifyEmail screen state and auth context integration.
7
+ * This hook is not exposed to package consumers.
8
+ */
9
+ const useVerifyEmail = ({ sessionToken }) => {
10
+ const [sessionTokenState, setSessionToken] = useState(sessionToken || '');
11
+ const [resendOTPCounter, setResendOTPCounter] = useState(0);
12
+ const [status, setStatus] = useState('');
13
+ useEffect(() => {
14
+ resendOTP();
15
+ }, []);
16
+ const resendOTP = useCallback(() => {
17
+ if (!sessionTokenState) {
18
+ console.error('useVerifyEmail: sessionToken is required to resend OTP');
19
+ return;
20
+ }
21
+ setResendOTPCounter(prevCounter => prevCounter + 1);
22
+ setStatus('loading');
23
+ axiosClient({
24
+ url: '/auth/registration/email/send-otp',
25
+ method: 'POST',
26
+ data: { sessionToken: sessionTokenState },
27
+ }).then((res) => {
28
+ setSessionToken(res.data.sessionToken);
29
+ }).catch((err) => {
30
+ console.log(err);
31
+ showMessage(err?.response?.data?.errors?.[0]?.message);
32
+ }).finally(() => setStatus(''));
33
+ }, [sessionTokenState]);
34
+ const validateOTP = useCallback(({ otp, onVerifiedOTP }) => {
35
+ if (!sessionTokenState) {
36
+ console.error('useVerifyEmail: sessionToken is required to resend OTP');
37
+ return;
38
+ }
39
+ setStatus('loading');
40
+ axiosClient({
41
+ url: '/auth/registration/email/verify-otp',
42
+ method: 'POST',
43
+ data: { otp, sessionToken: sessionTokenState },
44
+ }).then((res) => {
45
+ setStatus('valid');
46
+ onVerifiedOTP({ sessionToken: res?.data?.sessionToken });
47
+ setStatus('');
48
+ }).catch((err) => {
49
+ console.log(err);
50
+ if (err?.response?.status === 400) {
51
+ setStatus('invalid');
52
+ setTimeout(() => {
53
+ setStatus('');
54
+ }, 5000);
55
+ showMessage(err?.response?.data?.errors?.[0]?.message);
56
+ return;
57
+ }
58
+ setStatus('');
59
+ showMessage(err?.response?.data?.errors?.[0]?.message);
60
+ });
61
+ }, [sessionTokenState]);
62
+ return {
63
+ resendOTP,
64
+ validateOTP,
65
+ status,
66
+ resendOTPCounter,
67
+ };
68
+ };
69
+ export { useVerifyEmail };
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useVerifyEmail } from "./hooks/internal/useVerifyEmail";
3
+ import { EmailOTPVerify } from "../../components/EmailOTPVerify";
4
+ const VerifyEmail = ({ email, sessionToken, onVerifiedOTP }) => {
5
+ const { status, resendOTPCounter, validateOTP, resendOTP, } = useVerifyEmail({ sessionToken });
6
+ return (_jsx(EmailOTPVerify, { email: email, status: status, resendOTPCounter: resendOTPCounter, validateOTP: (otp) => validateOTP?.({ otp, onVerifiedOTP }), resendOTP: resendOTP }));
7
+ };
8
+ export default VerifyEmail;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { EmailOTPVerify } from "../../components/EmailOTPVerify";
3
+ import { useVerifyEmail } from "./hooks/internal/useVerifyEmail";
4
+ const VerifyEmail = ({ navigation, route }) => {
5
+ const { phone, sessionToken, email } = route.params || {};
6
+ const { status, resendOTPCounter, validateOTP, resendOTP, } = useVerifyEmail({ sessionToken });
7
+ return (_jsx(EmailOTPVerify, { email: email, status: status, resendOTPCounter: resendOTPCounter, validateOTP: (otp) => validateOTP?.({
8
+ otp,
9
+ onVerifiedOTP: ({ sessionToken }) => {
10
+ navigation.navigate('VerifyMobile', { phone, sessionToken });
11
+ }
12
+ }), resendOTP: resendOTP }));
13
+ };
14
+ export default VerifyEmail;
@@ -0,0 +1 @@
1
+ export {};