ordering-ui-react-native 0.18.37 → 0.18.39

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 (25) hide show
  1. package/package.json +1 -1
  2. package/src/components/StripeMethodForm/index.tsx +1 -1
  3. package/themes/original/src/components/AddressForm/index.tsx +7 -4
  4. package/themes/original/src/components/AddressList/index.tsx +1 -1
  5. package/themes/original/src/components/BusinessController/index.tsx +3 -3
  6. package/themes/original/src/components/BusinessListingSearch/index.tsx +330 -276
  7. package/themes/original/src/components/BusinessProductsList/index.tsx +3 -3
  8. package/themes/original/src/components/BusinessProductsListing/index.tsx +35 -8
  9. package/themes/original/src/components/Checkout/index.tsx +6 -5
  10. package/themes/original/src/components/GoogleMap/index.tsx +11 -2
  11. package/themes/original/src/components/LoginForm/index.tsx +15 -14
  12. package/themes/original/src/components/MyOrders/index.tsx +14 -1
  13. package/themes/original/src/components/NavBar/index.tsx +9 -4
  14. package/themes/original/src/components/OrdersOption/index.tsx +3 -1
  15. package/themes/original/src/components/ProductForm/index.tsx +3 -4
  16. package/themes/original/src/components/ProductOptionSubOption/index.tsx +7 -5
  17. package/themes/original/src/components/ProductOptionSubOption/styles.tsx +2 -2
  18. package/themes/original/src/components/SignupForm/index.tsx +14 -14
  19. package/themes/original/src/components/StripeElementsForm/index.tsx +17 -16
  20. package/themes/original/src/components/UserFormDetails/index.tsx +34 -5
  21. package/themes/original/src/components/UserProfile/index.tsx +2 -20
  22. package/themes/original/src/components/UserProfileForm/index.tsx +2 -1
  23. package/themes/original/src/components/Wallets/index.tsx +1 -1
  24. package/themes/original/src/types/index.tsx +2 -2
  25. package/themes/original/src/utils/index.tsx +11 -0
@@ -106,7 +106,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
106
106
  <SingleProductCard
107
107
  key={'prod_' + product.id + `_${i}`}
108
108
  isSoldOut={product.inventoried && !product.quantity}
109
- enableIntersection={!isFiltMode && categoryState.products?.length < 80}
109
+ enableIntersection={!isFiltMode}
110
110
  product={product}
111
111
  businessId={businessId}
112
112
  categoryState={categoryState}
@@ -135,7 +135,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
135
135
  key={'feat_' + product.id + `_${i}`}
136
136
  isSoldOut={product.inventoried && !product.quantity}
137
137
  product={product}
138
- enableIntersection={!isFiltMode && categoryState.products?.length < 80}
138
+ enableIntersection={!isFiltMode}
139
139
  businessId={businessId}
140
140
  categoryState={categoryState}
141
141
  onProductClick={onProductClick}
