ordering-ui-react-native 0.17.21 → 0.17.22-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 (211) hide show
  1. package/package.json +8 -7
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/BusinessesListing/index.tsx +1 -1
  4. package/src/components/OrderCreating/index.tsx +1 -21
  5. package/src/components/PaymentOptionsWebView/index.tsx +119 -120
  6. package/src/components/StripeMethodForm/index.tsx +108 -79
  7. package/src/components/VerifyPhone/styles.tsx +1 -2
  8. package/src/components/shared/OToast.tsx +4 -4
  9. package/src/types/index.tsx +5 -0
  10. package/src/utils/index.tsx +7 -1
  11. package/themes/business/index.tsx +2 -0
  12. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +265 -240
  13. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -4
  14. package/themes/business/src/components/BusinessController/index.tsx +0 -1
  15. package/themes/business/src/components/Chat/index.tsx +118 -107
  16. package/themes/business/src/components/DriverMap/index.tsx +17 -6
  17. package/themes/business/src/components/GoogleMap/index.tsx +58 -57
  18. package/themes/business/src/components/LoginForm/Otp/index.tsx +120 -0
  19. package/themes/business/src/components/LoginForm/Otp/styles.tsx +7 -0
  20. package/themes/business/src/components/LoginForm/index.tsx +238 -80
  21. package/themes/business/src/components/LoginForm/styles.tsx +10 -0
  22. package/themes/business/src/components/MapView/index.tsx +10 -10
  23. package/themes/business/src/components/NewOrderNotification/index.tsx +43 -50
  24. package/themes/business/src/components/OrderDetails/Delivery.tsx +4 -3
  25. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +90 -47
  26. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +59 -62
  27. package/themes/business/src/components/OrderDetailsLogistic/index.tsx +195 -0
  28. package/themes/business/src/components/OrderDetailsLogistic/styles.tsx +5 -0
  29. package/themes/business/src/components/OrderMessage/index.tsx +18 -17
  30. package/themes/business/src/components/OrderSummary/index.tsx +113 -121
  31. package/themes/business/src/components/OrdersOption/index.tsx +32 -75
  32. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +250 -0
  33. package/themes/business/src/components/PreviousOrders/OrdersGroupedItem.tsx +115 -0
  34. package/themes/business/src/components/PreviousOrders/index.tsx +445 -243
  35. package/themes/business/src/components/PreviousOrders/styles.tsx +31 -3
  36. package/themes/business/src/components/ProductItemAccordion/index.tsx +27 -3
  37. package/themes/business/src/components/ReviewCustomer/index.tsx +41 -24
  38. package/themes/business/src/components/StoresList/index.tsx +2 -2
  39. package/themes/business/src/components/shared/OLink.tsx +33 -13
  40. package/themes/business/src/components/shared/OModal.tsx +16 -9
  41. package/themes/business/src/components/shared/OText.tsx +8 -2
  42. package/themes/business/src/types/index.tsx +32 -2
  43. package/themes/business/src/utils/index.tsx +44 -1
  44. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  45. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  46. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  47. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -1
  48. package/themes/kiosk/src/components/Checkout/index.tsx +6 -0
  49. package/themes/kiosk/src/components/LoginForm/Otp/index.tsx +92 -0
  50. package/themes/kiosk/src/components/LoginForm/Otp/styles.tsx +7 -0
  51. package/themes/kiosk/src/components/LoginForm/index.tsx +473 -151
  52. package/themes/kiosk/src/components/LoginForm/styles.tsx +14 -1
  53. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  54. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  55. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  56. package/themes/kiosk/src/components/PhoneInputNumber/index.tsx +3 -2
  57. package/themes/kiosk/src/components/PhoneInputNumber/styles.tsx +1 -3
  58. package/themes/kiosk/src/components/ProductForm/index.tsx +1 -14
  59. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  60. package/themes/kiosk/src/components/shared/OModal.tsx +14 -11
  61. package/themes/kiosk/src/layouts/Container.tsx +7 -1
  62. package/themes/kiosk/src/types/index.d.ts +13 -0
  63. package/themes/kiosk/src/utils/index.tsx +15 -0
  64. package/themes/original/index.tsx +6 -0
  65. package/themes/original/src/components/AddressDetails/index.tsx +29 -11
  66. package/themes/original/src/components/AddressForm/index.tsx +50 -19
  67. package/themes/original/src/components/AddressList/index.tsx +26 -21
  68. package/themes/original/src/components/AddressList/styles.tsx +4 -2
  69. package/themes/original/src/components/AnalyticsSegment/index.tsx +193 -10
  70. package/themes/original/src/components/AppleLogin/index.tsx +4 -4
  71. package/themes/original/src/components/BusinessBasicInformation/index.tsx +166 -89
  72. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +9 -7
  73. package/themes/original/src/components/BusinessController/index.tsx +145 -68
  74. package/themes/original/src/components/BusinessController/styles.tsx +22 -9
  75. package/themes/original/src/components/BusinessFeaturedController/index.tsx +21 -54
  76. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +8 -0
  77. package/themes/original/src/components/BusinessInformation/index.tsx +10 -31
  78. package/themes/original/src/components/BusinessItemAccordion/index.tsx +23 -22
  79. package/themes/original/src/components/BusinessListingSearch/index.tsx +350 -323
  80. package/themes/original/src/components/BusinessPreorder/index.tsx +97 -16
  81. package/themes/original/src/components/BusinessProductsList/index.tsx +20 -11
  82. package/themes/original/src/components/BusinessProductsList/styles.tsx +8 -3
  83. package/themes/original/src/components/BusinessProductsListing/index.tsx +616 -495
  84. package/themes/original/src/components/BusinessProductsListing/styles.tsx +7 -9
  85. package/themes/original/src/components/BusinessReviews/index.tsx +3 -1
  86. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +1 -1
  87. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +105 -78
  88. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -9
  89. package/themes/original/src/components/BusinessesListing/index.tsx +5 -3
  90. package/themes/original/src/components/Cart/index.tsx +102 -69
  91. package/themes/original/src/components/CartContent/index.tsx +110 -19
  92. package/themes/original/src/components/CartContent/styles.tsx +15 -1
  93. package/themes/original/src/components/Checkout/index.tsx +323 -178
  94. package/themes/original/src/components/Checkout/styles.tsx +4 -2
  95. package/themes/original/src/components/CitiesControl/index.tsx +89 -0
  96. package/themes/original/src/components/CitiesControl/styles.tsx +17 -0
  97. package/themes/original/src/components/CouponControl/index.tsx +10 -3
  98. package/themes/original/src/components/DriverTips/index.tsx +52 -34
  99. package/themes/original/src/components/Favorite/index.tsx +7 -4
  100. package/themes/original/src/components/Favorite/styles.tsx +1 -1
  101. package/themes/original/src/components/FavoriteList/index.tsx +51 -80
  102. package/themes/original/src/components/FloatingButton/index.tsx +1 -2
  103. package/themes/original/src/components/FloatingButton/styles.tsx +1 -1
  104. package/themes/original/src/components/GPSButton/index.tsx +6 -4
  105. package/themes/original/src/components/GPSButton/styles.ts +3 -3
  106. package/themes/original/src/components/GiftCard/GiftCardUI/index.tsx +96 -0
  107. package/themes/original/src/components/GiftCard/GiftCardUI/styles.tsx +5 -0
  108. package/themes/original/src/components/GiftCard/PurchaseGiftCard/index.tsx +100 -0
  109. package/themes/original/src/components/GiftCard/PurchaseGiftCard/styles.tsx +8 -0
  110. package/themes/original/src/components/GiftCard/RedeemGiftCard/index.tsx +178 -0
  111. package/themes/original/src/components/GiftCard/RedeemGiftCard/styles.tsx +8 -0
  112. package/themes/original/src/components/GiftCard/SendGiftCard/index.tsx +165 -0
  113. package/themes/original/src/components/GiftCard/SendGiftCard/styles.tsx +9 -0
  114. package/themes/original/src/components/GoogleMap/index.tsx +4 -2
  115. package/themes/original/src/components/Help/index.tsx +8 -8
  116. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +11 -22
  117. package/themes/original/src/components/HelpAccountAndPayment/styles.tsx +6 -0
  118. package/themes/original/src/components/HelpGuide/index.tsx +12 -16
  119. package/themes/original/src/components/HelpGuide/styles.tsx +6 -0
  120. package/themes/original/src/components/HelpOrder/index.tsx +12 -25
  121. package/themes/original/src/components/HelpOrder/styles.tsx +8 -1
  122. package/themes/original/src/components/Home/index.tsx +13 -4
  123. package/themes/original/src/components/LanguageSelector/index.tsx +19 -14
  124. package/themes/original/src/components/LastOrder/index.tsx +1 -34
  125. package/themes/original/src/components/LoginForm/Otp/index.tsx +89 -73
  126. package/themes/original/src/components/LoginForm/Otp/styles.tsx +0 -1
  127. package/themes/original/src/components/LoginForm/index.tsx +59 -22
  128. package/themes/original/src/components/LottieAnimation/index.tsx +78 -0
  129. package/themes/original/src/components/MessageListing/index.tsx +16 -42
  130. package/themes/original/src/components/Messages/index.tsx +32 -10
  131. package/themes/original/src/components/MomentOption/index.tsx +195 -88
  132. package/themes/original/src/components/MultiCart/index.tsx +50 -0
  133. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +197 -116
  134. package/themes/original/src/components/MultiCheckout/index.tsx +267 -85
  135. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +37 -224
  136. package/themes/original/src/components/MultiOrdersDetails/index.tsx +67 -20
  137. package/themes/original/src/components/MultiOrdersDetails/styles.tsx +1 -1
  138. package/themes/original/src/components/MyOrders/index.tsx +55 -51
  139. package/themes/original/src/components/NavBar/index.tsx +6 -11
  140. package/themes/original/src/components/Notifications/index.tsx +46 -50
  141. package/themes/original/src/components/Notifications/styles.tsx +6 -3
  142. package/themes/original/src/components/OrderDetails/OrderEta.tsx +64 -0
  143. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +15 -3
  144. package/themes/original/src/components/OrderDetails/index.tsx +264 -349
  145. package/themes/original/src/components/OrderDetails/styles.tsx +10 -1
  146. package/themes/original/src/components/OrderItAgain/index.tsx +3 -1
  147. package/themes/original/src/components/OrderProgress/index.tsx +74 -112
  148. package/themes/original/src/components/OrderProgress/styles.tsx +5 -0
  149. package/themes/original/src/components/OrderSummary/index.tsx +87 -59
  150. package/themes/original/src/components/OrderTypeSelector/index.tsx +3 -2
  151. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +24 -19
  152. package/themes/original/src/components/OrdersOption/index.tsx +96 -88
  153. package/themes/original/src/components/PageBanner/index.tsx +171 -0
  154. package/themes/original/src/components/PageBanner/styles.tsx +11 -0
  155. package/themes/original/src/components/PaymentOptionStripe/styles.tsx +1 -1
  156. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  157. package/themes/original/src/components/PaymentOptions/index.tsx +34 -6
  158. package/themes/original/src/components/PhoneInputNumber/index.tsx +3 -3
  159. package/themes/original/src/components/PlaceSpot/index.tsx +12 -6
  160. package/themes/original/src/components/PreviousOrders/index.tsx +3 -2
  161. package/themes/original/src/components/ProductForm/index.tsx +231 -253
  162. package/themes/original/src/components/ProductForm/styles.tsx +4 -7
  163. package/themes/original/src/components/ProductItemAccordion/index.tsx +197 -138
  164. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -10
  165. package/themes/original/src/components/ProductOptionSubOption/styles.tsx +1 -2
  166. package/themes/original/src/components/ProfessionalFilter/SingleProfessionalCard/index.tsx +108 -0
  167. package/themes/original/src/components/ProfessionalFilter/index.tsx +20 -50
  168. package/themes/original/src/components/ProfessionalProfile/index.tsx +36 -7
  169. package/themes/original/src/components/Promotions/index.tsx +234 -220
  170. package/themes/original/src/components/Promotions/styles.tsx +10 -3
  171. package/themes/original/src/components/ReviewDriver/index.tsx +3 -3
  172. package/themes/original/src/components/ReviewOrder/index.tsx +26 -9
  173. package/themes/original/src/components/ReviewOrder/styles.tsx +7 -0
  174. package/themes/original/src/components/ReviewProducts/index.tsx +23 -11
  175. package/themes/original/src/components/ReviewTrigger/index.tsx +27 -9
  176. package/themes/original/src/components/ReviewTrigger/styles.tsx +8 -1
  177. package/themes/original/src/components/ScheduleAccordion/index.tsx +68 -0
  178. package/themes/original/src/components/ScheduleAccordion/styles.tsx +14 -0
  179. package/themes/original/src/components/ServiceForm/index.tsx +366 -288
  180. package/themes/original/src/components/Sessions/index.tsx +11 -8
  181. package/themes/original/src/components/Sessions/styles.tsx +5 -0
  182. package/themes/original/src/components/SignupForm/index.tsx +82 -67
  183. package/themes/original/src/components/SingleOrderCard/index.tsx +149 -63
  184. package/themes/original/src/components/SingleOrderCard/styles.tsx +11 -9
  185. package/themes/original/src/components/SingleProductCard/index.tsx +99 -55
  186. package/themes/original/src/components/SingleProductCard/styles.tsx +27 -13
  187. package/themes/original/src/components/SingleProductReview/index.tsx +8 -2
  188. package/themes/original/src/components/SingleProductReview/styles.tsx +1 -1
  189. package/themes/original/src/components/StripeCardsList/index.tsx +9 -2
  190. package/themes/original/src/components/StripeElementsForm/index.tsx +28 -15
  191. package/themes/original/src/components/UpsellingProducts/index.tsx +238 -224
  192. package/themes/original/src/components/UpsellingProducts/styles.tsx +12 -1
  193. package/themes/original/src/components/UserDetails/index.tsx +8 -4
  194. package/themes/original/src/components/UserFormDetails/index.tsx +47 -7
  195. package/themes/original/src/components/UserProfile/index.tsx +9 -14
  196. package/themes/original/src/components/UserProfileForm/index.tsx +21 -28
  197. package/themes/original/src/components/UserProfileForm/styles.tsx +7 -0
  198. package/themes/original/src/components/WalletTransactionItem/index.tsx +1 -1
  199. package/themes/original/src/components/Wallets/index.tsx +31 -17
  200. package/themes/original/src/components/Wallets/styles.tsx +2 -0
  201. package/themes/original/src/components/shared/CardAnimation.tsx +47 -0
  202. package/themes/original/src/components/shared/HeaderTitle.tsx +8 -3
  203. package/themes/original/src/components/shared/OBottomPopup.tsx +1 -1
  204. package/themes/original/src/components/shared/OButton.tsx +6 -2
  205. package/themes/original/src/components/shared/OIcon.tsx +8 -1
  206. package/themes/original/src/components/shared/OInput.tsx +16 -2
  207. package/themes/original/src/components/shared/OModal.tsx +3 -3
  208. package/themes/original/src/layouts/Container.tsx +13 -9
  209. package/themes/original/src/types/index.tsx +39 -9
  210. package/themes/original/src/utils/index.tsx +375 -58
  211. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -1,17 +1,18 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react'
