ordering-ui-react-native 0.15.47 → 0.15.49-release

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 (192) hide show
  1. package/package.json +6 -3
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/AddressForm/index.tsx +18 -2
  4. package/src/components/BusinessController/index.tsx +16 -8
  5. package/src/components/BusinessTypeFilter/index.tsx +3 -1
  6. package/src/components/BusinessesListing/index.tsx +1 -1
  7. package/src/components/Checkout/index.tsx +23 -2
  8. package/src/components/DriverTips/index.tsx +11 -6
  9. package/src/components/LanguageSelector/index.tsx +7 -2
  10. package/src/components/LoginForm/index.tsx +120 -30
  11. package/src/components/LoginForm/styles.tsx +6 -0
  12. package/src/components/OrderDetails/index.tsx +9 -23
  13. package/src/components/PaymentOptions/index.tsx +1 -1
  14. package/src/components/PaymentOptionsWebView/index.tsx +123 -124
  15. package/src/components/SignupForm/index.tsx +145 -61
  16. package/src/components/SingleProductCard/index.tsx +16 -4
  17. package/src/components/StripeMethodForm/index.tsx +1 -2
  18. package/src/components/UpsellingProducts/index.tsx +1 -1
  19. package/src/components/UserProfileForm/index.tsx +63 -6
  20. package/src/components/UserProfileForm/styles.tsx +8 -0
  21. package/src/components/VerifyPhone/styles.tsx +1 -2
  22. package/src/components/shared/OModal.tsx +1 -1
  23. package/src/hooks/useCountdownTimer.tsx +26 -0
  24. package/src/navigators/CheckoutNavigator.tsx +6 -0
  25. package/src/navigators/HomeNavigator.tsx +12 -0
  26. package/src/pages/BusinessesListing.tsx +1 -1
  27. package/src/pages/MultiCheckout.tsx +31 -0
  28. package/src/pages/MultiOrdersDetails.tsx +27 -0
  29. package/src/pages/Sessions.tsx +22 -0
  30. package/src/theme.json +0 -1
  31. package/src/types/index.tsx +18 -11
  32. package/src/utils/index.tsx +68 -1
  33. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +103 -15
  34. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -0
  35. package/themes/business/src/components/Chat/index.tsx +42 -90
  36. package/themes/business/src/components/DriverMap/index.tsx +6 -5
  37. package/themes/business/src/components/Home/index.tsx +128 -55
  38. package/themes/business/src/components/Home/styles.tsx +8 -1
  39. package/themes/business/src/components/LoginForm/index.tsx +89 -2
  40. package/themes/business/src/components/LoginForm/styles.tsx +6 -0
  41. package/themes/business/src/components/LogoutButton/index.tsx +1 -1
  42. package/themes/business/src/components/NewOrderNotification/index.tsx +79 -105
  43. package/themes/business/src/components/OrderDetails/Business.tsx +1 -1
  44. package/themes/business/src/components/OrderDetails/Delivery.tsx +35 -18
  45. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +159 -91
  46. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +6 -0
  47. package/themes/business/src/components/OrderDetails/styles.tsx +7 -0
  48. package/themes/business/src/components/OrdersListManager/index.tsx +1 -1
  49. package/themes/business/src/components/OrdersOption/index.tsx +5 -2
  50. package/themes/business/src/components/PreviousOrders/index.tsx +7 -5
  51. package/themes/business/src/components/ProductItemAccordion/index.tsx +2 -2
  52. package/themes/business/src/components/shared/OModal.tsx +1 -1
  53. package/themes/business/src/types/index.tsx +5 -1
  54. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  55. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  56. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  57. package/themes/kiosk/src/components/BusinessMenu/index.tsx +39 -28
  58. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -3
  59. package/themes/kiosk/src/components/Cart/index.tsx +99 -26
  60. package/themes/kiosk/src/components/Cart/styles.tsx +6 -0
  61. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +9 -2
  62. package/themes/kiosk/src/components/CartContent/index.tsx +0 -11
  63. package/themes/kiosk/src/components/CartItem/index.tsx +4 -3
  64. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +107 -62
  65. package/themes/kiosk/src/components/Checkout/index.tsx +40 -22
  66. package/themes/kiosk/src/components/CustomerName/index.tsx +0 -6
  67. package/themes/kiosk/src/components/DrawerView/index.tsx +1 -0
  68. package/themes/kiosk/src/components/DrawerView/styles.tsx +2 -2
  69. package/themes/kiosk/src/components/NavBar/index.tsx +29 -20
  70. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  71. package/themes/kiosk/src/components/OrderDetails/index.tsx +165 -65
  72. package/themes/kiosk/src/components/OrderDetails/styles.tsx +5 -0
  73. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +9 -11
  74. package/themes/kiosk/src/components/PaymentOptions/index.tsx +56 -54
  75. package/themes/kiosk/src/components/ProductForm/index.tsx +7 -8
  76. package/themes/kiosk/src/components/ProductItemAccordion/index.tsx +2 -2
  77. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -1
  78. package/themes/kiosk/src/components/ProductOptionSubOption/index.tsx +3 -1
  79. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +16 -5
  80. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  81. package/themes/kiosk/src/types/index.d.ts +3 -0
  82. package/themes/original/index.tsx +169 -4
  83. package/themes/original/src/components/ActiveOrders/index.tsx +15 -132
  84. package/themes/original/src/components/ActiveOrders/styles.tsx +0 -54
  85. package/themes/original/src/components/AddressForm/index.tsx +1 -1
  86. package/themes/original/src/components/AddressList/index.tsx +30 -18
  87. package/themes/original/src/components/AppleLogin/index.tsx +117 -78
  88. package/themes/original/src/components/BusinessBasicInformation/index.tsx +136 -45
  89. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +4 -0
  90. package/themes/original/src/components/BusinessController/index.tsx +48 -11
  91. package/themes/original/src/components/BusinessController/styles.tsx +27 -0
  92. package/themes/original/src/components/BusinessFeaturedController/index.tsx +20 -1
  93. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +23 -0
  94. package/themes/original/src/components/BusinessItemAccordion/index.tsx +8 -5
  95. package/themes/original/src/components/BusinessItemAccordion/styles.tsx +3 -1
  96. package/themes/original/src/components/BusinessListingSearch/index.tsx +196 -58
  97. package/themes/original/src/components/BusinessListingSearch/styles.tsx +22 -2
  98. package/themes/original/src/components/BusinessPreorder/index.tsx +1 -1
  99. package/themes/original/src/components/BusinessProductsCategories/index.tsx +2 -2
  100. package/themes/original/src/components/BusinessProductsList/CategoryDescription/index.tsx +44 -0
  101. package/themes/original/src/components/BusinessProductsList/index.tsx +119 -35
  102. package/themes/original/src/components/BusinessProductsList/styles.tsx +12 -4
  103. package/themes/original/src/components/BusinessProductsListing/index.tsx +109 -21
  104. package/themes/original/src/components/BusinessProductsListing/styles.tsx +22 -0
  105. package/themes/original/src/components/BusinessReviews/index.tsx +4 -25
  106. package/themes/original/src/components/BusinessTypeFilter/index.tsx +1 -2
  107. package/themes/original/src/components/BusinessesListing/index.tsx +127 -66
  108. package/themes/original/src/components/BusinessesListing/styles.tsx +11 -3
  109. package/themes/original/src/components/Cart/index.tsx +60 -41
  110. package/themes/original/src/components/Checkout/index.tsx +48 -32
  111. package/themes/original/src/components/DriverTips/index.tsx +17 -12
  112. package/themes/original/src/components/Favorite/index.tsx +92 -0
  113. package/themes/original/src/components/Favorite/styles.tsx +22 -0
  114. package/themes/original/src/components/FavoriteList/index.tsx +298 -0
  115. package/themes/original/src/components/FavoriteList/styles.tsx +5 -0
  116. package/themes/original/src/components/ForgotPasswordForm/index.tsx +84 -4
  117. package/themes/original/src/components/GPSButton/index.tsx +15 -8
  118. package/themes/original/src/components/GoogleMap/index.tsx +1 -0
  119. package/themes/original/src/components/Help/index.tsx +21 -4
  120. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +18 -1
  121. package/themes/original/src/components/Home/index.tsx +1 -1
  122. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  123. package/themes/original/src/components/LoginForm/Otp/index.tsx +91 -0
  124. package/themes/original/src/components/LoginForm/Otp/styles.tsx +7 -0
  125. package/themes/original/src/components/LoginForm/index.tsx +394 -155
  126. package/themes/original/src/components/LoginForm/styles.tsx +7 -4
  127. package/themes/original/src/components/LogoutButton/index.tsx +7 -1
  128. package/themes/original/src/components/MessageListing/index.tsx +10 -1
  129. package/themes/original/src/components/Messages/index.tsx +1 -1
  130. package/themes/original/src/components/MomentOption/index.tsx +10 -1
  131. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  132. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +243 -0
  133. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/styles.tsx +46 -0
  134. package/themes/original/src/components/MultiCheckout/index.tsx +298 -0
  135. package/themes/original/src/components/MultiCheckout/styles.tsx +59 -0
  136. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +372 -0
  137. package/themes/original/src/components/MultiOrdersDetails/index.tsx +258 -0
  138. package/themes/original/src/components/MultiOrdersDetails/styles.tsx +50 -0
  139. package/themes/original/src/components/MyOrders/index.tsx +120 -32
  140. package/themes/original/src/components/MyOrders/styles.tsx +8 -1
  141. package/themes/original/src/components/OrderDetails/index.tsx +64 -42
  142. package/themes/original/src/components/OrderDetails/styles.tsx +1 -2
  143. package/themes/original/src/components/OrderProgress/index.tsx +1 -1
  144. package/themes/original/src/components/OrderProgress/styles.tsx +1 -0
  145. package/themes/original/src/components/OrderSummary/index.tsx +3 -3
  146. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -2
  147. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +153 -0
  148. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/styles.tsx +6 -0
  149. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/index.tsx +53 -0
  150. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/styles.tsx +6 -0
  151. package/themes/original/src/components/OrdersOption/index.tsx +133 -41
  152. package/themes/original/src/components/OrdersOption/styles.tsx +4 -7
  153. package/themes/original/src/components/PaymentOptionCash/index.tsx +2 -2
  154. package/themes/original/src/components/PaymentOptionWallet/index.tsx +17 -23
  155. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -1
  156. package/themes/original/src/components/PaymentOptions/index.tsx +16 -14
  157. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  158. package/themes/original/src/components/PreviousOrders/index.tsx +18 -147
  159. package/themes/original/src/components/ProductForm/index.tsx +70 -62
  160. package/themes/original/src/components/ProductForm/styles.tsx +0 -1
  161. package/themes/original/src/components/ProductItemAccordion/index.tsx +2 -2
  162. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -12
  163. package/themes/original/src/components/Promotions/index.tsx +250 -0
  164. package/themes/original/src/components/Promotions/styles.tsx +60 -0
  165. package/themes/original/src/components/SearchBar/index.tsx +10 -4
  166. package/themes/original/src/components/Sessions/index.tsx +160 -0
  167. package/themes/original/src/components/Sessions/styles.tsx +15 -0
  168. package/themes/original/src/components/SignupForm/index.tsx +333 -128
  169. package/themes/original/src/components/SingleOrderCard/index.tsx +282 -0
  170. package/themes/original/src/components/SingleOrderCard/styles.tsx +54 -0
  171. package/themes/original/src/components/SingleProductCard/index.tsx +59 -17
  172. package/themes/original/src/components/StripeElementsForm/index.tsx +16 -8
  173. package/themes/original/src/components/StripeElementsForm/naked.tsx +2 -2
  174. package/themes/original/src/components/UpsellingProducts/index.tsx +86 -74
  175. package/themes/original/src/components/UserDetails/index.tsx +5 -96
  176. package/themes/original/src/components/UserFormDetails/index.tsx +34 -24
  177. package/themes/original/src/components/UserProfile/index.tsx +59 -5
  178. package/themes/original/src/components/UserProfileForm/index.tsx +20 -18
  179. package/themes/original/src/components/UserVerification/index.tsx +178 -192
  180. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  181. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  182. package/themes/original/src/components/Wallets/index.tsx +76 -9
  183. package/themes/original/src/components/Wallets/styles.tsx +21 -0
  184. package/themes/original/src/components/shared/HeaderTitle.tsx +2 -1
  185. package/themes/original/src/components/shared/OModal.tsx +4 -2
  186. package/themes/original/src/config/constants.tsx +6 -6
  187. package/themes/original/src/types/index.tsx +144 -9
  188. package/themes/original/src/utils/index.tsx +19 -2
  189. package/themes/single-business/src/components/AddressList/index.tsx +1 -1
  190. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +1 -1
  191. package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
  192. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -4,6 +4,7 @@ import Spinner from 'react-native-loading-spinner-overlay';
