ordering-components-external 13.2.32 → 13.2.34

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 (537) hide show
  1. package/.babelrc +22 -22
  2. package/.vscode/settings.json +3 -3
  3. package/_bundles/{7.ordering-component.5e6b244837705c07824f.js → 7.ordering-component.6cdb5ba8147ea6e69b23.js} +1 -1
  4. package/_bundles/{ordering-component.5e6b244837705c07824f.js → ordering-component.6cdb5ba8147ea6e69b23.js} +2 -2
  5. package/_modules/components/AddressDetails/index.js +26 -26
  6. package/_modules/components/AddressForm/index.js +50 -50
  7. package/_modules/components/AddressList/index.js +40 -40
  8. package/_modules/components/Analitycs/index.js +6 -6
  9. package/_modules/components/AnalyticsSegment/index.js +3 -3
  10. package/_modules/components/AppleLogin/index.js +26 -26
  11. package/_modules/components/BaseComponent/index.js +14 -14
  12. package/_modules/components/BusinessAndProductList/index.js +16 -16
  13. package/_modules/components/BusinessBasicInformation/index.js +20 -20
  14. package/_modules/components/BusinessController/index.js +50 -50
  15. package/_modules/components/BusinessInformation/BusinessOption/index.js +20 -20
  16. package/_modules/components/BusinessInformation/index.js +18 -18
  17. package/_modules/components/BusinessList/index.js +42 -42
  18. package/_modules/components/BusinessMenuListing/index.js +20 -20
  19. package/_modules/components/BusinessProductsCategories/index.js +16 -16
  20. package/_modules/components/BusinessProductsSearch/index.js +14 -14
  21. package/_modules/components/BusinessReviews/index.js +27 -27
  22. package/_modules/components/BusinessSearchList/index.js +18 -18
  23. package/_modules/components/BusinessSortControl/index.js +28 -28
  24. package/_modules/components/BusinessTypeFilter/index.js +26 -26
  25. package/_modules/components/BusinessesMap/index.js +27 -27
  26. package/_modules/components/Cart/index.js +38 -38
  27. package/_modules/components/CartStoresListing/index.js +4 -4
  28. package/_modules/components/Checkout/index.js +60 -60
  29. package/_modules/components/CmsContent/index.js +20 -20
  30. package/_modules/components/Contacts/index.js +28 -28
  31. package/_modules/components/CouponControl/index.js +22 -22
  32. package/_modules/components/DriverList/index.js +22 -22
  33. package/_modules/components/DriverTips/index.js +35 -35
  34. package/_modules/components/FacebookLoginButton/index.js +40 -40
  35. package/_modules/components/FacebookPixel/index.js +3 -3
  36. package/_modules/components/FavoriteList/index.js +28 -28
  37. package/_modules/components/FirebaseGoogleLoginButton/index.js +10 -10
  38. package/_modules/components/FloatingButton/index.js +20 -20
  39. package/_modules/components/ForgotPasswordForm/index.js +43 -43
  40. package/_modules/components/GiftCard/GiftCardOrdersList/index.js +4 -4
  41. package/_modules/components/GiftCard/PurchaseGiftCard/index.js +6 -6
  42. package/_modules/components/GiftCard/RedeemGiftCard/index.js +4 -4
  43. package/_modules/components/GiftCard/SendGiftCard/index.js +4 -4
  44. package/_modules/components/GoogleAutocompleteInput/index.js +18 -18
  45. package/_modules/components/GoogleIdentity/index.js +28 -28
  46. package/_modules/components/GoogleLoginButton/index.js +49 -49
  47. package/_modules/components/GoogleMaps/index.js +37 -37
  48. package/_modules/components/GpsButton/index.js +20 -20
  49. package/_modules/components/LanguageSelector/index.js +28 -28
  50. package/_modules/components/LoginForm/index.js +58 -58
  51. package/_modules/components/LogoutAction/index.js +17 -17
  52. package/_modules/components/MainSearch/index.js +31 -31
  53. package/_modules/components/MenuControl/index.js +51 -51
  54. package/_modules/components/Messages/index.js +22 -22
  55. package/_modules/components/MomentOption/index.js +51 -51
  56. package/_modules/components/MultiCartCreate/index.js +2 -2
  57. package/_modules/components/MultiCartsPaymethodsAndWallets/index.js +8 -8
  58. package/_modules/components/MultiCheckout/index.js +12 -12
  59. package/_modules/components/MultiOrdersDetails/index.js +6 -6
  60. package/_modules/components/MyOrders/index.js +24 -24
  61. package/_modules/components/MyOrdersList/index.js +26 -26
  62. package/_modules/components/NewOrderNotification/index.js +2 -2
  63. package/_modules/components/OrderChange/index.js +20 -20
  64. package/_modules/components/OrderDetails/index.js +43 -43
  65. package/_modules/components/OrderList/index.js +44 -44
  66. package/_modules/components/OrderReview/index.js +22 -22
  67. package/_modules/components/OrderTypeControl/index.js +18 -18
  68. package/_modules/components/OrdersControlFilters/index.js +6 -6
  69. package/_modules/components/OrdersDashboardComponents/Appointments/index.js +4 -4
  70. package/_modules/components/OrdersDashboardComponents/BusinessProductsListing/index.js +26 -26
  71. package/_modules/components/OrdersDashboardComponents/CheckPassword/index.js +24 -24
  72. package/_modules/components/OrdersDashboardComponents/CityList/index.js +20 -20
  73. package/_modules/components/OrdersDashboardComponents/CountryList/index.js +20 -20
  74. package/_modules/components/OrdersDashboardComponents/CustomOrderDetails/index.js +12 -12
  75. package/_modules/components/OrdersDashboardComponents/DashboardBusinessList/index.js +54 -54
  76. package/_modules/components/OrdersDashboardComponents/DashboardOrdersList/index.js +60 -60
  77. package/_modules/components/OrdersDashboardComponents/DriversList/index.js +58 -58
  78. package/_modules/components/OrdersDashboardComponents/ExportCSV/index.js +16 -16
  79. package/_modules/components/OrdersDashboardComponents/GiftCardsList/index.js +6 -6
  80. package/_modules/components/OrdersDashboardComponents/GoogleMapsApiKeySetting/index.js +4 -4
  81. package/_modules/components/OrdersDashboardComponents/LogisticInformation/index.js +20 -20
  82. package/_modules/components/OrdersDashboardComponents/Logistics/index.js +20 -20
  83. package/_modules/components/OrdersDashboardComponents/Messages/index.js +27 -27
  84. package/_modules/components/OrdersDashboardComponents/MetaFields/index.js +26 -26
  85. package/_modules/components/OrdersDashboardComponents/OrderDetails/index.js +36 -36
  86. package/_modules/components/OrdersDashboardComponents/OrderNotification/index.js +14 -14
  87. package/_modules/components/OrdersDashboardComponents/OrdersFilter/index.js +62 -62
  88. package/_modules/components/OrdersDashboardComponents/OrdersManage/index.js +56 -56
  89. package/_modules/components/OrdersDashboardComponents/PointsWalletLevels/index.js +25 -25
  90. package/_modules/components/OrdersDashboardComponents/ReviewCustomer/index.js +16 -16
  91. package/_modules/components/OrdersDashboardComponents/Schedule/index.js +46 -46
  92. package/_modules/components/OrdersDashboardComponents/SettingsList/index.js +39 -39
  93. package/_modules/components/OrdersDashboardComponents/UserFormDetails/index.js +66 -66
  94. package/_modules/components/OrdersDashboardComponents/UsersList/index.js +54 -54
  95. package/_modules/components/OrdersDashboardComponents/WebsocketStatus/index.js +4 -4
  96. package/_modules/components/PageBanner/index.js +4 -4
  97. package/_modules/components/PaymentOptionCash/index.js +24 -24
  98. package/_modules/components/PaymentOptionPaypal/index.js +24 -24
  99. package/_modules/components/PaymentOptionSquare/index.js +2 -2
  100. package/_modules/components/PaymentOptionStripe/index.js +32 -32
  101. package/_modules/components/PaymentOptionStripeDirect/index.js +24 -24
  102. package/_modules/components/PaymentOptionStripeLink/index.js +4 -4
  103. package/_modules/components/PaymentOptionStripeRedirect/StripeRedirectForm/index.js +19 -19
  104. package/_modules/components/PaymentOptionStripeRedirect/index.js +30 -30
  105. package/_modules/components/PaymentOptions/index.js +27 -27
  106. package/_modules/components/PaymethodList/index.js +20 -20
  107. package/_modules/components/PhoneAutocomplete/index.js +18 -18
  108. package/_modules/components/PlaceSpot/index.js +2 -2
  109. package/_modules/components/Popup/index.js +33 -33
  110. package/_modules/components/ProductComponent/index.js +27 -27
  111. package/_modules/components/ProductForm/index.js +159 -135
  112. package/_modules/components/ProductImages/index.js +18 -18
  113. package/_modules/components/ProductIngredient/index.js +17 -17
  114. package/_modules/components/ProductItemAccordion/index.js +8 -8
  115. package/_modules/components/ProductOption/index.js +8 -8
  116. package/_modules/components/ProductOptionSuboption/index.js +33 -33
  117. package/_modules/components/ProductShare/index.js +20 -20
  118. package/_modules/components/ProductsList/index.js +20 -20
  119. package/_modules/components/ProductsListing/index.js +39 -39
  120. package/_modules/components/ProfessionalInfo/index.js +24 -24
  121. package/_modules/components/QueryLoginSpoonity/index.js +20 -20
  122. package/_modules/components/ReCaptcha/index.js +4 -4
  123. package/_modules/components/ResetPassword/index.js +20 -20
  124. package/_modules/components/ReviewCustomer/index.js +16 -16
  125. package/_modules/components/ReviewDriver/index.js +20 -20
  126. package/_modules/components/ReviewProduct/index.js +22 -22
  127. package/_modules/components/SearchOptions/index.js +17 -17
  128. package/_modules/components/Sessions/index.js +21 -21
  129. package/_modules/components/SignupForm/index.js +58 -58
  130. package/_modules/components/SingleBusinessCard/index.js +28 -28
  131. package/_modules/components/SingleOrderCard/index.js +20 -20
  132. package/_modules/components/SingleProductCard/index.js +18 -18
  133. package/_modules/components/SingleProfessionalCard/index.js +18 -18
  134. package/_modules/components/SmartAppBanner/index.js +8 -8
  135. package/_modules/components/StoreProductList/index.js +22 -22
  136. package/_modules/components/StripeElementsForm/CardForm/index.js +25 -25
  137. package/_modules/components/StripeElementsForm/index.js +16 -16
  138. package/_modules/components/UpsellingPage/index.js +19 -19
  139. package/_modules/components/UserFormDetails/index.js +68 -68
  140. package/_modules/components/UserVerification/index.js +24 -17
  141. package/_modules/components/WebsocketStatus/index.js +4 -4
  142. package/_modules/components/WrapperGoogleMaps/index.js +3 -3
  143. package/_modules/contexts/ApiContext/index.js +8 -8
  144. package/_modules/contexts/BillingContext/index.js +7 -7
  145. package/_modules/contexts/BusinessContext/index.js +9 -9
  146. package/_modules/contexts/ConfigContext/index.js +9 -9
  147. package/_modules/contexts/EventContext/index.js +9 -9
  148. package/_modules/contexts/LanguageContext/index.js +13 -13
  149. package/_modules/contexts/OptimizationLoadContext/index.js +8 -8
  150. package/_modules/contexts/OrderContext/index.js +62 -62
  151. package/_modules/contexts/OrderingContext/index.js +7 -7
  152. package/_modules/contexts/OrderingThemeContext/index.js +11 -11
  153. package/_modules/contexts/ProductContext/index.js +13 -13
  154. package/_modules/contexts/SessionContext/index.js +9 -9
  155. package/_modules/contexts/SiteContext/index.js +9 -9
  156. package/_modules/contexts/UtilsContext/index.js +9 -9
  157. package/_modules/contexts/WebsocketContext/index.js +9 -9
  158. package/_modules/native/src/contexts/OrderingContext/index.js +7 -7
  159. package/cypress/fixtures/example.json +4 -4
  160. package/cypress/integration/naked/BusinessProductsCategories.spec.js +9 -9
  161. package/cypress/integration/naked/PhoneAutocomplete.spec.js +22 -22
  162. package/cypress/integration/naked/activeOrders.spec.js +15 -15
  163. package/cypress/integration/naked/addressDetails.spec.js +10 -10
  164. package/cypress/integration/naked/appleLogin.spec.js +14 -14
  165. package/cypress/integration/naked/businessBasicInformation.spec.js +14 -14
  166. package/cypress/integration/naked/businessController.spec.js +9 -9
  167. package/cypress/integration/naked/businessInformation.spec.js +19 -19
  168. package/cypress/integration/naked/businessProductsSearch.spec.js +9 -9
  169. package/cypress/integration/naked/businessReviews.spec.js +16 -16
  170. package/cypress/integration/naked/businessSortControl.spec.js +9 -9
  171. package/cypress/integration/naked/businessTypeFilter.spec.js +10 -10
  172. package/cypress/integration/naked/businessesMap.spec.js +13 -13
  173. package/cypress/integration/naked/cms.spec.js +9 -9
  174. package/cypress/integration/naked/config.spec.js +34 -34
  175. package/cypress/integration/naked/driverTips.spec.js +10 -10
  176. package/cypress/integration/naked/events.spec.js +13 -13
  177. package/cypress/integration/naked/facebookLogin.spec.js +13 -13
  178. package/cypress/integration/naked/floatingButton.spec.js +13 -13
  179. package/cypress/integration/naked/forgotPassword.spec.js +20 -20
  180. package/cypress/integration/naked/googleLogin.spec.js +11 -11
  181. package/cypress/integration/naked/languageExamples.spec.js +25 -25
  182. package/cypress/integration/naked/languageSelector.spec.js +10 -10
  183. package/cypress/integration/naked/login.spec.js +38 -38
  184. package/cypress/integration/naked/logout.spec.js +15 -15
  185. package/cypress/integration/naked/mainSearch.spec.js +9 -9
  186. package/cypress/integration/naked/menuControl.spec.js +9 -9
  187. package/cypress/integration/naked/messages.spec.js +25 -25
  188. package/cypress/integration/naked/momentOption.spec.js +10 -10
  189. package/cypress/integration/naked/myOrders.spec.js +11 -11
  190. package/cypress/integration/naked/myOrdersList.spec.js +9 -9
  191. package/cypress/integration/naked/orderContextAdvanced.spec.js +23 -23
  192. package/cypress/integration/naked/orderDetails.spec.js +11 -11
  193. package/cypress/integration/naked/paymentOptionCash.spec.js +21 -21
  194. package/cypress/integration/naked/paymentOptionStripe.spec.js +11 -11
  195. package/cypress/integration/naked/paymentOptionStripeDirect.spec.js +11 -11
  196. package/cypress/integration/naked/paymentOptions.spec.js +9 -9
  197. package/cypress/integration/naked/popupExample.spec.js +17 -17
  198. package/cypress/integration/naked/productImages.spec.js +11 -11
  199. package/cypress/integration/naked/productOptionExample.spec.js +21 -21
  200. package/cypress/integration/naked/productShare.spec.js +9 -9
  201. package/cypress/integration/naked/productsList.spec.js +9 -9
  202. package/cypress/integration/naked/resetPassword.spec.js +11 -11
  203. package/cypress/integration/naked/reviewOrders.spec.js +13 -13
  204. package/cypress/integration/naked/searchOptions.spec.js +18 -18
  205. package/cypress/integration/naked/signup.spec.js +31 -31
  206. package/cypress/integration/naked/upselling.spec.js +13 -13
  207. package/cypress/integration/naked/userDetails.spec.js +12 -12
  208. package/cypress/plugins/index.js +21 -21
  209. package/cypress/support/commands.js +35 -35
  210. package/cypress/support/index.js +20 -20
  211. package/cypress.json +12 -12
  212. package/example/App.js +263 -263
  213. package/example/components/ActiveOrdersUI/index.js +72 -72
  214. package/example/components/AddressDetailsUI/index.js +101 -101
  215. package/example/components/AddressFormUI/index.js +161 -161
  216. package/example/components/AddressListUI/index.js +33 -33
  217. package/example/components/AlertPopup/index.js +10 -10
  218. package/example/components/AlertUI/index.js +49 -49
  219. package/example/components/AlertUI/style.css +5 -5
  220. package/example/components/AppleLoginUI/index.js +40 -40
  221. package/example/components/BaseComponentUI/index.js +34 -34
  222. package/example/components/BusinessBasicInformationUI/index.js +118 -118
  223. package/example/components/BusinessControllerUI/index.js +89 -89
  224. package/example/components/BusinessInformationUI/BusinessOptionUI/index.js +83 -83
  225. package/example/components/BusinessInformationUI/index.js +83 -83
  226. package/example/components/BusinessProductsCategoriesUI/index.js +42 -42
  227. package/example/components/BusinessProductsSearchUI/index.js +38 -38
  228. package/example/components/BusinessReviewsUI/index.js +77 -77
  229. package/example/components/BusinessSortControlUI/index.js +47 -47
  230. package/example/components/BusinessTypeFilterUI/index.js +53 -53
  231. package/example/components/BusinessesMapUI/index.js +57 -57
  232. package/example/components/CartUI/index.js +154 -154
  233. package/example/components/ChangeView/index.js +19 -19
  234. package/example/components/CheckoutUI/index.js +206 -206
  235. package/example/components/CmsContentUI/index.js +52 -52
  236. package/example/components/ConfigsExample/index.js +118 -118
  237. package/example/components/CouponControlUI/index.js +63 -63
  238. package/example/components/DriverTipsUI/index.js +58 -58
  239. package/example/components/FacebookLoginButtonUI/index.js +48 -48
  240. package/example/components/FloatingButtonUI/index.js +145 -145
  241. package/example/components/ForgotPasswordFormUI/index.js +93 -93
  242. package/example/components/GoogleLoginUI/index.js +30 -30
  243. package/example/components/GpsButtonUI/index.js +22 -22
  244. package/example/components/Header/index.js +18 -18
  245. package/example/components/LanguageSelectorUI/index.js +57 -57
  246. package/example/components/LanguagesExample/index.js +51 -51
  247. package/example/components/LoginFormUI/index.js +159 -159
  248. package/example/components/LogoutButtonUI/index.js +21 -21
  249. package/example/components/MainSearchUI/index.js +131 -131
  250. package/example/components/MenuControlUI/index.js +103 -103
  251. package/example/components/MessagesUI/index.js +162 -162
  252. package/example/components/ModalUI/index.js +36 -36
  253. package/example/components/ModalUI/style.css +5 -5
  254. package/example/components/MomentOptionUI/index.js +68 -68
  255. package/example/components/MyOrdersListUI/index.js +51 -51
  256. package/example/components/MyOrdersUI/index.js +52 -52
  257. package/example/components/OrderChangeUI/index.js +54 -54
  258. package/example/components/OrderDetailsUI/index.js +174 -174
  259. package/example/components/OrderReviewUI/index.js +125 -125
  260. package/example/components/OrderTypeControlUI/index.js +32 -32
  261. package/example/components/PaymentOptionCashUI/index.js +60 -60
  262. package/example/components/PaymentOptionPaypalUI/index.js +50 -50
  263. package/example/components/PaymentOptionStripeDirectUI/index.js +89 -89
  264. package/example/components/PaymentOptionStripeRedirectUI/index.js +97 -97
  265. package/example/components/PaymentOptionStripeUI/index.js +129 -129
  266. package/example/components/PaymentOptionsUI/index.js +169 -169
  267. package/example/components/PhoneAutocompleteUI/index.js +67 -67
  268. package/example/components/PhoneAutocompleteUI/styles.css +49 -49
  269. package/example/components/ProductComponentUI/index.js +113 -113
  270. package/example/components/ProductFormUI/index.js +131 -131
  271. package/example/components/ProductImagesUI/index.js +82 -82
  272. package/example/components/ProductIngredientUI/index.js +21 -21
  273. package/example/components/ProductOptionSuboptionUI/index.js +65 -65
  274. package/example/components/ProductOptionUI/index.js +31 -31
  275. package/example/components/ProductShareUI/index.js +48 -48
  276. package/example/components/ProductsListUI/index.js +108 -108
  277. package/example/components/ProductsListingUI/index.js +42 -42
  278. package/example/components/ResetPasswordUI/index.js +121 -121
  279. package/example/components/SearchOptionsUI/index.js +82 -82
  280. package/example/components/SignupFormUI/index.js +117 -117
  281. package/example/components/SingleBusinessCardUI/index.js +82 -82
  282. package/example/components/SingleOrderCardUI/index.js +52 -52
  283. package/example/components/SingleProductCardUI/index.js +47 -47
  284. package/example/components/StripeElementsFormUI/CardFormUI/index.js +51 -51
  285. package/example/components/StripeElementsFormUI/CardFormUI/style.css +118 -118
  286. package/example/components/StripeElementsFormUI/index.js +38 -38
  287. package/example/components/StripeRedirectFormUI/index.js +99 -99
  288. package/example/components/TestComponent/index.js +5 -5
  289. package/example/components/UpsellingPageUI/index.js +26 -26
  290. package/example/components/UserDetailsUI/index.js +94 -94
  291. package/example/components/UserProfileUI/index.js +156 -156
  292. package/example/views/ActiveOrders/index.js +86 -86
  293. package/example/views/AddressDetailsExample/index.js +57 -57
  294. package/example/views/AppleLoginExample/index.js +51 -51
  295. package/example/views/BaseComponentExample/index.js +35 -35
  296. package/example/views/BusinessBasicInformationExample/index.js +43 -43
  297. package/example/views/BusinessControllerExample/index.js +55 -55
  298. package/example/views/BusinessInformationExample/index.js +68 -68
  299. package/example/views/BusinessProductsCategoriesExample/index.js +50 -50
  300. package/example/views/BusinessProductsSearchExample/index.js +39 -39
  301. package/example/views/BusinessReviewsExample/index.js +43 -43
  302. package/example/views/BusinessSortControlExample/index.js +53 -53
  303. package/example/views/BusinessTypeFilterExample/index.js +53 -53
  304. package/example/views/BusinessesMapExample/index.js +57 -57
  305. package/example/views/CheckoutExample/index.js +143 -143
  306. package/example/views/CmsContentExample/index.js +44 -44
  307. package/example/views/DriverTipsExample/index.js +47 -47
  308. package/example/views/EventsExample/index.js +26 -26
  309. package/example/views/FacebookLogin/index.js +63 -63
  310. package/example/views/FloatingButtonExample/index.js +47 -47
  311. package/example/views/ForgotPassword/index.js +77 -77
  312. package/example/views/GoogleLoginExample/index.js +85 -85
  313. package/example/views/Home/index.js +200 -200
  314. package/example/views/LanguageSelectorExample/index.js +55 -55
  315. package/example/views/Login/index.js +84 -84
  316. package/example/views/MainSearchExample/index.js +43 -43
  317. package/example/views/MenuControlExample/index.js +68 -68
  318. package/example/views/MessagesExample/index.js +58 -58
  319. package/example/views/MomentOptionExample/index.js +52 -52
  320. package/example/views/MyOrdersExample/index.js +35 -35
  321. package/example/views/MyOrdersListExample/index.js +50 -50
  322. package/example/views/OrderChangeExample/index.js +46 -46
  323. package/example/views/OrderContextExample/index.js +139 -139
  324. package/example/views/OrderDetailsExample/index.js +50 -50
  325. package/example/views/OrderReviewExample/index.js +64 -64
  326. package/example/views/PaymentOptionCashExample/index.js +51 -51
  327. package/example/views/PaymentOptionPaypalExample/index.js +71 -71
  328. package/example/views/PaymentOptionStripeDirectExample/index.js +43 -43
  329. package/example/views/PaymentOptionStripeExample/index.js +47 -47
  330. package/example/views/PaymentOptionStripeRedirectExample/index.js +56 -56
  331. package/example/views/PaymentOptionsExample/index.js +47 -47
  332. package/example/views/PhoneAutocompleteExample/index.js +34 -34
  333. package/example/views/PlacesExample/index.js +94 -94
  334. package/example/views/PopupExample/index.js +78 -78
  335. package/example/views/PopupExample/style.css +18 -18
  336. package/example/views/ProductDetail/index.js +323 -323
  337. package/example/views/ProductImagesExample/index.js +43 -43
  338. package/example/views/ProductOptionExample/index.js +88 -88
  339. package/example/views/ProductShareExample/index.js +51 -51
  340. package/example/views/ProductsListExample/index.js +77 -77
  341. package/example/views/ProductsListingExample/index.js +47 -47
  342. package/example/views/ResetPasswordExample/index.js +60 -60
  343. package/example/views/SearchOptionsExample/index.js +42 -42
  344. package/example/views/SessionManager/index.js +122 -122
  345. package/example/views/Signup/index.js +64 -64
  346. package/example/views/UpsellingPageExample/index.js +35 -35
  347. package/example/views/UserDetailsExample/index.js +69 -69
  348. package/example/views/UserProfile/index.js +73 -73
  349. package/index-example.js +23 -23
  350. package/index.html +13 -13
  351. package/native/index.js +257 -257
  352. package/native/src/NativeStrategy/index.js +20 -20
  353. package/native/src/contexts/OrderingContext/index.js +85 -85
  354. package/package.json +92 -92
  355. package/src/components/AddressDetails/index.js +149 -149
  356. package/src/components/AddressForm/index.js +380 -380
  357. package/src/components/AddressList/index.js +254 -254
  358. package/src/components/Analitycs/index.js +119 -119
  359. package/src/components/AnalyticsSegment/index.js +145 -145
  360. package/src/components/AppleLogin/index.js +164 -164
  361. package/src/components/BaseComponent/index.js +52 -52
  362. package/src/components/BusinessAndProductList/index.js +1005 -1005
  363. package/src/components/BusinessBasicInformation/index.js +119 -119
  364. package/src/components/BusinessController/index.js +351 -351
  365. package/src/components/BusinessInformation/BusinessOption/index.js +86 -86
  366. package/src/components/BusinessInformation/index.js +93 -93
  367. package/src/components/BusinessList/index.js +670 -670
  368. package/src/components/BusinessMenuListing/index.js +99 -99
  369. package/src/components/BusinessProductsCategories/index.js +60 -60
  370. package/src/components/BusinessProductsSearch/index.js +54 -54
  371. package/src/components/BusinessReviews/index.js +187 -187
  372. package/src/components/BusinessSearchList/index.js +364 -364
  373. package/src/components/BusinessSortControl/index.js +100 -100
  374. package/src/components/BusinessTypeFilter/index.js +142 -142
  375. package/src/components/BusinessesMap/index.js +110 -110
  376. package/src/components/Cart/index.js +211 -211
  377. package/src/components/CartStoresListing/index.js +157 -157
  378. package/src/components/Checkout/index.js +652 -652
  379. package/src/components/CmsContent/index.js +97 -97
  380. package/src/components/Contacts/index.js +512 -512
  381. package/src/components/CouponControl/index.js +171 -171
  382. package/src/components/DragAndDrop/index.js +41 -41
  383. package/src/components/DriverList/index.js +112 -112
  384. package/src/components/DriverTips/index.js +141 -141
  385. package/src/components/Emitter/index.js +36 -36
  386. package/src/components/ExamineClick/index.js +40 -40
  387. package/src/components/FacebookLoginButton/index.js +214 -214
  388. package/src/components/FacebookPixel/index.js +148 -148
  389. package/src/components/FavoriteList/index.js +278 -278
  390. package/src/components/FirebaseGoogleLoginButton/index.js +93 -93
  391. package/src/components/FloatingButton/index.js +70 -70
  392. package/src/components/ForgotPasswordForm/index.js +180 -180
  393. package/src/components/GiftCard/GiftCardOrdersList/index.js +155 -155
  394. package/src/components/GiftCard/PurchaseGiftCard/index.js +127 -127
  395. package/src/components/GiftCard/RedeemGiftCard/index.js +77 -77
  396. package/src/components/GiftCard/SendGiftCard/index.js +83 -83
  397. package/src/components/GoogleAutocompleteInput/index.js +154 -154
  398. package/src/components/GoogleIdentity/index.js +144 -144
  399. package/src/components/GoogleLoginButton/index.js +276 -276
  400. package/src/components/GoogleMaps/index.js +523 -523
  401. package/src/components/GpsButton/index.js +154 -154
  402. package/src/components/LanguageSelector/index.js +163 -163
  403. package/src/components/LoginForm/index.js +531 -531
  404. package/src/components/LogoutAction/index.js +211 -211
  405. package/src/components/MainSearch/index.js +149 -149
  406. package/src/components/MapView/index.js +116 -116
  407. package/src/components/MenuControl/index.js +238 -238
  408. package/src/components/Messages/index.js +166 -166
  409. package/src/components/MomentOption/index.js +322 -322
  410. package/src/components/MultiCartCreate/index.js +70 -70
  411. package/src/components/MultiCartsPaymethodsAndWallets/index.js +201 -201
  412. package/src/components/MultiCheckout/index.js +378 -378
  413. package/src/components/MultiOrdersDetails/index.js +109 -109
  414. package/src/components/MyOrders/index.js +150 -150
  415. package/src/components/MyOrdersList/index.js +104 -104
  416. package/src/components/NewOrderNotification/index.js +30 -30
  417. package/src/components/OrderChange/index.js +128 -128
  418. package/src/components/OrderDetails/index.js +684 -684
  419. package/src/components/OrderList/index.js +814 -814
  420. package/src/components/OrderListGroups/index.js +1256 -1256
  421. package/src/components/OrderReview/index.js +180 -180
  422. package/src/components/OrderTypeControl/index.js +75 -75
  423. package/src/components/OrderVerticalList/index.js +422 -422
  424. package/src/components/OrdersControlFilters/index.js +75 -75
  425. package/src/components/OrdersDashboardComponents/Appointments/index.js +72 -72
  426. package/src/components/OrdersDashboardComponents/BusinessProductsListing/index.js +629 -629
  427. package/src/components/OrdersDashboardComponents/CheckPassword/index.js +177 -177
  428. package/src/components/OrdersDashboardComponents/CityList/index.js +98 -98
  429. package/src/components/OrdersDashboardComponents/CountryList/index.js +162 -162
  430. package/src/components/OrdersDashboardComponents/CustomOrderDetails/index.js +238 -238
  431. package/src/components/OrdersDashboardComponents/DashboardBusinessList/index.js +617 -617
  432. package/src/components/OrdersDashboardComponents/DashboardOrdersList/index.js +943 -943
  433. package/src/components/OrdersDashboardComponents/DriversList/index.js +448 -448
  434. package/src/components/OrdersDashboardComponents/ExportCSV/index.js +192 -192
  435. package/src/components/OrdersDashboardComponents/GiftCardsList/index.js +189 -189
  436. package/src/components/OrdersDashboardComponents/GoogleMapsApiKeySetting/index.js +77 -77
  437. package/src/components/OrdersDashboardComponents/LogisticInformation/index.js +97 -97
  438. package/src/components/OrdersDashboardComponents/Logistics/index.js +174 -174
  439. package/src/components/OrdersDashboardComponents/Messages/index.js +384 -384
  440. package/src/components/OrdersDashboardComponents/MetaFields/index.js +186 -186
  441. package/src/components/OrdersDashboardComponents/OrderDetails/index.js +404 -404
  442. package/src/components/OrdersDashboardComponents/OrderNotification/index.js +70 -70
  443. package/src/components/OrdersDashboardComponents/OrdersFilter/index.js +362 -362
  444. package/src/components/OrdersDashboardComponents/OrdersManage/index.js +873 -873
  445. package/src/components/OrdersDashboardComponents/PointsWalletLevels/index.js +123 -123
  446. package/src/components/OrdersDashboardComponents/ReviewCustomer/index.js +113 -113
  447. package/src/components/OrdersDashboardComponents/Schedule/index.js +315 -315
  448. package/src/components/OrdersDashboardComponents/SettingsList/index.js +298 -298
  449. package/src/components/OrdersDashboardComponents/UserFormDetails/index.js +463 -463
  450. package/src/components/OrdersDashboardComponents/UsersList/index.js +944 -944
  451. package/src/components/OrdersDashboardComponents/WebsocketStatus/index.js +77 -77
  452. package/src/components/OrdersDashboardComponents/index.js +57 -57
  453. package/src/components/PageBanner/index.js +107 -107
  454. package/src/components/PaymentOptionCash/index.js +74 -74
  455. package/src/components/PaymentOptionPaypal/index.js +146 -146
  456. package/src/components/PaymentOptionSquare/index.js +336 -336
  457. package/src/components/PaymentOptionStripe/index.js +289 -289
  458. package/src/components/PaymentOptionStripeDirect/index.js +116 -116
  459. package/src/components/PaymentOptionStripeLink/index.js +101 -101
  460. package/src/components/PaymentOptionStripeRedirect/StripeRedirectForm/index.js +71 -71
  461. package/src/components/PaymentOptionStripeRedirect/index.js +122 -122
  462. package/src/components/PaymentOptionWallet/index.js +185 -185
  463. package/src/components/PaymentOptions/index.js +263 -263
  464. package/src/components/PaymethodList/index.js +119 -119
  465. package/src/components/PhoneAutocomplete/index.js +318 -318
  466. package/src/components/PlaceSpot/index.js +183 -183
  467. package/src/components/Popup/index.js +169 -169
  468. package/src/components/ProductComponent/index.js +269 -269
  469. package/src/components/ProductForm/index.js +1149 -1119
  470. package/src/components/ProductImages/index.js +64 -64
  471. package/src/components/ProductIngredient/index.js +72 -72
  472. package/src/components/ProductItemAccordion/index.js +72 -72
  473. package/src/components/ProductOption/index.js +42 -42
  474. package/src/components/ProductOptionSuboption/index.js +225 -225
  475. package/src/components/ProductShare/index.js +97 -97
  476. package/src/components/ProductsList/index.js +74 -74
  477. package/src/components/ProductsListing/index.js +166 -166
  478. package/src/components/ProfessionalInfo/index.js +156 -156
  479. package/src/components/PromotionsController/index.js +123 -123
  480. package/src/components/QueryLoginSpoonity/index.js +159 -159
  481. package/src/components/ReCaptcha/index.js +53 -53
  482. package/src/components/ResetPassword/index.js +111 -111
  483. package/src/components/ReviewCustomer/index.js +117 -117
  484. package/src/components/ReviewDriver/index.js +157 -157
  485. package/src/components/ReviewProduct/index.js +162 -162
  486. package/src/components/SearchOptions/index.js +69 -69
  487. package/src/components/Sessions/index.js +217 -217
  488. package/src/components/SignupForm/index.js +557 -557
  489. package/src/components/SingleBusinessCard/index.js +80 -80
  490. package/src/components/SingleOrderCard/index.js +160 -160
  491. package/src/components/SingleProductCard/index.js +130 -130
  492. package/src/components/SingleProfessionalCard/index.js +121 -121
  493. package/src/components/SmartAppBanner/index.js +71 -71
  494. package/src/components/StoreProductList/index.js +303 -303
  495. package/src/components/StripeElementsForm/CardForm/index.js +248 -248
  496. package/src/components/StripeElementsForm/index.js +78 -78
  497. package/src/components/UpsellingPage/index.js +156 -156
  498. package/src/components/UserFormDetails/index.js +742 -742
  499. package/src/components/UserVerification/index.js +246 -246
  500. package/src/components/WalletList/index.js +160 -160
  501. package/src/components/WebsocketStatus/index.js +80 -80
  502. package/src/components/WrapperGoogleMaps/index.js +67 -67
  503. package/src/constants/code-numbers.js +219 -219
  504. package/src/constants/timezones.js +427 -427
  505. package/src/contexts/ApiContext/index.js +59 -59
  506. package/src/contexts/BillingContext/index.js +28 -28
  507. package/src/contexts/BusinessContext/index.js +71 -71
  508. package/src/contexts/ConfigContext/index.js +217 -217
  509. package/src/contexts/CustomerContext/index.js +69 -69
  510. package/src/contexts/EventContext/index.js +31 -31
  511. package/src/contexts/LanguageContext/index.js +144 -144
  512. package/src/contexts/OptimizationLoadContext/index.js +95 -95
  513. package/src/contexts/OrderContext/index.js +1450 -1450
  514. package/src/contexts/OrderingContext/index.js +86 -86
  515. package/src/contexts/OrderingThemeContext/index.js +107 -107
  516. package/src/contexts/ProductContext/index.js +62 -62
  517. package/src/contexts/SessionContext/index.js +172 -172
  518. package/src/contexts/SiteContext/index.js +79 -79
  519. package/src/contexts/ToastContext/index.js +42 -42
  520. package/src/contexts/UtilsContext/index.js +343 -343
  521. package/src/contexts/ValidationsFieldsContext/index.js +65 -65
  522. package/src/contexts/WebsocketContext/index.js +95 -95
  523. package/src/contexts/WebsocketContext/socket.js +92 -92
  524. package/src/index.js +373 -373
  525. package/src/utils/index.js +32 -32
  526. package/src/webStrategy/index.js +18 -18
  527. package/webpack.dev.js +41 -41
  528. package/webpack.prod.js +64 -64
  529. /package/_bundles/{0.ordering-component.5e6b244837705c07824f.js → 0.ordering-component.6cdb5ba8147ea6e69b23.js} +0 -0
  530. /package/_bundles/{1.ordering-component.5e6b244837705c07824f.js → 1.ordering-component.6cdb5ba8147ea6e69b23.js} +0 -0
  531. /package/_bundles/{2.ordering-component.5e6b244837705c07824f.js → 2.ordering-component.6cdb5ba8147ea6e69b23.js} +0 -0
  532. /package/_bundles/{4.ordering-component.5e6b244837705c07824f.js → 4.ordering-component.6cdb5ba8147ea6e69b23.js} +0 -0
  533. /package/_bundles/{5.ordering-component.5e6b244837705c07824f.js → 5.ordering-component.6cdb5ba8147ea6e69b23.js} +0 -0
  534. /package/_bundles/{6.ordering-component.5e6b244837705c07824f.js → 6.ordering-component.6cdb5ba8147ea6e69b23.js} +0 -0
  535. /package/_bundles/{7.ordering-component.5e6b244837705c07824f.js.LICENSE.txt → 7.ordering-component.6cdb5ba8147ea6e69b23.js.LICENSE.txt} +0 -0
  536. /package/_bundles/{8.ordering-component.5e6b244837705c07824f.js → 8.ordering-component.6cdb5ba8147ea6e69b23.js} +0 -0
  537. /package/_bundles/{ordering-component.5e6b244837705c07824f.js.LICENSE.txt → ordering-component.6cdb5ba8147ea6e69b23.js.LICENSE.txt} +0 -0