2
- import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView } from 'react-native'
2
+ import { View, TouchableOpacity, StyleSheet, SafeAreaView, Dimensions, Platform, KeyboardAvoidingViewBase, KeyboardAvoidingView, Vibration, 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';
6
6
  import {
7
- BusinessAndProductList,
8
- useLanguage,
9
- useOrder,
10
- useSession,
11
- useUtils,
12
- ToastType,
13
- useToast,
14
- useConfig
7
+ BusinessAndProductList,
8
+ useLanguage,
9
+ useOrder,
10
+ useSession,
11
+ useUtils,
12
+ ToastType,
13
+ useToast,
14
+ useConfig,
15
+ useEvent
15
16
  } from 'ordering-components/native'
16
17
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
17
18
  import { OButton, OIcon, OModal, OText } from '../shared'
@@ -23,17 +24,17 @@ import { BusinessProductsList } from '../BusinessProductsList'
23
24
  import { BusinessProductsListingParams } from '../../types'
24
25
  import { _retrieveStoreData, _removeStoreData } from '../../providers/StoreUtil';
25
26
  import IconAntDesign from 'react-native-vector-icons/AntDesign';
27
+ import { useIsFocused } from '@react-navigation/native';
26
28
 
27
29
  import {
28
- TopHeader,
29
- WrapSearchBar,
30
- WrapContent,
31
- FiltProductsContainer,
32
- ContainerSafeAreaView,
33
- BackgroundGray,
34
- ProfessionalFilterWrapper,
35
- NearBusiness,
36
- TopActions
30
+ TopHeader,
31
+ WrapSearchBar,
32
+ WrapContent,
33
+ FiltProductsContainer,
34
+ BackgroundGray,
35
+ ProfessionalFilterWrapper,
36
+ NearBusiness,
37
+ TopActions
37
38
  } from './styles'
38
39
  import { FloatingButton } from '../FloatingButton'
39
40
  import { UpsellingRedirect } from './UpsellingRedirect'
@@ -41,509 +42,629 @@ import Animated from 'react-native-reanimated'
41
42
  import { ProfessionalFilter } from '../ProfessionalFilter';
42
43
  import { ServiceForm } from '../ServiceForm';
43
44
  import { BusinessesListing } from '../BusinessesListing/Layout/Original'
45
+ import { PageBanner } from '../PageBanner'
44
46
 
45
47
  const PIXELS_TO_SCROLL = 2000
46
48
 
47
49
  const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
48
- const {
49
- navigation,
50
- errors,
51
- businessState,
52
- categoryState,
53
- handleChangeSearch,
54
- categorySelected,
55
- searchValue,
56
- handleChangeCategory,
57
- handleSearchRedirect,
58
- featuredProducts,
59
- errorQuantityProducts,
60
- header,
61
- logo,
62
- alertState,
63
- setAlertState,
64
- multiRemoveProducts,
65
- getNextProducts,
66
- handleUpdateProducts,
67
- professionalSelected,
68
- handleChangeProfessionalSelected,
69
- onBusinessClick
70
- } = props
50
+ const {
51
+ navigation,
52
+ errors,
53
+ businessState,
54
+ categoryState,
55
+ handleChangeSearch,
56
+ categorySelected,
57
+ searchValue,
58
+ handleChangeCategory,
59
+ handleSearchRedirect,
60
+ featuredProducts,
61
+ errorQuantityProducts,
62
+ header,
63
+ logo,
64
+ alertState,
65
+ setAlertState,
66
+ multiRemoveProducts,
67
+ getNextProducts,
68
+ handleUpdateProducts,
69
+ professionalSelected,
70
+ handleUpdateProfessionals,
71
+ handleChangeProfessionalSelected,
72
+ onBusinessClick,
73
+ businessSingleId
74
+ } = props
71
75
 
72
- const insets = useSafeAreaInsets()
73
- const theme = useTheme();
74
- const [, t] = useLanguage()
75
- const [{ auth }] = useSession()
76
- const [orderState, { clearCart }] = useOrder()
77
- const [{ parsePrice }] = useUtils()
78
- const [, { showToast }] = useToast()
79
- const [{ configs }] = useConfig()
80
- const isPreOrder = configs?.preorder_status_enabled?.value === '1'
76
+ const insets = useSafeAreaInsets()
77
+ const theme = useTheme();
78
+ const [, t] = useLanguage()
79
+ const [{ auth }] = useSession()
80
+ const [orderState, { addProduct, updateProduct }] = useOrder()
81
+ const [{ parsePrice }] = useUtils()
82
+ const [, { showToast }] = useToast()
83
+ const [{ configs }] = useConfig()
84
+ const [events] = useEvent()
85
+ const isFocused = useIsFocused();
86
+ const isPreOrder = configs?.preorder_status_enabled?.value === '1'
81
87
 
82
- const isChewLayout = theme?.business_view?.components?.header?.components?.layout?.type === 'chew'
83
- const showLogo = !theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
84
- const hideBusinessNearCity = theme?.business_view?.components?.near_business?.hidden ?? true
88
+ const isChewLayout = theme?.header?.components?.layout?.type === 'chew'
89
+ const showLogo = !theme?.business_view?.components?.header?.components?.business?.components?.logo?.hidden
90
+ const hideBusinessNearCity = theme?.business_view?.components?.near_business?.hidden ?? true
91
+ const backgroundColor = theme?.business_view?.components?.style?.backgroundColor
92
+ const styles = StyleSheet.create({
93
+ mainContainer: {
94
+ flex: 1
95
+ },
96
+ BackIcon: {
97
+ paddingRight: 20,
98
+ },
99
+ headerItem: {
100
+ flexDirection: 'row',
101
+ alignItems: 'center',
102
+ marginVertical: 2,
103
+ marginHorizontal: 20,
104
+ },
105
+ btnBackArrow: {
106
+ borderWidth: 0,
107
+ backgroundColor: theme.colors.clear,
108
+ shadowColor: theme.colors.clear,
109
+ padding: 40,
110
+ },
111
+ searchIcon: {
112
+ borderWidth: 0,
113
+ padding: 15,
114
+ justifyContent: 'center',
115
+ shadowColor: theme.colors.clear,
116
+ },
117
+ businessSkeleton: {
118
+ borderRadius: 8,
119
+ marginRight: 20,
120
+ width: 56,
121
+ height: 56
122
+ },
123
+ })
85
124
 
86
- const styles = StyleSheet.create({
87
- mainContainer: {
88
- flex: 1
89
- },
90
- BackIcon: {
91
- paddingRight: 20,
92
- },
93
- headerItem: {
94
- flexDirection: 'row',
95
- alignItems: 'center',
96
- marginVertical: 2,
97
- marginHorizontal: 20,
98
- },
99
- btnBackArrow: {
100
- borderWidth: 0,
101
- backgroundColor: theme.colors.clear,
102
- shadowColor: theme.colors.clear,
103
- padding: 40,
104
- },
105
- searchIcon: {
106
- borderWidth: 0,
107
- padding: 15,
108
- justifyContent: 'center',
109
- shadowColor: theme.colors.clear,
110
- },
111
- businessSkeleton: {
112
- borderRadius: 8,
113
- marginRight: 20,
114
- width: 56,
115
- height: 56
116
- },
117
- })
125
+ const { business, loading, error } = businessState
126
+ const [openBusinessInformation, setOpenBusinessInformation] = useState(false)
127
+ const [isOpenSearchBar, setIsOpenSearchBar] = useState(false)
128
+ const [openUpselling, setOpenUpselling] = useState(false)
129
+ const [canOpenUpselling, setCanOpenUpselling] = useState(false)
130
+ const scrollViewRef = useRef<any>(null)
131
+ const [categoriesLayout, setCategoriesLayout] = useState<any>({})
132
+ const [productListLayout, setProductListLayout] = useState<any>(null)
133
+ const [isCategoryClicked, setCategoryClicked] = useState(false)
134
+ const [subcategoriesSelected, setSubcategoriesSelected] = useState([])
135
+ const [openService, setOpenService] = useState(false)
136
+ const [currentProduct, setCurrentProduct] = useState(null)
137
+ const [searchBarHeight, setSearchBarHeight] = useState(60)
138
+ const [viewedCategory, setViewedCategory] = useState<any>(null)
118
139
 
119
- const { business, loading, error } = businessState
120
- const [openBusinessInformation, setOpenBusinessInformation] = useState(false)
121
- const [isOpenSearchBar, setIsOpenSearchBar] = useState(false)
122
- const [openUpselling, setOpenUpselling] = useState(false)
123
- const [canOpenUpselling, setCanOpenUpselling] = useState(false)
124
- const scrollViewRef = useRef<any>(null)
125
- const [categoriesLayout, setCategoriesLayout] = useState<any>({})
126
- const [productListLayout, setProductListLayout] = useState<any>(null)
127
- const [isCategoryClicked, setCategoryClicked] = useState(false)
128
- const [subcategoriesSelected, setSubcategoriesSelected] = useState([])
129
- const [openService, setOpenService] = useState(false)
130
- const [currentProduct, setCurrentProduct] = useState(null)
140
+ const isCheckoutMultiBusinessEnabled: Boolean = configs?.checkout_multi_business_enabled?.value === '1'
141
+ const isQuickAddProduct = configs?.add_product_with_one_click?.value === '1'
142
+ 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) || []
131
143
 