4
4
  import { useForm, Controller } from 'react-hook-form';
5
5
  import { PhoneInputNumber } from '../PhoneInputNumber';
6
6
  import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
7
+ import Recaptcha from 'react-native-recaptcha-that-works'
7
8
 
8
9
  import {
9
10
  LoginForm as LoginFormController,
@@ -17,8 +18,6 @@ import { useTheme } from 'styled-components/native';
17
18
  import { FacebookLogin } from '../FacebookLogin';
18
19
  import { VerifyPhone } from '../../../../../src/components/VerifyPhone';
19
20
  import { OModal } from '../../../../../src/components/shared';
20
-
21
-
22
21
  import {
23
22
  Container,
24
23
  ButtonsWrapper,
@@ -32,16 +31,19 @@ import {
32
31
  LineSeparator,
33
32
  SkeletonWrapper,
34
33
  TabBtn,
34
+ RecaptchaButton
35
35
  } from './styles';
36
36
 
37
37
  import NavBar from '../NavBar';
38
38
 
39
- import { OText, OButton, OInput, OIcon } from '../shared';
39
+ import { OText, OButton, OInput } from '../shared';
40
40
  import { LoginParams } from '../../types';
41
41
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
42
42
  import { GoogleLogin } from '../GoogleLogin';
43
43
  import { AppleLogin } from '../AppleLogin';
44
+ import { Otp } from './Otp'
44
45
  import { TouchableOpacity } from 'react-native-gesture-handler';
46
+ import Alert from '../../../../../src/providers/AlertProvider'
45
47
 
46
48
  const LoginFormUI = (props: LoginParams) => {
47
49
  const {
@@ -50,6 +52,7 @@ const LoginFormUI = (props: LoginParams) => {
50
52
  navigation,
51
53
  useLoginByEmail,
52
54
  useLoginByCellphone,
55
+ useLoginOtp,
53
56
  loginButtonText,
54
57
  forgotButtonText,
55
58
  verifyPhoneState,
@@ -60,7 +63,14 @@ const LoginFormUI = (props: LoginParams) => {
60
63
  handleSendVerifyCode,
61
64
  handleCheckPhoneCode,
62
65
  onNavigationRedirect,
63
- notificationState
66
+ notificationState,
67
+ handleReCaptcha,
68
+ enableReCaptcha,
69
+ otpType,
70
+ setOtpType,
71
+ generateOtpCode,
72
+ useLoginOtpEmail,
73
+ useLoginOtpCellphone,
64
74
  } = props;
65
75
 
66
76
  const [, { showToast }] = useToast();
@@ -72,6 +82,7 @@ const LoginFormUI = (props: LoginParams) => {
72
82
  const [isLoadingVerifyModal, setIsLoadingVerifyModal] = useState(false);
73
83
  const [isModalVisible, setIsModalVisible] = useState(false);
74
84
  const [isFBLoading, setIsFBLoading] = useState(false);
85
+ const [willVerifyOtpState, setWillVerifyOtpState] = useState(false)
75
86
  const [phoneInputData, setPhoneInputData] = useState({
76
87
  error: '',
77
88
  phone: {
@@ -79,8 +90,19 @@ const LoginFormUI = (props: LoginParams) => {
79
90
  cellphone: null,
80
91
  },
81
92
  });
93
+ const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
94
+ const [recaptchaVerified, setRecaptchaVerified] = useState(false)
95
+ const [alertState, setAlertState] = useState({ open: false, title: '', content: [] })
96
+ const [tabLayouts, setTabLayouts] = useState<any>({})
97
+ const tabsRef = useRef<any>(null)
82
98
 
83
99
  const theme = useTheme();
100
+ const isOtpEmail = loginTab === 'otp' && otpType === 'email'
101
+ const isOtpCellphone = loginTab === 'otp' && otpType === 'cellphone'
102
+
103
+ const googleLoginEnabled = configs?.google_login_enabled?.value === '1' || !configs?.google_login_enabled?.enabled
104
+ const facebookLoginEnabled = configs?.facebook_login_enabled?.value === '1' || !configs?.facebook_login_enabled?.enabled
105
+ const appleLoginEnabled = configs?.apple_login_enabled?.value === '1' || !configs?.apple_login_enabled?.enabled
84
106
 
85
107
  const loginStyle = StyleSheet.create({
86
108
  btnOutline: {
@@ -100,28 +122,69 @@ const LoginFormUI = (props: LoginParams) => {
100
122
  flexGrow: 1,
101
123
  marginBottom: 7,
102
124
  },
125
+ recaptchaIcon: {
126
+ width: 100,
127
+ height: 100,
128
+ },
129
+ borderStyleBase: {
130
+ width: 30,
131
+ height: 45
132
+ },
133
+
134
+ borderStyleHighLighted: {
135
+ borderColor: "#03DAC6",
136
+ },
137
+
138
+ underlineStyleBase: {
139
+ width: 45,
140
+ height: 60,
141
+ borderWidth: 1,
142
+ fontSize: 16
143
+ },
144
+
145
+ underlineStyleHighLighted: {
146
+ borderColor: theme.colors.primary,
147
+ color: theme.colors.primary,
148
+ fontSize: 16
149
+ },
103
150
  });
104
151
 
105
152
  const emailRef = useRef<any>({});
106
153
  const passwordRef = useRef<any>({});
154
+ const recaptchaRef = useRef<any>({});
107
155
 
108
- const handleChangeTab = (val: string) => {
156
+ const handleChangeTab = (val: string, otpType?: string) => {
109
157
  props.handleChangeTab(val);
110
158
  setPasswordSee(false);
159
+ handleCategoryScroll(otpType ? `${val}_${otpType}` : val)
111
160
  };
112
161
 
113
- const onSubmit = (values: any) => {
162
+ const onSubmit = (values?: any) => {
114
163
  Keyboard.dismiss();
115
- if (phoneInputData.error) {
116
- showToast(ToastType.Error, phoneInputData.error);
117
- return;
164
+ if (loginTab === 'otp') {
165
+ if (phoneInputData.error && (loginTab !== 'otp' || (otpType === 'cellphone' && loginTab === 'otp'))) {
166
+ showToast(ToastType.Error, t('INVALID_PHONE_NUMBER', 'Invalid phone number'));
167
+ return
168
+ }
169
+ if (loginTab === 'otp') {
170
+ generateOtpCode({
171
+ ...values,
172
+ ...phoneInputData.phone
173
+ })
174
+ }
175
+ setWillVerifyOtpState(true)
176
+ } else {
177
+ if (phoneInputData.error) {
178
+ showToast(ToastType.Error, phoneInputData.error);
179
+ return;
180
+ }
181
+ handleButtonLoginClick({
182
+ ...values,
183
+ ...phoneInputData.phone,
184
+ });
118
185
  }
119
- handleButtonLoginClick({
120
- ...values,
121
- ...phoneInputData.phone,
122
- });
123
- };
124
186
 
187
+ };
125
188
  const handleVerifyCodeClick = () => {
126
189
  if (phoneInputData.error) {
127
190
  showToast(ToastType.Error, phoneInputData.error);
@@ -156,6 +219,66 @@ const LoginFormUI = (props: LoginParams) => {
156
219
  onChange(value.toLowerCase().replace(/[&,()%";:ç?<>{}\\[\]\s]/g, ''));
157
220
  };
158
221
 
222
+ const handleOpenRecaptcha = () => {
223
+ setRecaptchaVerified(false)
224
+ if (!recaptchaConfig?.siteKey) {
225
+ showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
226
+ return
227
+ }
228
+ if (!recaptchaConfig?.baseUrl) {
229
+ showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
230
+ return
231
+ }
232
+
233
+ recaptchaRef.current.open()
234
+ }
235
+
236
+ const onRecaptchaVerify = (token: any) => {
237
+ setRecaptchaVerified(true)
238
+ handleReCaptcha(token)
239
+ }
240
+
241
+ const handleChangeOtpType = (type: string) => {
242
+ handleChangeTab('otp', type)
243
+ setOtpType(type)
244
+ }
245
+
246
+ const handleLoginOtp = (code: string) => {
247
+ handleButtonLoginClick({ code })
248
+ setWillVerifyOtpState(false)
249
+ }
250
+
251
+ const closeAlert = () => {
252
+ setAlertState({
253
+ open: false,
254
+ title: '',
255
+ content: []
256
+ })
257
+ }
258
+
259
+ const handleCategoryScroll = (opc: string) => {
260
+ tabsRef.current.scrollTo({
261
+ x: tabLayouts?.[opc]?.x - 40,
262
+ animated: true
263
+ })
264
+ }
265
+
266
+ const handleOnLayout = (event: any, opc: string) => {
267
+ const _tabLayouts = { ...tabLayouts }
268
+ const categoryKey = opc
269
+ _tabLayouts[categoryKey] = event.nativeEvent.layout
270
+ setTabLayouts(_tabLayouts)
271
+ }
272
+
273
+ useEffect(() => {
274
+ if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
275
+ setRecaptchaConfig({
276
+ siteKey: configs?.security_recaptcha_site_key?.value || null,
277
+ baseUrl: configs?.security_recaptcha_base_url?.value || null
278
+ })
279
+ }
280
+ }, [configs, enableReCaptcha])
281
+
159
282
  useEffect(() => {
160
283
  if (!formState.loading && formState.result?.error) {
161
284
  formState.result?.result &&
@@ -194,16 +317,26 @@ const LoginFormUI = (props: LoginParams) => {
194
317
  }, [phoneInputData?.phone?.cellphone])
195
318
 
196
319
  useEffect(() => {
197
- register('cellphone', {
198
- required: loginTab === 'cellphone'
199
- ? t('VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Mobile phone is required').replace('_attribute_', t('CELLPHONE', 'Cellphone'))
200
- : null
201
- })
202
- }, [register])
320
+ register('cellphone', {
321
+ required: loginTab === 'cellphone'
322
+ ? t('VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Mobile phone is required').replace('_attribute_', t('CELLPHONE', 'Cellphone'))
323
+ : null
324
+ })
325
+ }, [register])
326
+
327
+ useEffect(() => {
328
+ reset()
329
+ }, [loginTab])
203
330
 
204
331
  useEffect(() => {
205
- reset()
206
- }, [loginTab])
332
+ if (checkPhoneCodeState?.result?.error) {
333
+ setAlertState({
334
+ open: true,
335
+ content: t(checkPhoneCodeState?.result?.error, checkPhoneCodeState?.result?.error),
336
+ title: ''
337
+ })
338
+ }
339
+ }, [checkPhoneCodeState])
207
340
 
208
341
  return (
209
342
  <Container>
@@ -218,11 +351,18 @@ const LoginFormUI = (props: LoginParams) => {
218
351
  titleStyle={{ marginRight: 0, marginLeft: 0 }}
219
352
  />
220
353
  <FormSide>
221
- {useLoginByEmail && useLoginByCellphone && (
354
+ {(Number(useLoginByEmail) + Number(useLoginByCellphone) + Number(useLoginOtpEmail) + Number(useLoginOtpCellphone) > 1) && (
222
355
  <LoginWith>
223
- <OTabs>
356
+ <OTabs
357
+ horizontal
358
+ showsHorizontalScrollIndicator={false}
359
+ ref={tabsRef}
360
+ >
224
361
  {useLoginByEmail && (
225
- <TabBtn onPress={() => handleChangeTab('email')}>
362
+ <TabBtn
363
+ onPress={() => handleChangeTab('email')}
364
+ onLayout={(event: any) => handleOnLayout(event, 'email')}
365
+ >
226
366
  <OTab
227
367
  style={{
228
368
  borderBottomColor:
@@ -244,7 +384,10 @@ const LoginFormUI = (props: LoginParams) => {
244
384
  </TabBtn>
245
385
  )}
246
386
  {useLoginByCellphone && (
247
- <TabBtn onPress={() => handleChangeTab('cellphone')}>
387
+ <TabBtn
388
+ onPress={() => handleChangeTab('cellphone')}
389
+ onLayout={(event: any) => handleOnLayout(event, 'cellphone')}
390
+ >
248
391
  <OTab
249
392
  style={{
250
393
  borderBottomColor:
@@ -265,13 +408,63 @@ const LoginFormUI = (props: LoginParams) => {
265
408
  </OTab>
266
409
  </TabBtn>
267
410
  )}
411
+ {useLoginOtpEmail && (
412
+ <TabBtn
413
+ onPress={() => handleChangeOtpType('email')}
414
+ onLayout={(event: any) => handleOnLayout(event, 'otp_email')}
415
+ >
416
+ <OTab
417
+ style={{
418
+ borderBottomColor:
419
+ isOtpEmail
420
+ ? theme.colors.textNormal
421
+ : theme.colors.border,
422
+ }}>
423
+ <OText
424
+ size={14}
425
+ color={
426
+ isOtpEmail
427
+ ? theme.colors.textNormal
428
+ : theme.colors.disabled
429
+ }
430
+ weight={isOtpEmail ? 'bold' : 'normal'}>
431
+ {t('BY_OTP_EMAIL', 'By Otp Email')}
432
+ </OText>
433
+ </OTab>
434
+ </TabBtn>
435
+ )}
436
+ {useLoginOtpCellphone && (
437
+ <TabBtn
438
+ onPress={() => handleChangeOtpType('cellphone')}
439
+ onLayout={(event: any) => handleOnLayout(event, 'otp_cellphone')}
440
+ >
441
+ <OTab
442
+ style={{
443
+ borderBottomColor:
444
+ isOtpCellphone
445
+ ? theme.colors.textNormal
446
+ : theme.colors.border,
447
+ }}>
448
+ <OText
449
+ size={14}
450
+ color={
451
+ isOtpCellphone
452
+ ? theme.colors.textNormal
453
+ : theme.colors.disabled
454
+ }
455
+ weight={isOtpCellphone ? 'bold' : 'normal'}>
456
+ {t('BY_OTP_PHONE', 'By Otp Phone')}
457
+ </OText>
458
+ </OTab>
459
+ </TabBtn>
460
+ )}
268
461
  </OTabs>
269
462
  </LoginWith>
270
463
  )}
271
464
 
272
- {(useLoginByCellphone || useLoginByEmail) && (
465
+ {(useLoginByCellphone || useLoginByEmail || useLoginOtp) && (
273
466
  <FormInput>
274
- {useLoginByEmail && loginTab === 'email' && (
467
+ {((useLoginByEmail && loginTab === 'email') || (loginTab === 'otp' && otpType === 'email')) && (
275
468
  <>
276
469
  {errors?.email && (
277
470
  <OText
@@ -307,10 +500,10 @@ const LoginFormUI = (props: LoginParams) => {
307
500
  rules={{
308
501
  required: {
309
502
  value: true,
310
- message: t(
311
- 'VALIDATION_ERROR_EMAIL_REQUIRED',
312
- 'The field Email is required',
313
- ).replace('_attribute_', t('EMAIL', 'Email'))
503
+ message: t(
504
+ 'VALIDATION_ERROR_EMAIL_REQUIRED',
505
+ 'The field Email is required',
506
+ ).replace('_attribute_', t('EMAIL', 'Email'))
314
507
  },
315
508
  pattern: {
316
509
  value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
@@ -325,7 +518,7 @@ const LoginFormUI = (props: LoginParams) => {
325
518
  </>
326
519
 
327
520
  )}
328
- {useLoginByCellphone && loginTab === 'cellphone' && (
521
+ {((useLoginByCellphone && loginTab === 'cellphone') || (loginTab === 'otp' && otpType === 'cellphone')) && (
329
522
  <View style={{ marginBottom: 28 }}>
330
523
  <PhoneInputNumber
331
524
  data={phoneInputData}
@@ -346,62 +539,97 @@ const LoginFormUI = (props: LoginParams) => {
346
539
  {errors?.password?.message}{errors?.password?.type === 'required' && '*'}
347
540
  </OText>
348
541
  )}
349
- <Controller
350
- control={control}
351
- render={({ onChange, value }: any) => (
352
- <OInput
353
- isSecured={!passwordSee ? true : false}
354
- placeholder={t('PASSWORD', 'Password')}
355
- style={{...loginStyle.inputStyle, marginBottom: 14}}
356
- icon={theme.images.general.lock}
357
- iconCustomRight={
358
- !passwordSee ? (
359
- <MaterialCommunityIcons
360
- name="eye-outline"
361
- size={24}
362
- onPress={() => setPasswordSee(!passwordSee)}
363
- color={theme.colors.disabled}
364
- />
365
- ) : (
366
- <MaterialCommunityIcons
367
- name="eye-off-outline"
368
- size={24}
369
- onPress={() => setPasswordSee(!passwordSee)}
370
- color={theme.colors.disabled}
371
- />
372
- )
542
+ {loginTab !== 'otp' && (
543
+
544
+ <Controller
545
+ control={control}
546
+ render={({ onChange, value }: any) => (
547
+ <OInput
548
+ isSecured={!passwordSee ? true : false}
549
+ placeholder={t('PASSWORD', 'Password')}
550
+ style={{ ...loginStyle.inputStyle, marginBottom: 14 }}
551
+ icon={theme.images.general.lock}
552
+ iconCustomRight={
553
+ !passwordSee ? (
554
+ <MaterialCommunityIcons
555
+ name="eye-outline"
556
+ size={24}
557
+ onPress={() => setPasswordSee(!passwordSee)}
558
+ color={theme.colors.disabled}
559
+ />
560
+ ) : (
561
+ <MaterialCommunityIcons
562
+ name="eye-off-outline"
563
+ size={24}
564
+ onPress={() => setPasswordSee(!passwordSee)}
565
+ color={theme.colors.disabled}
566
+ />
567
+ )
568
+ }
569
+ value={value}
570
+ forwardRef={passwordRef}
571
+ onChange={(val: any) => onChange(val)}
572
+ returnKeyType="done"
573
+ onSubmitEditing={handleSubmit(onSubmit)}
574
+ blurOnSubmit
575
+ borderColor={errors?.password ? theme.colors.danger5 : theme.colors.border}
576
+ />
577
+ )}
578
+ name="password"
579
+ rules={{
580
+ required: {
581
+ value: true,
582
+ message: t(
583
+ 'VALIDATION_ERROR_PASSWORD_REQUIRED',
584
+ 'The field Password is required',
585
+ ).replace('_attribute_', t('PASSWORD', 'Password'))
373
586
  }
374
- value={value}
375
- forwardRef={passwordRef}
376
- onChange={(val: any) => onChange(val)}
377
- returnKeyType="done"
378
- onSubmitEditing={handleSubmit(onSubmit)}
379
- blurOnSubmit
380
- borderColor={errors?.password ? theme.colors.danger5 : theme.colors.border}
381
- />
382
- )}
383
- name="password"
384
- rules={{
385
- required: {
386
- value: true,
387
- message: t(
388
- 'VALIDATION_ERROR_PASSWORD_REQUIRED',
389
- 'The field Password is required',
390
- ).replace('_attribute_', t('PASSWORD', 'Password'))
391
- }
392
- }}
393
- defaultValue=""
394
- />
395
- {onNavigationRedirect && forgotButtonText && (
587
+ }}
588
+ defaultValue=""
589
+ />
590
+ )}
591
+ {onNavigationRedirect && forgotButtonText && loginTab !== 'otp' && (
396
592
  <TouchableOpacity onPress={() => onNavigationRedirect('Forgot')}>
397
593
  <OText size={14} mBottom={18}>
398
594
  {forgotButtonText}
399
595
  </OText>
400
596
  </TouchableOpacity>
401
597
  )}
598
+
599
+ {enableReCaptcha && (
600
+ <>
601
+ <TouchableOpacity
602
+ onPress={handleOpenRecaptcha}
603
+ >
604
+ <RecaptchaButton>
605
+ {recaptchaVerified ? (
606
+ <MaterialCommunityIcons
607
+ name="checkbox-marked"
608
+ size={26}
609
+ color={theme.colors.primary}
610
+ />
611
+ ) : (
612
+ <MaterialCommunityIcons
613
+ name="checkbox-blank-outline"
614
+ size={26}
615
+ color={theme.colors.mediumGray}
616
+ />
617
+ )}
618
+ <OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
619
+ </RecaptchaButton>
620
+ </TouchableOpacity>
621
+ <Recaptcha
622
+ ref={recaptchaRef}
623
+ siteKey={recaptchaConfig?.siteKey}
624
+ baseUrl={recaptchaConfig?.baseUrl}
625
+ onVerify={onRecaptchaVerify}
626
+ onExpire={() => setRecaptchaVerified(false)}
627
+ />
628
+ </>
629
+ )}
402
630
  <OButton
403
631
  onClick={handleSubmit(onSubmit)}
404
- text={loginButtonText}
632
+ text={loginTab !== 'otp' ? loginButtonText : t('GET_VERIFY_CODE', 'Get verify code')}
405
633
  bgColor={theme.colors.primary}
406
634
  borderColor={theme.colors.primary}
407
635
  textStyle={{ color: 'white' }}
@@ -410,11 +638,11 @@ const LoginFormUI = (props: LoginParams) => {
410
638
  style={{ borderRadius: 7.6, marginTop: 10, marginBottom: 25 }}
411
639
  />
412
640
  {onNavigationRedirect && registerButtonText && (
413
- <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center'}}>
641
+ <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center' }}>
414
642
  <OText size={14}>
415
643
  {t('NEW_ON_PLATFORM', 'New on Ordering?')}
416
644
  </OText>
417
- <TouchableOpacity onPress={() => onNavigationRedirect('Signup')}>
645
+ <TouchableOpacity onPress={() => onNavigationRedirect('Signup')}>
418
646
  <OText size={14} mLeft={5} color={theme.colors.skyBlue}>
419
647
  {t('CREATE_ACCOUNT', 'Create account')}
420
648
  </OText>
@@ -425,11 +653,11 @@ const LoginFormUI = (props: LoginParams) => {
425
653
  )}
426
654
 
427
655
  {useLoginByCellphone &&
428
- loginTab === 'cellphone' &&
429
- configs && Object.keys(configs).length > 0 &&
430
- (configs?.twilio_service_enabled?.value === 'true' ||
431
- configs?.twilio_service_enabled?.value === '1') &&
432
- configs?.twilio_module?.value && (
656
+ loginTab === 'cellphone' &&
657
+ configs && Object.keys(configs).length > 0 &&
658
+ (configs?.twilio_service_enabled?.value === 'true' ||
659
+ configs?.twilio_service_enabled?.value === '1') &&
660
+ configs?.twilio_module?.value && (
433
661
  <>
434
662
  <OrSeparator>
435
663
  <LineSeparator />
@@ -454,59 +682,60 @@ const LoginFormUI = (props: LoginParams) => {
454
682
  )}
455
683
 
456
684
  {configs && Object.keys(configs).length > 0 ? (
457
- (((configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') && configs?.facebook_id?.value) ||
458
- (configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null)) &&
459
- (
460
- <>
461
- <View
462
- style={{
463
- flexDirection: 'row',
464
- width: '100%',
465
- justifyContent: 'space-between',
466
- alignItems: 'center',
467
- marginVertical: 15
468
- }}>
469
- <View style={loginStyle.line} />
470
- <OText
471
- size={14}
472
- mBottom={10}
473
- style={{ paddingHorizontal: 19 }}
474
- color={theme.colors.disabled}>
475
- {t('OR', 'or')}
476
- </OText>
477
- <View style={loginStyle.line} />
478
- </View>
479
- <ButtonsWrapper>
480
- <SocialButtons>
481
- {(configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') &&
482
- configs?.facebook_id?.value && (
483
- <FacebookLogin
484
- notificationState={notificationState}
485
- handleErrors={(err: any) => showToast(ToastType.Error, err)}
486
- handleLoading={(val: boolean) => setIsFBLoading(val)}
487
- handleSuccessFacebookLogin={handleSuccessFacebook}
488
- />
489
- )}
490
- {(configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && (
491
- <GoogleLogin
492
- notificationState={notificationState}
493
- webClientId={configs?.google_login_client_id?.value}
494
- handleErrors={(err: any) => showToast(ToastType.Error, err)}
495
- handleLoading={(val: boolean) => setIsFBLoading(val)}
496
- handleSuccessGoogleLogin={handleSuccessFacebook}
497
- />
498
- )}
499
- {(configs?.apple_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && (
500
- <AppleLogin
501
- notificationState={notificationState}
502
- handleErrors={(err: any) => showToast(ToastType.Error, err)}
503
- handleLoading={(val: boolean) => setIsFBLoading(val)}
504
- handleSuccessAppleLogin={handleSuccessFacebook}
505
- />
506
- )}
507
- </SocialButtons>
508
- </ButtonsWrapper>
509
- </>
685
+ (((configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') && configs?.facebook_id?.value) ||
686
+ (configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null)) &&
687
+ (
688
+ <>
689
+ <View
690
+ style={{
691
+ flexDirection: 'row',
692
+ width: '100%',
693
+ justifyContent: 'space-between',
694
+ alignItems: 'center',
695
+ marginVertical: 15
696
+ }}>
697
+ <View style={loginStyle.line} />
698
+ <OText
699
+ size={14}
700
+ mBottom={10}
701
+ style={{ paddingHorizontal: 19 }}
702
+ color={theme.colors.disabled}>
703
+ {t('OR', 'or')}
704
+ </OText>
705
+ <View style={loginStyle.line} />
706
+ </View>
707
+ <ButtonsWrapper>
708
+ <SocialButtons>
709
+ {(configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') &&
710
+ configs?.facebook_id?.value &&
711
+ facebookLoginEnabled && (
712
+ <FacebookLogin
713
+ notificationState={notificationState}
714
+ handleErrors={(err: any) => showToast(ToastType.Error, err)}
715
+ handleLoading={(val: boolean) => setIsFBLoading(val)}
716
+ handleSuccessFacebookLogin={handleSuccessFacebook}
717
+ />
718
+ )}
719
+ {(configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && googleLoginEnabled && (
720
+ <GoogleLogin
721
+ notificationState={notificationState}
722
+ webClientId={configs?.google_login_client_id?.value}
723
+ handleErrors={(err: any) => showToast(ToastType.Error, err)}
724
+ handleLoading={(val: boolean) => setIsFBLoading(val)}
725
+ handleSuccessGoogleLogin={handleSuccessFacebook}
726
+ />
727
+ )}
728
+ {(configs?.apple_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && appleLoginEnabled && (
729
+ <AppleLogin
730
+ notificationState={notificationState}
731
+ handleErrors={(err: any) => showToast(ToastType.Error, err)}
732
+ handleLoading={(val: boolean) => setIsFBLoading(val)}
733
+ handleSuccessAppleLogin={handleSuccessFacebook}
734
+ />
735
+ )}
736
+ </SocialButtons>
737
+ </ButtonsWrapper>
738
+ </>
510
739
  )
511
740
  ) : (
512
741
  <SkeletonWrapper>
@@ -522,24 +751,12 @@ const LoginFormUI = (props: LoginParams) => {
522
751
  </Placeholder>
523
752
  </SkeletonWrapper>
524
753
  )}
525
-
526
- {/* {onNavigationRedirect && registerButtonText && (
527
- <ButtonsWrapper>
528
- <OButton
529
- onClick={() => onNavigationRedirect('Signup')}
530
- text={registerButtonText}
531
- style={loginStyle.btnOutline}
532
- borderColor={theme.colors.primary}
533
- imgRightSrc={null}
534
- />
535
- </ButtonsWrapper>
536
- )} */}
537
754
  </FormSide>
538
755
  <OModal
539
756
  open={isModalVisible}
540
757
  onClose={() => setIsModalVisible(false)}
541
- entireModal
542
- title={t('VERIFY_PHONE', 'Verify Phone')}
758
+ entireModal
759
+ title={t('VERIFY_PHONE', 'Verify Phone')}
543
760
  >
544
761
  <VerifyPhone
545
762
  phone={phoneInputData.phone}
@@ -548,9 +765,30 @@ const LoginFormUI = (props: LoginParams) => {
548
765
  handleCheckPhoneCode={handleCheckPhoneCode}
549
766
  setCheckPhoneCodeState={setCheckPhoneCodeState}
550
767
  handleVerifyCodeClick={handleVerifyCodeClick}
551
- onClose={() => setIsModalVisible(false)}
768
+ onClose={() => setIsModalVisible(false)}
552
769
  />
553
770
  </OModal>
771
+ <OModal
772
+ open={willVerifyOtpState}
773
+ onClose={() => setWillVerifyOtpState(false)}
774
+ entireModal
775
+ title={t('ENTER_VERIFICATION_CODE', 'Enter verification code')}
776
+ >
777
+ <Otp
778
+ willVerifyOtpState={willVerifyOtpState}
779
+ setWillVerifyOtpState={setWillVerifyOtpState}
780
+ handleLoginOtp={handleLoginOtp}
781
+ onSubmit={onSubmit}
782
+ setAlertState={setAlertState}
783
+ />
784
+ </OModal>
785
+ <Alert
786
+ open={alertState.open}
787
+ content={alertState.content}
788
+ title={alertState.title || ''}
789
+ onAccept={closeAlert}
790
+ onClose={closeAlert}
791
+ />
554
792
  <Spinner visible={isFBLoading} />
555
793
  </Container>
556
794
  );
@@ -559,6 +797,7 @@ const LoginFormUI = (props: LoginParams) => {
559
797
  export const LoginForm = (props: any) => {
560
798
  const loginProps = {
561
799
  ...props,
800
+ isRecaptchaEnable: true,
562
801
  UIComponent: LoginFormUI,
563
802
  };
564
803
  return <LoginFormController {...loginProps} />;