@@ -1,1005 +1,1005 @@
1
- import React, { useEffect, useState } from 'react'
2
- import PropTypes from 'prop-types'
3
- import dayjs from 'dayjs'
4
- import utc from 'dayjs/plugin/utc'
5
- import { useOrder } from '../../contexts/OrderContext'
6
- import { useLanguage } from '../../contexts/LanguageContext'
7
- import { useConfig } from '../../contexts/ConfigContext'
8
- import { useToast, ToastType } from '../../contexts/ToastContext'
9
- import { useCustomer } from '../../contexts/CustomerContext'
10
- dayjs.extend(utc)
11
-
12
- export const BusinessAndProductList = (props) => {
13
- const {
14
- isSearchByName,
15
- isSearchByDescription,
16
- slug,
17
- categoryId,
18
- productId,
19
- isInitialRender,
20
- ordering,
21
- businessProps,
22
- menusProps,
23
- isGetMenus,
24
- UIComponent,
25
- location,
26
- avoidProductDuplicate,
27
- isApp,
28
- isFetchAllProducts,
29
- isCustomerMode
30
- } = props
31
-
32
- const [orderState, { removeProduct }] = useOrder()
33
- const [alertState, setAlertState] = useState({ open: false, content: [] })
34
- const [{ configs }] = useConfig()
35
- const [, { showToast }] = useToast()
36
- const [languageState, t] = useLanguage()
37
- const [customerState] = useCustomer()
38
- const [categorySelected, setCategorySelected] = useState({ id: null, name: t('ALL', 'All') })
39
- const [searchValue, setSearchValue] = useState(null)
40
- const [sortByValue, setSortByValue] = useState(null)
41
- const [filterByMenus, setFilterByMenus] = useState(null)
42
- const [professionalSelected, setProfessionalSelected] = useState(null)
43
- const [businessState, setBusinessState] = useState({ business: {}, menus: null, loading: !props.avoidBusinessLoading, error: null })
44
- const [loadedFirstTime, setLoadedFirstTime] = useState(false)
45
- const [categoriesState, setCategoriesState] = useState({})
46
- const [orderOptions, setOrderOptions] = useState({})
47
- const [productModal, setProductModal] = useState({ product: null, loading: false, error: null })
48
- const [notFound, setNotFound] = useState(false)
49
- const [featuredProducts, setFeaturedProducts] = useState(false)
50
- const [openCategories, setOpenCategories] = useState({ values: [] })
51
- const [priceFilterValues, setPriceFilterValues] = useState({ min: null, max: null })
52
- const requestsState = {}
53
-
54
- const categoryStateDefault = {
55
- loading: true,
56
- pagination: { currentPage: 0, pageSize: isApp ? 5 : 20, totalItems: null, totalPages: 0, nextPageItems: 10 },
57
- products: []
58
- }
59
-
60
- let [categoryState, setCategoryState] = useState(categoryStateDefault)
61
- const [errors, setErrors] = useState(null)
62
- const [errorQuantityProducts, setErrorQuantityProducts] = useState(false)
63
-
64
- const categoryKey = searchValue
65
- ? 'search'
66
- : categorySelected.id === 'featured'
67
- ? 'featured'
68
- : categorySelected.id
69
- ? `categoryId:${categorySelected.id}`
70
- : 'all'
71
-
72
- const isUseParentCategory = configs?.use_parent_category?.value === 'true' ||
73
- configs?.use_parent_category?.value === '1'
74
-
75
- /**
76
- * Change category selected
77
- * @param {Object} category Category object
78
- */
79
- const handleChangeCategory = (category) => {
80
- if (category?.subcategories?.length) {
81
- if (!category?.parent_category_id && !openCategories.values.includes(category.id)) {
82
- openCategories.values = []
83
- }
84
- if (openCategories.values.includes(category.id)) {
85
- openCategories.values = openCategories.values.filter(categoryId => categoryId !== category.id)
86
- } else {
87
- openCategories.values.push(category.id)
88
- }
89
- setOpenCategories({
90
- ...openCategories,
91
- values: openCategories.values
92
- })
93
- }
94
- if (category?.id === null) {
95
- setOpenCategories({ ...openCategories, values: [] })
96
- }
97
- setCategorySelected(category)
98
- }
99
-
100
- const handleChangeSearch = (search) => {
101
- setSearchValue(search)
102
- }
103
-
104
- const handleChangeSortBy = (val) => {
105
- setSortByValue(val)
106
- }
107
-
108
- const handleChangeFilterByMenus = (val) => {
109
- setFilterByMenus(val)
110
- }
111
-
112
- const handleChangePriceFilterValues = (name, value) => {
113
- setPriceFilterValues({
114
- ...priceFilterValues,
115
- [name]: value
116
- })
117
- }
118
-
119
- const isMatchSearch = (name, description, price) => {
120
- if (!searchValue && !priceFilterValues?.min && !priceFilterValues?.max) return true
121
- return (
122
- ((searchValue
123
- ? (name && (name.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').includes(searchValue.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) && isSearchByName)) : true) &&
124
- (priceFilterValues?.min ? parseFloat(price) >= parseFloat(priceFilterValues?.min) : true) &&
125
- (priceFilterValues?.max ? parseFloat(price) <= parseFloat(priceFilterValues?.max) : true))
126
- ) ||
127
- (
128
- ((searchValue
129
- ? (description && (description.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').includes(searchValue.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) && isSearchByDescription)) : true) &&
130
- (priceFilterValues?.min ? parseFloat(price) >= parseFloat(priceFilterValues?.min) : true) &&
131
- (priceFilterValues?.max ? parseFloat(price) <= parseFloat(priceFilterValues?.max) : true)))
132
- }
133
-
134
- const isValidMoment = (date, format) => dayjs.utc(date, format).format(format) === date
135
-
136
- const isFeaturedSearch = (product) => {
137
- if (product.featured) {
138
- if (!searchValue) return true
139
- return (
140
- product.name && (product.name.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
141
- .includes(searchValue.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) && isSearchByName)
142
- ) ||
143
- (
144
- product.description && (product.description.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
145
- .includes(searchValue.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) && isSearchByDescription)
146
- )
147
- }
148
- return false
149
- }
150
-
151
- const sortProductsArray = (option, array) => {
152
- let _array
153
- if (option === 'rank' || option === null) {
154
- _array = array.sort((a, b) => a.rank - b.rank)
155
- }
156
- if (option === 'rank_desc') {
157
- _array = array.sort((a, b) => b.rank - a.rank)
158
- }
159
- if (option === 'a-z') {
160
- _array = array.sort((a, b) =>
161
- (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0)
162
- )
163
- }
164
- setCategoryState({ ...categoryState, products: _array })
165
- }
166
-
167
- const subCategoriesList = []
168
-
169
- const iterateCategories = (categories) => {
170
- return (
171
- categories?.length > 0 && categories?.forEach(category => {
172
- subCategoriesList.push(category)
173
- iterateCategories(category.subcategories)
174
- })
175
- )
176
- }
177
-
178
- /**
179
- * Method to change professional
180
- * @param {object} professional a professional info
181
- */
182
- const handleChangeProfessionalSelected = (professional) => {
183
- setProfessionalSelected(professional)
184
- }
185
-
186
- const handleUpdateProducts = (productId, changes) => {
187
- const updatedProducts = categoryState?.products.map(product => {
188
- if (product?.id === productId) {
189
- return {
190
- ...product,
191
- ...changes
192
- }
193
- }
194
- return product
195
- })
196
- setCategoryState({
197
- ...categoryState,
198
- products: updatedProducts
199
- })
200
- if (categoriesState?.featured?.products) {
201
- const updatedFeaturedProducts = categoriesState?.featured?.products.map(product => {
202
- if (product?.id === productId) {
203
- return {
204
- ...product,
205
- ...changes
206
- }
207
- }
208
- return product
209
- })
210
- setCategoriesState({
211
- ...categoriesState,
212
- featured: {
213
- ...categoriesState.featured,
214
- products: updatedFeaturedProducts
215
- }
216
- })
217
- }
218
- const updatedCategories = businessState?.business?.categories?.map(_category => {
219
- const updatedProducts = _category?.products.map(_product => {
220
- if (_product?.id === productId) {
221
- return {
222
- ..._product,
223
- ...changes
224
- }
225
- }
226
- return _product
227
- })
228
- return {
229
- ..._category,
230
- products: updatedProducts
231
- }
232
- })
233
- setBusinessState({
234
- ...businessState,
235
- business: {
236
- ...businessState?.business,
237
- categories: updatedCategories
238
- }
239
- })
240
- }
241
-
242
- const getProducts = async () => {
243
- for (let i = 0; i < businessState?.business?.categories?.length ?? 0; i++) {
244
- const category = businessState?.business?.categories[i]
245
- const isFeatured = category?.products?.some((product) => product.featured)
246
- if (isFeatured) {
247
- setFeaturedProducts(isFeatured)
248
- break
249
- }
250
- }
251
- const categoryState = {
252
- ...categoryStateDefault,
253
- loading: false
254
- }
255
- if (categorySelected.id !== 'featured' && categorySelected.id !== null) {
256
- iterateCategories(businessState?.business?.categories)
257
- const categoriesList = [].concat(...businessState?.business?.categories.map(category => category.children))
258
- const categories = isUseParentCategory ? categoriesList : businessState?.business?.categories
259
- const parentCategory = categories?.find(category => category.category_id === categorySelected.id) ?? {}
260
- const categoryFinded = subCategoriesList.find(subCat => subCat.id === parentCategory.category_id) ?? {}
261
-
262
- const productsFiltered = businessState?.business?.categories
263
- ?.find(category => category.id === (isUseParentCategory ? parentCategory?.parent_category_id : categorySelected.id))
264
- ?.products
265
- .filter(product => isUseParentCategory
266
- ? (categoryFinded?.children?.some(cat => cat.category_id === product?.category_id) && isMatchSearch(product.name, product.description, product?.price))
267
- : isMatchSearch(product.name, product.description, product?.price))
268
-
269
- categoryState.products = productsFiltered || []
270
- } else if (categorySelected.id === 'featured') {
271
- const productsFiltered = businessState?.business?.categories?.reduce(
272
- (products, category) => [
273
- ...products,
274
- ...category.products.map(product => ({
275
- ...product,
276
- ...(category.slug ? { category: { ...product?.category, slug: category.slug } } : {})
277
- }))
278
- ], []
279
- ).filter(
280
- product => isFeaturedSearch(product)
281
- )
282
- categoryState.products = productsFiltered || []
283
- } else {
284
- let _categoriesCustom = null
285
- if (avoidProductDuplicate) {
286
- const customCategories = ['favorites']
287
- _categoriesCustom = businessState?.business?.categories?.filter(({ id }) => (!customCategories.includes(id)))
288
- }
289
-
290
- const productsToFilter = avoidProductDuplicate ? _categoriesCustom : businessState?.business?.categories
291
- const productsFiltered = productsToFilter?.reduce(
292
- (products, category) => [
293
- ...products,
294
- ...category.products.map(product => ({
295
- ...product,
296
- ...(category.slug ? { category: { ...product?.category, slug: category.slug } } : {})
297
- }))
298
- ], []
299
- ).filter(
300
- product => isMatchSearch(product.name, product.description, product?.price)
301
- )
302
- categoryState.products = productsFiltered || []
303
- }
304
- setErrorQuantityProducts(!categoryState.products?.length)
305
- setCategoryState({ ...categoryState })
306
- }
307
-
308
- const getLazyProducts = async ({ page, pageSize = categoryStateDefault.pagination.pageSize }) => {
309
- const parameters = {
310
- version: 'v2',
311
- type: orderState.options?.type ?? 1,
312
- ...(!isFetchAllProducts && { page }),
313
- ...(!isFetchAllProducts && { page_size: pageSize }),
314
- ...(!isFetchAllProducts && { orderBy: 'rank' })
315
- }
316
-
317
- if (orderState.options?.moment && isValidMoment(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss')) {
318
- const moment = dayjs.utc(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss').local().unix()
319
- parameters.timestamp = moment
320
- }
321
-
322
- if (sortByValue) {
323
- parameters.orderBy = sortByValue === 'a-z' ? 'name' : sortByValue
324
- }
325
-
326
- let where = null
327
- const searchConditions = []
328
- if (searchValue) {
329
- if (isSearchByName) {
330
- searchConditions.push(
331
- {
332
- attribute: 'name',
333
- value: {
334
- condition: 'ilike',
335
- value: props?.isForceSearch ? `%${searchValue}%` : encodeURI(`%${searchValue}%`)
336
- }
337
- }
338
- )
339
- }
340
- if (isSearchByDescription) {
341
- searchConditions.push(
342
- {
343
- attribute: 'description',
344
- value: {
345
- condition: 'ilike',
346
- value: props?.isForceSearch ? `%${searchValue}%` : encodeURI(`%${searchValue}%`)
347
- }
348
- }
349
- )
350
- }
351
- }
352
-
353
- if (priceFilterValues?.min) {
354
- searchConditions.push(
355
- {
356
- attribute: 'price',
357
- value: {
358
- condition: '>=',
359
- value: encodeURI(priceFilterValues?.min)
360
- }
361
- }
362
- )
363
- }
364
-
365
- if (priceFilterValues?.max) {
366
- searchConditions.push(
367
- {
368
- attribute: 'price',
369
- value: {
370
- condition: '<=',
371
- value: encodeURI(priceFilterValues?.max)
372
- }
373
- }
374
- )
375
- }
376
-
377
- where = {
378
- conditions: searchConditions,
379
- conector: 'OR'
380
- }
381
-
382
- if (categorySelected.id === 'featured') {
383
- parameters.params = 'features'
384
- }
385
-
386
- if (categorySelected.id === 'featured' && searchValue) {
387
- parameters.params = 'features'
388
- where = {
389
- conditions: [
390
- {
391
- conditions: searchConditions,
392
- conector: 'OR'
393
- }
394
- ],
395
- conector: 'AND'
396
- }
397
- }
398
-
399
- const source = {}
400
- requestsState.products = source
401
- const promises = []
402
-
403
- const functionFetch = categorySelected.id && categorySelected.id !== 'featured'
404
- ? ordering.businesses(businessState.business.id).categories(categorySelected.id).products()
405
- : where?.conditions?.length === 0 ? ordering.businesses(businessState.business.id).categories() : ordering.businesses(businessState.business.id).products()
406
-
407
- let productEndpoint = where?.conditions?.length > 0
408
- ? functionFetch.parameters(parameters).where(where)
409
- : functionFetch.parameters(parameters)
410
-
411
- promises.push(await productEndpoint.get({ cancelToken: source }))
412
-
413
- if (isUseParentCategory && (!categorySelected.id || categorySelected.id === 'featured')) {
414
- parameters.params = 'features'
415
- productEndpoint = where?.conditions?.length > 0
416
- ? ordering.businesses(businessState.business.id).products().parameters(parameters).where(where)
417
- : ordering.businesses(businessState.business.id).products().parameters(parameters)
418
-
419
- promises.push(await productEndpoint.get({ cancelToken: source }))
420
- }
421
-
422
- return promises
423
- }
424
-
425
- const loadProducts = async ({ newFetch } = {}) => {
426
- setErrors(null)
427
- const curCategoryState = categoriesState[categoryKey] ?? categoryStateDefault
428
- if (
429
- !newFetch &&
430
- ((curCategoryState.pagination.currentPage > 0 &&
431
- curCategoryState.pagination.currentPage === curCategoryState.pagination.totalPages) ||
432
- (curCategoryState?.products?.length > 0 && curCategoryState.pagination.totalPages > 0))
433
- ) {
434
- setCategoryState({ ...curCategoryState, loading: false })
435
- return
436
- }
437
-
438
- const isLazy = !!businessState?.business?.lazy_load_products_recommended
439
-
440
- if (!isLazy) {
441
- getProducts()
442
- return
443
- }
444
-
445
- const pageSize = categoryStateDefault.pagination.pageSize
446
-
447
- try {
448
- setCategoryState({ ...curCategoryState, loading: true })
449
- const [lazyRes, featuredRes] = await getLazyProducts({ page: 1, pageSize })
450
-
451
- const { content } = lazyRes
452
- const error = content?.error
453
- const result = content?.result
454
- const pagination = content?.pagination
455
-
456
- const errorsList = []
457
-
458
- if (error) {
459
- errorsList.push(result[0])
460
- }
461
- if (featuredRes?.content?.error) {
462
- errorsList.push(featuredRes?.content?.result[0])
463
- }
464
- if (errorsList?.length) {
465
- setErrors(errorsList[0])
466
- setCategoryState({ ...curCategoryState, loading: false })
467
- return
468
- }
469
-
470
- if (featuredRes?.content?.result?.length) {
471
- const oldFeatured = categoriesState?.featured
472
- const featureState = {
473
- pagination: {
474
- ...oldFeatured?.pagination,
475
- currentPage: featuredRes?.content?.pagination?.current_page,
476
- totalItems: featuredRes?.content?.pagination?.total,
477
- totalPages: featuredRes?.content?.pagination?.total_pages
478
- },
479
- loading: false,
480
- products: newFetch
481
- ? [...featuredRes?.content?.result]
482
- : oldFeatured?.products?.concat(featuredRes?.content?.result)
483
- }
484
- setErrorQuantityProducts(!featureState.products?.length)
485
- categoriesState.featured = featureState
486
- }
487
-
488
- if (categorySelected.id && categorySelected.id !== 'featured') {
489
- const newcategoryState = {
490
- pagination: {
491
- ...curCategoryState.pagination,
492
- currentPage: pagination.current_page,
493
- totalItems: pagination.total,
494
- totalPages: pagination.total_pages
495
- },
496
- loading: false,
497
- products: result
498
- }
499
- setErrorQuantityProducts(!newcategoryState.products?.length)
500
- categoriesState[categoryKey] = newcategoryState
501
- categoryState = newcategoryState
502
- setCategoryState({ ...newcategoryState })
503
- setCategoriesState({ ...categoriesState })
504
-
505
- const isFeatured = categoriesState.all.products.some(product => product.featured) ||
506
- categoriesState?.featured?.products?.some(product => product.featured)
507
- setFeaturedProducts(isFeatured)
508
- }
509
-
510
- if (!(categorySelected.id && categorySelected.id !== 'featured')) {
511
- const productsList = searchValue
512
- ? [...result]
513
- : [].concat(...result.map(category =>
514
- category?.products?.map(product => ({
515
- ...product,
516
- ...(category?.slug ? { category: { ...product.category, slug: category.slug } } : {})
517
- }))
518
- )).filter(item => item)
519
- const productsListFeatured = featuredRes?.content?.result ?? []
520
- const paginationData = categorySelected.id === 'featured'
521
- ? categoriesState?.featured?.pagination ?? {}
522
- : curCategoryState?.pagination ?? {}
523
- const newcategoryState = {
524
- pagination: {
525
- ...paginationData,
526
- currentPage: categorySelected.id === 'featured'
527
- ? featuredRes?.content?.pagination?.current_page
528
- : pagination?.current_page,
529
- totalItems: categorySelected.id === 'featured'
530
- ? featuredRes?.content?.pagination?.total
531
- : pagination?.total,
532
- totalPages: categorySelected.id === 'featured'
533
- ? featuredRes?.content?.pagination?.total_pages
534
- : pagination?.total_pages
535
- },
536
- loading: false,
537
- products: categorySelected.id === 'featured'
538
- ? productsListFeatured
539
- : searchValue
540
- ? [...productsListFeatured, ...productsList].filter((product, i, _hash) => _hash.findIndex(_product => _product?.id === product?.id) === i)
541
- : [...productsListFeatured, ...curCategoryState.products.concat(productsList)]
542
- }
543
-
544
- categoriesState[categoryKey] = newcategoryState
545
- setCategoryState({ ...newcategoryState })
546
- setCategoriesState({ ...categoriesState })
547
-
548
- const isFeatured = categoriesState.all.products.some(product => product.featured) ||
549
- categoriesState?.featured?.products?.some(product => product.featured)
550
- setFeaturedProducts(isFeatured)
551
- }
552
- } catch (err) {
553
- if (err?.constructor?.name !== 'Cancel') {
554
- setErrors([err?.message ?? 'ERROR'])
555
- setCategoryState({ ...curCategoryState, loading: false })
556
- }
557
- }
558
- }
559
-
560
- const loadMoreProducts = async () => {
561
- setErrors(null)
562
- const curCategoryState = categoriesState[categoryKey] ?? categoryStateDefault
563
- setCategoryState({ ...curCategoryState, loading: true })
564
-
565
- try {
566
- const [lazyRes, featuredRes] = await getLazyProducts({
567
- page: curCategoryState.pagination.currentPage + 1
568
- })
569
- const { content } = lazyRes
570
- const error = content?.error
571
- const result = content?.result
572
- const pagination = content?.pagination
573
-
574
- const errorsList = []
575
-
576
- if (error) {
577
- errorsList.push(result[0])
578
- }
579
- if (featuredRes?.content?.error) {
580
- errorsList.push(featuredRes?.content?.result[0])
581
- }
582
- if (errorsList?.length) {
583
- setErrors(errorsList[0])
584
- setCategoryState({ ...curCategoryState, loading: false })
585
- return
586
- }
587
-
588
- if (featuredRes) {
589
- const oldFeatured = categoriesState?.featured
590
- const featureState = {
591
- pagination: {
592
- ...oldFeatured?.pagination,
593
- currentPage: featuredRes?.content?.pagination?.current_page,
594
- totalItems: featuredRes?.content?.pagination?.total,
595
- totalPages: featuredRes?.content?.pagination?.total_pages
596
- },
597
- loading: false,
598
- products: [...(oldFeatured?.products ?? []), ...(featuredRes?.content?.result ?? [])]
599
- }
600
- categoriesState.featured = featureState
601
- }
602
-
603
- if ((categorySelected.id && categorySelected.id !== 'featured')) {
604
- const newcategoryState = {
605
- pagination: {
606
- ...curCategoryState?.pagination,
607
- currentPage: pagination?.current_page,
608
- totalItems: pagination?.total,
609
- totalPages: pagination?.total_pages
610
- },
611
- loading: false,
612
- products: [...(curCategoryState?.products ?? []), ...result]
613
- }
614
-
615
- categoriesState[categoryKey] = newcategoryState
616
- categoryState = { ...categoryState, ...newcategoryState }
617
- setCategoryState({ ...categoryState, ...newcategoryState })
618
- setCategoriesState({ ...categoriesState })
619
-
620
- const isFeatured = categoriesState?.all?.products?.some(product => product.featured) ||
621
- categoriesState?.featured?.products?.some(product => product.featured)
622
- setFeaturedProducts(isFeatured)
623
- }
624
-
625
- if (!(categorySelected.id && categorySelected.id !== 'featured')) {
626
- const productsList = [].concat(...result.map(category => category?.products)).filter(item => item)
627
- const productsListFeatured = featuredRes?.content?.result ?? []
628
- const paginationData = categorySelected.id === 'featured'
629
- ? categoriesState?.featured?.pagination ?? {}
630
- : curCategoryState?.pagination ?? {}
631
- const newcategoryState = {
632
- pagination: {
633
- ...paginationData,
634
- currentPage: categorySelected.id === 'featured'
635
- ? featuredRes?.content?.pagination?.current_page
636
- : pagination?.current_page,
637
- totalItems: categorySelected.id === 'featured'
638
- ? featuredRes?.content?.pagination?.total
639
- : pagination?.total,
640
- totalPages: categorySelected.id === 'featured'
641
- ? featuredRes?.content?.pagination?.total_pages
642
- : pagination?.total_pages
643
- },
644
- loading: false,
645
- products: categorySelected.id === 'featured'
646
- ? productsListFeatured
647
- : [...productsListFeatured, ...(curCategoryState?.products?.concat(productsList) ?? [])]
648
- }
649
-
650
- categoriesState[categoryKey] = newcategoryState
651
- categoryState = newcategoryState
652
- setCategoryState({ ...newcategoryState })
653
- setCategoriesState({ ...categoriesState })
654
-
655
- const isFeatured = categoriesState?.all?.products?.some(product => product.featured) ||
656
- categoriesState?.featured?.products?.some(product => product.featured)
657
- setFeaturedProducts(isFeatured)
658
- }
659
-
660
- setCategoryState({ ...categoryState, loading: false })
661
- } catch (err) {
662
- if (err?.constructor?.name !== 'Cancel') {
663
- setErrors([err?.message ?? 'ERROR'])
664
- setCategoryState({ ...curCategoryState, loading: false })
665
- }
666
- }
667
- }
668
-
669
- const getProduct = async () => {
670
- if ((categoryId && productId && businessState.business.id) || (props.product?.businessId && props.product?.categoryId && props.product?.id)) {
671
- try {
672
- setProductModal({
673
- ...productModal,
674
- loading: true
675
- })
676
- const source = {}
677
- requestsState.product = source
678
- const parameters = {
679
- type: orderState.options?.type || 1,
680
- moment: orderState.options?.moment || null,
681
- version: 'v2'
682
- }
683
-
684
- if (orderState.options?.moment && isValidMoment(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss')) {
685
- const moment = dayjs.utc(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss').local().unix()
686
- parameters.timestamp = moment
687
- }
688
- const { content: { result } } = await ordering
689
- .businesses(businessState.business.id || props.product?.businessId)
690
- .categories(categoryId || props.product?.categoryId)
691
- .products(productId || props.product?.id)
692
- .parameters(parameters)
693
- .get({ cancelToken: source })
694
- const product = Array.isArray(result) ? null : result
695
-
696
- setNotFound(!result)
697
- setProductModal({
698
- ...productModal,
699
- product,
700
- loading: false
701
- })
702
- } catch (e) {
703
- setProductModal({
704
- ...productModal,
705
- loading: false,
706
- error: [e]
707
- })
708
- }
709
- }
710
- }
711
-
712
- useEffect(() => {
713
- if (isInitialRender) {
714
- getProduct()
715
- }
716
- }, [JSON.stringify(businessState.business?.id), isInitialRender])
717
-
718
- const getBusiness = async () => {
719
- try {
720
- setBusinessState({ ...businessState, loading: true })
721
- const source = {}
722
- requestsState.business = source
723
- const parameters = {
724
- version: 'v2',
725
- type: orderState.options?.type || 1,
726
- location: location
727
- ? `${location?.lat},${location?.lng}`
728
- : orderState.options?.address?.location
729
- ? `${orderState.options?.address?.location?.lat},${orderState.options?.address?.location?.lng}`
730
- : null
731
- }
732
- if (orderState.options?.moment && isValidMoment(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss')) {
733
- const moment = dayjs.utc(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss').local().unix()
734
- parameters.timestamp = moment
735
- }
736
-
737
- if (filterByMenus) {
738
- parameters.menu_id = filterByMenus
739
- }
740
-
741
- if (professionalSelected) {
742
- parameters.professional_id = professionalSelected?.id
743
- }
744
-
745
- if (isCustomerMode && customerState?.user?.id) {
746
- parameters.user_id = customerState?.user?.id
747
- }
748
-
749
- const { content: { result } } = await ordering.businesses(slug).select(businessProps).parameters(parameters).get({ cancelToken: source })
750
-
751
- setErrorQuantityProducts(!result?.categories || result?.categories?.length === 0)
752
-
753
- const data = {
754
- ...businessState,
755
- business: result,
756
- loading: false
757
- }
758
-
759
- if (menusProps && isGetMenus) {
760
- const { content: { result: menus } } = await ordering
761
- .businesses(result.id)
762
- .menus()
763
- .select(menusProps)
764
- .get()
765
-
766
- data.menus = menus
767
- }
768
-
769
- setBusinessState(data)
770
- setLoadedFirstTime(true)
771
- } catch (err) {
772
- setBusinessState({
773
- ...businessState,
774
- loading: false,
775
- error: [err.message]
776
- })
777
- setLoadedFirstTime(true)
778
- }
779
- }
780
-
781
- const multiRemoveProducts = async (unavailableProducts, carts) => {
782
- const allPromise = []
783
- unavailableProducts.forEach(product => {
784
- allPromise.push(new Promise((resolve, reject) => {
785
- resolve(removeProduct(product, carts))
786
- }))
787
- })
788
- await Promise.all(allPromise) && setAlertState({ open: true, content: [t('NOT_AVAILABLE_PRODUCTS', 'These products are not available.')] })
789
- }
790
-
791
- const handleUpdateProfessionals = (selectedProfessional) => {
792
- const professionals = businessState?.business?.professionals.map(professional => {
793
- if (selectedProfessional?.id === professional?.id) {
794
- return {
795
- ...professional,
796
- ...selectedProfessional
797
- }
798
- }
799
- return professional
800
- })
801
- setBusinessState({ ...businessState, business: { ...businessState?.business, professionals } })
802
- }
803
-
804
- const updateCategories = (categories, result) => {
805
- return categories.map((category) => {
806
- if (category.id === result.id) {
807
- return {
808
- ...category,
809
- ...result
810
- }
811
- }
812
- if (Array.isArray(category?.subcategories) && category.subcategories.length > 0) {
813
- return {
814
- ...category,
815
- subcategories: updateCategories(category.subcategories, result)
816
- }
817
- }
818
- return category
819
- })
820
- }
821
-
822
- const updateStoreProduct = async (categoryId, productId, updateParams = {}) => {
823
- try {
824
- const { content: { result, error } } = await ordering.businesses(businessState?.business?.id).categories(categoryId).products(productId).save(updateParams)
825
-
826
- if (!error) {
827
- const updatedProducts = categoryState.products.map(product => {
828
- if (product.id === result.id) {
829
- return {
830
- ...product,
831
- ...result
832
- }
833
- }
834
- return product
835
- })
836
- setCategoryState({ ...categoryState, products: updatedProducts })
837
- showToast(ToastType.Success, result?.enabled
838
- ? t('ENABLED_PRODUCT', 'Enabled product')
839
- : t('DISABLED_PRODUCT', 'Disabled product'))
840
- } else {
841
- showToast(ToastType.Error, result)
842
- }
843
- } catch (err) {
844
- showToast(ToastType.Error, err.message)
845
- }
846
- }
847
-
848
- const updateStoreCategory = async (categoryId, updateParams = {}) => {
849
- try {
850
- const { content: { result, error } } = await ordering.businesses(businessState?.business?.id).categories(categoryId).save(updateParams)
851
-
852
- if (!error) {
853
- const updatedCategories = updateCategories(businessState?.business.categories, result)
854
- const updatedBusiness = { ...businessState?.business, categories: updatedCategories }
855
- setBusinessState({ ...businessState, business: updatedBusiness })
856
- showToast(ToastType.Success, result?.enabled
857
- ? t('ENABLED_CATEGORY', 'Enabled category')
858
- : t('DISABLED_CATEGORY', 'Disabled category'))
859
- } else {
860
- showToast(ToastType.Error, result)
861
- }
862
- } catch (err) {
863
- showToast(ToastType.Error, err.message)
864
- }
865
- }
866
-
867
- useEffect(() => {
868
- if (!businessState.loading) {
869
- loadProducts({ newFetch: true })
870
- }
871
- }, [businessState.loading])
872
-
873
- useEffect(() => {
874
- loadProducts({ newFetch: !!searchValue })
875
- }, [searchValue])
876
-
877
- useEffect(() => {
878
- loadProducts({ newFetch: !!searchValue })
879
- }, [categorySelected.id])
880
-
881
- useEffect(() => {
882
- loadProducts({ newFetch: !!searchValue })
883
- sortProductsArray(sortByValue, categoryState?.products)
884
- }, [sortByValue])
885
-
886
- useEffect(() => {
887
- loadProducts()
888
- }, [slug])
889
-
890
- useEffect(() => {
891
- loadProducts({ newFetch: true })
892
- }, [priceFilterValues])
893
-
894
- useEffect(() => {
895
- if (!orderState.loading && Object.keys(orderOptions || {})?.length > 0 && !languageState.loading && !props.avoidBusinessLoading) {
896
- getBusiness()
897
- }
898
- }, [JSON.stringify(orderOptions), languageState.loading, slug, filterByMenus, professionalSelected])
899
-
900
- useEffect(() => {
901
- if (!orderState.loading && Object.keys(orderOptions || {})?.length > 0 && !languageState.loading && !businessState.loading && props.avoidBusinessLoading) {
902
- getBusiness()
903
- }
904
- }, [JSON.stringify(orderOptions), languageState.loading, slug, filterByMenus, professionalSelected])
905
-
906
- /**
907
- * getBusiness if orderState is loading the first time when is rendered
908
- */
909
- useEffect(() => {
910
- if (props.product && !orderState.loading && !Object.keys(businessState.business)?.length) {
911
- getBusiness()
912
- }
913
- }, [orderState.loading])
914
-
915
- /**
916
- * getProduct when login after guest
917
- */
918
- useEffect(() => {
919
- if (props.product?.businessId && props.product?.categoryId && props.product?.id && !orderState.loading) {
920
- getProduct()
921
- }
922
- }, [props.product])
923
-
924
- useEffect(() => {
925
- if (!orderState.loading) {
926
- setOrderOptions({
927
- type: orderState?.options?.type,
928
- moment: orderState?.options?.moment,
929
- location: orderState?.options?.address?.location
930
- })
931
- }
932
- }, [orderState?.loading, orderState?.options?.type, orderState?.options?.moment, JSON.stringify(orderState?.options?.address?.location)])
933
-
934
- /**
935
- * Cancel business request
936
- */
937
- useEffect(() => {
938
- const request = requestsState.business
939
- return () => {
940
- request && request.cancel && request.cancel()
941
- }
942
- }, [requestsState.business])
943
-
944
- /**
945
- * Cancel products request on unmount and pagination
946
- */
947
- useEffect(() => {
948
- const request = requestsState.products
949
- return () => {
950
- request && request.cancel && request.cancel()
951
- }
952
- }, [requestsState.products])
953
-
954
- return (
955
- <>
956
- {UIComponent && (
957
- <UIComponent
958
- {...props}
959
- errors={errors}
960
- categorySelected={categorySelected}
961
- searchValue={searchValue}
962
- sortByValue={sortByValue}
963
- filterByMenus={filterByMenus}
964
- categoryState={categoryState}
965
- businessState={businessState}
966
- productModal={productModal}
967
- openCategories={openCategories.values}
968
- featuredProducts={featuredProducts}
969
- errorQuantityProducts={errorQuantityProducts}
970
- categoriesState={categoriesState}
971
- handleChangeCategory={handleChangeCategory}
972
- handleChangeSearch={handleChangeSearch}
973
- handleChangeSortBy={handleChangeSortBy}
974
- handleChangeFilterByMenus={handleChangeFilterByMenus}
975
- getNextProducts={loadMoreProducts}
976
- updateProductModal={(val) => setProductModal({ ...productModal, product: val })}
977
- multiRemoveProducts={multiRemoveProducts}
978
- setAlertState={setAlertState}
979
- alertState={alertState}
980
- handleUpdateProducts={handleUpdateProducts}
981
- professionalSelected={professionalSelected}
982
- handleChangeProfessionalSelected={handleChangeProfessionalSelected}
983
- priceFilterValues={priceFilterValues}
984
- handleChangePriceFilterValues={handleChangePriceFilterValues}
985
- handleUpdateProfessionals={handleUpdateProfessionals}
986
- notFound={notFound}
987
- setNotFound={setNotFound}
988
- updateStoreCategory={updateStoreCategory}
989
- updateStoreProduct={updateStoreProduct}
990
- loadedFirstTime={loadedFirstTime}
991
- />
992
- )}
993
- </>
994
- )
995
- }
996
-
997
- BusinessAndProductList.propTypes = {
998
- /**
999
- * UI Component, this must be containt all graphic elements and use parent props
1000
- */
1001
- UIComponent: PropTypes.elementType
1002
- }
1003
-
1004
- BusinessAndProductList.defaultProps = {
1005
- }
1
+ import React, { useEffect, useState } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import dayjs from 'dayjs'
4
+ import utc from 'dayjs/plugin/utc'
5
+ import { useOrder } from '../../contexts/OrderContext'
6
+ import { useLanguage } from '../../contexts/LanguageContext'
7
+ import { useConfig } from '../../contexts/ConfigContext'
8
+ import { useToast, ToastType } from '../../contexts/ToastContext'
9
+ import { useCustomer } from '../../contexts/CustomerContext'
10
+ dayjs.extend(utc)
11
+
12
+ export const BusinessAndProductList = (props) => {
13
+ const {
14
+ isSearchByName,
15
+ isSearchByDescription,
16
+ slug,
17
+ categoryId,
18
+ productId,
19
+ isInitialRender,
20
+ ordering,
21
+ businessProps,
22
+ menusProps,
23
+ isGetMenus,
24
+ UIComponent,
25
+ location,
26
+ avoidProductDuplicate,
27
+ isApp,
28
+ isFetchAllProducts,
29
+ isCustomerMode
30
+ } = props
31
+
32
+ const [orderState, { removeProduct }] = useOrder()
33
+ const [alertState, setAlertState] = useState({ open: false, content: [] })
34
+ const [{ configs }] = useConfig()
35
+ const [, { showToast }] = useToast()
36
+ const [languageState, t] = useLanguage()
37
+ const [customerState] = useCustomer()
38
+ const [categorySelected, setCategorySelected] = useState({ id: null, name: t('ALL', 'All') })
39
+ const [searchValue, setSearchValue] = useState(null)
40
+ const [sortByValue, setSortByValue] = useState(null)
41
+ const [filterByMenus, setFilterByMenus] = useState(null)
42
+ const [professionalSelected, setProfessionalSelected] = useState(null)
43
+ const [businessState, setBusinessState] = useState({ business: {}, menus: null, loading: !props.avoidBusinessLoading, error: null })
44
+ const [loadedFirstTime, setLoadedFirstTime] = useState(false)
45
+ const [categoriesState, setCategoriesState] = useState({})
46
+ const [orderOptions, setOrderOptions] = useState({})
47
+ const [productModal, setProductModal] = useState({ product: null, loading: false, error: null })
48
+ const [notFound, setNotFound] = useState(false)
49
+ const [featuredProducts, setFeaturedProducts] = useState(false)
50
+ const [openCategories, setOpenCategories] = useState({ values: [] })
51
+ const [priceFilterValues, setPriceFilterValues] = useState({ min: null, max: null })
52
+ const requestsState = {}
53
+
54
+ const categoryStateDefault = {
55
+ loading: true,
56
+ pagination: { currentPage: 0, pageSize: isApp ? 5 : 20, totalItems: null, totalPages: 0, nextPageItems: 10 },
57
+ products: []
58
+ }
59
+
60
+ let [categoryState, setCategoryState] = useState(categoryStateDefault)
61
+ const [errors, setErrors] = useState(null)
62
+ const [errorQuantityProducts, setErrorQuantityProducts] = useState(false)
63
+
64
+ const categoryKey = searchValue
65
+ ? 'search'
66
+ : categorySelected.id === 'featured'
67
+ ? 'featured'
68
+ : categorySelected.id
69
+ ? `categoryId:${categorySelected.id}`
70
+ : 'all'
71
+
72
+ const isUseParentCategory = configs?.use_parent_category?.value === 'true' ||
73
+ configs?.use_parent_category?.value === '1'
74
+
75
+ /**
76
+ * Change category selected
77
+ * @param {Object} category Category object
78
+ */
79
+ const handleChangeCategory = (category) => {
80
+ if (category?.subcategories?.length) {
81
+ if (!category?.parent_category_id && !openCategories.values.includes(category.id)) {
82
+ openCategories.values = []
83
+ }
84
+ if (openCategories.values.includes(category.id)) {
85
+ openCategories.values = openCategories.values.filter(categoryId => categoryId !== category.id)
86
+ } else {
87
+ openCategories.values.push(category.id)
88
+ }
89
+ setOpenCategories({
90
+ ...openCategories,
91
+ values: openCategories.values
92
+ })
93
+ }
94
+ if (category?.id === null) {
95
+ setOpenCategories({ ...openCategories, values: [] })
96
+ }
97
+ setCategorySelected(category)
98
+ }
99
+
100
+ const handleChangeSearch = (search) => {
101
+ setSearchValue(search)
102
+ }
103
+
104
+ const handleChangeSortBy = (val) => {
105
+ setSortByValue(val)
106
+ }
107
+
108
+ const handleChangeFilterByMenus = (val) => {
109
+ setFilterByMenus(val)
110
+ }
111
+
112
+ const handleChangePriceFilterValues = (name, value) => {
113
+ setPriceFilterValues({
114
+ ...priceFilterValues,
115
+ [name]: value
116
+ })
117
+ }
118
+
119
+ const isMatchSearch = (name, description, price) => {
120
+ if (!searchValue && !priceFilterValues?.min && !priceFilterValues?.max) return true
121
+ return (
122
+ ((searchValue
123
+ ? (name && (name.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').includes(searchValue.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) && isSearchByName)) : true) &&
124
+ (priceFilterValues?.min ? parseFloat(price) >= parseFloat(priceFilterValues?.min) : true) &&
125
+ (priceFilterValues?.max ? parseFloat(price) <= parseFloat(priceFilterValues?.max) : true))
126
+ ) ||
127
+ (
128
+ ((searchValue
129
+ ? (description && (description.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').includes(searchValue.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) && isSearchByDescription)) : true) &&
130
+ (priceFilterValues?.min ? parseFloat(price) >= parseFloat(priceFilterValues?.min) : true) &&
131
+ (priceFilterValues?.max ? parseFloat(price) <= parseFloat(priceFilterValues?.max) : true)))
132
+ }
133
+
134
+ const isValidMoment = (date, format) => dayjs.utc(date, format).format(format) === date
135
+
136
+ const isFeaturedSearch = (product) => {
137
+ if (product.featured) {
138
+ if (!searchValue) return true
139
+ return (
140
+ product.name && (product.name.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
141
+ .includes(searchValue.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) && isSearchByName)
142
+ ) ||
143
+ (
144
+ product.description && (product.description.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
145
+ .includes(searchValue.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '')) && isSearchByDescription)
146
+ )
147
+ }
148
+ return false
149
+ }
150
+
151
+ const sortProductsArray = (option, array) => {
152
+ let _array
153
+ if (option === 'rank' || option === null) {
154
+ _array = array.sort((a, b) => a.rank - b.rank)
155
+ }
156
+ if (option === 'rank_desc') {
157
+ _array = array.sort((a, b) => b.rank - a.rank)
158
+ }
159
+ if (option === 'a-z') {
160
+ _array = array.sort((a, b) =>
161
+ (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0)
162
+ )
163
+ }
164
+ setCategoryState({ ...categoryState, products: _array })
165
+ }
166
+
167
+ const subCategoriesList = []
168
+
169
+ const iterateCategories = (categories) => {
170
+ return (
171
+ categories?.length > 0 && categories?.forEach(category => {
172
+ subCategoriesList.push(category)
173
+ iterateCategories(category.subcategories)
174
+ })
175
+ )
176
+ }
177
+
178
+ /**
179
+ * Method to change professional
180
+ * @param {object} professional a professional info
181
+ */
182
+ const handleChangeProfessionalSelected = (professional) => {
183
+ setProfessionalSelected(professional)
184
+ }
185
+
186
+ const handleUpdateProducts = (productId, changes) => {
187
+ const updatedProducts = categoryState?.products.map(product => {
188
+ if (product?.id === productId) {
189
+ return {
190
+ ...product,
191
+ ...changes
192
+ }
193
+ }
194
+ return product
195
+ })
196
+ setCategoryState({
197
+ ...categoryState,
198
+ products: updatedProducts
199
+ })
200
+ if (categoriesState?.featured?.products) {
201
+ const updatedFeaturedProducts = categoriesState?.featured?.products.map(product => {
202
+ if (product?.id === productId) {
203
+ return {
204
+ ...product,
205
+ ...changes
206
+ }
207
+ }
208
+ return product
209
+ })
210
+ setCategoriesState({
211
+ ...categoriesState,
212
+ featured: {
213
+ ...categoriesState.featured,
214
+ products: updatedFeaturedProducts
215
+ }
216
+ })
217
+ }
218
+ const updatedCategories = businessState?.business?.categories?.map(_category => {
219
+ const updatedProducts = _category?.products.map(_product => {
220
+ if (_product?.id === productId) {
221
+ return {
222
+ ..._product,
223
+ ...changes
224
+ }
225
+ }
226
+ return _product
227
+ })
228
+ return {
229
+ ..._category,
230
+ products: updatedProducts
231
+ }
232
+ })
233
+ setBusinessState({
234
+ ...businessState,
235
+ business: {
236
+ ...businessState?.business,
237
+ categories: updatedCategories
238
+ }
239
+ })
240
+ }
241
+
242
+ const getProducts = async () => {
243
+ for (let i = 0; i < businessState?.business?.categories?.length ?? 0; i++) {
244
+ const category = businessState?.business?.categories[i]
245
+ const isFeatured = category?.products?.some((product) => product.featured)
246
+ if (isFeatured) {
247
+ setFeaturedProducts(isFeatured)
248
+ break
249
+ }
250
+ }
251
+ const categoryState = {
252
+ ...categoryStateDefault,
253
+ loading: false
254
+ }
255
+ if (categorySelected.id !== 'featured' && categorySelected.id !== null) {
256
+ iterateCategories(businessState?.business?.categories)
257
+ const categoriesList = [].concat(...businessState?.business?.categories.map(category => category.children))
258
+ const categories = isUseParentCategory ? categoriesList : businessState?.business?.categories
259
+ const parentCategory = categories?.find(category => category.category_id === categorySelected.id) ?? {}
260
+ const categoryFinded = subCategoriesList.find(subCat => subCat.id === parentCategory.category_id) ?? {}
261
+
262
+ const productsFiltered = businessState?.business?.categories
263
+ ?.find(category => category.id === (isUseParentCategory ? parentCategory?.parent_category_id : categorySelected.id))
264
+ ?.products
265
+ .filter(product => isUseParentCategory
266
+ ? (categoryFinded?.children?.some(cat => cat.category_id === product?.category_id) && isMatchSearch(product.name, product.description, product?.price))
267
+ : isMatchSearch(product.name, product.description, product?.price))
268
+
269
+ categoryState.products = productsFiltered || []
270
+ } else if (categorySelected.id === 'featured') {
271
+ const productsFiltered = businessState?.business?.categories?.reduce(
272
+ (products, category) => [
273
+ ...products,
274
+ ...category.products.map(product => ({
275
+ ...product,
276
+ ...(category.slug ? { category: { ...product?.category, slug: category.slug } } : {})
277
+ }))
278
+ ], []
279
+ ).filter(
280
+ product => isFeaturedSearch(product)
281
+ )
282
+ categoryState.products = productsFiltered || []
283
+ } else {
284
+ let _categoriesCustom = null
285
+ if (avoidProductDuplicate) {
286
+ const customCategories = ['favorites']
287
+ _categoriesCustom = businessState?.business?.categories?.filter(({ id }) => (!customCategories.includes(id)))
288
+ }
289
+
290
+ const productsToFilter = avoidProductDuplicate ? _categoriesCustom : businessState?.business?.categories
291
+ const productsFiltered = productsToFilter?.reduce(
292
+ (products, category) => [
293
+ ...products,
294
+ ...category.products.map(product => ({
295
+ ...product,
296
+ ...(category.slug ? { category: { ...product?.category, slug: category.slug } } : {})
297
+ }))
298
+ ], []
299
+ ).filter(
300
+ product => isMatchSearch(product.name, product.description, product?.price)
301
+ )
302
+ categoryState.products = productsFiltered || []
303
+ }
304
+ setErrorQuantityProducts(!categoryState.products?.length)
305
+ setCategoryState({ ...categoryState })
306
+ }
307
+
308
+ const getLazyProducts = async ({ page, pageSize = categoryStateDefault.pagination.pageSize }) => {
309
+ const parameters = {
310
+ version: 'v2',
311
+ type: orderState.options?.type ?? 1,
312
+ ...(!isFetchAllProducts && { page }),
313
+ ...(!isFetchAllProducts && { page_size: pageSize }),
314
+ ...(!isFetchAllProducts && { orderBy: 'rank' })
315
+ }
316
+
317
+ if (orderState.options?.moment && isValidMoment(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss')) {
318
+ const moment = dayjs.utc(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss').local().unix()
319
+ parameters.timestamp = moment
320
+ }
321
+
322
+ if (sortByValue) {
323
+ parameters.orderBy = sortByValue === 'a-z' ? 'name' : sortByValue
324
+ }
325
+
326
+ let where = null
327
+ const searchConditions = []
328
+ if (searchValue) {
329
+ if (isSearchByName) {
330
+ searchConditions.push(
331
+ {
332
+ attribute: 'name',
333
+ value: {
334
+ condition: 'ilike',
335
+ value: props?.isForceSearch ? `%${searchValue}%` : encodeURI(`%${searchValue}%`)
336
+ }
337
+ }
338
+ )
339
+ }
340
+ if (isSearchByDescription) {
341
+ searchConditions.push(
342
+ {
343
+ attribute: 'description',
344
+ value: {
345
+ condition: 'ilike',
346
+ value: props?.isForceSearch ? `%${searchValue}%` : encodeURI(`%${searchValue}%`)
347
+ }
348
+ }
349
+ )
350
+ }
351
+ }
352
+
353
+ if (priceFilterValues?.min) {
354
+ searchConditions.push(
355
+ {
356
+ attribute: 'price',
357
+ value: {
358
+ condition: '>=',
359
+ value: encodeURI(priceFilterValues?.min)
360
+ }
361
+ }
362
+ )
363
+ }
364
+
365
+ if (priceFilterValues?.max) {
366
+ searchConditions.push(
367
+ {
368
+ attribute: 'price',
369
+ value: {
370
+ condition: '<=',
371
+ value: encodeURI(priceFilterValues?.max)
372
+ }
373
+ }
374
+ )
375
+ }
376
+
377
+ where = {
378
+ conditions: searchConditions,
379
+ conector: 'OR'
380
+ }
381
+
382
+ if (categorySelected.id === 'featured') {
383
+ parameters.params = 'features'
384
+ }
385
+
386
+ if (categorySelected.id === 'featured' && searchValue) {
387
+ parameters.params = 'features'
388
+ where = {
389
+ conditions: [
390
+ {
391
+ conditions: searchConditions,
392
+ conector: 'OR'
393
+ }
394
+ ],
395
+ conector: 'AND'
396
+ }
397
+ }
398
+
399
+ const source = {}
400
+ requestsState.products = source
401
+ const promises = []
402
+
403
+ const functionFetch = categorySelected.id && categorySelected.id !== 'featured'
404
+ ? ordering.businesses(businessState.business.id).categories(categorySelected.id).products()
405
+ : where?.conditions?.length === 0 ? ordering.businesses(businessState.business.id).categories() : ordering.businesses(businessState.business.id).products()
406
+
407
+ let productEndpoint = where?.conditions?.length > 0
408
+ ? functionFetch.parameters(parameters).where(where)
409
+ : functionFetch.parameters(parameters)
410
+
411
+ promises.push(await productEndpoint.get({ cancelToken: source }))
412
+
413
+ if (isUseParentCategory && (!categorySelected.id || categorySelected.id === 'featured')) {
414
+ parameters.params = 'features'
415
+ productEndpoint = where?.conditions?.length > 0
416
+ ? ordering.businesses(businessState.business.id).products().parameters(parameters).where(where)
417
+ : ordering.businesses(businessState.business.id).products().parameters(parameters)
418
+
419
+ promises.push(await productEndpoint.get({ cancelToken: source }))
420
+ }
421
+
422
+ return promises
423
+ }
424
+
425
+ const loadProducts = async ({ newFetch } = {}) => {
426
+ setErrors(null)
427
+ const curCategoryState = categoriesState[categoryKey] ?? categoryStateDefault
428
+ if (
429
+ !newFetch &&
430
+ ((curCategoryState.pagination.currentPage > 0 &&
431
+ curCategoryState.pagination.currentPage === curCategoryState.pagination.totalPages) ||
432
+ (curCategoryState?.products?.length > 0 && curCategoryState.pagination.totalPages > 0))
433
+ ) {
434
+ setCategoryState({ ...curCategoryState, loading: false })
435
+ return
436
+ }
437
+
438
+ const isLazy = !!businessState?.business?.lazy_load_products_recommended
439
+
440
+ if (!isLazy) {
441
+ getProducts()
442
+ return
443
+ }
444
+
445
+ const pageSize = categoryStateDefault.pagination.pageSize
446
+
447
+ try {
448
+ setCategoryState({ ...curCategoryState, loading: true })
449
+ const [lazyRes, featuredRes] = await getLazyProducts({ page: 1, pageSize })
450
+
451
+ const { content } = lazyRes
452
+ const error = content?.error
453
+ const result = content?.result
454
+ const pagination = content?.pagination
455
+
456
+ const errorsList = []
457
+
458
+ if (error) {
459
+ errorsList.push(result[0])
460
+ }
461
+ if (featuredRes?.content?.error) {
462
+ errorsList.push(featuredRes?.content?.result[0])
463
+ }
464
+ if (errorsList?.length) {
465
+ setErrors(errorsList[0])
466
+ setCategoryState({ ...curCategoryState, loading: false })
467
+ return
468
+ }
469
+
470
+ if (featuredRes?.content?.result?.length) {
471
+ const oldFeatured = categoriesState?.featured
472
+ const featureState = {
473
+ pagination: {
474
+ ...oldFeatured?.pagination,
475
+ currentPage: featuredRes?.content?.pagination?.current_page,
476
+ totalItems: featuredRes?.content?.pagination?.total,
477
+ totalPages: featuredRes?.content?.pagination?.total_pages
478
+ },
479
+ loading: false,
480
+ products: newFetch
481
+ ? [...featuredRes?.content?.result]
482
+ : oldFeatured?.products?.concat(featuredRes?.content?.result)
483
+ }
484
+ setErrorQuantityProducts(!featureState.products?.length)
485
+ categoriesState.featured = featureState
486
+ }
487
+
488
+ if (categorySelected.id && categorySelected.id !== 'featured') {
489
+ const newcategoryState = {
490
+ pagination: {
491
+ ...curCategoryState.pagination,
492
+ currentPage: pagination.current_page,
493
+ totalItems: pagination.total,
494
+ totalPages: pagination.total_pages
495
+ },
496
+ loading: false,
497
+ products: result
498
+ }
499
+ setErrorQuantityProducts(!newcategoryState.products?.length)
500
+ categoriesState[categoryKey] = newcategoryState
501
+ categoryState = newcategoryState
502
+ setCategoryState({ ...newcategoryState })
503
+ setCategoriesState({ ...categoriesState })
504
+
505
+ const isFeatured = categoriesState.all.products.some(product => product.featured) ||
506
+ categoriesState?.featured?.products?.some(product => product.featured)
507
+ setFeaturedProducts(isFeatured)
508
+ }
509
+
510
+ if (!(categorySelected.id && categorySelected.id !== 'featured')) {
511
+ const productsList = searchValue
512
+ ? [...result]
513
+ : [].concat(...result.map(category =>
514
+ category?.products?.map(product => ({
515
+ ...product,
516
+ ...(category?.slug ? { category: { ...product.category, slug: category.slug } } : {})
517
+ }))
518
+ )).filter(item => item)
519
+ const productsListFeatured = featuredRes?.content?.result ?? []
520
+ const paginationData = categorySelected.id === 'featured'
521
+ ? categoriesState?.featured?.pagination ?? {}
522
+ : curCategoryState?.pagination ?? {}
523
+ const newcategoryState = {
524
+ pagination: {
525
+ ...paginationData,
526
+ currentPage: categorySelected.id === 'featured'
527
+ ? featuredRes?.content?.pagination?.current_page
528
+ : pagination?.current_page,
529
+ totalItems: categorySelected.id === 'featured'
530
+ ? featuredRes?.content?.pagination?.total
531
+ : pagination?.total,
532
+ totalPages: categorySelected.id === 'featured'
533
+ ? featuredRes?.content?.pagination?.total_pages
534
+ : pagination?.total_pages
535
+ },
536
+ loading: false,
537
+ products: categorySelected.id === 'featured'
538
+ ? productsListFeatured
539
+ : searchValue
540
+ ? [...productsListFeatured, ...productsList].filter((product, i, _hash) => _hash.findIndex(_product => _product?.id === product?.id) === i)
541
+ : [...productsListFeatured, ...curCategoryState.products.concat(productsList)]
542
+ }
543
+
544
+ categoriesState[categoryKey] = newcategoryState
545
+ setCategoryState({ ...newcategoryState })
546
+ setCategoriesState({ ...categoriesState })
547
+
548
+ const isFeatured = categoriesState.all.products.some(product => product.featured) ||
549
+ categoriesState?.featured?.products?.some(product => product.featured)
550
+ setFeaturedProducts(isFeatured)
551
+ }
552
+ } catch (err) {
553
+ if (err?.constructor?.name !== 'Cancel') {
554
+ setErrors([err?.message ?? 'ERROR'])
555
+ setCategoryState({ ...curCategoryState, loading: false })
556
+ }
557
+ }
558
+ }
559
+
560
+ const loadMoreProducts = async () => {
561
+ setErrors(null)
562
+ const curCategoryState = categoriesState[categoryKey] ?? categoryStateDefault
563
+ setCategoryState({ ...curCategoryState, loading: true })
564
+
565
+ try {
566
+ const [lazyRes, featuredRes] = await getLazyProducts({
567
+ page: curCategoryState.pagination.currentPage + 1
568
+ })
569
+ const { content } = lazyRes
570
+ const error = content?.error
571
+ const result = content?.result
572
+ const pagination = content?.pagination
573
+
574
+ const errorsList = []
575
+
576
+ if (error) {
577
+ errorsList.push(result[0])
578
+ }
579
+ if (featuredRes?.content?.error) {
580
+ errorsList.push(featuredRes?.content?.result[0])
581
+ }
582
+ if (errorsList?.length) {
583
+ setErrors(errorsList[0])
584
+ setCategoryState({ ...curCategoryState, loading: false })
585
+ return
586
+ }
587
+
588
+ if (featuredRes) {
589
+ const oldFeatured = categoriesState?.featured
590
+ const featureState = {
591
+ pagination: {
592
+ ...oldFeatured?.pagination,
593
+ currentPage: featuredRes?.content?.pagination?.current_page,
594
+ totalItems: featuredRes?.content?.pagination?.total,
595
+ totalPages: featuredRes?.content?.pagination?.total_pages
596
+ },
597
+ loading: false,
598
+ products: [...(oldFeatured?.products ?? []), ...(featuredRes?.content?.result ?? [])]
599
+ }
600
+ categoriesState.featured = featureState
601
+ }
602
+
603
+ if ((categorySelected.id && categorySelected.id !== 'featured')) {
604
+ const newcategoryState = {
605
+ pagination: {
606
+ ...curCategoryState?.pagination,
607
+ currentPage: pagination?.current_page,
608
+ totalItems: pagination?.total,
609
+ totalPages: pagination?.total_pages
610
+ },
611
+ loading: false,
612
+ products: [...(curCategoryState?.products ?? []), ...result]
613
+ }
614
+
615
+ categoriesState[categoryKey] = newcategoryState
616
+ categoryState = { ...categoryState, ...newcategoryState }
617
+ setCategoryState({ ...categoryState, ...newcategoryState })
618
+ setCategoriesState({ ...categoriesState })
619
+
620
+ const isFeatured = categoriesState?.all?.products?.some(product => product.featured) ||
621
+ categoriesState?.featured?.products?.some(product => product.featured)
622
+ setFeaturedProducts(isFeatured)
623
+ }
624
+
625
+ if (!(categorySelected.id && categorySelected.id !== 'featured')) {
626
+ const productsList = [].concat(...result.map(category => category?.products)).filter(item => item)
627
+ const productsListFeatured = featuredRes?.content?.result ?? []
628
+ const paginationData = categorySelected.id === 'featured'
629
+ ? categoriesState?.featured?.pagination ?? {}
630
+ : curCategoryState?.pagination ?? {}
631
+ const newcategoryState = {
632
+ pagination: {
633
+ ...paginationData,
634
+ currentPage: categorySelected.id === 'featured'
635
+ ? featuredRes?.content?.pagination?.current_page
636
+ : pagination?.current_page,
637
+ totalItems: categorySelected.id === 'featured'
638
+ ? featuredRes?.content?.pagination?.total
639
+ : pagination?.total,
640
+ totalPages: categorySelected.id === 'featured'
641
+ ? featuredRes?.content?.pagination?.total_pages
642
+ : pagination?.total_pages
643
+ },
644
+ loading: false,
645
+ products: categorySelected.id === 'featured'
646
+ ? productsListFeatured
647
+ : [...productsListFeatured, ...(curCategoryState?.products?.concat(productsList) ?? [])]
648
+ }
649
+
650
+ categoriesState[categoryKey] = newcategoryState
651
+ categoryState = newcategoryState
652
+ setCategoryState({ ...newcategoryState })
653
+ setCategoriesState({ ...categoriesState })
654
+
655
+ const isFeatured = categoriesState?.all?.products?.some(product => product.featured) ||
656
+ categoriesState?.featured?.products?.some(product => product.featured)
657
+ setFeaturedProducts(isFeatured)
658
+ }
659
+
660
+ setCategoryState({ ...categoryState, loading: false })
661
+ } catch (err) {
662
+ if (err?.constructor?.name !== 'Cancel') {
663
+ setErrors([err?.message ?? 'ERROR'])
664
+ setCategoryState({ ...curCategoryState, loading: false })
665
+ }
666
+ }
667
+ }
668
+
669
+ const getProduct = async () => {
670
+ if ((categoryId && productId && businessState.business.id) || (props.product?.businessId && props.product?.categoryId && props.product?.id)) {
671
+ try {
672
+ setProductModal({
673
+ ...productModal,
674
+ loading: true
675
+ })
676
+ const source = {}
677
+ requestsState.product = source
678
+ const parameters = {
679
+ type: orderState.options?.type || 1,
680
+ moment: orderState.options?.moment || null,
681
+ version: 'v2'
682
+ }
683
+
684
+ if (orderState.options?.moment && isValidMoment(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss')) {
685
+ const moment = dayjs.utc(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss').local().unix()
686
+ parameters.timestamp = moment
687
+ }
688
+ const { content: { result } } = await ordering
689
+ .businesses(businessState.business.id || props.product?.businessId)
690
+ .categories(categoryId || props.product?.categoryId)
691
+ .products(productId || props.product?.id)
692
+ .parameters(parameters)
693
+ .get({ cancelToken: source })
694
+ const product = Array.isArray(result) ? null : result
695
+
696
+ setNotFound(!result)
697
+ setProductModal({
698
+ ...productModal,
699
+ product,
700
+ loading: false
701
+ })
702
+ } catch (e) {
703
+ setProductModal({
704
+ ...productModal,
705
+ loading: false,
706
+ error: [e]
707
+ })
708
+ }
709
+ }
710
+ }
711
+
712
+ useEffect(() => {
713
+ if (isInitialRender) {
714
+ getProduct()
715
+ }
716
+ }, [JSON.stringify(businessState.business?.id), isInitialRender])
717
+
718
+ const getBusiness = async () => {
719
+ try {
720
+ setBusinessState({ ...businessState, loading: true })
721
+ const source = {}
722
+ requestsState.business = source
723
+ const parameters = {
724
+ version: 'v2',
725
+ type: orderState.options?.type || 1,
726
+ location: location
727
+ ? `${location?.lat},${location?.lng}`
728
+ : orderState.options?.address?.location
729
+ ? `${orderState.options?.address?.location?.lat},${orderState.options?.address?.location?.lng}`
730
+ : null
731
+ }
732
+ if (orderState.options?.moment && isValidMoment(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss')) {
733
+ const moment = dayjs.utc(orderState.options?.moment, 'YYYY-MM-DD HH:mm:ss').local().unix()
734
+ parameters.timestamp = moment
735
+ }
736
+
737
+ if (filterByMenus) {
738
+ parameters.menu_id = filterByMenus
739
+ }
740
+
741
+ if (professionalSelected) {
742
+ parameters.professional_id = professionalSelected?.id
743
+ }
744
+
745
+ if (isCustomerMode && customerState?.user?.id) {
746
+ parameters.user_id = customerState?.user?.id
747
+ }
748
+
749
+ const { content: { result } } = await ordering.businesses(slug).select(businessProps).parameters(parameters).get({ cancelToken: source })
750
+
751
+ setErrorQuantityProducts(!result?.categories || result?.categories?.length === 0)
752
+
753
+ const data = {
754
+ ...businessState,
755
+ business: result,
756
+ loading: false
757
+ }
758
+
759
+ if (menusProps && isGetMenus) {
760
+ const { content: { result: menus } } = await ordering
761
+ .businesses(result.id)
762
+ .menus()
763
+ .select(menusProps)
764
+ .get()
765
+
766
+ data.menus = menus
767
+ }
768
+
769
+ setBusinessState(data)
770
+ setLoadedFirstTime(true)
771
+ } catch (err) {
772
+ setBusinessState({
773
+ ...businessState,
774
+ loading: false,
775
+ error: [err.message]
776
+ })
777
+ setLoadedFirstTime(true)
778
+ }
779
+ }
780
+
781
+ const multiRemoveProducts = async (unavailableProducts, carts) => {
782
+ const allPromise = []
783
+ unavailableProducts.forEach(product => {
784
+ allPromise.push(new Promise((resolve, reject) => {
785
+ resolve(removeProduct(product, carts))
786
+ }))
787
+ })
788
+ await Promise.all(allPromise) && setAlertState({ open: true, content: [t('NOT_AVAILABLE_PRODUCTS', 'These products are not available.')] })
789
+ }
790
+
791
+ const handleUpdateProfessionals = (selectedProfessional) => {
792
+ const professionals = businessState?.business?.professionals.map(professional => {
793
+ if (selectedProfessional?.id === professional?.id) {
794
+ return {
795
+ ...professional,
796
+ ...selectedProfessional
797
+ }
798
+ }
799
+ return professional
800
+ })
801
+ setBusinessState({ ...businessState, business: { ...businessState?.business, professionals } })
802
+ }
803
+
804
+ const updateCategories = (categories, result) => {
805
+ return categories.map((category) => {
806
+ if (category.id === result.id) {
807
+ return {
808
+ ...category,
809
+ ...result
810
+ }
811
+ }
812
+ if (Array.isArray(category?.subcategories) && category.subcategories.length > 0) {
813
+ return {
814
+ ...category,
815
+ subcategories: updateCategories(category.subcategories, result)
816
+ }
817
+ }
818
+ return category
819
+ })
820
+ }
821
+
822
+ const updateStoreProduct = async (categoryId, productId, updateParams = {}) => {
823
+ try {
824
+ const { content: { result, error } } = await ordering.businesses(businessState?.business?.id).categories(categoryId).products(productId).save(updateParams)
825
+
826
+ if (!error) {
827
+ const updatedProducts = categoryState.products.map(product => {
828
+ if (product.id === result.id) {
829
+ return {
830
+ ...product,
831
+ ...result
832
+ }
833
+ }
834
+ return product
835
+ })
836
+ setCategoryState({ ...categoryState, products: updatedProducts })
837
+ showToast(ToastType.Success, result?.enabled
838
+ ? t('ENABLED_PRODUCT', 'Enabled product')
839
+ : t('DISABLED_PRODUCT', 'Disabled product'))
840
+ } else {
841
+ showToast(ToastType.Error, result)
842
+ }
843
+ } catch (err) {
844
+ showToast(ToastType.Error, err.message)
845
+ }
846
+ }
847
+
848
+ const updateStoreCategory = async (categoryId, updateParams = {}) => {
849
+ try {
850
+ const { content: { result, error } } = await ordering.businesses(businessState?.business?.id).categories(categoryId).save(updateParams)
851
+
852
+ if (!error) {
853
+ const updatedCategories = updateCategories(businessState?.business.categories, result)
854
+ const updatedBusiness = { ...businessState?.business, categories: updatedCategories }
855
+ setBusinessState({ ...businessState, business: updatedBusiness })
856
+ showToast(ToastType.Success, result?.enabled
857
+ ? t('ENABLED_CATEGORY', 'Enabled category')
858
+ : t('DISABLED_CATEGORY', 'Disabled category'))
859
+ } else {
860
+ showToast(ToastType.Error, result)
861
+ }
862
+ } catch (err) {
863
+ showToast(ToastType.Error, err.message)
864
+ }
865
+ }
866
+
867
+ useEffect(() => {
868
+ if (!businessState.loading) {
869
+ loadProducts({ newFetch: true })
870
+ }
871
+ }, [businessState.loading])
872
+
873
+ useEffect(() => {
874
+ loadProducts({ newFetch: !!searchValue })
875
+ }, [searchValue])
876
+
877
+ useEffect(() => {
878
+ loadProducts({ newFetch: !!searchValue })
879
+ }, [categorySelected.id])
880
+
881
+ useEffect(() => {
882
+ loadProducts({ newFetch: !!searchValue })
883
+ sortProductsArray(sortByValue, categoryState?.products)
884
+ }, [sortByValue])
885
+
886
+ useEffect(() => {
887
+ loadProducts()
888
+ }, [slug])
889
+
890
+ useEffect(() => {
891
+ loadProducts({ newFetch: true })
892
+ }, [priceFilterValues])
893
+
894
+ useEffect(() => {
895
+ if (!orderState.loading && Object.keys(orderOptions || {})?.length > 0 && !languageState.loading && !props.avoidBusinessLoading) {
896
+ getBusiness()
897
+ }
898
+ }, [JSON.stringify(orderOptions), languageState.loading, slug, filterByMenus, professionalSelected])
899
+
900
+ useEffect(() => {
901
+ if (!orderState.loading && Object.keys(orderOptions || {})?.length > 0 && !languageState.loading && !businessState.loading && props.avoidBusinessLoading) {
902
+ getBusiness()
903
+ }
904
+ }, [JSON.stringify(orderOptions), languageState.loading, slug, filterByMenus, professionalSelected])
905
+
906
+ /**
907
+ * getBusiness if orderState is loading the first time when is rendered
908
+ */
909
+ useEffect(() => {
910
+ if (props.product && !orderState.loading && !Object.keys(businessState.business)?.length) {
911
+ getBusiness()
912
+ }
913
+ }, [orderState.loading])
914
+
915
+ /**
916
+ * getProduct when login after guest
917
+ */
918
+ useEffect(() => {
919
+ if (props.product?.businessId && props.product?.categoryId && props.product?.id && !orderState.loading) {
920
+ getProduct()
921
+ }
922
+ }, [props.product])
923
+
924
+ useEffect(() => {
925
+ if (!orderState.loading) {
926
+ setOrderOptions({
927
+ type: orderState?.options?.type,
928
+ moment: orderState?.options?.moment,
929
+ location: orderState?.options?.address?.location
930
+ })
931
+ }
932
+ }, [orderState?.loading, orderState?.options?.type, orderState?.options?.moment, JSON.stringify(orderState?.options?.address?.location)])
933
+
934
+ /**
935
+ * Cancel business request
936
+ */
937
+ useEffect(() => {
938
+ const request = requestsState.business
939
+ return () => {
940
+ request && request.cancel && request.cancel()
941
+ }
942
+ }, [requestsState.business])
943
+
944
+ /**
945
+ * Cancel products request on unmount and pagination
946
+ */
947
+ useEffect(() => {
948
+ const request = requestsState.products
949
+ return () => {
950
+ request && request.cancel && request.cancel()
951
+ }
952
+ }, [requestsState.products])
953
+
954
+ return (
955
+ <>
956
+ {UIComponent && (
957
+ <UIComponent
958
+ {...props}
959
+ errors={errors}
960
+ categorySelected={categorySelected}
961
+ searchValue={searchValue}
962
+ sortByValue={sortByValue}
963
+ filterByMenus={filterByMenus}
964
+ categoryState={categoryState}
965
+ businessState={businessState}
966
+ productModal={productModal}
967
+ openCategories={openCategories.values}
968
+ featuredProducts={featuredProducts}
969
+ errorQuantityProducts={errorQuantityProducts}
970
+ categoriesState={categoriesState}
971
+ handleChangeCategory={handleChangeCategory}
972
+ handleChangeSearch={handleChangeSearch}
973
+ handleChangeSortBy={handleChangeSortBy}
974
+ handleChangeFilterByMenus={handleChangeFilterByMenus}
975
+ getNextProducts={loadMoreProducts}
976
+ updateProductModal={(val) => setProductModal({ ...productModal, product: val })}
977
+ multiRemoveProducts={multiRemoveProducts}
978
+ setAlertState={setAlertState}
979
+ alertState={alertState}
980
+ handleUpdateProducts={handleUpdateProducts}
981
+ professionalSelected={professionalSelected}
982
+ handleChangeProfessionalSelected={handleChangeProfessionalSelected}
983
+ priceFilterValues={priceFilterValues}
984
+ handleChangePriceFilterValues={handleChangePriceFilterValues}
985
+ handleUpdateProfessionals={handleUpdateProfessionals}
986
+ notFound={notFound}
987
+ setNotFound={setNotFound}
988
+ updateStoreCategory={updateStoreCategory}
989
+ updateStoreProduct={updateStoreProduct}
990
+ loadedFirstTime={loadedFirstTime}
991
+ />
992
+ )}
993
+ </>
994
+ )
995
+ }
996
+
997
+ BusinessAndProductList.propTypes = {
998
+ /**
999
+ * UI Component, this must be containt all graphic elements and use parent props
1000
+ */
1001
+ UIComponent: PropTypes.elementType
1002
+ }
1003
+
1004
+ BusinessAndProductList.defaultProps = {
1005
+ }