132
- const isCheckoutMultiBusinessEnabled: Boolean = configs?.checkout_multi_business_enabled?.value === '1'
133
- 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) || []
144
+ const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
145
+ const isOpenFiltProducts = isOpenSearchBar && !!searchValue
146
+ const filtProductsHeight = Platform.OS === 'ios' ? 165 : 100
147
+ const onRedirect = (route: string, params?: any) => {
148
+ navigation.navigate(route, params)
149
+ }
150
+ const onProductClick = async (product: any) => {
151
+ if (product.extras.length === 0 && !product.inventoried && auth && isQuickAddProduct) {
152
+ const isProductAddedToCart = currentCart?.products?.find((Cproduct: any) => Cproduct.id === product.id)
153
+ const productQuantity = isProductAddedToCart?.quantity
154
+ const addCurrentProduct = {
155
+ ...product,
156
+ quantity: 1
157
+ }
158
+ const updateCurrentProduct = {
159
+ id: product.id,
160
+ code: isProductAddedToCart?.code,
161
+ quantity: productQuantity + 1
162
+ }
163
+ Vibration.vibrate()
164
+ const cartData = currentCart?.business_id ? currentCart : { business_id: business.id }
165
+ if (isProductAddedToCart) {
166
+ await updateProduct(updateCurrentProduct, cartData, isQuickAddProduct)
167
+ } else {
168
+ await addProduct(addCurrentProduct, cartData, isQuickAddProduct)
169
+ }
170
+ } else {
171
+ const productAddedToCartLength = currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0) || 0
172
+ if (product?.type === 'service' && business?.professionals?.length > 0) {
173
+ setCurrentProduct(product)
174
+ setOpenService(true)
175
+ return
176
+ }
177
+ onRedirect('ProductDetails', {
178
+ product: product,
179
+ businessSlug: business.slug,
180
+ businessId: business.id,
181
+ productAddedToCartLength
182
+ })
183
+ }
184
+ events.emit('product_clicked', product)
185
+ }
134
186
 