@@ -237,7 +237,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
237
237
  {products.sort((a: any, b: any) => a.rank - b.rank).map((product: any, i: any) => (
238
238
  <SingleProductCard
239
239
  key={`${product?.id}_${i}`}
240
- enableIntersection={!isFiltMode && categoryState.products?.length < 80}
240
+ enableIntersection={!isFiltMode}
241
241
  isSoldOut={product.inventoried && !product.quantity}
242
242
  businessId={businessId}
243
243
  product={product}
@@ -1,5 +1,5 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react'
2
- import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView, Vibration, BackHandler } from 'react-native'
2
+ import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView, Keyboard, KeyboardEvent, BackHandler } from 'react-native'
3
3
  import { IOScrollView } from 'react-native-intersection-observer'
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
5
5
  import { useTheme } from 'styled-components/native';
@@ -25,6 +25,7 @@ import { BusinessProductsListingParams } from '../../types'
25
25
  import { _retrieveStoreData, _removeStoreData } from '../../providers/StoreUtil';
26
26
  import IconAntDesign from 'react-native-vector-icons/AntDesign';
27
27
  import { useIsFocused } from '@react-navigation/native';
28
+ import AntDesignIcon from 'react-native-vector-icons/AntDesign'
28
29
 
29
30
  import {
30
31
  TopHeader,
@@ -43,6 +44,7 @@ import { ProfessionalFilter } from '../ProfessionalFilter';
43
44
  import { ServiceForm } from '../ServiceForm';
44
45
  import { BusinessesListing } from '../BusinessesListing/Layout/Original'
45
46
  import { PageBanner } from '../PageBanner'
47
+ import { vibrateApp } from '../../utils';
46
48
 
47
49
  const PIXELS_TO_SCROLL = 2000
48
50
 
@@ -135,20 +137,22 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
135
137
  const [openService, setOpenService] = useState(false)
136
138
  const [currentProduct, setCurrentProduct] = useState(null)
137
139
  const [searchBarHeight, setSearchBarHeight] = useState(60)
140
+ const [keyboardHeight, setKeyboardHeight] = useState(0);
138
141
  const [viewedCategory, setViewedCategory] = useState<any>(null)
139
142
 
140
143
  const isCheckoutMultiBusinessEnabled: Boolean = configs?.checkout_multi_business_enabled?.value === '1'
141
144
  const isQuickAddProduct = configs?.add_product_with_one_click?.value === '1'
142
145
  const openCarts = (Object.values(orderState?.carts)?.filter((cart: any) => cart?.products && cart?.products?.length && cart?.status !== 2 && cart?.valid_schedule && cart?.valid_products && cart?.valid_address && cart?.valid_maximum && cart?.valid_minimum && !cart?.wallets) || null) || []
143
-
144
146
  const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
145
147
  const isOpenFiltProducts = isOpenSearchBar && !!searchValue
146
148
  const filtProductsHeight = Platform.OS === 'ios' ? 165 : 100
149
+ const viewOrderButtonVisible = !loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0
150
+
147
151
  const onRedirect = (route: string, params?: any) => {
148
152
  navigation.navigate(route, params)
149
153
  }
150
154
  const onProductClick = async (product: any) => {
151
- if (product.extras.length === 0 && !product.inventoried && auth && isQuickAddProduct) {
155
+ if (product.ingredients?.length === 0 && product.extras.length === 0 && !product.inventoried && auth && isQuickAddProduct) {
152
156
  const isProductAddedToCart = currentCart?.products?.find((Cproduct: any) => Cproduct.id === product.id)
153
157
  const productQuantity = isProductAddedToCart?.quantity
154
158
  const addCurrentProduct = {
@@ -156,11 +160,12 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
156
160
  quantity: 1
157
161
  }
158
162
  const updateCurrentProduct = {
163
+ name: product?.name,
159
164
  id: product.id,
160
165
  code: isProductAddedToCart?.code,
161
166
  quantity: productQuantity + 1
162
167
  }
163
- Vibration.vibrate()
168
+ vibrateApp()
164
169
  const cartData = currentCart?.business_id ? currentCart : { business_id: business.id }
165
170
  if (isProductAddedToCart) {
166
171
  await updateProduct(updateCurrentProduct, cartData, isQuickAddProduct)
@@ -307,6 +312,24 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
307
312
  }
308
313
  }, [isFocused])
309
314
 
315
+
316
+ useEffect(() => {
317
+ function onKeyboardDidShow(e: KeyboardEvent) {
318
+ setKeyboardHeight(e?.endCoordinates?.height);
319
+ }
320
+
321
+ function onKeyboardDidHide() {
322
+ setKeyboardHeight(0);
323
+ }
324
+
325
+ const showSubscription = Keyboard.addListener('keyboardDidShow', onKeyboardDidShow);
326
+ const hideSubscription = Keyboard.addListener('keyboardDidHide', onKeyboardDidHide);
327
+ return () => {
328
+ showSubscription.remove();
329
+ hideSubscription.remove();
330
+ };
331
+ }, []);
332
+
310
333
  const subtotalWithTaxes = currentCart?.taxes?.reduce((acc: any, item: any) => {
311
334
  if (item?.type === 1)
312
335
  return acc = acc + item?.summary?.tax
@@ -369,7 +392,10 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
369
392
  <>
370
393
  {!(businessSingleId && auth) && (
371
394
  <TopActions onPress={() => handleBackNavigation()}>
372
- <OIcon src={theme.images.general.arrow_left} color={theme.colors.textNormal} />
395
+ <AntDesignIcon
396
+ name='arrowleft'
397
+ size={26}
398
+ />
373
399
  </TopActions>
374
400
  )}
375
401
  {!errorQuantityProducts && (
@@ -427,8 +453,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
427
453
  {business?.categories?.length > 0 && isOpenFiltProducts && (
428
454
  <FiltProductsContainer
429
455
  style={{
430
- height: Dimensions.get('window').height - filtProductsHeight,
431
- top: Platform.OS === 'ios' ? (searchBarHeight - 10) + insets.top : searchBarHeight
456
+ height: Dimensions.get('window').height - filtProductsHeight - keyboardHeight - (keyboardHeight > 0 && viewOrderButtonVisible ? 55 : 0),
457
+ top: Platform.OS === 'ios' ? (searchBarHeight - 10) + insets.top : searchBarHeight,
432
458
  }}
433
459
  contentContainerStyle={{ flexGrow: 1 }}
434
460
  >
@@ -593,7 +619,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
593
619
  </>
594
620
  )}
595
621
  </IOScrollView>
596
- {!loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0 && (
622
+ {viewOrderButtonVisible && (
597
623
  <View style={{ marginBottom: 0 }}>
598
624
  <FloatingButton
599
625
  btnText={
@@ -649,6 +675,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
649
675
  professionalList={business?.professionals}
650
676
  professionalSelected={professionalSelected}
651
677
  handleChangeProfessional={handleChangeProfessionalSelected}
678
+ handleChangeProfessional={handleChangeProfessionalSelected}
652
679
  handleUpdateProfessionals={handleUpdateProfessionals}
653
680
  onSave={() => setOpenService(false)}
654
681
  onClose={() => setOpenService(false)}
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- import { View, StyleSheet, TouchableOpacity, Platform, I18nManager, Vibration, ScrollView } from 'react-native';
2
+ import { View, StyleSheet, TouchableOpacity, Platform, I18nManager, ScrollView } from 'react-native';
3
3
  import { initStripe, useConfirmPayment } from '@stripe/stripe-react-native';
4
4
  import Picker from 'react-native-country-picker-modal';
5
5
  import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
@@ -52,7 +52,7 @@ import { FloatingButton } from '../FloatingButton';
52
52
  import { Container } from '../../layouts/Container';
53
53
  import NavBar from '../NavBar';
54
54
  import { OrderSummary } from '../OrderSummary';
55
- import { getTypesText } from '../../utils';
55
+ import { getTypesText, vibrateApp } from '../../utils';
56
56
  import { CartStoresListing } from '../CartStoresListing';
57
57
  import { PaymentOptionsWebView } from '../../../../../src/components/PaymentOptionsWebView';
58
58
 
@@ -222,7 +222,7 @@ const CheckoutUI = (props: any) => {
222
222
 
223
223
  const handlePlaceOrder = (confirmPayment: any, forcePlace: boolean = false) => {
224
224
  if (!userErrors.length && (!requiredFields?.length || allowedGuest) || forcePlace) {
225
- Vibration.vibrate()
225
+ vibrateApp()
226
226
  handlerClickPlaceOrder && handlerClickPlaceOrder(null, null, confirmPayment)
227
227
  return
228
228
  }
@@ -351,6 +351,7 @@ const CheckoutUI = (props: any) => {
351
351
  btnStyle={{ paddingLeft: 0, paddingTop: Platform.OS == 'ios' ? 0 : 2 }}
352
352
  titleWrapStyle={{ paddingHorizontal: 0 }}
353
353
  titleStyle={{ marginRight: 0, marginLeft: 0 }}
354
+ style={{ marginTop: 20 }}
354
355
  />
355
356
  </View>
356
357
  <ChContainer style={styles.pagePadding}>
@@ -755,7 +756,7 @@ const CheckoutUI = (props: any) => {
755
756
 
756
757
  {!cartState.loading && cart && (
757
758
  <View>
758
- <ChErrors style={{ marginBottom: 30 }}>
759
+ <ChErrors style={{ marginBottom: Platform.OS === 'ios' ? 35 : 10 }}>
759
760
  {!cart?.valid_address && cart?.status !== 2 && (
760
761
  <OText
761
762
  color={theme.colors.error}
@@ -882,7 +883,7 @@ const CheckoutUI = (props: any) => {
882
883
  </Container>
883
884
  {!cartState.loading && cart && cart?.status !== 2 && (
884
885
  <FloatingButton
885
- handleClick={isDisabledButtonPlace ? () => Vibration.vibrate() : () => handlePlaceOrder(null)}
886
+ handleClick={isDisabledButtonPlace ? () => vibrateApp() : () => handlePlaceOrder(null)}
886
887
  isSecondaryBtn={isDisabledButtonPlace}
887
888
  disabled={isDisabledButtonPlace}
888
889
  btnText={subtotalWithTaxes >= cart?.minimum
@@ -43,7 +43,7 @@ export const GoogleMap = (props: GoogleMapsParams) => {
43
43
  ERROR_MAX_LIMIT_LOCATION: `Sorry, You can only set the position to ${maxLimitLocation}m`
44
44
  }
45
45
 
46
- const geocodePosition = (pos: { latitude: number, longitude: number }) => {
46
+ const geocodePosition = (pos: { latitude: number, longitude: number }, isMovingRegion ?: boolean) => {
47
47
  Geocoder.from({
48
48
  latitude: pos.latitude,
49
49
  longitude: pos.longitude
@@ -68,7 +68,9 @@ export const GoogleMap = (props: GoogleMapsParams) => {
68
68
  }
69
69
  handleChangeAddressMap && handleChangeAddressMap(address, details)
70
70
  setSaveLocation && setSaveLocation(false)
71
- handleToggleMap && handleToggleMap()
71
+ if(!isMovingRegion){
72
+ handleToggleMap && handleToggleMap()
73
+ }
72
74
  } else {
73
75
  setMapErrors && setMapErrors('ERROR_NOT_FOUND_ADDRESS')
74
76
  }
@@ -92,6 +94,9 @@ export const GoogleMap = (props: GoogleMapsParams) => {
92
94
  const _maxLimitLocation = typeof maxLimitLocation === 'string' ? parseInt(maxLimitLocation, 10) : maxLimitLocation
93
95
 
94
96
  if (distance <= _maxLimitLocation) {
97
+ if (!aproxEqual(curPos.latitude, center.lat) || !aproxEqual(curPos.longitude, center.lng)){
98
+ geocodePosition(curPos, true)
99
+ }
95
100
  setMarkerPosition(curPos)
96
101
  setRegion({ ...region, longitude: curPos.longitude, latitude: curPos.latitude })
97
102
  } else {
@@ -100,6 +105,10 @@ export const GoogleMap = (props: GoogleMapsParams) => {
100
105
  }
101
106
  }
102
107
 
108
+ const aproxEqual = (n1 : number, n2 : number, epsilon = 0.000001) => {
109
+ return Math.abs(n1 - n2) < epsilon
110
+ }
111
+
103
112
  const calculateDistance = (pointA: { lat: number, lng: number }, pointB: { latitude: number, longitude: number }) => {
104
113
 
105
114
  const lat1 = pointA.lat;
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useState, useRef } from 'react';
2
- import { StyleSheet, View, Keyboard, Vibration } from 'react-native';
2
+ import { StyleSheet, View, Keyboard } from 'react-native';
3
3
  import Spinner from 'react-native-loading-spinner-overlay';
4
4
  import { useForm, Controller } from 'react-hook-form';
5
5
  import { PhoneInputNumber } from '../PhoneInputNumber';
@@ -45,6 +45,7 @@ import { AppleLogin } from '../AppleLogin';
45
45
  import { Otp } from './Otp'
46
46
  import { TouchableOpacity } from 'react-native-gesture-handler';
47
47
  import Alert from '../../../../../src/providers/AlertProvider'
48
+ import { vibrateApp } from '../../utils';
48
49
 
49
50
  const LoginFormUI = (props: LoginParams) => {
50
51
  const {
@@ -166,7 +167,7 @@ const LoginFormUI = (props: LoginParams) => {
166
167
  if (loginTab === 'otp') {
167
168
  if (phoneInputData.error && (loginTab !== 'otp' || (otpType === 'cellphone' && loginTab === 'otp'))) {
168
169
  showToast(ToastType.Error, t('INVALID_PHONE_NUMBER', 'Invalid phone number'));
169
- Vibration.vibrate()
170
+ vibrateApp()
170
171
  return
171
172
  }
172
173
  if (loginTab === 'otp') {
@@ -179,7 +180,7 @@ const LoginFormUI = (props: LoginParams) => {
179
180
  } else {
180
181
  if (phoneInputData.error) {
181
182
  showToast(ToastType.Error, phoneInputData.error);
182
- Vibration.vibrate()
183
+ vibrateApp()
183
184
  return;
184
185
  }
185
186
  handleButtonLoginClick({
@@ -192,7 +193,7 @@ const LoginFormUI = (props: LoginParams) => {
192
193
  const handleVerifyCodeClick = () => {
193
194
  if (phoneInputData.error) {
194
195
  showToast(ToastType.Error, phoneInputData.error);
195
- Vibration.vibrate()
196
+ vibrateApp()
196
197
  return;
197
198
  }
198
199
  if (
@@ -207,7 +208,7 @@ const LoginFormUI = (props: LoginParams) => {
207
208
  'The field Mobile phone is required.',
208
209
  ),
209
210
  );
210
- Vibration.vibrate()
211
+ vibrateApp()
211
212
  return;
212
213
  }
213
214
  handleSendVerifyCode && handleSendVerifyCode(phoneInputData.phone);
@@ -229,12 +230,12 @@ const LoginFormUI = (props: LoginParams) => {
229
230
  setRecaptchaVerified(false)
230
231
  if (!recaptchaConfig?.siteKey) {
231
232
  showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
232
- Vibration.vibrate()
233
+ vibrateApp()
233
234
  return
234
235
  }
235
236
  if (!recaptchaConfig?.baseUrl) {
236
237
  showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
237
- Vibration.vibrate()
238
+ vibrateApp()
238
239
  return
239
240
  }
240
241
 
@@ -311,7 +312,7 @@ const LoginFormUI = (props: LoginParams) => {
311
312
  baseUrl: configs?.security_recaptcha_base_url?.value || null
312
313
  })
313
314
  showToast(ToastType.Info, t('TRY_AGAIN', 'Please try again'))
314
- Vibration.vibrate()
315
+ vibrateApp()
315
316
  return
316
317
  }
317
318
  formState.result?.result &&
@@ -321,7 +322,7 @@ const LoginFormUI = (props: LoginParams) => {
321
322
  ? formState.result?.result
322
323
  : formState.result?.result[0],
323
324
  );
324
- formState.result?.result && Vibration.vibrate()
325
+ formState.result?.result && vibrateApp()
325
326
  }
326
327
  }, [formState]);
327
328
 
@@ -333,7 +334,7 @@ const LoginFormUI = (props: LoginParams) => {
333
334
  ? verifyPhoneState?.result?.result
334
335
  : verifyPhoneState?.result?.result[0];
335
336
  verifyPhoneState.result?.result && showToast(ToastType.Error, message);
336
- verifyPhoneState.result?.result && Vibration.vibrate();
337
+ verifyPhoneState.result?.result && vibrateApp();
337
338
  setIsLoadingVerifyModal(false);
338
339
  return;
339
340
  }
@@ -374,7 +375,7 @@ const LoginFormUI = (props: LoginParams) => {
374
375
  }, [checkPhoneCodeState])
375
376
 
376
377
  useEffect(() => {
377
- if (!!Object.values(errors)?.length) Vibration.vibrate()
378
+ if (!!Object.values(errors)?.length) vibrateApp()
378
379
  }, [errors])
379
380
 
380
381
  return (
@@ -766,7 +767,7 @@ const LoginFormUI = (props: LoginParams) => {
766
767
  facebookLoginEnabled && (
767
768
  <FacebookLogin
768
769
  notificationState={notificationState}
769
- handleErrors={(err: any) => { showToast(ToastType.Error, err), Vibration.vibrate() }}
770
+ handleErrors={(err: any) => { showToast(ToastType.Error, err), vibrateApp() }}
770
771
  handleLoading={(val: boolean) => setIsFBLoading(val)}
771
772
  handleSuccessFacebookLogin={handleSuccessFacebook}
772
773
  />
@@ -775,7 +776,7 @@ const LoginFormUI = (props: LoginParams) => {
775
776
  <GoogleLogin
776
777
  notificationState={notificationState}
777
778
  webClientId={configs?.google_login_client_id?.value}
778
- handleErrors={(err: any) => { showToast(ToastType.Error, err), Vibration.vibrate() }}
779
+ handleErrors={(err: any) => { showToast(ToastType.Error, err), vibrateApp() }}
779
780
  handleLoading={(val: boolean) => setIsFBLoading(val)}
780
781
  handleSuccessGoogleLogin={handleSuccessFacebook}
781
782
  />
@@ -783,7 +784,7 @@ const LoginFormUI = (props: LoginParams) => {
783
784
  {(configs?.apple_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && appleLoginEnabled && (
784
785
  <AppleLogin
785
786
  notificationState={notificationState}
786
- handleErrors={(err: any) => { showToast(ToastType.Error, err), Vibration.vibrate() }}
787
+ handleErrors={(err: any) => { showToast(ToastType.Error, err), vibrateApp() }}
787
788
  handleLoading={(val: boolean) => setIsFBLoading(val)}
788
789
  handleSuccessAppleLogin={handleSuccessFacebook}
789
790
  />
@@ -25,11 +25,12 @@ export const MyOrders = (props: any) => {
25
25
  const [ordersLength, setOrdersLength] = useState({
26
26
  activeOrdersLength: null,
27
27
  previousOrdersLength: 0,
28
+ preordersLength: 0
28
29
  });
29
30
  const [selectedOption, setSelectedOption] = useState(!hideOrders ? 'orders' : 'business')
30
31
 
31
32
  const notOrderOptions = ['business', 'products']
32
- const allEmpty = (ordersLength?.activeOrdersLength === 0 && ordersLength?.previousOrdersLength === 0) || ((isEmptyBusinesses || businessOrderIds?.length === 0) && hideOrders)
33
+ const allEmpty = (ordersLength?.activeOrdersLength === 0 && ordersLength?.previousOrdersLength === 0 && ordersLength?.preordersLength === 0) || ((isEmptyBusinesses || businessOrderIds?.length === 0) && hideOrders)
33
34
 
34
35
  const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
35
36
  const showNavbar = theme?.bar_menu?.components?.orders?.hidden
@@ -147,6 +148,18 @@ export const MyOrders = (props: any) => {
147
148
  )}
148
149
  {selectedOption === 'orders' && (
149
150
  <>
151
+ {ordersLength?.preordersLength > 0 && (
152
+ <View style={{ paddingHorizontal: isChewLayout ? 20 : 40 }}>
153
+ <OrdersOption
154
+ {...props}
155
+ preOrders
156
+ ordersLength={ordersLength}
157
+ setOrdersLength={setOrdersLength}
158
+ setRefreshOrders={setRefreshOrders}
159
+ refreshOrders={refreshOrders}
160
+ />
161
+ </View>
162
+ )}
150
163
  <View style={{ paddingHorizontal: isChewLayout ? 20 : 40 }}>
151
164
  <OrdersOption
152
165
  {...props}
@@ -17,8 +17,10 @@ const TitleTopWrapper = styled.View`
17
17
  const btnBackArrow = {
18
18
  borderWidth: 0,
19
19
  backgroundColor: '#FFF',
20
- borderColor: '#FFF',
21
- shadowColor: '#FFF'
20
+ borderColor: '#fff',
21
+ shadowColor: '#FFF',
22
+ paddingLeft: 30,
23
+ paddingRight: 30
22
24
  }
23
25
 
24
26
  interface Props {
@@ -63,8 +65,11 @@ const NavBar = (props: Props) => {
63
65
  return (
64
66
  <Wrapper style={{ paddingTop: props.paddingTop, ...{ flexDirection: props.isVertical ? 'column' : 'row', alignItems: props.isVertical ? 'flex-start' : 'center' }, ...props.style }}>
65
67
  <OButton
66
- imgLeftSrc={theme.images.general.arrow_left}
67
- imgLeftStyle={{ width: 26 }}
68
+ iconProps={{
69
+ name: 'arrowleft',
70
+ size: 26
71
+ }}
72
+ icon={AntDesignIcon}
68
73
  imgRightSrc={null}
69
74
  style={{ ...btnBackArrow, ...props.btnStyle, ...props.isVertical ? (I18nManager.isRTL ? { paddingRight: 0 } : { paddingLeft: 0 }) : {} }}
70
75
  onClick={props?.onActionLeft}
@@ -99,7 +99,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
99
99
  return false
100
100
  })
101
101
  setOrders(orders)
102
- }, [_orders?.length])
102
+ }, [JSON.stringify(_orders)])
103
103
 
104
104
  const onProductClick = (product: any) => {
105
105
  if (product?.product_id && product?.category_id && product?.businessId &&
@@ -167,6 +167,8 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
167
167
  setOrdersLength && setOrdersLength({ ...ordersLength, activeOrdersLength: updateOrders?.length })
168
168
  } else if (!preOrders) {
169
169
  setOrdersLength && setOrdersLength({ ...ordersLength, previousOrdersLength: updateOrders?.length })
170
+ } else {
171
+ setOrdersLength && setOrdersLength({ ...ordersLength, preordersLength: updateOrders?.length })
170
172
  }
171
173
  }, [_orders, activeOrders, preOrders])
172
174
 
@@ -9,8 +9,7 @@ import {
9
9
  I18nManager,
10
10
  SafeAreaView,
11
11
  Platform,
12
- Button,
13
- Vibration
12
+ Button
14
13
  } from 'react-native';
15
14
  import {
16
15
  ProductForm as ProductOptions,
@@ -55,7 +54,7 @@ import { ProductOptionSubOption } from '../ProductOptionSubOption';
55
54
  import { NotFoundSource } from '../NotFoundSource';
56
55
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
57
56
  import NavBar from '../NavBar';
58
- import { orderTypeList } from '../../utils';
57
+ import { orderTypeList, vibrateApp } from '../../utils';
59
58
  const windowWidth = Dimensions.get('window').width;
60
59
 
61
60
  export const ProductOptionsUI = (props: any) => {
@@ -225,7 +224,7 @@ export const ProductOptionsUI = (props: any) => {
225
224
  };
226
225
 
227
226
  const handleSaveProduct = () => {
228
- Vibration.vibrate()
227
+ vibrateApp()
229
228
  if (!productCart.quantity) {
230
229
  showToast(ToastType.Error, t('VALIDATION_ERROR_REQUIRED', 'The quantity field is required').replace('_attribute_', t('PRODUCT_POTIONS_QUANTITY', 'Quantity')))
231
230
  return
@@ -41,8 +41,7 @@ export const ProductOptionSubOptionUI = (props: any) => {
41
41
  const [showMessage, setShowMessage] = useState(false)
42
42
  const [isDirty, setIsDirty] = useState(false)
43
43
 
44
- const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
45
- const iconsSize = isChewLayout ? 20 : 16
44
+ const iconsSize = 20
46
45
 
47
46
  const handleSuboptionClick = () => {
48
47
  toggleSelect()
@@ -117,7 +116,8 @@ export const ProductOptionSubOptionUI = (props: any) => {
117
116
  <OIcon
118
117
  src={theme.images.general.half_l}
119
118
  color={state.selected && state.position === 'left' ? theme.colors.primary : '#cbcbcb'}
120
- width={16}
119
+ width={20}
120
+ height={20}
121
121
  style={styles.inverse}
122
122
  />
123
123
  </Circle>
@@ -125,14 +125,16 @@ export const ProductOptionSubOptionUI = (props: any) => {
125
125
  <OIcon
126
126
  src={theme.images.general.half_f}
127
127
  color={state.selected && state.position === 'whole' ? theme.colors.primary : '#cbcbcb'}
128
- width={16}
128
+ width={20}
129
+ height={20}
129
130
  />
130
131
  </Circle>
131
132
  <Circle disabled={disabled} onPress={() => changePosition('right')}>
132
133
  <OIcon
133
134
  src={theme.images.general.half_r}
134
135
  color={state.selected && state.position === 'right' ? theme.colors.primary : '#cbcbcb'}
135
- width={16}
136
+ width={20}
137
+ height={20}
136
138
  />
137
139
  </Circle>
138
140
  </>
@@ -10,7 +10,7 @@ export const Container = styled.TouchableOpacity`
10
10
  export const IconControl = styled.TouchableOpacity`
11
11
  flex-direction: row;
12
12
  padding: 10px;
13
- width: 45%;
13
+ width: 38%;
14
14
  align-items: center;
15
15
  `
16
16
 
@@ -18,7 +18,7 @@ export const QuantityControl = styled.View`
18
18
  flex-direction: row;
19
19
  align-items: center;
20
20
  justify-content: flex-start;
21
- margin-horizontal: 5px;
21
+ margin-right: 5px;
22
22
  flex: 1;
23
23
  width: 60px;
24
24
  `
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
- import { View, Pressable, StyleSheet, Linking, Platform, TouchableOpacity, Vibration } from 'react-native';
2
+ import { View, Pressable, StyleSheet, Linking, Platform, TouchableOpacity } from 'react-native';
3
3
  import { useForm, Controller } from 'react-hook-form';
4
4
  import Spinner from 'react-native-loading-spinner-overlay';
5
5
  import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
@@ -37,7 +37,7 @@ import Alert from '../../../../../src/providers/AlertProvider'
37
37
  import { OText, OButton, OInput } from '../shared';
38
38
  import { OModal } from '../../../../../src/components/shared';
39
39
  import { SignupParams } from '../../types';
40
- import { sortInputFields } from '../../utils';
40
+ import { sortInputFields, vibrateApp } from '../../utils';
41
41
  import { GoogleLogin } from '../GoogleLogin';
42
42
  import { AppleLogin } from '../AppleLogin';
43
43
 
@@ -246,7 +246,7 @@ const SignupFormUI = (props: SignupParams) => {
246
246
  const onSubmit = (values?: any) => {
247
247
  if (phoneInputData.error && signUpTab !== 'otpEmail') {
248
248
  showToast(ToastType.Error, phoneInputData.error);
249
- Vibration.vibrate()
249
+ vibrateApp()
250
250
  return;
251
251
  }
252
252
  if (
@@ -264,7 +264,7 @@ const SignupFormUI = (props: SignupParams) => {
264
264
  'The field Mobile phone is required.',
265
265
  ),
266
266
  );
267
- Vibration.vibrate()
267
+ vibrateApp()
268
268
  return;
269
269
  }
270
270
  if (signUpTab === 'otpEmail' || signUpTab === 'otpCellphone') {
@@ -333,7 +333,7 @@ const SignupFormUI = (props: SignupParams) => {
333
333
  await Linking.openURL(url);
334
334
  } else {
335
335
  showToast(ToastType.Error, t('VALIDATION_ERROR_ACTIVE_URL', 'The _attribute_ is not a valid URL.').replace('_attribute_', t('URL', 'URL')))
336
- Vibration.vibrate()
336
+ vibrateApp()
337
337
  }
338
338
  }
339
339
 
@@ -341,12 +341,12 @@ const SignupFormUI = (props: SignupParams) => {
341
341
  setRecaptchaVerified(false)
342
342
  if (!recaptchaConfig?.siteKey) {
343
343
  showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
344
- Vibration.vibrate()
344
+ vibrateApp()
345
345
  return
346
346
  }
347
347
  if (!recaptchaConfig?.baseUrl) {
348
348
  showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
349
- Vibration.vibrate()
349
+ vibrateApp()
350
350
  return
351
351
  }
352
352
  recaptchaRef.current.open()
@@ -390,11 +390,11 @@ const SignupFormUI = (props: SignupParams) => {
390
390
  baseUrl: configs?.security_recaptcha_base_url?.value || null
391
391
  })
392
392
  showToast(ToastType.Info, t('TRY_AGAIN', 'Please try again'))
393
- Vibration.vibrate()
393
+ vibrateApp()
394
394
  return
395
395
  }
396
396
  formState.result?.result && showToast(ToastType.Error, formState.result?.result[0]);
397
- formState.result?.result && Vibration.vibrate()
397
+ formState.result?.result && vibrateApp()
398
398
  setIsLoadingVerifyModal(false);
399
399
  }
400
400
  }, [formState]);
@@ -402,7 +402,7 @@ const SignupFormUI = (props: SignupParams) => {
402
402
  useEffect(() => {
403
403
  if (Object.keys(errors).length > 0) {
404
404
  setIsLoadingVerifyModal(false);
405
- Vibration.vibrate()
405
+ vibrateApp()
406
406
  }
407
407
  }, [errors])
408
408
 
@@ -431,7 +431,7 @@ const SignupFormUI = (props: SignupParams) => {
431
431
  ? verifyPhoneState?.result?.result
432
432
  : verifyPhoneState?.result?.result[0];
433
433
  verifyPhoneState.result?.result && showToast(ToastType.Error, message);
434
- verifyPhoneState.result?.result && Vibration.vibrate()
434
+ verifyPhoneState.result?.result && vibrateApp()
435
435
  setIsLoadingVerifyModal(false);
436
436
  return;
437
437
  }
@@ -930,7 +930,7 @@ const SignupFormUI = (props: SignupParams) => {
930
930
  (
931
931
  <FacebookLogin
932
932
  notificationState={notificationState}
933
- handleErrors={(err: any) => { showToast(ToastType.Error, err), Vibration.vibrate() }}
933
+ handleErrors={(err: any) => { showToast(ToastType.Error, err), vibrateApp() }}
934
934
  handleLoading={(val: boolean) => setIsFBLoading(val)}
935
935
  handleSuccessFacebookLogin={handleSuccessFacebook}
936
936
  />
@@ -939,7 +939,7 @@ const SignupFormUI = (props: SignupParams) => {
939
939
  <GoogleLogin
940
940
  notificationState={notificationState}
941
941
  webClientId={configs?.google_login_client_id?.value}
942
- handleErrors={(err: any) => { showToast(ToastType.Error, err), Vibration.vibrate() }}
942
+ handleErrors={(err: any) => { showToast(ToastType.Error, err), vibrateApp() }}
943
943
  handleLoading={(val: boolean) => setIsFBLoading(val)}
944
944
  handleSuccessGoogleLogin={handleSuccessFacebook}
945
945
  />
@@ -947,7 +947,7 @@ const SignupFormUI = (props: SignupParams) => {
947
947
  {(configs?.apple_login_client_id?.value !== '' && configs?.apple_login_client_id?.value !== null) && appleLoginEnabled && (
948
948
  <AppleLogin
949
949
  notificationState={notificationState}
950
- handleErrors={(err: any) => { showToast(ToastType.Error, err), Vibration.vibrate() }}
950
+ handleErrors={(err: any) => { showToast(ToastType.Error, err), vibrateApp() }}
951
951
  handleLoading={(val: boolean) => setIsFBLoading(val)}
952
952
  handleSuccessAppleLogin={handleSuccessFacebook}
953
953
  />