135
- const currentCart: any = Object.values(orderState.carts).find((cart: any) => cart?.business?.slug === business?.slug) ?? {}
136
- const isOpenFiltProducts = isOpenSearchBar && !!searchValue
137
- const filtProductsHeight = Platform.OS === 'ios' ? 0 : 100
138
- const onRedirect = (route: string, params?: any) => {
139
- navigation.navigate(route, params)
140
- }
187
+ const handleCancel = () => {
188
+ setIsOpenSearchBar(false)
189
+ handleChangeSearch('')
190
+ }
141
191
 
142
- const onProductClick = (product: any) => {
143
- const productAddedToCartLength = currentCart?.products?.reduce((productsLength: number, Cproduct: any) => { return productsLength + (Cproduct?.id === product?.id ? Cproduct?.quantity : 0) }, 0) || 0
144
- if (product?.type === 'service' && business?.professionals?.length > 0) {
145
- setCurrentProduct(product)
146
- setOpenService(true)
147
- return
148
- }
149
- onRedirect('ProductDetails', {
150
- product: product,
151
- businessSlug: business.slug,
152
- businessId: business.id,
153
- productAddedToCartLength
154
- })
155
- }
192
+ const handleUpsellingPage = (cart: any) => {
193
+ const isProductCartParam = !!cart?.products?.length
194
+ setOpenUpselling(false)
195
+ setCanOpenUpselling(false)
196
+ const cartsAvailable: any = Object.values(orderState?.carts)
197
+ ?.filter((_cart: any) => _cart?.valid && _cart?.status !== 2 && _cart?.products?.length)
198
+ ?.filter((_c: any) => !isProductCartParam ? _c.uuid !== cart?.uuid : _c)
199
+ if (cartsAvailable.length === 1 || !isCheckoutMultiBusinessEnabled) {
200
+ const cart = isCheckoutMultiBusinessEnabled ? cartsAvailable[0] : currentCart
156
201
 
157
- const handleCancel = () => {
158
- setIsOpenSearchBar(false)
159
- handleChangeSearch('')
160
- }
202
+ props.onNavigationRedirect('CheckoutNavigator', {
203
+ screen: 'CheckoutPage',
204
+ cartUuid: cart?.uuid,
205
+ businessLogo: cart?.business?.logo,
206
+ businessName: cart?.business?.name,
207
+ cartTotal: cart?.total
208
+ }, true)
209
+ } else {
210
+ const groupKeys: any = {}
211
+ cartsAvailable.forEach((_cart: any) => {
212
+ groupKeys[_cart?.group?.uuid]
213
+ ? groupKeys[_cart?.group?.uuid] += 1
214
+ : groupKeys[_cart?.group?.uuid ?? 'null'] = 1
215
+ })
161
216
 
162
- const handleUpsellingPage = () => {
163
- if (isCheckoutMultiBusinessEnabled && openCarts.length > 1) {
164
- onRedirect('CheckoutNavigator', {
165
- screen: 'MultiCheckout'
166
- })
167
- } else {
168
- onRedirect('CheckoutNavigator', {
169
- screen: 'CheckoutPage',
170
- cartUuid: currentCart?.uuid,
171
- businessLogo: logo,
172
- businessName: business?.name,
173
- cartTotal: currentCart?.total
174
- })
175
- }
176
- setOpenUpselling(false)
177
- }
217
+ if (
218
+ (Object.keys(groupKeys).length === 1 && Object.keys(groupKeys)[0] === 'null') ||
219
+ Object.keys(groupKeys).length > 1
220
+ ) {
221
+ props.onNavigationRedirect('CheckoutNavigator', {
222
+ screen: 'MultiCheckout',
223
+ checkCarts: true
224
+ }, true)
225
+ } else {
226
+ props.onNavigationRedirect('CheckoutNavigator', {
227
+ screen: 'MultiCheckout',
228
+ cartUuid: cartsAvailable[0]?.group?.uuid
229
+ }, true)
230
+ }
231
+ }
232
+ }
178
233
 
179
- const handleCloseUpsellingPage = () => {
180
- setOpenUpselling(false)
181
- }
234
+ const handleCloseUpsellingPage = () => {
235
+ setOpenUpselling(false)
236
+ }
182
237
 
183
- const [selectedCategoryId, setSelectedCategoryId] = useState<any>(null)
238
+ const [selectedCategoryId, setSelectedCategoryId] = useState<any>(null)
184
239
 
185
- const handlePageScroll = useCallback(({ nativeEvent }: any) => {
186
- const scrollOffset = nativeEvent.contentOffset.y
187
- if (businessState?.business?.lazy_load_products_recommended) {
188
- const height = nativeEvent.contentSize.height
189
- const hasMore = !(categoryState.pagination.totalPages === categoryState.pagination.currentPage)
190
- if (scrollOffset + PIXELS_TO_SCROLL > height && !loading && hasMore && getNextProducts) {
191
- getNextProducts()
192
- showToast(ToastType.Info, t('LOADING_MORE_PRODUCTS', 'Loading more products'))
193
- }
194
- } else {
195
- if (!scrollOffset || !categoriesLayout || !productListLayout || isCategoryClicked) return
240
+ const handlePageScroll = useCallback(({ nativeEvent }: any) => {
241
+ const scrollOffset = nativeEvent.contentOffset.y
242
+ if (businessState?.business?.lazy_load_products_recommended) {
243
+ const height = nativeEvent.contentSize.height
244
+ const hasMore = !(categoryState.pagination.totalPages === categoryState.pagination.currentPage)
245
+ if (scrollOffset + PIXELS_TO_SCROLL > height && !loading && hasMore && getNextProducts) {
246
+ getNextProducts()
247
+ showToast(ToastType.Info, t('LOADING_MORE_PRODUCTS', 'Loading more products'))
248
+ }
249
+ } else {
250
+ if (!scrollOffset || !categoriesLayout || !productListLayout || isCategoryClicked) return
196
251
 
197
- for (const key in categoriesLayout) {
198
- const categoryOffset = categoriesLayout[key].y + productListLayout?.y - 70
199
- if (scrollOffset < 10) {
200
- setSelectedCategoryId('cat_all');
201
- return;
202
- }
203
- if (categoryOffset - 50 <= scrollOffset && scrollOffset <= categoryOffset + 50) {
204
- if (selectedCategoryId !== key) {
205
- setSelectedCategoryId(key)
206
- }
207
- }
208
- }
209
- }
210
- }, [isCategoryClicked, selectedCategoryId, productListLayout])
252
+ for (const key in categoriesLayout) {
253
+ const categoryOffset = categoriesLayout[key].y + productListLayout?.y - 70
254
+ if (scrollOffset < 10) {
255
+ setSelectedCategoryId('cat_all');
256
+ return;
257
+ }
258
+ if (categoryOffset - 50 <= scrollOffset && scrollOffset <= categoryOffset + 50) {
259
+ if (selectedCategoryId !== key) {
260
+ setSelectedCategoryId(key)
261
+ }
262
+ }
263
+ }
264
+ }
265
+ }, [isCategoryClicked, selectedCategoryId, productListLayout])
211
266
 
212
- const handleTouchDrag = useCallback(() => {
213
- setCategoryClicked(false);
214
- }, []);
267
+ const handleTouchDrag = useCallback(() => {
268
+ setCategoryClicked(false);
269
+ }, []);
215
270
 
216
- const handleBackNavigation = () => {
217
- navigation?.canGoBack() ? navigation.goBack() : navigation.navigate('BottomTab')
218
- }
271
+ const handleBackNavigation = () => {
272
+ navigation?.canGoBack() ? navigation.goBack() : navigation.navigate('BottomTab')
273
+ }
219
274
 
220
- const adjustBusiness = async (adjustBusinessId: number) => {
221
- const _carts = orderState?.carts?.[adjustBusinessId]
222
- const products = _carts?.products
223
- const unavailableProducts = products.filter((product: any) => product.valid !== true)
224
- const alreadyRemoved = await _retrieveStoreData('already-removed')
225
- _removeStoreData('already-removed')
226
- if (unavailableProducts.length > 0) {
227
- multiRemoveProducts && await multiRemoveProducts(unavailableProducts, _carts)
228
- return
229
- }
275
+ const adjustBusiness = async (adjustBusinessId: number) => {
276
+ const _carts = orderState?.carts?.[adjustBusinessId]
277
+ const products = _carts?.products
278
+ const unavailableProducts = products.filter((product: any) => product.valid !== true)
279
+ const alreadyRemoved = await _retrieveStoreData('already-removed')
280
+ _removeStoreData('already-removed')
281
+ if (unavailableProducts.length > 0) {
282
+ multiRemoveProducts && await multiRemoveProducts(unavailableProducts, _carts)
283
+ return
284
+ }
230
285
 
231
- if (alreadyRemoved === 'removed') {
232
- setAlertState({ open: true, content: [t('NOT_AVAILABLE_PRODUCT', 'This product is not available.')] })
233
- }
234
- }
286
+ if (alreadyRemoved === 'removed') {
287
+ setAlertState({ open: true, content: [t('NOT_AVAILABLE_PRODUCT', 'This product is not available.')] })
288
+ }
289
+ }
235
290
 
236
- const removeCartByReOrder = async () => {
237
- const adjustBusinessId = await _retrieveStoreData('adjust-cart-products')
238
- if (currentCart && adjustBusinessId) {
239
- _removeStoreData('adjust-cart-products')
240
- adjustBusiness(adjustBusinessId)
241
- }
242
- }
291
+ const removeCartByReOrder = async () => {
292
+ const adjustBusinessId = await _retrieveStoreData('adjust-cart-products')
293
+ if (currentCart && adjustBusinessId) {
294
+ _removeStoreData('adjust-cart-products')
295
+ adjustBusiness(adjustBusinessId)
296
+ }
297
+ }
243
298
 
244
- useEffect(() => {
245
- removeCartByReOrder()
246
- }, [currentCart])
299
+ useEffect(() => {
300
+ removeCartByReOrder()
301
+ }, [currentCart])
247
302
 
248
- return (
249
- <>
250
- <View style={{ flex: 1 }}>
251
- <Animated.View style={{ position: 'relative' }}>
252
- <TopHeader
253
- style={{
254
- marginTop: Platform.OS === 'ios' ? insets.top : 40
255
- }}
256
- >
257
- {!isOpenSearchBar && (
258
- <>
259
- <TopActions onPress={() => handleBackNavigation()}>
260
- <IconAntDesign name='arrowleft' size={26} />
261
- </TopActions>
262
- {!errorQuantityProducts && (
263
- <View style={{ ...styles.headerItem }}>
264
- <TouchableOpacity
265
- onPress={() => setIsOpenSearchBar(true)}
266
- style={styles.searchIcon}
267
- >
268
- <OIcon src={theme.images.general.search} color={theme.colors.textNormal} width={16} />
269
- </TouchableOpacity>
270
- </View>
271
- )}
272
- </>
273
- )}
274
- {isOpenSearchBar && (
275
- <WrapSearchBar>
276
- <SearchBar
277
- autoFocus
278
- onSearch={handleChangeSearch}
279
- onCancel={() => handleCancel()}
280
- isCancelXButtonShow
281
- noBorderShow
282
- placeholder={t('SEARCH_PRODUCTS', 'Search Products')}
283
- lazyLoad={businessState?.business?.lazy_load_products_recommended}
284
- />
285
- </WrapSearchBar>
286
- )}
287
- </TopHeader>
288
- {!hideBusinessNearCity && loading && (
289
- <NearBusiness style={{ paddingBottom: 10 }}>
290
- <Placeholder Animation={Fade}>
291
- <View style={{ flexDirection: 'row' }}>
292
- {[...Array(10).keys()].map(i => (
293
- <View style={styles.businessSkeleton} key={i}>
294
- <PlaceholderLine style={{ width: '100%', height: '100%' }} />
295
- </View>
296
- ))}
297
- </View>
298
- </Placeholder>
299
- </NearBusiness>
300
- )}
301
- {!loading && !hideBusinessNearCity && businessState?.business?.city_id && (
302
- <NearBusiness>
303
- <BusinessesListing
304
- logosLayout
305
- propsToFetch={['id', 'logo', 'location', 'timezone', 'schedule', 'open', 'slug']}
306
- cityId={businessState?.business?.city_id}
307
- onBusinessClick={onBusinessClick}
308
- actualSlug={businessState?.business?.slug}
309
- />
310
- </NearBusiness>
311
- )}
312
- </Animated.View>
303
+ useEffect(() => {
304
+ if (!isFocused) {
305
+ handleChangeSearch('')
306
+ setIsOpenSearchBar(false)
307
+ }
308
+ }, [isFocused])
313
309
 
314
- {business?.categories?.length > 0 && isOpenFiltProducts && (
315
- <FiltProductsContainer
316
- isIos={Platform.OS === 'ios'}
317
- style={{
318
- height: Dimensions.get('window').height - filtProductsHeight
319
- }}
320
- contentContainerStyle={{ flexGrow: 1 }}
321
- >
322
- <View style={{ padding: 20, backgroundColor: theme.colors.white }}>
323
- <BusinessProductsList
324
- categories={[
325
- { id: null, name: t('ALL', 'All') },
326
- { id: 'featured', name: t('FEATURED', 'Featured') },
327
- ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)
328
- ]}
329
- category={categorySelected}
330
- categoryState={categoryState}
331
- businessId={business.id}
332
- errors={errors}
333
- onProductClick={onProductClick}
334
- handleSearchRedirect={handleSearchRedirect}
335
- featured={featuredProducts}
336
- searchValue={searchValue}
337
- handleClearSearch={handleChangeSearch}
338
- errorQuantityProducts={errorQuantityProducts}
339
- handleCancelSearch={handleCancel}
340
- categoriesLayout={categoriesLayout}
341
- subcategoriesSelected={subcategoriesSelected}
342
- lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
343
- setCategoriesLayout={setCategoriesLayout}
344
- currentCart={currentCart}
345
- setSubcategoriesSelected={setSubcategoriesSelected}
346
- onClickCategory={handleChangeCategory}
347
- handleUpdateProducts={handleUpdateProducts}
348
- previouslyProducts={business?.previously_products}
349
- navigation={navigation}
350
- isFiltMode
351
- />
352
- </View>
353
- </FiltProductsContainer>
354
- )}
355
- {isOpenFiltProducts && (
356
- <BackgroundGray />
357
- )}
358
- <IOScrollView
359
- stickyHeaderIndices={[business?.professionals?.length > 0 ? 3 : 2]}
360
- style={{
361
- ...styles.mainContainer,
362
- marginBottom: currentCart?.products?.length > 0 && categoryState.products.length !== 0 ?
363
- 50 : 0
364
- }}
365
- ref={scrollViewRef}
366
- onScroll={handlePageScroll}
367
- onScrollBeginDrag={handleTouchDrag}
368
- scrollEventThrottle={16}
369
- bounces={false}
370
- >
371
- <BusinessBasicInformation
372
- navigation={navigation}
373
- businessState={businessState}
374
- openBusinessInformation={openBusinessInformation}
375
- header={header}
376
- logo={logo}
377
- isPreOrder={isPreOrder}
378
- />
379
- {business?.professionals?.length > 0 && (
380
- <ProfessionalFilterWrapper>
381
- <OText
382
- size={16}
383
- style={{ marginBottom: 16 }}
384
- weight={Platform.OS === 'ios' ? '600' : 'bold'}
385
- >
386
- {t('PROFESSIONALS', 'Professionals')}
387
- </OText>
388
- <ProfessionalFilter
389
- professionals={business?.professionals}
390
- professionalSelected={professionalSelected}
391
- handleChangeProfessionalSelected={handleChangeProfessionalSelected}
392
- />
393
- </ProfessionalFilterWrapper>
394
- )}
395
- <View
396
- style={{
397
- height: 8,
398
- backgroundColor: theme.colors.backgroundGray100,
399
- marginTop: isChewLayout && showLogo ? 10 : 0
400
- }}
401
- />
402
- {!loading && business?.id && !(business?.categories?.length === 0) && (
403
- <BusinessProductsCategories
404
- categories={[{ id: null, name: t('ALL', 'All') }, { id: 'featured', name: t('FEATURED', 'Featured') }, ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)]}
405
- categorySelected={categorySelected}
406
- onClickCategory={handleChangeCategory}
407
- featured={featuredProducts}
408
- openBusinessInformation={openBusinessInformation}
409
- scrollViewRef={scrollViewRef}
410
- productListLayout={productListLayout}
411
- categoriesLayout={categoriesLayout}
412
- selectedCategoryId={selectedCategoryId}
413
- lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
414
- setSelectedCategoryId={setSelectedCategoryId}
415
- setCategoryClicked={setCategoryClicked}
416
- />
417
- )}
418
- {!loading && business?.id && (
419
- <>
420
- <WrapContent
421
- onLayout={(event: any) => setProductListLayout(event.nativeEvent.layout)}
422
- >
423
- <BusinessProductsList
424
- categories={[
425
- { id: null, name: t('ALL', 'All') },
426
- { id: 'featured', name: t('FEATURED', 'Featured') },
427
- ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)
428
- ]}
429
- category={categorySelected}
430
- categoryState={categoryState}
431
- businessId={business.id}
432
- errors={errors}
433
- onProductClick={onProductClick}
434
- handleSearchRedirect={handleSearchRedirect}
435
- featured={featuredProducts}
436
- searchValue={searchValue}
437
- handleClearSearch={handleChangeSearch}
438
- errorQuantityProducts={errorQuantityProducts}
439
- handleCancelSearch={handleCancel}
440
- categoriesLayout={categoriesLayout}
441
- subcategoriesSelected={subcategoriesSelected}
442
- lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
443
- setCategoriesLayout={setCategoriesLayout}
444
- currentCart={currentCart}
445
- setSubcategoriesSelected={setSubcategoriesSelected}
446
- onClickCategory={handleChangeCategory}
447
- handleUpdateProducts={handleUpdateProducts}
448
- navigation={navigation}
449
- previouslyProducts={business?.previously_products}
450
- />
451
- </WrapContent>
452
- </>
453
- )}
454
- {loading && !error && (
455
- <>
456
- <BusinessProductsCategories
457
- categories={[]}
458
- categorySelected={categorySelected}
459
- onClickCategory={handleChangeCategory}
460
- featured={featuredProducts}
461
- openBusinessInformation={openBusinessInformation}
462
- loading={loading}
463
- />
464
- <WrapContent>
465
- <BusinessProductsList
466
- categories={[]}
467
- category={categorySelected}
468
- categoryState={categoryState}
469
- isBusinessLoading={loading}
470
- errorQuantityProducts={errorQuantityProducts}
471
- handleUpdateProducts={handleUpdateProducts}
472
- navigation={navigation}
473
- />
474
- </WrapContent>
475
- </>
476
- )}
477
- </IOScrollView>
478
- {!loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0 && (
479
- <FloatingButton
480
- btnText={
481
- openUpselling
482
- ? t('LOADING', 'Loading')
483
- : currentCart?.subtotal >= currentCart?.minimum
484
- ? t('VIEW_ORDER', 'View Order')
485
- : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
486
- }
487
- isSecondaryBtn={currentCart?.subtotal < currentCart?.minimum || openUpselling}
488
- btnLeftValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
489
- btnRightValueShow={currentCart?.subtotal >= currentCart?.minimum && currentCart?.products?.length > 0}
490
- btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
491
- btnRightValue={parsePrice(currentCart?.total)}
492
- disabled={currentCart?.subtotal < currentCart?.minimum || openUpselling}
493
- handleClick={() => setOpenUpselling(true)}
494
- />
495
- )}
496
- {openUpselling && (
497
- <UpsellingRedirect
498
- businessId={currentCart?.business_id}
499
- business={currentCart?.business}
500
- cartProducts={currentCart?.products}
501
- cart={currentCart}
502
- setOpenUpselling={setOpenUpselling}
503
- handleUpsellingPage={handleUpsellingPage}
504
- handleCloseUpsellingPage={handleCloseUpsellingPage}
505
- openUpselling={openUpselling}
506
- canOpenUpselling={canOpenUpselling}
507
- setCanOpenUpselling={setCanOpenUpselling}
508
- onRedirect={onRedirect}
509
- />
510
- )}
511
- <Alert
512
- open={alertState?.open || false}
513
- title=''
514
- content={[t('NOT_AVAILABLE_PRODUCTS', 'These products are not available.')]}
515
- onAccept={() => setAlertState({ open: false, content: [] })}
516
- onClose={() => setAlertState({ open: false, content: [] })}
517
- />
518
- </View>
519
- <OModal
520
- open={openService}
521
- onClose={() => setOpenService(false)}
522
- entireModal
523
- >
524
- <ServiceForm
525
- navigation={navigation}
526
- product={currentProduct}
527
- businessSlug={business.slug}
528
- businessId={business.id}
529
- professionalList={business?.professionals}
530
- professionalSelected={professionalSelected}
531
- handleChangeProfessional={handleChangeProfessionalSelected}
532
- onSave={() => setOpenService(false)}
533
- onClose={() => setOpenService(false)}
534
- />
535
- </OModal>
536
- </>
537
- )
310
+ const subtotalWithTaxes = currentCart?.taxes?.reduce((acc: any, item: any) => {
311
+ if (item?.type === 1)
312
+ return acc = acc + item?.summary?.tax
313
+ return acc = acc
314
+ }, currentCart?.subtotal)
315
+
316
+ const onChangeSearch = (query: any) => {
317
+ handleChangeSearch(query)
318
+ if (query) {
319
+ events.emit('products_searched', query)
320
+ }
321
+ }
322
+
323
+ useEffect(() => {
324
+ let categoryId: any = null
325
+ if (business?.lazy_load_products_recommended) {
326
+ if (categorySelected?.id) {
327
+ categoryId = categorySelected.id
328
+ }
329
+ } else {
330
+ if (selectedCategoryId) {
331
+ const originCategoryId = selectedCategoryId.replace('cat_', '')
332
+ if (!isNaN(originCategoryId)) {
333
+ categoryId = Number(originCategoryId)
334
+ }
335
+ }
336
+ }
337
+ if (categoryId) {
338
+ const _viewedCategory = business.categories.find(category => category.id === categoryId)
339
+ if (_viewedCategory?.id !== viewedCategory?.id) {
340
+ setViewedCategory(_viewedCategory)
341
+ events.emit('product_list_viewed', _viewedCategory)
342
+ }
343
+ }
344
+ }, [business?.lazy_load_products_recommended, selectedCategoryId, categorySelected?.id, viewedCategory])
345
+
346
+ useEffect(() => {
347
+ const handleArrowBack: any = () => {
348
+ navigation.goBack()
349
+ return true
350
+ }
351
+ BackHandler.addEventListener('hardwareBackPress', handleArrowBack);
352
+ return () => {
353
+ BackHandler.removeEventListener('hardwareBackPress', handleArrowBack);
354
+ }
355
+ }, [])
356
+
357
+ return (
358
+ <>
359
+ <View style={{ flex: 1, backgroundColor: backgroundColor }}>
360
+ <Animated.View style={{ position: 'relative' }}>
361
+ <TopHeader
362
+ style={{
363
+ marginTop: Platform.OS === 'ios' ? insets.top : 0
364
+ }}
365
+ onLayout={(event: any) => setSearchBarHeight(event.nativeEvent.layout.height)}
366
+ hideArrow={(businessSingleId && auth)}
367
+ >
368
+ {!isOpenSearchBar && (
369
+ <>
370
+ {!(businessSingleId && auth) && (
371
+ <TopActions onPress={() => handleBackNavigation()}>
372
+ <OIcon src={theme.images.general.arrow_left} color={theme.colors.textNormal} />
373
+ </TopActions>
374
+ )}
375
+ {!errorQuantityProducts && (
376
+ <View style={{ ...styles.headerItem }}>
377
+ <TouchableOpacity
378
+ onPress={() => setIsOpenSearchBar(true)}
379
+ style={styles.searchIcon}
380
+ >
381
+ <OIcon src={theme.images.general.search} color={theme.colors.textNormal} width={20} />
382
+ </TouchableOpacity>
383
+ </View>
384
+ )}
385
+ </>
386
+ )}
387
+ {isOpenSearchBar && (
388
+ <WrapSearchBar>
389
+ <SearchBar
390
+ autoFocus
391
+ onSearch={onChangeSearch}
392
+ onCancel={() => handleCancel()}
393
+ isCancelXButtonShow
394
+ noBorderShow
395
+ placeholder={t('SEARCH_PRODUCTS', 'Search Products')}
396
+ lazyLoad
397
+ />
398
+ </WrapSearchBar>
399
+ )}
400
+ </TopHeader>
401
+ {!hideBusinessNearCity && loading && (
402
+ <NearBusiness style={{ paddingBottom: 10 }}>
403
+ <Placeholder Animation={Fade}>
404
+ <View style={{ flexDirection: 'row' }}>
405
+ {[...Array(10).keys()].map(i => (
406
+ <View style={styles.businessSkeleton} key={i}>
407
+ <PlaceholderLine style={{ width: '100%', height: '100%' }} />
408
+ </View>
409
+ ))}
410
+ </View>
411
+ </Placeholder>
412
+ </NearBusiness>
413
+ )}
414
+ {!loading && !hideBusinessNearCity && businessState?.business?.city_id && (
415
+ <NearBusiness>
416
+ <BusinessesListing
417
+ logosLayout
418
+ propsToFetch={['id', 'logo', 'location', 'timezone', 'schedule', 'open', 'slug']}
419
+ cityId={businessState?.business?.city_id}
420
+ onBusinessClick={onBusinessClick}
421
+ actualSlug={businessState?.business?.slug}
422
+ />
423
+ </NearBusiness>
424
+ )}
425
+ </Animated.View>
426
+
427
+ {business?.categories?.length > 0 && isOpenFiltProducts && (
428
+ <FiltProductsContainer
429
+ style={{
430
+ height: Dimensions.get('window').height - filtProductsHeight,
431
+ top: Platform.OS === 'ios' ? (searchBarHeight - 10) + insets.top : searchBarHeight
432
+ }}
433
+ contentContainerStyle={{ flexGrow: 1 }}
434
+ >
435
+ <View style={{ padding: 20, backgroundColor: theme.colors.white }}>
436
+ <BusinessProductsList
437
+ categories={[
438
+ { id: null, name: t('ALL', 'All') },
439
+ { id: 'featured', name: t('FEATURED', 'Featured') },
440
+ ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)
441
+ ]}
442
+ category={categorySelected}
443
+ categoryState={categoryState}
444
+ businessId={business.id}
445
+ errors={errors}
446
+ onProductClick={onProductClick}
447
+ handleSearchRedirect={handleSearchRedirect}
448
+ featured={featuredProducts}
449
+ searchValue={searchValue}
450
+ handleClearSearch={handleChangeSearch}
451
+ errorQuantityProducts={errorQuantityProducts}
452
+ handleCancelSearch={handleCancel}
453
+ categoriesLayout={categoriesLayout}
454
+ subcategoriesSelected={subcategoriesSelected}
455
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
456
+ setCategoriesLayout={setCategoriesLayout}
457
+ currentCart={currentCart}
458
+ setSubcategoriesSelected={setSubcategoriesSelected}
459
+ onClickCategory={handleChangeCategory}
460
+ handleUpdateProducts={handleUpdateProducts}
461
+ previouslyProducts={business?.previously_products}
462
+ navigation={navigation}
463
+ isFiltMode
464
+ businessSingleId={businessSingleId}
465
+ />
466
+ </View>
467
+ </FiltProductsContainer>
468
+ )}
469
+ {isOpenFiltProducts && (
470
+ <BackgroundGray isIos={Platform.OS === 'ios'} />
471
+ )}
472
+ <IOScrollView
473
+ stickyHeaderIndices={[business?.professionals?.length > 0 ? 4 : 3]}
474
+ style={{
475
+ ...styles.mainContainer,
476
+ marginBottom: currentCart?.products?.length > 0 && categoryState.products.length !== 0 ?
477
+ 50 : 0
478
+ }}
479
+ ref={scrollViewRef}
480
+ onScroll={handlePageScroll}
481
+ onScrollBeginDrag={handleTouchDrag}
482
+ scrollEventThrottle={16}
483
+ bounces={false}
484
+ >
485
+ <BusinessBasicInformation
486
+ navigation={navigation}
487
+ businessState={businessState}
488
+ openBusinessInformation={openBusinessInformation}
489
+ header={header}
490
+ logo={logo}
491
+ isPreOrder={isPreOrder}
492
+ />
493
+ {business?.professionals?.length > 0 && (
494
+ <ProfessionalFilterWrapper>
495
+ <OText
496
+ size={16}
497
+ style={{ marginBottom: 16 }}
498
+ weight={Platform.OS === 'ios' ? '600' : 'bold'}
499
+ >
500
+ {t('PROFESSIONALS', 'Professionals')}
501
+ </OText>
502
+ <ProfessionalFilter
503
+ professionals={business?.professionals}
504
+ professionalSelected={professionalSelected}
505
+ handleChangeProfessionalSelected={handleChangeProfessionalSelected}
506
+ handleUpdateProfessionals={handleUpdateProfessionals}
507
+ />
508
+ </ProfessionalFilterWrapper>
509
+ )}
510
+ <PageBanner position='app_business_page' navigation={navigation} />
511
+ <View
512
+ style={{
513
+ height: 8,
514
+ backgroundColor: theme.colors.backgroundGray100,
515
+ marginTop: isChewLayout && showLogo ? 10 : 0
516
+ }}
517
+ />
518
+ {!loading && business?.id && !(business?.categories?.length === 0) && (
519
+ <BusinessProductsCategories
520
+ categories={[{ id: null, name: t('ALL', 'All') }, { id: 'featured', name: t('FEATURED', 'Featured') }, ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)]}
521
+ categorySelected={categorySelected}
522
+ onClickCategory={handleChangeCategory}
523
+ featured={featuredProducts}
524
+ openBusinessInformation={openBusinessInformation}
525
+ scrollViewRef={scrollViewRef}
526
+ productListLayout={productListLayout}
527
+ categoriesLayout={categoriesLayout}
528
+ selectedCategoryId={selectedCategoryId}
529
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
530
+ setSelectedCategoryId={setSelectedCategoryId}
531
+ setCategoryClicked={setCategoryClicked}
532
+ />
533
+ )}
534
+ {!loading && business?.id && (
535
+ <>
536
+ <WrapContent
537
+ onLayout={(event: any) => setProductListLayout(event.nativeEvent.layout)}
538
+ style={{ paddingHorizontal: isChewLayout ? 20 : 40 }}
539
+ >
540
+ <BusinessProductsList
541
+ categories={[
542
+ { id: null, name: t('ALL', 'All') },
543
+ { id: 'featured', name: t('FEATURED', 'Featured') },
544
+ ...business?.categories.sort((a: any, b: any) => a.rank - b.rank)
545
+ ]}
546
+ category={categorySelected}
547
+ categoryState={categoryState}
548
+ businessId={business.id}
549
+ errors={errors}
550
+ onProductClick={onProductClick}
551
+ handleSearchRedirect={handleSearchRedirect}
552
+ featured={featuredProducts}
553
+ searchValue={searchValue}
554
+ handleClearSearch={handleChangeSearch}
555
+ errorQuantityProducts={errorQuantityProducts}
556
+ handleCancelSearch={handleCancel}
557
+ categoriesLayout={categoriesLayout}
558
+ subcategoriesSelected={subcategoriesSelected}
559
+ lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
560
+ setCategoriesLayout={setCategoriesLayout}
561
+ currentCart={currentCart}
562
+ setSubcategoriesSelected={setSubcategoriesSelected}
563
+ onClickCategory={handleChangeCategory}
564
+ handleUpdateProducts={handleUpdateProducts}
565
+ navigation={navigation}
566
+ previouslyProducts={business?.previously_products}
567
+ businessSingleId={businessSingleId}
568
+ />
569
+ </WrapContent>
570
+ </>
571
+ )}
572
+ {loading && !error && (
573
+ <>
574
+ <BusinessProductsCategories
575
+ categories={[]}
576
+ categorySelected={categorySelected}
577
+ onClickCategory={handleChangeCategory}
578
+ featured={featuredProducts}
579
+ openBusinessInformation={openBusinessInformation}
580
+ loading={loading}
581
+ />
582
+ <WrapContent>
583
+ <BusinessProductsList
584
+ categories={[]}
585
+ category={categorySelected}
586
+ categoryState={categoryState}
587
+ isBusinessLoading={loading}
588
+ errorQuantityProducts={errorQuantityProducts}
589
+ handleUpdateProducts={handleUpdateProducts}
590
+ navigation={navigation}
591
+ />
592
+ </WrapContent>
593
+ </>
594
+ )}
595
+ </IOScrollView>
596
+ {!loading && auth && currentCart?.products?.length > 0 && categoryState.products.length !== 0 && (
597
+ <View style={{ marginBottom: 0 }}>
598
+ <FloatingButton
599
+ btnText={
600
+ openUpselling
601
+ ? t('LOADING', 'Loading')
602
+ : subtotalWithTaxes >= currentCart?.minimum
603
+ ? t('VIEW_ORDER', 'View Order')
604
+ : `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(currentCart?.minimum)}`
605
+ }
606
+ isSecondaryBtn={subtotalWithTaxes < currentCart?.minimum || openUpselling}
607
+ btnLeftValueShow={subtotalWithTaxes >= currentCart?.minimum && currentCart?.products?.length > 0}
608
+ btnRightValueShow={subtotalWithTaxes >= currentCart?.minimum && currentCart?.products?.length > 0}
609
+ btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
610
+ btnRightValue={parsePrice(currentCart?.total)}
611
+ disabled={subtotalWithTaxes < currentCart?.minimum || openUpselling}
612
+ handleClick={() => setOpenUpselling(true)}
613
+ />
614
+ </View>
615
+ )}
616
+ {openUpselling && (
617
+ <UpsellingRedirect
618
+ businessId={currentCart?.business_id}
619
+ business={currentCart?.business}
620
+ cartProducts={currentCart?.products}
621
+ cart={currentCart}
622
+ setOpenUpselling={setOpenUpselling}
623
+ handleUpsellingPage={handleUpsellingPage}
624
+ handleCloseUpsellingPage={handleCloseUpsellingPage}
625
+ openUpselling={openUpselling}
626
+ canOpenUpselling={canOpenUpselling}
627
+ setCanOpenUpselling={setCanOpenUpselling}
628
+ onRedirect={onRedirect}
629
+ />
630
+ )}
631
+ <Alert
632
+ open={alertState?.open || false}
633
+ title=''
634
+ content={[t('NOT_AVAILABLE_PRODUCTS', 'These products are not available.')]}
635
+ onAccept={() => setAlertState({ open: false, content: [] })}
636
+ onClose={() => setAlertState({ open: false, content: [] })}
637
+ />
638
+ </View>
639
+ <OModal
640
+ open={openService}
641
+ onClose={() => setOpenService(false)}
642
+ entireModal
643
+ >
644
+ <ServiceForm
645
+ navigation={navigation}
646
+ product={currentProduct}
647
+ businessSlug={business.slug}
648
+ businessId={business.id}
649
+ professionalList={business?.professionals}
650
+ professionalSelected={professionalSelected}
651
+ handleChangeProfessional={handleChangeProfessionalSelected}
652
+ handleUpdateProfessionals={handleUpdateProfessionals}
653
+ onSave={() => setOpenService(false)}
654
+ onClose={() => setOpenService(false)}
655
+ />
656
+ </OModal>
657
+ </>
658
+ )
538
659
  }
539
660
 
540
661
  export const BusinessProductsListing = (props: BusinessProductsListingParams) => {
541
- const businessProductslistingProps = {
542
- ...props,
543
- isForceSearch: Platform.OS === 'ios',
544
- UIComponent: BusinessProductsListingUI
545
- }
546
- return (
547
- <BusinessAndProductList {...businessProductslistingProps} />
548
- )
662
+ const businessProductslistingProps = {
663
+ ...props,
664
+ isForceSearch: Platform.OS === 'ios',
665
+ UIComponent: BusinessProductsListingUI
666
+ }
667
+ return (
668
+ <BusinessAndProductList {...businessProductslistingProps} />
669
+ )
549
670
  }