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,1450 +1,1450 @@
1
- import React, { createContext, useContext, useState, useEffect } from 'react'
2
- import { useSession } from '../SessionContext'
3
- import { useApi } from '../ApiContext'
4
- import { useWebsocket } from '../WebsocketContext'
5
- import { useLanguage } from '../LanguageContext'
6
- import { useEvent } from '../EventContext'
7
- import { useConfig } from '../ConfigContext'
8
- import { useCustomer } from '../CustomerContext'
9
- import { ToastType, useToast } from '../ToastContext'
10
- import dayjs from 'dayjs'
11
- import utc from 'dayjs/plugin/utc'
12
-
13
- dayjs.extend(utc)
14
-
15
- /**
16
- * Create OrderContext
17
- * This context will manage the current order with options internally and provide an easy interface
18
- */
19
- export const OrderContext = createContext()
20
-
21
- /**
22
- * Custom provider to order manager
23
- * This provider has a reducer for manage order state
24
- * @param {props} props
25
- */
26
- export const OrderProvider = ({ Alert, children, strategy, isAlsea, isDisableToast, franchiseId, isDisabledDefaultOpts, businessSlug, userAgent }) => {
27
- const [confirmAlert, setConfirm] = useState({ show: false })
28
- const [alert, setAlert] = useState({ show: false })
29
- const [ordering] = useApi()
30
- const socket = useWebsocket()
31
- const [languageState, t] = useLanguage()
32
- const [events] = useEvent()
33
- const [configState] = useConfig()
34
- const [session, { logout }] = useSession()
35
- const [customerState, { setUserCustomer }] = useCustomer()
36
- const [, { showToast }] = useToast()
37
-
38
- const configTypes = configState?.configs?.order_types_allowed?.value.split('|').map(value => Number(value)) || []
39
-
40
- const orderTypes = {
41
- delivery: 1,
42
- pickup: 2,
43
- eatin: 3,
44
- curbside: 4,
45
- drivethru: 5,
46
- catering_delivery: 7,
47
- catering_pickup: 8
48
- }
49
-
50
- const [state, setState] = useState({
51
- loading: true,
52
- options: isDisabledDefaultOpts
53
- ? { type: null, moment: null, city_id: null }
54
- : {
55
- type: orderTypes[configState?.configs?.default_order_type?.value],
56
- moment: null,
57
- city_id: null
58
- },
59
- carts: {},
60
- confirmAlert,
61
- alert
62
- })
63
-
64
- /**
65
- * Refresh order options and carts from API
66
- */
67
- const refreshOrderOptions = async () => {
68
- try {
69
- if (!state.loading) {
70
- setState({ ...state, loading: true })
71
- }
72
- const countryCodeFromLocalStorage = await strategy.getItem('country-code')
73
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
74
- const userCustomerId = customerFromLocalStorage?.id
75
- const options = {}
76
- if (userCustomerId) {
77
- options.query = {
78
- user_id: userCustomerId
79
- }
80
- }
81
- if (franchiseId) {
82
- options.query = {
83
- ...options.query,
84
- franchise_id: franchiseId
85
- }
86
- }
87
-
88
- const countryCode = countryCodeFromLocalStorage && countryCodeFromLocalStorage !== state?.options?.address?.country_code
89
- ? countryCodeFromLocalStorage
90
- : state?.options?.address?.country_code
91
-
92
- if (countryCode) {
93
- options.headers = {
94
- 'X-Socket-Id-X': socket?.getId(),
95
- 'X-Country-Code-X': countryCode
96
- }
97
- }
98
-
99
- const res = await ordering.setAccessToken(session.token).orderOptions().get(options)
100
- const error = res?.content?.error
101
- const result = res?.content?.result
102
-
103
- if (!error) {
104
- const { carts, ...options } = result
105
- state.carts = {}
106
- carts.forEach(cart => {
107
- state.carts[`businessId:${cart.business_id}`] = cart
108
- })
109
- state.options = {
110
- ...state.options,
111
- ...options
112
- }
113
-
114
- if (!countryCodeFromLocalStorage && options?.address?.country_code) {
115
- await updateOrderOptions({ country_code: options?.address?.country_code })
116
- }
117
- }
118
- if (error) {
119
- setAlert({ show: true, content: result })
120
- if (res?.status === 401) {
121
- session.auth && logout()
122
- }
123
- }
124
- const localOptions = await strategy.getItem('options', true)
125
- if (localOptions) {
126
- const options = {}
127
- if (Object.keys(localOptions.address).length > 0) {
128
- const conditions = [
129
- { attribute: 'address', value: localOptions?.address?.address }
130
- ]
131
- const userId = userCustomerId || session.user.id
132
- const addressesResponse = await ordering.setAccessToken(session.token).users(userId).addresses().where(conditions).get()
133
- let address = addressesResponse.content.result.find(address => {
134
- localOptions.address.internal_number = localOptions.address?.internal_number || null
135
- localOptions.address.zipcode = localOptions.address?.zipcode || null
136
- localOptions.address.address_notes = localOptions.address?.address_notes || null
137
-
138
- return address?.location?.lat === localOptions?.address?.location.lat &&
139
- address?.location?.lng === localOptions?.address?.location?.lng &&
140
- address?.internal_number === localOptions?.address?.internal_number &&
141
- address?.zipcode === localOptions?.address?.zipcode &&
142
- address?.address_notes === localOptions?.address?.address_notes
143
- })
144
- if (!address) {
145
- Object.keys(localOptions.address).forEach(key => localOptions?.address?.[key] === null && delete localOptions?.address?.[key])
146
- const { content: { error, result } } = await ordering.setAccessToken(session.token).users(userId).addresses().save(localOptions.address)
147
- if (!error) {
148
- address = result
149
- }
150
- } else {
151
- await ordering.setAccessToken(session.token).users(userId).addresses(address.id).save({ default: true })
152
- }
153
- address && (options.address_id = address.id)
154
- }
155
- if (localOptions.type) {
156
- options.type = localOptions.type
157
- }
158
- if (localOptions.moment) {
159
- options.moment = dayjs.utc(localOptions.moment, 'YYYY-MM-DD HH:mm:ss').unix()
160
- }
161
- if (localOptions?.address_id) {
162
- options.address_id = localOptions?.address_id
163
- }
164
- if (localOptions?.city_id) {
165
- options.city_id = localOptions?.city_id
166
- }
167
- if (options && Object.keys(options).length > 0) {
168
- updateOrderOptions(options)
169
- } else {
170
- setState({ ...state, loading: false })
171
- }
172
- await strategy.removeItem('options')
173
- } else {
174
- setState({ ...state, loading: false })
175
- }
176
- } catch (err) {
177
- const message = err?.message?.includes('Internal error')
178
- ? 'INTERNAL_ERROR'
179
- : !err.message
180
- ? t('NETWORK_ERROR', 'Network error')
181
- : err.message
182
- setAlert({ show: true, content: [message] })
183
- setState({ ...state, loading: false })
184
- }
185
- }
186
-
187
- const checkAddress = (address) => {
188
- const props = ['address', 'address_notes', 'zipcode', 'location', 'internal_number']
189
- const values = []
190
- props.forEach(prop => {
191
- if (state.options?.address && state.options?.address?.[prop]) {
192
- if (prop === 'location') {
193
- values.push(address?.[prop]?.lat === state.options?.address?.[prop]?.lat &&
194
- address?.[prop]?.lng === state.options?.address?.[prop]?.lng)
195
- } else {
196
- values.push(address?.[prop] === state.options?.address?.[prop])
197
- }
198
- } else {
199
- values.push(!address?.[prop])
200
- }
201
- })
202
- return values.every(value => value)
203
- }
204
-
205
- /**
206
- * Change order address
207
- */
208
- const changeAddress = async (addressId, params) => {
209
- const isCountryCodeChanged = state.options?.address?.country_code !== params?.country_code
210
- if (typeof addressId === 'object') {
211
- const optionsStorage = await strategy.getItem('options', true)
212
- const options = {
213
- ...state.options,
214
- ...optionsStorage,
215
- address: {
216
- ...optionsStorage?.address,
217
- ...addressId
218
- }
219
- }
220
- if (!session.auth) {
221
- options.type = state?.options?.type
222
- }
223
- await strategy.setItem('options', options, true)
224
- setState({
225
- ...state,
226
- options
227
- })
228
- return
229
- }
230
-
231
- const _params = { country_code: params?.country_code }
232
-
233
- params?.type && (_params.type = params?.type)
234
-
235
- if (params && params?.address && !checkAddress(params?.address)) {
236
- _params.address_id = params?.address?.id
237
- await updateOrderOptions(_params)
238
- if (isCountryCodeChanged) {
239
- events.emit('country_code_changed', params?.country_code)
240
- }
241
- return
242
- }
243
- addressId && (_params.address_id = addressId)
244
- if (params && params?.isEdit) {
245
- if (addressId !== state.options.address_id) {
246
- return
247
- }
248
- await updateOrderOptions(_params)
249
- if (isCountryCodeChanged) {
250
- events.emit('country_code_changed', params?.country_code)
251
- }
252
- return
253
- }
254
- await updateOrderOptions(_params)
255
- if (isCountryCodeChanged) {
256
- events.emit('country_code_changed', params?.country_code)
257
- }
258
- }
259
-
260
- /**
261
- * Change order type
262
- */
263
- const changeType = async (type) => {
264
- const options = {
265
- ...state.options,
266
- type
267
- }
268
- if (state.options.type === type) {
269
- return
270
- }
271
-
272
- const cityId = state.options?.city_id
273
- const params = { type }
274
-
275
- if (cityId && type !== 2) {
276
- params.city_id = null
277
- }
278
-
279
- if (!session.auth) {
280
- const _options = { ...options, ...params }
281
- await strategy.setItem('options', _options, true)
282
- setState({
283
- ...state,
284
- options: _options
285
- })
286
- }
287
-
288
- updateOrderOptions(params)
289
- }
290
-
291
- /**
292
- * Change order moment
293
- */
294
- const changeMoment = async (moment) => {
295
- const momentUnix = moment ? moment.getTime() / 1000 : null
296
- const momentFormatted = momentUnix ? dayjs.unix(momentUnix).utc().format('YYYY-MM-DD HH:mm:ss') : null
297
-
298
- const options = {
299
- ...state.options,
300
- moment: momentFormatted
301
- }
302
- if (state.options.moment === momentFormatted) {
303
- return
304
- }
305
-
306
- if (!session.auth) {
307
- await strategy.setItem('options', options, true)
308
- setState({
309
- ...state,
310
- options
311
- })
312
- }
313
-
314
- updateOrderOptions({ moment: momentUnix })
315
- }
316
-
317
- /**
318
- * Change order city
319
- */
320
- const changeCityFilter = async (id) => {
321
- const options = {
322
- ...state.options,
323
- city_id: id
324
- }
325
- if (state.options.city_id === id) {
326
- return
327
- }
328
-
329
- if (!session.auth) {
330
- await strategy.setItem('options', options, true)
331
- setState({
332
- ...state,
333
- options
334
- })
335
- }
336
-
337
- updateOrderOptions({ city_id: id })
338
- }
339
- /**
340
- * Update order option data
341
- * @param {object} changes Changes to update order options
342
- */
343
- const updateOrderOptions = async (changes) => {
344
- if (session.auth) {
345
- const countryCodeFromLocalStorage = await strategy.getItem('country-code')
346
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
347
- const userCustomerId = customerFromLocalStorage?.id
348
- const body = {
349
- ...changes,
350
- user_id: userCustomerId || session.user.id
351
- }
352
- try {
353
- setState({ ...state, loading: true })
354
- const options = {}
355
- state.loading = true
356
- options.headers = {
357
- 'X-Socket-Id-X': socket?.getId()
358
- }
359
- const countryCode = changes?.country_code && changes?.country_code !== state?.options?.address?.country_code
360
- ? changes?.country_code
361
- : countryCodeFromLocalStorage ?? changes?.country_code ?? state?.options?.address?.country_code
362
-
363
- if (countryCode) {
364
- options.headers = {
365
- ...options.headers,
366
- 'X-Country-Code-X': countryCode
367
- }
368
- await strategy.setItem('country-code', countryCode)
369
- }
370
- if (franchiseId) {
371
- options.query = {
372
- ...options.query,
373
- franchise_id: franchiseId
374
- }
375
- }
376
- if (body?.country_code) {
377
- delete body?.country_code
378
- }
379
- const { content: { error, result } } = await ordering
380
- .setAccessToken(session.token)
381
- .orderOptions()
382
- .save(body, options)
383
- if (!error) {
384
- const { carts, ...options } = result
385
- state.carts = {}
386
- carts.forEach(cart => {
387
- state.carts[`businessId:${cart.business_id}`] = cart
388
- })
389
- state.options = {
390
- ...state.options,
391
- ...options
392
- }
393
- } else {
394
- setAlert({ show: true, content: result })
395
- }
396
- setState({ ...state, loading: false })
397
- state.loading = false
398
- return !error
399
- } catch (err) {
400
- const message = err?.message?.includes('Internal error')
401
- ? 'INTERNAL_ERROR'
402
- : err.message
403
- setAlert({ show: true, content: [message] })
404
- setState({ ...state, loading: false })
405
- state.loading = false
406
- return false
407
- }
408
- }
409
- }
410
-
411
- /**
412
- * Add product to cart
413
- * @param {object} product product for add
414
- * @param {object} cart cart of the product
415
- * @param {boolean} isQuickAddProduct option to add product when clicks
416
- */
417
- const addProduct = async (
418
- product,
419
- cart,
420
- isQuickAddProduct,
421
- isPlatformProduct = false
422
- ) => {
423
- try {
424
- setState({ ...state, loading: true })
425
- const countryCode = await strategy.getItem('country-code')
426
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
427
- const userCustomerId = customerFromLocalStorage?.id
428
- let body
429
- const headers = {
430
- 'X-Socket-Id-X': socket?.getId(),
431
- 'X-Country-Code-X': countryCode
432
- }
433
- if (!isPlatformProduct) {
434
- body = {
435
- product,
436
- business_id: cart.business_id,
437
- user_id: userCustomerId || session.user.id
438
- }
439
- } else {
440
- body = {
441
- platform_product: { ...product }
442
- }
443
- }
444
-
445
- const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().addProduct(body, { headers })
446
-
447
- if (!error) {
448
- state.carts[`businessId:${result.business_id}`] = result
449
- events.emit('cart_product_added', product, result)
450
- if (product?.favorite) {
451
- events.emit('wishlist_product_added_to_cart', product, result)
452
- }
453
- events.emit('cart_updated', result)
454
- events.emit('product_added', product, result)
455
- isQuickAddProduct && !isDisableToast && showToast(ToastType.Success, t('PRODUCT_ADDED_NOTIFICATION', 'Product _PRODUCT_ added succesfully').replace('_PRODUCT_', product.name))
456
- } else {
457
- setAlert({ show: true, content: result })
458
- }
459
- setState({ ...state, loading: false })
460
- if (isPlatformProduct) {
461
- return { error, result }
462
- } else {
463
- return !error
464
- }
465
- } catch (err) {
466
- setState({ ...state, loading: false })
467
- if (isPlatformProduct) {
468
- return { error: true, result: err.message }
469
- } else {
470
- return false
471
- }
472
- }
473
- }
474
-
475
- /**
476
- * Add multi products to cart / (domino's)
477
- * @param {object} product product for add
478
- * @param {object} cart cart of the product
479
- * @param {boolean} isQuickAddProduct option to add product when clicks
480
- */
481
- const addMultiProduct = async (
482
- product,
483
- cart,
484
- isQuickAddProduct
485
- ) => {
486
- try {
487
- setState({ ...state, loading: true })
488
- const countryCode = await strategy.getItem('country-code')
489
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
490
- const userCustomerId = customerFromLocalStorage?.id
491
- const headers = {
492
- 'X-Socket-Id-X': socket?.getId(),
493
- 'X-Country-Code-X': countryCode
494
- }
495
- const body = {
496
- products: JSON.stringify(product),
497
- business_id: cart.business_id,
498
- user_id: userCustomerId || session.user.id
499
- }
500
- const response = await fetch(`${ordering.root}/carts/multi_product`, {
501
- method: 'POST',
502
- body: JSON.stringify({
503
- ...body,
504
- products: JSON.stringify([product])
505
- }),
506
- headers: {
507
- ...headers,
508
- Authorization: `Bearer ${session.token}`,
509
- 'Content-Type': 'application/json'
510
- }
511
- })
512
- const { result, error } = await response.json()
513
- if (!error) {
514
- state.carts[`businessId:${result.business_id}`] = result
515
- events.emit('cart_product_added', product, result)
516
- if (product?.favorite) {
517
- events.emit('wishlist_product_added_to_cart', product, result)
518
- }
519
- events.emit('cart_updated', result)
520
- events.emit('product_added', product, result)
521
- isQuickAddProduct && !isDisableToast && showToast(ToastType.Success, t('PRODUCT_ADDED_NOTIFICATION', 'Product _PRODUCT_ added succesfully').replace('_PRODUCT_', product.name))
522
- } else {
523
- setAlert({ show: true, content: result })
524
- }
525
- setState({ ...state, loading: false })
526
- return !error
527
- } catch (err) {
528
- setState({ ...state, loading: false })
529
- return false
530
- }
531
- }
532
-
533
- /**
534
- * Remove product to cart
535
- */
536
- const removeProduct = async (product, cart) => {
537
- try {
538
- setState({ ...state, loading: true })
539
- const countryCode = await strategy.getItem('country-code')
540
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
541
- const userCustomerId = customerFromLocalStorage?.id
542
- const body = {
543
- product: {
544
- id: product.id,
545
- code: product.code,
546
- business_id: product.business_id
547
- },
548
- business_id: cart.business_id,
549
- user_id: userCustomerId || session.user.id
550
- }
551
- const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().removeProduct(body, {
552
- headers: {
553
- 'X-Socket-Id-X': socket?.getId(),
554
- 'X-Country-Code-X': countryCode
555
- }
556
- })
557
- if (!error) {
558
- state.carts[`businessId:${result.business_id}`] = result
559
- events.emit('cart_product_removed', product, result)
560
- events.emit('cart_updated', result)
561
- } else {
562
- setAlert({ show: true, content: result })
563
- }
564
- setState({ ...state, loading: false })
565
- return !error
566
- } catch (err) {
567
- setState({ ...state, loading: false })
568
- return false
569
- }
570
- }
571
-
572
- /**
573
- * Clear products of cart
574
- */
575
- const clearCart = async (uuid, configurations = {}) => {
576
- try {
577
- setState({ ...state, loading: !configurations?.disableLoading })
578
- const countryCode = await strategy.getItem('country-code')
579
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
580
- const userCustomerId = customerFromLocalStorage?.id
581
- const body = JSON.stringify({
582
- uuid,
583
- user_id: userCustomerId || session.user.id
584
- })
585
- const response = await fetch(`${ordering.root}/carts/clear`, {
586
- method: 'POST',
587
- headers: {
588
- 'Content-Type': 'application/json',
589
- Authorization: `Bearer ${session.token}`,
590
- 'X-App-X': ordering.appId,
591
- 'X-Socket-Id-X': socket?.getId(),
592
- 'X-Country-Code-X': countryCode
593
- },
594
- body
595
- })
596
- const { error, result } = await response.json()
597
- if (!error) {
598
- state.carts[`businessId:${result.business_id}`] = result
599
- } else {
600
- setAlert({ show: true, content: result })
601
- }
602
- setState({ ...state, loading: false })
603
- return { error, result }
604
- } catch (err) {
605
- setState({ ...state, loading: false })
606
- return false
607
- }
608
- }
609
-
610
- /**
611
- * Update product to cart
612
- */
613
- const updateProduct = async (product, cart, isQuickAddProduct) => {
614
- try {
615
- setState({ ...state, loading: true })
616
- const countryCode = await strategy.getItem('country-code')
617
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
618
- const userCustomerId = customerFromLocalStorage?.id
619
- const body = {
620
- product,
621
- business_id: cart.business_id,
622
- user_id: userCustomerId || session.user.id
623
- }
624
- const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().updateProduct(body, {
625
- headers: {
626
- 'X-Socket-Id-X': socket?.getId(),
627
- 'X-Country-Code-X': countryCode
628
- }
629
- })
630
- if (!error) {
631
- state.carts[`businessId:${result.business_id}`] = result
632
- events.emit('cart_product_updated', product, result)
633
- events.emit('cart_updated', result)
634
- isQuickAddProduct && !isDisableToast && showToast(ToastType.Success, t('PRODUCT_UPDATED_NOTIFICATION', 'Product _PRODUCT_ updated succesfully').replace('_PRODUCT_', product.name))
635
- } else {
636
- setAlert({ show: true, content: result })
637
- }
638
- setState({ ...state, loading: false })
639
- return !error
640
- } catch (err) {
641
- setState({ ...state, loading: false })
642
- return false
643
- }
644
- }
645
-
646
- /**
647
- * Apply coupon to cart
648
- */
649
- const applyCoupon = async (couponData, customParams) => {
650
- if (!couponData.business_id) {
651
- throw new Error('`business_id` is required.')
652
- }
653
- if (typeof couponData.coupon === 'undefined') {
654
- throw new Error('`coupon` is required.')
655
- }
656
- if (state.carts[`businessId:${couponData.business_id}`]?.coupon === couponData.coupon) {
657
- return
658
- }
659
-
660
- try {
661
- setState({ ...state, loading: true })
662
- const countryCode = await strategy.getItem('country-code')
663
- if (customParams && isAlsea) {
664
- const response = await fetch('https://alsea-plugins.ordering.co/alseaplatform/vcoupon2.php', {
665
- method: 'POST',
666
- body: JSON.stringify({
667
- userId: customParams.userId,
668
- businessId: customParams.businessId,
669
- couponId: couponData.coupon
670
- }),
671
- headers: {
672
- Accept: 'application/json',
673
- 'Content-Type': 'application/x-www-form-urlencoded',
674
- 'Access-Control-Allow-Origin': '*',
675
- 'X-App-X': ordering.appId,
676
- 'X-Socket-Id-X': socket?.getId(),
677
- 'X-Country-Code-X': countryCode
678
- }
679
- })
680
- const result = await response.json()
681
-
682
- if (result.message !== 'Cup\u00f3n v\u00e1lido') {
683
- setAlert({ show: true, content: result.message === 'Not found' ? ['ERROR_INVALID_COUPON'] : [result.message] })
684
- setState({ ...state, loading: false })
685
- return
686
- }
687
- }
688
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
689
- const userCustomerId = customerFromLocalStorage?.id
690
- const body = {
691
- business_id: couponData.business_id,
692
- coupon: couponData.coupon,
693
- user_id: userCustomerId || session.user.id
694
- }
695
- const { content } = await ordering
696
- .setAccessToken(session.token)
697
- .carts()
698
- .applyCoupon(body, {
699
- headers: {
700
- 'X-Socket-Id-X': socket?.getId(),
701
- 'X-Country-Code-X': countryCode
702
- }
703
- })
704
- const result = content
705
- if (!result.error) {
706
- state.carts[`businessId:${result.result.business_id}`] = result.result
707
- events.emit('cart_updated', result.result)
708
- } else {
709
- setAlert({ show: true, content: result.result })
710
- }
711
- setState({ ...state, loading: false })
712
- return !result.error
713
- } catch (err) {
714
- setState({ ...state, loading: false })
715
- return false
716
- }
717
- }
718
-
719
- const applyOffer = async (offerData) => {
720
- if (!offerData.business_id) {
721
- throw new Error('`business_id` is required.')
722
- }
723
- if (typeof offerData.coupon === 'undefined') {
724
- throw new Error('`coupon` is required.')
725
- }
726
- try {
727
- setState({ ...state, loading: true })
728
- const countryCode = await strategy.getItem('country-code')
729
- const response = await fetch(`${ordering.root}/carts/add_offer`, {
730
- method: 'POST',
731
- body: JSON.stringify({
732
- user_id: offerData.userId,
733
- business_id: offerData.business_id,
734
- coupon: offerData.coupon,
735
- force: offerData.force ?? false
736
- }),
737
- headers: {
738
- 'Content-Type': 'application/json',
739
- Authorization: `Bearer ${session.token}`,
740
- 'X-App-X': ordering.appId,
741
- 'X-Socket-Id-X': socket?.getId(),
742
- 'X-Country-Code-X': countryCode
743
- }
744
- })
745
- const result = await response.json()
746
- if (!result.error) {
747
- state.carts[`businessId:${result.result.business_id}`] = result.result
748
- events.emit('cart_updated', result.result)
749
- events.emit('offer_applied', { ...result.result, ...offerData })
750
- } else {
751
- setAlert({ show: true, content: result.result })
752
- events.emit('offer_denied', { ...offerData, reason: result.result })
753
- }
754
- setState({ ...state, loading: false })
755
- return !result.error
756
- } catch (err) {
757
- setState({ ...state, loading: false })
758
- return false
759
- }
760
- }
761
-
762
- const removeOffer = async (offerData) => {
763
- if (!offerData.business_id) {
764
- throw new Error('`business_id` is required.')
765
- }
766
- if (typeof offerData.offer_id === 'undefined') {
767
- throw new Error('`offer_id` is required.')
768
- }
769
- try {
770
- const countryCode = await strategy.getItem('country-code')
771
- setState({ ...state, loading: true })
772
- const offerRemoveData = {
773
- business_id: offerData.business_id,
774
- offer_id: offerData.offer_id
775
- }
776
- if (offerData.user_id) offerRemoveData.user_id = offerData.user_id
777
- const response = await fetch(`${ordering.root}/carts/remove_offer`, {
778
- method: 'POST',
779
- body: JSON.stringify(offerRemoveData),
780
- headers: {
781
- 'Content-Type': 'application/json',
782
- Authorization: `Bearer ${session.token}`,
783
- 'X-App-X': ordering.appId,
784
- 'X-Socket-Id-X': socket?.getId(),
785
- 'X-Country-Code-X': countryCode
786
- }
787
- })
788
- const result = await response.json()
789
- if (!result.error) {
790
- state.carts[`businessId:${result.result.business_id}`] = result.result
791
- events.emit('cart_updated', result.result)
792
- events.emit('offer_removed', offerData)
793
- } else {
794
- setAlert({ show: true, content: result.result })
795
- }
796
- setState({ ...state, loading: false })
797
- return !result.error
798
- } catch (err) {
799
- setState({ ...state, loading: false })
800
- return false
801
- }
802
- }
803
-
804
- /**
805
- * Apply coupon to cart
806
- */
807
- const changeDriverTip = async (businessId, driverTipRate = 0, isFixedPrice) => {
808
- if (!businessId) {
809
- throw new Error('`businessId` is required.')
810
- }
811
- if (!driverTipRate && driverTipRate !== 0) {
812
- throw new Error('`driverTipRate` is required.')
813
- }
814
- if (!state.carts[`businessId:${businessId}`] || state.carts[`businessId:${businessId}`]?.driver_tip_rate === driverTipRate) {
815
- return
816
- }
817
- try {
818
- setState({ ...state, loading: true })
819
- const countryCode = await strategy.getItem('country-code')
820
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
821
- const userCustomerId = customerFromLocalStorage?.id
822
- const body = {
823
- business_id: businessId,
824
- [isFixedPrice ? 'driver_tip' : 'driver_tip_rate']: driverTipRate,
825
- user_id: userCustomerId || session.user.id
826
- }
827
- const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().changeDriverTip(body, {
828
- headers: {
829
- 'X-Socket-Id-X': socket?.getId(),
830
- 'X-Country-Code-X': countryCode
831
- }
832
- })
833
- if (!error) {
834
- state.carts[`businessId:${result.business_id}`] = result
835
- events.emit('cart_updated', result)
836
- } else {
837
- setAlert({ show: true, content: result })
838
- }
839
- setState({ ...state, loading: false })
840
- return !error
841
- } catch (err) {
842
- setState({ ...state, loading: false })
843
- return false
844
- }
845
- }
846
-
847
- /**
848
- * Change payment method
849
- */
850
- const changePaymethod = async (businessId, paymethodId, paymethodData) => {
851
- if (!businessId) {
852
- throw new Error('`businessId` is required.')
853
- }
854
- if (!paymethodId) {
855
- throw new Error('`paymethodId` is required.')
856
- }
857
- if (!paymethodData) {
858
- throw new Error('`paymethodData` is required.')
859
- }
860
- if (!state.carts[`businessId:${businessId}`] || state.carts[`businessId:${businessId}`]?.paymethodId === paymethodId) {
861
- return
862
- }
863
- try {
864
- setState({ ...state, loading: true })
865
- const countryCode = await strategy.getItem('country-code')
866
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
867
- const userCustomerId = customerFromLocalStorage?.id
868
- const body = {
869
- business_id: businessId,
870
- paymethod_id: paymethodId,
871
- paymethod_data: paymethodData,
872
- user_id: userCustomerId ?? session.user.id
873
- }
874
- const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().changePaymethod(body, {
875
- headers: {
876
- 'X-Socket-Id-X': socket?.getId(),
877
- 'X-Country-Code-X': countryCode
878
- }
879
- })
880
- if (!error) {
881
- state.carts[`businessId:${result.business_id}`] = result
882
- events.emit('cart_updated', result)
883
- }
884
- setState({ ...state, loading: false })
885
- return !error
886
- } catch (err) {
887
- refreshOrderOptions()
888
- setState({ ...state, loading: false })
889
- return false
890
- }
891
- }
892
-
893
- /**
894
- * Place cart
895
- */
896
- const placeCart = async (cardId, data) => {
897
- try {
898
- setState({ ...state, loading: true })
899
- const countryCode = await strategy.getItem('country-code')
900
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
901
- const userCustomerId = customerFromLocalStorage?.id
902
- const body = {
903
- ...data,
904
- user_id: userCustomerId || session.user.id
905
- }
906
- let headers = {
907
- 'X-Socket-Id-X': socket?.getId(),
908
- 'X-Country-Code-X': countryCode
909
- }
910
- if (userAgent) {
911
- headers = { ...headers, 'User-Agent': userAgent }
912
- }
913
- const { content: { error, result } } = await ordering.setAccessToken(session.token).carts(cardId).place(body, { headers: headers })
914
- if (!error) {
915
- if (result.status !== 1) {
916
- state.carts[`businessId:${result.business_id}`] = result
917
- events.emit('cart_updated', result)
918
- } else {
919
- delete state.carts[`businessId:${result.business_id}`]
920
- const orderObject = {
921
- id: result.order.uuid,
922
- business: { name: result.business.name },
923
- total: result.total,
924
- tax_total: result.tax,
925
- delivery_zone_price: result.delivery_price,
926
- business_id: result.business_id,
927
- paymethod: result.paymethod_data.gateway
928
- }
929
- events.emit('order_placed', orderObject)
930
- }
931
- } else {
932
- setAlert({ show: true, content: result })
933
- setState({ ...state, loading: false })
934
- return
935
- }
936
- setState({ ...state, loading: false })
937
- return { error, result }
938
- } catch (err) {
939
- setState({ ...state, loading: false })
940
- return {
941
- error: true,
942
- result: [err.message]
943
- }
944
- }
945
- }
946
-
947
- /**
948
- * Place multi carts
949
- */
950
- const placeMultiCarts = async (data, cartUuid) => {
951
- try {
952
- setState({ ...state, loading: true })
953
- const countryCode = await strategy.getItem('country-code')
954
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
955
- const userCustomerId = customerFromLocalStorage?.id
956
- const body = {
957
- ...data,
958
- user_id: userCustomerId || session.user.id
959
- }
960
- const requestOptions = {
961
- method: 'POST',
962
- headers: {
963
- 'Content-Type': 'application/json',
964
- Authorization: `bearer ${session.token}`,
965
- 'X-App-X': ordering.appId,
966
- 'X-Socket-Id-X': socket?.getId(),
967
- 'X-Country-Code-X': countryCode
968
- },
969
- body: JSON.stringify(body)
970
- }
971
-
972
- const response = await fetch(`${ordering.root}/cart_groups/${cartUuid}/place`, requestOptions)
973
- const { error, result } = await response.json()
974
- if (!error) {
975
- result.carts.forEach(cart => {
976
- delete state.carts[`businessId:${cart.business_id}`]
977
- const orderObject = {
978
- id: cart.uuid,
979
- business: { name: cart.business.name },
980
- total: cart.total,
981
- tax_total: cart.tax,
982
- delivery_zone_price: cart.delivery_price,
983
- business_id: cart.business_id
984
- }
985
- events.emit('order_placed', orderObject)
986
- })
987
- } else {
988
- setAlert({ show: true, content: result })
989
- }
990
- setState({ ...state, loading: false })
991
- return { error, result }
992
- } catch (err) {
993
- setState({ ...state, loading: false })
994
- return {
995
- error: true,
996
- result: [err.message]
997
- }
998
- }
999
- }
1000
-
1001
- /**
1002
- * Confirm cart
1003
- */
1004
- const confirmCart = async (cardId, data) => {
1005
- try {
1006
- setState({ ...state, loading: true })
1007
- const countryCode = await strategy.getItem('country-code')
1008
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
1009
- const userCustomerId = customerFromLocalStorage?.id
1010
- const body = {
1011
- ...data,
1012
- user_id: userCustomerId || session.user.id
1013
- }
1014
- let fetchurl
1015
- if (body.user_id === userCustomerId || data) {
1016
- fetchurl = await ordering.setAccessToken(session.token).carts(cardId).confirmWithData(body, {
1017
- headers: {
1018
- 'X-Socket-Id-X': socket?.getId(),
1019
- 'X-Country-Code-X': countryCode
1020
- }
1021
- })
1022
- } else {
1023
- fetchurl = await ordering.setAccessToken(session.token).carts(cardId).confirm(body, {
1024
- headers: {
1025
- 'X-Socket-Id-X': socket?.getId(),
1026
- 'X-Country-Code-X': countryCode
1027
- }
1028
- })
1029
- }
1030
- const { content: { error, result, cart } } = fetchurl
1031
- if (!error) {
1032
- if (result.status !== 1) {
1033
- state.carts[`businessId:${result.business_id}`] = result
1034
- events.emit('cart_updated', result)
1035
- } else {
1036
- delete state.carts[`businessId:${result.business_id}`]
1037
- }
1038
- } else if (cart) {
1039
- state.carts[`businessId:${cart.business_id}`] = cart
1040
- events.emit('cart_updated', cart)
1041
- }
1042
- setState({ ...state, loading: false })
1043
- return { error, result }
1044
- } catch (err) {
1045
- setState({ ...state, loading: false })
1046
- return {
1047
- error: true,
1048
- result: [err.message]
1049
- }
1050
- }
1051
- }
1052
-
1053
- /**
1054
- * Confirm multi carts
1055
- */
1056
- const confirmMultiCarts = async (cartUuid) => {
1057
- try {
1058
- setState({ ...state, loading: true })
1059
- const countryCode = await strategy.getItem('country-code')
1060
- const requestOptions = {
1061
- method: 'POST',
1062
- headers: {
1063
- 'Content-Type': 'application/json',
1064
- Authorization: `bearer ${session.token}`,
1065
- 'X-App-X': ordering.appId,
1066
- 'X-Socket-Id-X': socket?.getId(),
1067
- 'X-Country-Code-X': countryCode
1068
- }
1069
- }
1070
- const response = await fetch(`${ordering.root}/cart_groups/${cartUuid}/confirm`, requestOptions)
1071
- const { result, error } = await response.json()
1072
- if (!error) {
1073
- result.carts.forEach(cart => {
1074
- if (result.status !== 'completed') {
1075
- state.carts[`businessId:${cart.business_id}`] = result
1076
- events.emit('cart_updated', result)
1077
- } else {
1078
- delete state.carts[`businessId:${cart.business_id}`]
1079
- }
1080
- })
1081
- }
1082
- setState({ ...state, loading: false })
1083
- return { error, result }
1084
- } catch (err) {
1085
- setState({ ...state, loading: false })
1086
- return {
1087
- error: true,
1088
- result: [err.message]
1089
- }
1090
- }
1091
- }
1092
-
1093
- /**
1094
- * Reorder an order and get cart
1095
- */
1096
- const reorder = async (orderId, offAlert, configurations = {}) => {
1097
- try {
1098
- setState({ ...state, loading: !configurations?.disableLoading })
1099
- const countryCode = await strategy.getItem('country-code')
1100
- const customerFromLocalStorage = await strategy.getItem('user-customer', true)
1101
- const userCustomerId = customerFromLocalStorage?.id
1102
- const query = userCustomerId
1103
- ? { user_id: userCustomerId }
1104
- : null
1105
- const options = {
1106
- headers: {
1107
- 'X-Socket-Id-X': socket?.getId(),
1108
- 'X-Country-Code-X': countryCode
1109
- }
1110
- }
1111
- if (query) {
1112
- options.query = query
1113
- }
1114
- const { content: { error, result } } = await ordering.setAccessToken(session.token).orders(orderId).reorder(options)
1115
- if (!error) {
1116
- state.carts[`businessId:${result.business_id}`] = result
1117
- events.emit('cart_added', result)
1118
- } else if (!offAlert) {
1119
- setAlert({ show: true, content: result })
1120
- }
1121
- setState({ ...state, loading: false })
1122
- return { error, result }
1123
- } catch (err) {
1124
- setState({ ...state, loading: false })
1125
- return { error: true, result: [err.message] }
1126
- }
1127
- }
1128
-
1129
- const setOptionFromLocalStorage = async () => {
1130
- const optionsLocalStorage = await strategy.getItem('options', true)
1131
- setState({
1132
- ...state,
1133
- loading: false,
1134
- options: isDisabledDefaultOpts
1135
- ? { type: null, moment: null }
1136
- : {
1137
- type: optionsLocalStorage?.type || orderTypes[configState?.configs?.default_order_type?.value],
1138
- moment: optionsLocalStorage?.moment || null,
1139
- address: optionsLocalStorage?.address || state?.options?.address || {},
1140
- city_id: optionsLocalStorage?.city_id || null
1141
- }
1142
- })
1143
- }
1144
-
1145
- /**
1146
- * get Latest past Order that has no review
1147
- */
1148
- const getLastOrderHasNoReview = async () => {
1149
- if (session?.token) {
1150
- const pastOrderTypes = [1, 2, 5, 6, 10, 11, 12, 15, 16, 17]
1151
- const where = [{ attribute: 'status', value: pastOrderTypes }]
1152
- if (franchiseId) {
1153
- where.push({
1154
- attribute: 'ref_business',
1155
- conditions: [
1156
- {
1157
- attribute: 'franchise_id',
1158
- value: {
1159
- condition: '=',
1160
- value: franchiseId
1161
- }
1162
- }
1163
- ]
1164
- })
1165
- }
1166
- if (typeof businessSlug === 'number' && businessSlug) {
1167
- where.push({
1168
- attribute: 'ref_business',
1169
- conditions: [
1170
- {
1171
- attribute: 'id',
1172
- value: {
1173
- condition: '=',
1174
- value: businessSlug
1175
- }
1176
- }
1177
- ]
1178
- })
1179
- }
1180
- if (typeof businessSlug === 'string' && businessSlug) {
1181
- where.push({
1182
- attribute: 'ref_business',
1183
- conditions: [
1184
- {
1185
- attribute: 'slug',
1186
- value: {
1187
- condition: '=',
1188
- value: businessSlug
1189
- }
1190
- }
1191
- ]
1192
- })
1193
- }
1194
- const options = {
1195
- query: {
1196
- orderBy: '-delivery_datetime',
1197
- page: 1,
1198
- page_size: 10,
1199
- where
1200
- }
1201
- }
1202
- const { content: { result, error } } = await ordering.setAccessToken(session?.token).orders().get(options)
1203
-
1204
- if (!error && result?.length > 0) {
1205
- const _noRviewOrder = result?.find(order => !order?.review)
1206
- if (_noRviewOrder?.cart_group_id) {
1207
- where.push({ attribute: 'cart_group_id', value: _noRviewOrder?.cart_group_id })
1208
- const options = {
1209
- query: {
1210
- where,
1211
- page: 1,
1212
- page_size: 10
1213
- }
1214
- }
1215
- const { content: { result, error } } = await ordering.setAccessToken(session?.token).orders().get(options)
1216
- if (!error) {
1217
- const noReviewOrders = result.filter(order => !order?.review)
1218
- return noReviewOrders
1219
- } else {
1220
- return null
1221
- }
1222
- } else {
1223
- return _noRviewOrder
1224
- }
1225
- } else {
1226
- return null
1227
- }
1228
- } else {
1229
- return null
1230
- }
1231
- }
1232
-
1233
- const setStateValues = (values) => {
1234
- setState({ ...state, ...values })
1235
- }
1236
-
1237
- const setUserCustomerOptions = async (params) => {
1238
- setState({ ...state, loading: true })
1239
- const options = params.options ?? {}
1240
- await setUserCustomer(params.customer ?? {}, true)
1241
- await updateOrderOptions(options)
1242
- setState({ ...state, loading: false })
1243
- }
1244
-
1245
- const handleOrderStateLoading = (loading) => {
1246
- setState({
1247
- ...state,
1248
- loading
1249
- })
1250
- }
1251
-
1252
- const handleLogEvent = async (events) => {
1253
- try {
1254
- const countryCode = await strategy.getItem('country-code')
1255
- const headers = {
1256
- 'X-Socket-Id-X': socket?.getId(),
1257
- 'X-Country-Code-X': countryCode
1258
- }
1259
- await fetch(`${ordering.root}/tracking_events`, {
1260
- method: 'POST',
1261
- body: JSON.stringify({
1262
- events
1263
- }),
1264
- headers: {
1265
- ...headers,
1266
- Authorization: `Bearer ${session.token}`,
1267
- 'Content-Type': 'application/json'
1268
- }
1269
- })
1270
- } catch (err) {}
1271
- }
1272
-
1273
- useEffect(() => {
1274
- if (session.loading || languageState.loading) return
1275
- if (session.auth) {
1276
- refreshOrderOptions()
1277
- }
1278
- }, [session.auth, session.loading, languageState.loading])
1279
-
1280
- useEffect(() => {
1281
- if (session.loading || configState.loading) return
1282
- if (!session.auth) {
1283
- setOptionFromLocalStorage()
1284
- }
1285
- }, [session.auth, session.loading, configState])
1286
-
1287
- useEffect(() => {
1288
- if (configTypes?.length > 0 && state.options.type && !configTypes.includes(state.options.type)) {
1289
- const validDefaultValue = configTypes.includes(configState?.configs?.default_order_type?.type)
1290
- updateOrderOptions(validDefaultValue ? { type: configState?.configs?.default_order_type?.type } : { type: configTypes[0] })
1291
- if (!session.auth && !state?.loading) {
1292
- changeType(validDefaultValue ? configState?.configs?.default_order_type?.type : configTypes[0])
1293
- }
1294
- }
1295
- }, [configTypes?.length, state.options.type])
1296
- /**
1297
- * Update carts from sockets
1298
- */
1299
- useEffect(() => {
1300
- const handleCartUpdate = (cart) => {
1301
- if (!isDisableToast) {
1302
- showToast(ToastType.Info, t('UPDATING_CART_INFO', 'Updating cart information...'))
1303
- }
1304
-
1305
- if (cart.status === 1) {
1306
- if (state.carts[`businessId:${cart.business_id}`]) {
1307
- delete state.carts[`businessId:${cart.business_id}`]
1308
- }
1309
- } else {
1310
- const cartFinded = Object.values(state.carts).find(_cart => _cart?.uuid === cart?.uuid)
1311
- const oldBusinessId = cartFinded?.business_id
1312
- const newBusinessId = cart?.business_id
1313
-
1314
- if (!oldBusinessId || oldBusinessId === newBusinessId) {
1315
- state.carts[`businessId:${cart.business_id}`] = {
1316
- ...state.carts[`businessId:${cart.business_id}`],
1317
- ...cart
1318
- }
1319
- } else {
1320
- delete state.carts[`businessId:${oldBusinessId}`]
1321
- state.carts[`businessId:${newBusinessId}`] = cart
1322
- }
1323
- }
1324
- }
1325
- const handleOrderOptionUpdate = ({ carts, ...options }) => {
1326
- if (!isDisableToast) {
1327
- showToast(ToastType.Info, t('UPDATING_ORDER_OPTIONS', 'Updating order options...'))
1328
- }
1329
-
1330
- const newCarts = {}
1331
- carts.forEach(cart => {
1332
- newCarts[`businessId:${cart.business_id}`] = cart
1333
- })
1334
- const newState = {
1335
- ...state,
1336
- options: {
1337
- ...state.options,
1338
- ...options
1339
- },
1340
- carts: {
1341
- ...state.carts,
1342
- ...newCarts
1343
- }
1344
- }
1345
- setState({ ...newState, loading: false })
1346
- }
1347
- socket.on('carts_update', handleCartUpdate)
1348
- socket.on('order_options_update', handleOrderOptionUpdate)
1349
- return () => {
1350
- socket.off('carts_update', handleCartUpdate)
1351
- socket.off('order_options_update', handleOrderOptionUpdate)
1352
- }
1353
- }, [state, socket])
1354
-
1355
- /**
1356
- * Join to carts room
1357
- */
1358
- useEffect(() => {
1359
- if (!session.auth || session.loading) return
1360
- socket.join(`carts_${customerState?.user?.id || session?.user?.id}`)
1361
- socket.join(`orderoptions_${customerState?.user?.id || session?.user?.id}`)
1362
- return () => {
1363
- socket.leave(`carts_${customerState?.user?.id || session?.user?.id}`)
1364
- socket.leave(`orderoptions_${customerState?.user?.id || session?.user?.id}`)
1365
- }
1366
- }, [socket, session.auth, session.loading, customerState?.user?.id, session?.user?.id])
1367
-
1368
- const functions = {
1369
- refreshOrderOptions,
1370
- changeAddress,
1371
- changeType,
1372
- changeMoment,
1373
- addProduct,
1374
- removeProduct,
1375
- updateProduct,
1376
- clearCart,
1377
- applyCoupon,
1378
- applyOffer,
1379
- removeOffer,
1380
- changeDriverTip,
1381
- placeCart,
1382
- confirmCart,
1383
- reorder,
1384
- setAlert,
1385
- setConfirm,
1386
- changePaymethod,
1387
- setUserCustomerOptions,
1388
- setStateValues,
1389
- placeMultiCarts,
1390
- getLastOrderHasNoReview,
1391
- changeCityFilter,
1392
- confirmMultiCarts,
1393
- addMultiProduct,
1394
- handleOrderStateLoading,
1395
- handleLogEvent
1396
- }
1397
-
1398
- const copyState = JSON.parse(JSON.stringify(state))
1399
-
1400
- return (
1401
- <OrderContext.Provider value={[copyState, functions]}>
1402
- {
1403
- Alert && (
1404
- <Alert
1405
- open={alert.show}
1406
- title={alert.title || t('ERROR', 'Error')}
1407
- onAccept={() => setAlert({ show: false })}
1408
- onClose={() => setAlert({ show: false })}
1409
- content={alert.content}
1410
- />
1411
- )
1412
- }
1413
- {children}
1414
- </OrderContext.Provider>
1415
- )
1416
- }
1417
-
1418
- /**
1419
- * Hook to get and update order state
1420
- */
1421
- export const useOrder = () => {
1422
- const orderManager = useContext(OrderContext)
1423
- const warningMessage = () => {
1424
- console.warn('Must use OrderProvider to wrappe the app.')
1425
- }
1426
- /**
1427
- * Functions to avoid fails
1428
- */
1429
- const functionsPlaceholders = {
1430
- refreshOrderOptions: warningMessage,
1431
- changeAddress: warningMessage,
1432
- changeType: warningMessage,
1433
- changeMoment: warningMessage,
1434
- addProduct: warningMessage,
1435
- removeProduct: warningMessage,
1436
- updateProduct: warningMessage,
1437
- clearCart: warningMessage,
1438
- applyCoupon: warningMessage,
1439
- placeCart: warningMessage,
1440
- confirmCart: warningMessage,
1441
- setAlert: warningMessage,
1442
- setConfirm: warningMessage,
1443
- changeDriverTip: warningMessage,
1444
- reorder: warningMessage,
1445
- changePaymethod: warningMessage,
1446
- setStateValues: warningMessage,
1447
- getLastOrderHasNoReview: warningMessage
1448
- }
1449
- return orderManager || [{}, functionsPlaceholders]
1450
- }
1
+ import React, { createContext, useContext, useState, useEffect } from 'react'
2
+ import { useSession } from '../SessionContext'
3
+ import { useApi } from '../ApiContext'
4
+ import { useWebsocket } from '../WebsocketContext'
5
+ import { useLanguage } from '../LanguageContext'
6
+ import { useEvent } from '../EventContext'
7
+ import { useConfig } from '../ConfigContext'
8
+ import { useCustomer } from '../CustomerContext'
9
+ import { ToastType, useToast } from '../ToastContext'
10
+ import dayjs from 'dayjs'
11
+ import utc from 'dayjs/plugin/utc'
12
+
13
+ dayjs.extend(utc)
14
+
15
+ /**
16
+ * Create OrderContext
17
+ * This context will manage the current order with options internally and provide an easy interface
18
+ */
19
+ export const OrderContext = createContext()
20
+
21
+ /**
22
+ * Custom provider to order manager
23
+ * This provider has a reducer for manage order state
24
+ * @param {props} props
25
+ */
26
+ export const OrderProvider = ({ Alert, children, strategy, isAlsea, isDisableToast, franchiseId, isDisabledDefaultOpts, businessSlug, userAgent }) => {
27
+ const [confirmAlert, setConfirm] = useState({ show: false })
28
+ const [alert, setAlert] = useState({ show: false })
29
+ const [ordering] = useApi()
30
+ const socket = useWebsocket()
31
+ const [languageState, t] = useLanguage()
32
+ const [events] = useEvent()
33
+ const [configState] = useConfig()
34
+ const [session, { logout }] = useSession()
35
+ const [customerState, { setUserCustomer }] = useCustomer()
36
+ const [, { showToast }] = useToast()
37
+
38
+ const configTypes = configState?.configs?.order_types_allowed?.value.split('|').map(value => Number(value)) || []
39
+
40
+ const orderTypes = {
41
+ delivery: 1,
42
+ pickup: 2,
43
+ eatin: 3,
44
+ curbside: 4,
45
+ drivethru: 5,
46
+ catering_delivery: 7,
47
+ catering_pickup: 8
48
+ }
49
+
50
+ const [state, setState] = useState({
51
+ loading: true,
52
+ options: isDisabledDefaultOpts
53
+ ? { type: null, moment: null, city_id: null }
54
+ : {
55
+ type: orderTypes[configState?.configs?.default_order_type?.value],
56
+ moment: null,
57
+ city_id: null
58
+ },
59
+ carts: {},
60
+ confirmAlert,
61
+ alert
62
+ })
63
+
64
+ /**
65
+ * Refresh order options and carts from API
66
+ */
67
+ const refreshOrderOptions = async () => {
68
+ try {
69
+ if (!state.loading) {
70
+ setState({ ...state, loading: true })
71
+ }
72
+ const countryCodeFromLocalStorage = await strategy.getItem('country-code')
73
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
74
+ const userCustomerId = customerFromLocalStorage?.id
75
+ const options = {}
76
+ if (userCustomerId) {
77
+ options.query = {
78
+ user_id: userCustomerId
79
+ }
80
+ }
81
+ if (franchiseId) {
82
+ options.query = {
83
+ ...options.query,
84
+ franchise_id: franchiseId
85
+ }
86
+ }
87
+
88
+ const countryCode = countryCodeFromLocalStorage && countryCodeFromLocalStorage !== state?.options?.address?.country_code
89
+ ? countryCodeFromLocalStorage
90
+ : state?.options?.address?.country_code
91
+
92
+ if (countryCode) {
93
+ options.headers = {
94
+ 'X-Socket-Id-X': socket?.getId(),
95
+ 'X-Country-Code-X': countryCode
96
+ }
97
+ }
98
+
99
+ const res = await ordering.setAccessToken(session.token).orderOptions().get(options)
100
+ const error = res?.content?.error
101
+ const result = res?.content?.result
102
+
103
+ if (!error) {
104
+ const { carts, ...options } = result
105
+ state.carts = {}
106
+ carts.forEach(cart => {
107
+ state.carts[`businessId:${cart.business_id}`] = cart
108
+ })
109
+ state.options = {
110
+ ...state.options,
111
+ ...options
112
+ }
113
+
114
+ if (!countryCodeFromLocalStorage && options?.address?.country_code) {
115
+ await updateOrderOptions({ country_code: options?.address?.country_code })
116
+ }
117
+ }
118
+ if (error) {
119
+ setAlert({ show: true, content: result })
120
+ if (res?.status === 401) {
121
+ session.auth && logout()
122
+ }
123
+ }
124
+ const localOptions = await strategy.getItem('options', true)
125
+ if (localOptions) {
126
+ const options = {}
127
+ if (Object.keys(localOptions.address).length > 0) {
128
+ const conditions = [
129
+ { attribute: 'address', value: localOptions?.address?.address }
130
+ ]
131
+ const userId = userCustomerId || session.user.id
132
+ const addressesResponse = await ordering.setAccessToken(session.token).users(userId).addresses().where(conditions).get()
133
+ let address = addressesResponse.content.result.find(address => {
134
+ localOptions.address.internal_number = localOptions.address?.internal_number || null
135
+ localOptions.address.zipcode = localOptions.address?.zipcode || null
136
+ localOptions.address.address_notes = localOptions.address?.address_notes || null
137
+
138
+ return address?.location?.lat === localOptions?.address?.location.lat &&
139
+ address?.location?.lng === localOptions?.address?.location?.lng &&
140
+ address?.internal_number === localOptions?.address?.internal_number &&
141
+ address?.zipcode === localOptions?.address?.zipcode &&
142
+ address?.address_notes === localOptions?.address?.address_notes
143
+ })
144
+ if (!address) {
145
+ Object.keys(localOptions.address).forEach(key => localOptions?.address?.[key] === null && delete localOptions?.address?.[key])
146
+ const { content: { error, result } } = await ordering.setAccessToken(session.token).users(userId).addresses().save(localOptions.address)
147
+ if (!error) {
148
+ address = result
149
+ }
150
+ } else {
151
+ await ordering.setAccessToken(session.token).users(userId).addresses(address.id).save({ default: true })
152
+ }
153
+ address && (options.address_id = address.id)
154
+ }
155
+ if (localOptions.type) {
156
+ options.type = localOptions.type
157
+ }
158
+ if (localOptions.moment) {
159
+ options.moment = dayjs.utc(localOptions.moment, 'YYYY-MM-DD HH:mm:ss').unix()
160
+ }
161
+ if (localOptions?.address_id) {
162
+ options.address_id = localOptions?.address_id
163
+ }
164
+ if (localOptions?.city_id) {
165
+ options.city_id = localOptions?.city_id
166
+ }
167
+ if (options && Object.keys(options).length > 0) {
168
+ updateOrderOptions(options)
169
+ } else {
170
+ setState({ ...state, loading: false })
171
+ }
172
+ await strategy.removeItem('options')
173
+ } else {
174
+ setState({ ...state, loading: false })
175
+ }
176
+ } catch (err) {
177
+ const message = err?.message?.includes('Internal error')
178
+ ? 'INTERNAL_ERROR'
179
+ : !err.message
180
+ ? t('NETWORK_ERROR', 'Network error')
181
+ : err.message
182
+ setAlert({ show: true, content: [message] })
183
+ setState({ ...state, loading: false })
184
+ }
185
+ }
186
+
187
+ const checkAddress = (address) => {
188
+ const props = ['address', 'address_notes', 'zipcode', 'location', 'internal_number']
189
+ const values = []
190
+ props.forEach(prop => {
191
+ if (state.options?.address && state.options?.address?.[prop]) {
192
+ if (prop === 'location') {
193
+ values.push(address?.[prop]?.lat === state.options?.address?.[prop]?.lat &&
194
+ address?.[prop]?.lng === state.options?.address?.[prop]?.lng)
195
+ } else {
196
+ values.push(address?.[prop] === state.options?.address?.[prop])
197
+ }
198
+ } else {
199
+ values.push(!address?.[prop])
200
+ }
201
+ })
202
+ return values.every(value => value)
203
+ }
204
+
205
+ /**
206
+ * Change order address
207
+ */
208
+ const changeAddress = async (addressId, params) => {
209
+ const isCountryCodeChanged = state.options?.address?.country_code !== params?.country_code
210
+ if (typeof addressId === 'object') {
211
+ const optionsStorage = await strategy.getItem('options', true)
212
+ const options = {
213
+ ...state.options,
214
+ ...optionsStorage,
215
+ address: {
216
+ ...optionsStorage?.address,
217
+ ...addressId
218
+ }
219
+ }
220
+ if (!session.auth) {
221
+ options.type = state?.options?.type
222
+ }
223
+ await strategy.setItem('options', options, true)
224
+ setState({
225
+ ...state,
226
+ options
227
+ })
228
+ return
229
+ }
230
+
231
+ const _params = { country_code: params?.country_code }
232
+
233
+ params?.type && (_params.type = params?.type)
234
+
235
+ if (params && params?.address && !checkAddress(params?.address)) {
236
+ _params.address_id = params?.address?.id
237
+ await updateOrderOptions(_params)
238
+ if (isCountryCodeChanged) {
239
+ events.emit('country_code_changed', params?.country_code)
240
+ }
241
+ return
242
+ }
243
+ addressId && (_params.address_id = addressId)
244
+ if (params && params?.isEdit) {
245
+ if (addressId !== state.options.address_id) {
246
+ return
247
+ }
248
+ await updateOrderOptions(_params)
249
+ if (isCountryCodeChanged) {
250
+ events.emit('country_code_changed', params?.country_code)
251
+ }
252
+ return
253
+ }
254
+ await updateOrderOptions(_params)
255
+ if (isCountryCodeChanged) {
256
+ events.emit('country_code_changed', params?.country_code)
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Change order type
262
+ */
263
+ const changeType = async (type) => {
264
+ const options = {
265
+ ...state.options,
266
+ type
267
+ }
268
+ if (state.options.type === type) {
269
+ return
270
+ }
271
+
272
+ const cityId = state.options?.city_id
273
+ const params = { type }
274
+
275
+ if (cityId && type !== 2) {
276
+ params.city_id = null
277
+ }
278
+
279
+ if (!session.auth) {
280
+ const _options = { ...options, ...params }
281
+ await strategy.setItem('options', _options, true)
282
+ setState({
283
+ ...state,
284
+ options: _options
285
+ })
286
+ }
287
+
288
+ updateOrderOptions(params)
289
+ }
290
+
291
+ /**
292
+ * Change order moment
293
+ */
294
+ const changeMoment = async (moment) => {
295
+ const momentUnix = moment ? moment.getTime() / 1000 : null
296
+ const momentFormatted = momentUnix ? dayjs.unix(momentUnix).utc().format('YYYY-MM-DD HH:mm:ss') : null
297
+
298
+ const options = {
299
+ ...state.options,
300
+ moment: momentFormatted
301
+ }
302
+ if (state.options.moment === momentFormatted) {
303
+ return
304
+ }
305
+
306
+ if (!session.auth) {
307
+ await strategy.setItem('options', options, true)
308
+ setState({
309
+ ...state,
310
+ options
311
+ })
312
+ }
313
+
314
+ updateOrderOptions({ moment: momentUnix })
315
+ }
316
+
317
+ /**
318
+ * Change order city
319
+ */
320
+ const changeCityFilter = async (id) => {
321
+ const options = {
322
+ ...state.options,
323
+ city_id: id
324
+ }
325
+ if (state.options.city_id === id) {
326
+ return
327
+ }
328
+
329
+ if (!session.auth) {
330
+ await strategy.setItem('options', options, true)
331
+ setState({
332
+ ...state,
333
+ options
334
+ })
335
+ }
336
+
337
+ updateOrderOptions({ city_id: id })
338
+ }
339
+ /**
340
+ * Update order option data
341
+ * @param {object} changes Changes to update order options
342
+ */
343
+ const updateOrderOptions = async (changes) => {
344
+ if (session.auth) {
345
+ const countryCodeFromLocalStorage = await strategy.getItem('country-code')
346
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
347
+ const userCustomerId = customerFromLocalStorage?.id
348
+ const body = {
349
+ ...changes,
350
+ user_id: userCustomerId || session.user.id
351
+ }
352
+ try {
353
+ setState({ ...state, loading: true })
354
+ const options = {}
355
+ state.loading = true
356
+ options.headers = {
357
+ 'X-Socket-Id-X': socket?.getId()
358
+ }
359
+ const countryCode = changes?.country_code && changes?.country_code !== state?.options?.address?.country_code
360
+ ? changes?.country_code
361
+ : countryCodeFromLocalStorage ?? changes?.country_code ?? state?.options?.address?.country_code
362
+
363
+ if (countryCode) {
364
+ options.headers = {
365
+ ...options.headers,
366
+ 'X-Country-Code-X': countryCode
367
+ }
368
+ await strategy.setItem('country-code', countryCode)
369
+ }
370
+ if (franchiseId) {
371
+ options.query = {
372
+ ...options.query,
373
+ franchise_id: franchiseId
374
+ }
375
+ }
376
+ if (body?.country_code) {
377
+ delete body?.country_code
378
+ }
379
+ const { content: { error, result } } = await ordering
380
+ .setAccessToken(session.token)
381
+ .orderOptions()
382
+ .save(body, options)
383
+ if (!error) {
384
+ const { carts, ...options } = result
385
+ state.carts = {}
386
+ carts.forEach(cart => {
387
+ state.carts[`businessId:${cart.business_id}`] = cart
388
+ })
389
+ state.options = {
390
+ ...state.options,
391
+ ...options
392
+ }
393
+ } else {
394
+ setAlert({ show: true, content: result })
395
+ }
396
+ setState({ ...state, loading: false })
397
+ state.loading = false
398
+ return !error
399
+ } catch (err) {
400
+ const message = err?.message?.includes('Internal error')
401
+ ? 'INTERNAL_ERROR'
402
+ : err.message
403
+ setAlert({ show: true, content: [message] })
404
+ setState({ ...state, loading: false })
405
+ state.loading = false
406
+ return false
407
+ }
408
+ }
409
+ }
410
+
411
+ /**
412
+ * Add product to cart
413
+ * @param {object} product product for add
414
+ * @param {object} cart cart of the product
415
+ * @param {boolean} isQuickAddProduct option to add product when clicks
416
+ */
417
+ const addProduct = async (
418
+ product,
419
+ cart,
420
+ isQuickAddProduct,
421
+ isPlatformProduct = false
422
+ ) => {
423
+ try {
424
+ setState({ ...state, loading: true })
425
+ const countryCode = await strategy.getItem('country-code')
426
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
427
+ const userCustomerId = customerFromLocalStorage?.id
428
+ let body
429
+ const headers = {
430
+ 'X-Socket-Id-X': socket?.getId(),
431
+ 'X-Country-Code-X': countryCode
432
+ }
433
+ if (!isPlatformProduct) {
434
+ body = {
435
+ product,
436
+ business_id: cart.business_id,
437
+ user_id: userCustomerId || session.user.id
438
+ }
439
+ } else {
440
+ body = {
441
+ platform_product: { ...product }
442
+ }
443
+ }
444
+
445
+ const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().addProduct(body, { headers })
446
+
447
+ if (!error) {
448
+ state.carts[`businessId:${result.business_id}`] = result
449
+ events.emit('cart_product_added', product, result)
450
+ if (product?.favorite) {
451
+ events.emit('wishlist_product_added_to_cart', product, result)
452
+ }
453
+ events.emit('cart_updated', result)
454
+ events.emit('product_added', product, result)
455
+ isQuickAddProduct && !isDisableToast && showToast(ToastType.Success, t('PRODUCT_ADDED_NOTIFICATION', 'Product _PRODUCT_ added succesfully').replace('_PRODUCT_', product.name))
456
+ } else {
457
+ setAlert({ show: true, content: result })
458
+ }
459
+ setState({ ...state, loading: false })
460
+ if (isPlatformProduct) {
461
+ return { error, result }
462
+ } else {
463
+ return !error
464
+ }
465
+ } catch (err) {
466
+ setState({ ...state, loading: false })
467
+ if (isPlatformProduct) {
468
+ return { error: true, result: err.message }
469
+ } else {
470
+ return false
471
+ }
472
+ }
473
+ }
474
+
475
+ /**
476
+ * Add multi products to cart / (domino's)
477
+ * @param {object} product product for add
478
+ * @param {object} cart cart of the product
479
+ * @param {boolean} isQuickAddProduct option to add product when clicks
480
+ */
481
+ const addMultiProduct = async (
482
+ product,
483
+ cart,
484
+ isQuickAddProduct
485
+ ) => {
486
+ try {
487
+ setState({ ...state, loading: true })
488
+ const countryCode = await strategy.getItem('country-code')
489
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
490
+ const userCustomerId = customerFromLocalStorage?.id
491
+ const headers = {
492
+ 'X-Socket-Id-X': socket?.getId(),
493
+ 'X-Country-Code-X': countryCode
494
+ }
495
+ const body = {
496
+ products: JSON.stringify(product),
497
+ business_id: cart.business_id,
498
+ user_id: userCustomerId || session.user.id
499
+ }
500
+ const response = await fetch(`${ordering.root}/carts/multi_product`, {
501
+ method: 'POST',
502
+ body: JSON.stringify({
503
+ ...body,
504
+ products: JSON.stringify([product])
505
+ }),
506
+ headers: {
507
+ ...headers,
508
+ Authorization: `Bearer ${session.token}`,
509
+ 'Content-Type': 'application/json'
510
+ }
511
+ })
512
+ const { result, error } = await response.json()
513
+ if (!error) {
514
+ state.carts[`businessId:${result.business_id}`] = result
515
+ events.emit('cart_product_added', product, result)
516
+ if (product?.favorite) {
517
+ events.emit('wishlist_product_added_to_cart', product, result)
518
+ }
519
+ events.emit('cart_updated', result)
520
+ events.emit('product_added', product, result)
521
+ isQuickAddProduct && !isDisableToast && showToast(ToastType.Success, t('PRODUCT_ADDED_NOTIFICATION', 'Product _PRODUCT_ added succesfully').replace('_PRODUCT_', product.name))
522
+ } else {
523
+ setAlert({ show: true, content: result })
524
+ }
525
+ setState({ ...state, loading: false })
526
+ return !error
527
+ } catch (err) {
528
+ setState({ ...state, loading: false })
529
+ return false
530
+ }
531
+ }
532
+
533
+ /**
534
+ * Remove product to cart
535
+ */
536
+ const removeProduct = async (product, cart) => {
537
+ try {
538
+ setState({ ...state, loading: true })
539
+ const countryCode = await strategy.getItem('country-code')
540
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
541
+ const userCustomerId = customerFromLocalStorage?.id
542
+ const body = {
543
+ product: {
544
+ id: product.id,
545
+ code: product.code,
546
+ business_id: product.business_id
547
+ },
548
+ business_id: cart.business_id,
549
+ user_id: userCustomerId || session.user.id
550
+ }
551
+ const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().removeProduct(body, {
552
+ headers: {
553
+ 'X-Socket-Id-X': socket?.getId(),
554
+ 'X-Country-Code-X': countryCode
555
+ }
556
+ })
557
+ if (!error) {
558
+ state.carts[`businessId:${result.business_id}`] = result
559
+ events.emit('cart_product_removed', product, result)
560
+ events.emit('cart_updated', result)
561
+ } else {
562
+ setAlert({ show: true, content: result })
563
+ }
564
+ setState({ ...state, loading: false })
565
+ return !error
566
+ } catch (err) {
567
+ setState({ ...state, loading: false })
568
+ return false
569
+ }
570
+ }
571
+
572
+ /**
573
+ * Clear products of cart
574
+ */
575
+ const clearCart = async (uuid, configurations = {}) => {
576
+ try {
577
+ setState({ ...state, loading: !configurations?.disableLoading })
578
+ const countryCode = await strategy.getItem('country-code')
579
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
580
+ const userCustomerId = customerFromLocalStorage?.id
581
+ const body = JSON.stringify({
582
+ uuid,
583
+ user_id: userCustomerId || session.user.id
584
+ })
585
+ const response = await fetch(`${ordering.root}/carts/clear`, {
586
+ method: 'POST',
587
+ headers: {
588
+ 'Content-Type': 'application/json',
589
+ Authorization: `Bearer ${session.token}`,
590
+ 'X-App-X': ordering.appId,
591
+ 'X-Socket-Id-X': socket?.getId(),
592
+ 'X-Country-Code-X': countryCode
593
+ },
594
+ body
595
+ })
596
+ const { error, result } = await response.json()
597
+ if (!error) {
598
+ state.carts[`businessId:${result.business_id}`] = result
599
+ } else {
600
+ setAlert({ show: true, content: result })
601
+ }
602
+ setState({ ...state, loading: false })
603
+ return { error, result }
604
+ } catch (err) {
605
+ setState({ ...state, loading: false })
606
+ return false
607
+ }
608
+ }
609
+
610
+ /**
611
+ * Update product to cart
612
+ */
613
+ const updateProduct = async (product, cart, isQuickAddProduct) => {
614
+ try {
615
+ setState({ ...state, loading: true })
616
+ const countryCode = await strategy.getItem('country-code')
617
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
618
+ const userCustomerId = customerFromLocalStorage?.id
619
+ const body = {
620
+ product,
621
+ business_id: cart.business_id,
622
+ user_id: userCustomerId || session.user.id
623
+ }
624
+ const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().updateProduct(body, {
625
+ headers: {
626
+ 'X-Socket-Id-X': socket?.getId(),
627
+ 'X-Country-Code-X': countryCode
628
+ }
629
+ })
630
+ if (!error) {
631
+ state.carts[`businessId:${result.business_id}`] = result
632
+ events.emit('cart_product_updated', product, result)
633
+ events.emit('cart_updated', result)
634
+ isQuickAddProduct && !isDisableToast && showToast(ToastType.Success, t('PRODUCT_UPDATED_NOTIFICATION', 'Product _PRODUCT_ updated succesfully').replace('_PRODUCT_', product.name))
635
+ } else {
636
+ setAlert({ show: true, content: result })
637
+ }
638
+ setState({ ...state, loading: false })
639
+ return !error
640
+ } catch (err) {
641
+ setState({ ...state, loading: false })
642
+ return false
643
+ }
644
+ }
645
+
646
+ /**
647
+ * Apply coupon to cart
648
+ */
649
+ const applyCoupon = async (couponData, customParams) => {
650
+ if (!couponData.business_id) {
651
+ throw new Error('`business_id` is required.')
652
+ }
653
+ if (typeof couponData.coupon === 'undefined') {
654
+ throw new Error('`coupon` is required.')
655
+ }
656
+ if (state.carts[`businessId:${couponData.business_id}`]?.coupon === couponData.coupon) {
657
+ return
658
+ }
659
+
660
+ try {
661
+ setState({ ...state, loading: true })
662
+ const countryCode = await strategy.getItem('country-code')
663
+ if (customParams && isAlsea) {
664
+ const response = await fetch('https://alsea-plugins.ordering.co/alseaplatform/vcoupon2.php', {
665
+ method: 'POST',
666
+ body: JSON.stringify({
667
+ userId: customParams.userId,
668
+ businessId: customParams.businessId,
669
+ couponId: couponData.coupon
670
+ }),
671
+ headers: {
672
+ Accept: 'application/json',
673
+ 'Content-Type': 'application/x-www-form-urlencoded',
674
+ 'Access-Control-Allow-Origin': '*',
675
+ 'X-App-X': ordering.appId,
676
+ 'X-Socket-Id-X': socket?.getId(),
677
+ 'X-Country-Code-X': countryCode
678
+ }
679
+ })
680
+ const result = await response.json()
681
+
682
+ if (result.message !== 'Cup\u00f3n v\u00e1lido') {
683
+ setAlert({ show: true, content: result.message === 'Not found' ? ['ERROR_INVALID_COUPON'] : [result.message] })
684
+ setState({ ...state, loading: false })
685
+ return
686
+ }
687
+ }
688
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
689
+ const userCustomerId = customerFromLocalStorage?.id
690
+ const body = {
691
+ business_id: couponData.business_id,
692
+ coupon: couponData.coupon,
693
+ user_id: userCustomerId || session.user.id
694
+ }
695
+ const { content } = await ordering
696
+ .setAccessToken(session.token)
697
+ .carts()
698
+ .applyCoupon(body, {
699
+ headers: {
700
+ 'X-Socket-Id-X': socket?.getId(),
701
+ 'X-Country-Code-X': countryCode
702
+ }
703
+ })
704
+ const result = content
705
+ if (!result.error) {
706
+ state.carts[`businessId:${result.result.business_id}`] = result.result
707
+ events.emit('cart_updated', result.result)
708
+ } else {
709
+ setAlert({ show: true, content: result.result })
710
+ }
711
+ setState({ ...state, loading: false })
712
+ return !result.error
713
+ } catch (err) {
714
+ setState({ ...state, loading: false })
715
+ return false
716
+ }
717
+ }
718
+
719
+ const applyOffer = async (offerData) => {
720
+ if (!offerData.business_id) {
721
+ throw new Error('`business_id` is required.')
722
+ }
723
+ if (typeof offerData.coupon === 'undefined') {
724
+ throw new Error('`coupon` is required.')
725
+ }
726
+ try {
727
+ setState({ ...state, loading: true })
728
+ const countryCode = await strategy.getItem('country-code')
729
+ const response = await fetch(`${ordering.root}/carts/add_offer`, {
730
+ method: 'POST',
731
+ body: JSON.stringify({
732
+ user_id: offerData.userId,
733
+ business_id: offerData.business_id,
734
+ coupon: offerData.coupon,
735
+ force: offerData.force ?? false
736
+ }),
737
+ headers: {
738
+ 'Content-Type': 'application/json',
739
+ Authorization: `Bearer ${session.token}`,
740
+ 'X-App-X': ordering.appId,
741
+ 'X-Socket-Id-X': socket?.getId(),
742
+ 'X-Country-Code-X': countryCode
743
+ }
744
+ })
745
+ const result = await response.json()
746
+ if (!result.error) {
747
+ state.carts[`businessId:${result.result.business_id}`] = result.result
748
+ events.emit('cart_updated', result.result)
749
+ events.emit('offer_applied', { ...result.result, ...offerData })
750
+ } else {
751
+ setAlert({ show: true, content: result.result })
752
+ events.emit('offer_denied', { ...offerData, reason: result.result })
753
+ }
754
+ setState({ ...state, loading: false })
755
+ return !result.error
756
+ } catch (err) {
757
+ setState({ ...state, loading: false })
758
+ return false
759
+ }
760
+ }
761
+
762
+ const removeOffer = async (offerData) => {
763
+ if (!offerData.business_id) {
764
+ throw new Error('`business_id` is required.')
765
+ }
766
+ if (typeof offerData.offer_id === 'undefined') {
767
+ throw new Error('`offer_id` is required.')
768
+ }
769
+ try {
770
+ const countryCode = await strategy.getItem('country-code')
771
+ setState({ ...state, loading: true })
772
+ const offerRemoveData = {
773
+ business_id: offerData.business_id,
774
+ offer_id: offerData.offer_id
775
+ }
776
+ if (offerData.user_id) offerRemoveData.user_id = offerData.user_id
777
+ const response = await fetch(`${ordering.root}/carts/remove_offer`, {
778
+ method: 'POST',
779
+ body: JSON.stringify(offerRemoveData),
780
+ headers: {
781
+ 'Content-Type': 'application/json',
782
+ Authorization: `Bearer ${session.token}`,
783
+ 'X-App-X': ordering.appId,
784
+ 'X-Socket-Id-X': socket?.getId(),
785
+ 'X-Country-Code-X': countryCode
786
+ }
787
+ })
788
+ const result = await response.json()
789
+ if (!result.error) {
790
+ state.carts[`businessId:${result.result.business_id}`] = result.result
791
+ events.emit('cart_updated', result.result)
792
+ events.emit('offer_removed', offerData)
793
+ } else {
794
+ setAlert({ show: true, content: result.result })
795
+ }
796
+ setState({ ...state, loading: false })
797
+ return !result.error
798
+ } catch (err) {
799
+ setState({ ...state, loading: false })
800
+ return false
801
+ }
802
+ }
803
+
804
+ /**
805
+ * Apply coupon to cart
806
+ */
807
+ const changeDriverTip = async (businessId, driverTipRate = 0, isFixedPrice) => {
808
+ if (!businessId) {
809
+ throw new Error('`businessId` is required.')
810
+ }
811
+ if (!driverTipRate && driverTipRate !== 0) {
812
+ throw new Error('`driverTipRate` is required.')
813
+ }
814
+ if (!state.carts[`businessId:${businessId}`] || state.carts[`businessId:${businessId}`]?.driver_tip_rate === driverTipRate) {
815
+ return
816
+ }
817
+ try {
818
+ setState({ ...state, loading: true })
819
+ const countryCode = await strategy.getItem('country-code')
820
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
821
+ const userCustomerId = customerFromLocalStorage?.id
822
+ const body = {
823
+ business_id: businessId,
824
+ [isFixedPrice ? 'driver_tip' : 'driver_tip_rate']: driverTipRate,
825
+ user_id: userCustomerId || session.user.id
826
+ }
827
+ const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().changeDriverTip(body, {
828
+ headers: {
829
+ 'X-Socket-Id-X': socket?.getId(),
830
+ 'X-Country-Code-X': countryCode
831
+ }
832
+ })
833
+ if (!error) {
834
+ state.carts[`businessId:${result.business_id}`] = result
835
+ events.emit('cart_updated', result)
836
+ } else {
837
+ setAlert({ show: true, content: result })
838
+ }
839
+ setState({ ...state, loading: false })
840
+ return !error
841
+ } catch (err) {
842
+ setState({ ...state, loading: false })
843
+ return false
844
+ }
845
+ }
846
+
847
+ /**
848
+ * Change payment method
849
+ */
850
+ const changePaymethod = async (businessId, paymethodId, paymethodData) => {
851
+ if (!businessId) {
852
+ throw new Error('`businessId` is required.')
853
+ }
854
+ if (!paymethodId) {
855
+ throw new Error('`paymethodId` is required.')
856
+ }
857
+ if (!paymethodData) {
858
+ throw new Error('`paymethodData` is required.')
859
+ }
860
+ if (!state.carts[`businessId:${businessId}`] || state.carts[`businessId:${businessId}`]?.paymethodId === paymethodId) {
861
+ return
862
+ }
863
+ try {
864
+ setState({ ...state, loading: true })
865
+ const countryCode = await strategy.getItem('country-code')
866
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
867
+ const userCustomerId = customerFromLocalStorage?.id
868
+ const body = {
869
+ business_id: businessId,
870
+ paymethod_id: paymethodId,
871
+ paymethod_data: paymethodData,
872
+ user_id: userCustomerId ?? session.user.id
873
+ }
874
+ const { content: { error, result } } = await ordering.setAccessToken(session.token).carts().changePaymethod(body, {
875
+ headers: {
876
+ 'X-Socket-Id-X': socket?.getId(),
877
+ 'X-Country-Code-X': countryCode
878
+ }
879
+ })
880
+ if (!error) {
881
+ state.carts[`businessId:${result.business_id}`] = result
882
+ events.emit('cart_updated', result)
883
+ }
884
+ setState({ ...state, loading: false })
885
+ return !error
886
+ } catch (err) {
887
+ refreshOrderOptions()
888
+ setState({ ...state, loading: false })
889
+ return false
890
+ }
891
+ }
892
+
893
+ /**
894
+ * Place cart
895
+ */
896
+ const placeCart = async (cardId, data) => {
897
+ try {
898
+ setState({ ...state, loading: true })
899
+ const countryCode = await strategy.getItem('country-code')
900
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
901
+ const userCustomerId = customerFromLocalStorage?.id
902
+ const body = {
903
+ ...data,
904
+ user_id: userCustomerId || session.user.id
905
+ }
906
+ let headers = {
907
+ 'X-Socket-Id-X': socket?.getId(),
908
+ 'X-Country-Code-X': countryCode
909
+ }
910
+ if (userAgent) {
911
+ headers = { ...headers, 'User-Agent': userAgent }
912
+ }
913
+ const { content: { error, result } } = await ordering.setAccessToken(session.token).carts(cardId).place(body, { headers: headers })
914
+ if (!error) {
915
+ if (result.status !== 1) {
916
+ state.carts[`businessId:${result.business_id}`] = result
917
+ events.emit('cart_updated', result)
918
+ } else {
919
+ delete state.carts[`businessId:${result.business_id}`]
920
+ const orderObject = {
921
+ id: result.order.uuid,
922
+ business: { name: result.business.name },
923
+ total: result.total,
924
+ tax_total: result.tax,
925
+ delivery_zone_price: result.delivery_price,
926
+ business_id: result.business_id,
927
+ paymethod: result.paymethod_data.gateway
928
+ }
929
+ events.emit('order_placed', orderObject)
930
+ }
931
+ } else {
932
+ setAlert({ show: true, content: result })
933
+ setState({ ...state, loading: false })
934
+ return
935
+ }
936
+ setState({ ...state, loading: false })
937
+ return { error, result }
938
+ } catch (err) {
939
+ setState({ ...state, loading: false })
940
+ return {
941
+ error: true,
942
+ result: [err.message]
943
+ }
944
+ }
945
+ }
946
+
947
+ /**
948
+ * Place multi carts
949
+ */
950
+ const placeMultiCarts = async (data, cartUuid) => {
951
+ try {
952
+ setState({ ...state, loading: true })
953
+ const countryCode = await strategy.getItem('country-code')
954
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
955
+ const userCustomerId = customerFromLocalStorage?.id
956
+ const body = {
957
+ ...data,
958
+ user_id: userCustomerId || session.user.id
959
+ }
960
+ const requestOptions = {
961
+ method: 'POST',
962
+ headers: {
963
+ 'Content-Type': 'application/json',
964
+ Authorization: `bearer ${session.token}`,
965
+ 'X-App-X': ordering.appId,
966
+ 'X-Socket-Id-X': socket?.getId(),
967
+ 'X-Country-Code-X': countryCode
968
+ },
969
+ body: JSON.stringify(body)
970
+ }
971
+
972
+ const response = await fetch(`${ordering.root}/cart_groups/${cartUuid}/place`, requestOptions)
973
+ const { error, result } = await response.json()
974
+ if (!error) {
975
+ result.carts.forEach(cart => {
976
+ delete state.carts[`businessId:${cart.business_id}`]
977
+ const orderObject = {
978
+ id: cart.uuid,
979
+ business: { name: cart.business.name },
980
+ total: cart.total,
981
+ tax_total: cart.tax,
982
+ delivery_zone_price: cart.delivery_price,
983
+ business_id: cart.business_id
984
+ }
985
+ events.emit('order_placed', orderObject)
986
+ })
987
+ } else {
988
+ setAlert({ show: true, content: result })
989
+ }
990
+ setState({ ...state, loading: false })
991
+ return { error, result }
992
+ } catch (err) {
993
+ setState({ ...state, loading: false })
994
+ return {
995
+ error: true,
996
+ result: [err.message]
997
+ }
998
+ }
999
+ }
1000
+
1001
+ /**
1002
+ * Confirm cart
1003
+ */
1004
+ const confirmCart = async (cardId, data) => {
1005
+ try {
1006
+ setState({ ...state, loading: true })
1007
+ const countryCode = await strategy.getItem('country-code')
1008
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
1009
+ const userCustomerId = customerFromLocalStorage?.id
1010
+ const body = {
1011
+ ...data,
1012
+ user_id: userCustomerId || session.user.id
1013
+ }
1014
+ let fetchurl
1015
+ if (body.user_id === userCustomerId || data) {
1016
+ fetchurl = await ordering.setAccessToken(session.token).carts(cardId).confirmWithData(body, {
1017
+ headers: {
1018
+ 'X-Socket-Id-X': socket?.getId(),
1019
+ 'X-Country-Code-X': countryCode
1020
+ }
1021
+ })
1022
+ } else {
1023
+ fetchurl = await ordering.setAccessToken(session.token).carts(cardId).confirm(body, {
1024
+ headers: {
1025
+ 'X-Socket-Id-X': socket?.getId(),
1026
+ 'X-Country-Code-X': countryCode
1027
+ }
1028
+ })
1029
+ }
1030
+ const { content: { error, result, cart } } = fetchurl
1031
+ if (!error) {
1032
+ if (result.status !== 1) {
1033
+ state.carts[`businessId:${result.business_id}`] = result
1034
+ events.emit('cart_updated', result)
1035
+ } else {
1036
+ delete state.carts[`businessId:${result.business_id}`]
1037
+ }
1038
+ } else if (cart) {
1039
+ state.carts[`businessId:${cart.business_id}`] = cart
1040
+ events.emit('cart_updated', cart)
1041
+ }
1042
+ setState({ ...state, loading: false })
1043
+ return { error, result }
1044
+ } catch (err) {
1045
+ setState({ ...state, loading: false })
1046
+ return {
1047
+ error: true,
1048
+ result: [err.message]
1049
+ }
1050
+ }
1051
+ }
1052
+
1053
+ /**
1054
+ * Confirm multi carts
1055
+ */
1056
+ const confirmMultiCarts = async (cartUuid) => {
1057
+ try {
1058
+ setState({ ...state, loading: true })
1059
+ const countryCode = await strategy.getItem('country-code')
1060
+ const requestOptions = {
1061
+ method: 'POST',
1062
+ headers: {
1063
+ 'Content-Type': 'application/json',
1064
+ Authorization: `bearer ${session.token}`,
1065
+ 'X-App-X': ordering.appId,
1066
+ 'X-Socket-Id-X': socket?.getId(),
1067
+ 'X-Country-Code-X': countryCode
1068
+ }
1069
+ }
1070
+ const response = await fetch(`${ordering.root}/cart_groups/${cartUuid}/confirm`, requestOptions)
1071
+ const { result, error } = await response.json()
1072
+ if (!error) {
1073
+ result.carts.forEach(cart => {
1074
+ if (result.status !== 'completed') {
1075
+ state.carts[`businessId:${cart.business_id}`] = result
1076
+ events.emit('cart_updated', result)
1077
+ } else {
1078
+ delete state.carts[`businessId:${cart.business_id}`]
1079
+ }
1080
+ })
1081
+ }
1082
+ setState({ ...state, loading: false })
1083
+ return { error, result }
1084
+ } catch (err) {
1085
+ setState({ ...state, loading: false })
1086
+ return {
1087
+ error: true,
1088
+ result: [err.message]
1089
+ }
1090
+ }
1091
+ }
1092
+
1093
+ /**
1094
+ * Reorder an order and get cart
1095
+ */
1096
+ const reorder = async (orderId, offAlert, configurations = {}) => {
1097
+ try {
1098
+ setState({ ...state, loading: !configurations?.disableLoading })
1099
+ const countryCode = await strategy.getItem('country-code')
1100
+ const customerFromLocalStorage = await strategy.getItem('user-customer', true)
1101
+ const userCustomerId = customerFromLocalStorage?.id
1102
+ const query = userCustomerId
1103
+ ? { user_id: userCustomerId }
1104
+ : null
1105
+ const options = {
1106
+ headers: {
1107
+ 'X-Socket-Id-X': socket?.getId(),
1108
+ 'X-Country-Code-X': countryCode
1109
+ }
1110
+ }
1111
+ if (query) {
1112
+ options.query = query
1113
+ }
1114
+ const { content: { error, result } } = await ordering.setAccessToken(session.token).orders(orderId).reorder(options)
1115
+ if (!error) {
1116
+ state.carts[`businessId:${result.business_id}`] = result
1117
+ events.emit('cart_added', result)
1118
+ } else if (!offAlert) {
1119
+ setAlert({ show: true, content: result })
1120
+ }
1121
+ setState({ ...state, loading: false })
1122
+ return { error, result }
1123
+ } catch (err) {
1124
+ setState({ ...state, loading: false })
1125
+ return { error: true, result: [err.message] }
1126
+ }
1127
+ }
1128
+
1129
+ const setOptionFromLocalStorage = async () => {
1130
+ const optionsLocalStorage = await strategy.getItem('options', true)
1131
+ setState({
1132
+ ...state,
1133
+ loading: false,
1134
+ options: isDisabledDefaultOpts
1135
+ ? { type: null, moment: null }
1136
+ : {
1137
+ type: optionsLocalStorage?.type || orderTypes[configState?.configs?.default_order_type?.value],
1138
+ moment: optionsLocalStorage?.moment || null,
1139
+ address: optionsLocalStorage?.address || state?.options?.address || {},
1140
+ city_id: optionsLocalStorage?.city_id || null
1141
+ }
1142
+ })
1143
+ }
1144
+
1145
+ /**
1146
+ * get Latest past Order that has no review
1147
+ */
1148
+ const getLastOrderHasNoReview = async () => {
1149
+ if (session?.token) {
1150
+ const pastOrderTypes = [1, 2, 5, 6, 10, 11, 12, 15, 16, 17]
1151
+ const where = [{ attribute: 'status', value: pastOrderTypes }]
1152
+ if (franchiseId) {
1153
+ where.push({
1154
+ attribute: 'ref_business',
1155
+ conditions: [
1156
+ {
1157
+ attribute: 'franchise_id',
1158
+ value: {
1159
+ condition: '=',
1160
+ value: franchiseId
1161
+ }
1162
+ }
1163
+ ]
1164
+ })
1165
+ }
1166
+ if (typeof businessSlug === 'number' && businessSlug) {
1167
+ where.push({
1168
+ attribute: 'ref_business',
1169
+ conditions: [
1170
+ {
1171
+ attribute: 'id',
1172
+ value: {
1173
+ condition: '=',
1174
+ value: businessSlug
1175
+ }
1176
+ }
1177
+ ]
1178
+ })
1179
+ }
1180
+ if (typeof businessSlug === 'string' && businessSlug) {
1181
+ where.push({
1182
+ attribute: 'ref_business',
1183
+ conditions: [
1184
+ {
1185
+ attribute: 'slug',
1186
+ value: {
1187
+ condition: '=',
1188
+ value: businessSlug
1189
+ }
1190
+ }
1191
+ ]
1192
+ })
1193
+ }
1194
+ const options = {
1195
+ query: {
1196
+ orderBy: '-delivery_datetime',
1197
+ page: 1,
1198
+ page_size: 10,
1199
+ where
1200
+ }
1201
+ }
1202
+ const { content: { result, error } } = await ordering.setAccessToken(session?.token).orders().get(options)
1203
+
1204
+ if (!error && result?.length > 0) {
1205
+ const _noRviewOrder = result?.find(order => !order?.review)
1206
+ if (_noRviewOrder?.cart_group_id) {
1207
+ where.push({ attribute: 'cart_group_id', value: _noRviewOrder?.cart_group_id })
1208
+ const options = {
1209
+ query: {
1210
+ where,
1211
+ page: 1,
1212
+ page_size: 10
1213
+ }
1214
+ }
1215
+ const { content: { result, error } } = await ordering.setAccessToken(session?.token).orders().get(options)
1216
+ if (!error) {
1217
+ const noReviewOrders = result.filter(order => !order?.review)
1218
+ return noReviewOrders
1219
+ } else {
1220
+ return null
1221
+ }
1222
+ } else {
1223
+ return _noRviewOrder
1224
+ }
1225
+ } else {
1226
+ return null
1227
+ }
1228
+ } else {
1229
+ return null
1230
+ }
1231
+ }
1232
+
1233
+ const setStateValues = (values) => {
1234
+ setState({ ...state, ...values })
1235
+ }
1236
+
1237
+ const setUserCustomerOptions = async (params) => {
1238
+ setState({ ...state, loading: true })
1239
+ const options = params.options ?? {}
1240
+ await setUserCustomer(params.customer ?? {}, true)
1241
+ await updateOrderOptions(options)
1242
+ setState({ ...state, loading: false })
1243
+ }
1244
+
1245
+ const handleOrderStateLoading = (loading) => {
1246
+ setState({
1247
+ ...state,
1248
+ loading
1249
+ })
1250
+ }
1251
+
1252
+ const handleLogEvent = async (events) => {
1253
+ try {
1254
+ const countryCode = await strategy.getItem('country-code')
1255
+ const headers = {
1256
+ 'X-Socket-Id-X': socket?.getId(),
1257
+ 'X-Country-Code-X': countryCode
1258
+ }
1259
+ await fetch(`${ordering.root}/tracking_events`, {
1260
+ method: 'POST',
1261
+ body: JSON.stringify({
1262
+ events
1263
+ }),
1264
+ headers: {
1265
+ ...headers,
1266
+ Authorization: `Bearer ${session.token}`,
1267
+ 'Content-Type': 'application/json'
1268
+ }
1269
+ })
1270
+ } catch (err) {}
1271
+ }
1272
+
1273
+ useEffect(() => {
1274
+ if (session.loading || languageState.loading) return
1275
+ if (session.auth) {
1276
+ refreshOrderOptions()
1277
+ }
1278
+ }, [session.auth, session.loading, languageState.loading])
1279
+
1280
+ useEffect(() => {
1281
+ if (session.loading || configState.loading) return
1282
+ if (!session.auth) {
1283
+ setOptionFromLocalStorage()
1284
+ }
1285
+ }, [session.auth, session.loading, configState])
1286
+
1287
+ useEffect(() => {
1288
+ if (configTypes?.length > 0 && state.options.type && !configTypes.includes(state.options.type)) {
1289
+ const validDefaultValue = configTypes.includes(configState?.configs?.default_order_type?.type)
1290
+ updateOrderOptions(validDefaultValue ? { type: configState?.configs?.default_order_type?.type } : { type: configTypes[0] })
1291
+ if (!session.auth && !state?.loading) {
1292
+ changeType(validDefaultValue ? configState?.configs?.default_order_type?.type : configTypes[0])
1293
+ }
1294
+ }
1295
+ }, [configTypes?.length, state.options.type])
1296
+ /**
1297
+ * Update carts from sockets
1298
+ */
1299
+ useEffect(() => {
1300
+ const handleCartUpdate = (cart) => {
1301
+ if (!isDisableToast) {
1302
+ showToast(ToastType.Info, t('UPDATING_CART_INFO', 'Updating cart information...'))
1303
+ }
1304
+
1305
+ if (cart.status === 1) {
1306
+ if (state.carts[`businessId:${cart.business_id}`]) {
1307
+ delete state.carts[`businessId:${cart.business_id}`]
1308
+ }
1309
+ } else {
1310
+ const cartFinded = Object.values(state.carts).find(_cart => _cart?.uuid === cart?.uuid)
1311
+ const oldBusinessId = cartFinded?.business_id
1312
+ const newBusinessId = cart?.business_id
1313
+
1314
+ if (!oldBusinessId || oldBusinessId === newBusinessId) {
1315
+ state.carts[`businessId:${cart.business_id}`] = {
1316
+ ...state.carts[`businessId:${cart.business_id}`],
1317
+ ...cart
1318
+ }
1319
+ } else {
1320
+ delete state.carts[`businessId:${oldBusinessId}`]
1321
+ state.carts[`businessId:${newBusinessId}`] = cart
1322
+ }
1323
+ }
1324
+ }
1325
+ const handleOrderOptionUpdate = ({ carts, ...options }) => {
1326
+ if (!isDisableToast) {
1327
+ showToast(ToastType.Info, t('UPDATING_ORDER_OPTIONS', 'Updating order options...'))
1328
+ }
1329
+
1330
+ const newCarts = {}
1331
+ carts.forEach(cart => {
1332
+ newCarts[`businessId:${cart.business_id}`] = cart
1333
+ })
1334
+ const newState = {
1335
+ ...state,
1336
+ options: {
1337
+ ...state.options,
1338
+ ...options
1339
+ },
1340
+ carts: {
1341
+ ...state.carts,
1342
+ ...newCarts
1343
+ }
1344
+ }
1345
+ setState({ ...newState, loading: false })
1346
+ }
1347
+ socket.on('carts_update', handleCartUpdate)
1348
+ socket.on('order_options_update', handleOrderOptionUpdate)
1349
+ return () => {
1350
+ socket.off('carts_update', handleCartUpdate)
1351
+ socket.off('order_options_update', handleOrderOptionUpdate)
1352
+ }
1353
+ }, [state, socket])
1354
+
1355
+ /**
1356
+ * Join to carts room
1357
+ */
1358
+ useEffect(() => {
1359
+ if (!session.auth || session.loading) return
1360
+ socket.join(`carts_${customerState?.user?.id || session?.user?.id}`)
1361
+ socket.join(`orderoptions_${customerState?.user?.id || session?.user?.id}`)
1362
+ return () => {
1363
+ socket.leave(`carts_${customerState?.user?.id || session?.user?.id}`)
1364
+ socket.leave(`orderoptions_${customerState?.user?.id || session?.user?.id}`)
1365
+ }
1366
+ }, [socket, session.auth, session.loading, customerState?.user?.id, session?.user?.id])
1367
+
1368
+ const functions = {
1369
+ refreshOrderOptions,
1370
+ changeAddress,
1371
+ changeType,
1372
+ changeMoment,
1373
+ addProduct,
1374
+ removeProduct,
1375
+ updateProduct,
1376
+ clearCart,
1377
+ applyCoupon,
1378
+ applyOffer,
1379
+ removeOffer,
1380
+ changeDriverTip,
1381
+ placeCart,
1382
+ confirmCart,
1383
+ reorder,
1384
+ setAlert,
1385
+ setConfirm,
1386
+ changePaymethod,
1387
+ setUserCustomerOptions,
1388
+ setStateValues,
1389
+ placeMultiCarts,
1390
+ getLastOrderHasNoReview,
1391
+ changeCityFilter,
1392
+ confirmMultiCarts,
1393
+ addMultiProduct,
1394
+ handleOrderStateLoading,
1395
+ handleLogEvent
1396
+ }
1397
+
1398
+ const copyState = JSON.parse(JSON.stringify(state))
1399
+
1400
+ return (
1401
+ <OrderContext.Provider value={[copyState, functions]}>
1402
+ {
1403
+ Alert && (
1404
+ <Alert
1405
+ open={alert.show}
1406
+ title={alert.title || t('ERROR', 'Error')}
1407
+ onAccept={() => setAlert({ show: false })}
1408
+ onClose={() => setAlert({ show: false })}
1409
+ content={alert.content}
1410
+ />
1411
+ )
1412
+ }
1413
+ {children}
1414
+ </OrderContext.Provider>
1415
+ )
1416
+ }
1417
+
1418
+ /**
1419
+ * Hook to get and update order state
1420
+ */
1421
+ export const useOrder = () => {
1422
+ const orderManager = useContext(OrderContext)
1423
+ const warningMessage = () => {
1424
+ console.warn('Must use OrderProvider to wrappe the app.')
1425
+ }
1426
+ /**
1427
+ * Functions to avoid fails
1428
+ */
1429
+ const functionsPlaceholders = {
1430
+ refreshOrderOptions: warningMessage,
1431
+ changeAddress: warningMessage,
1432
+ changeType: warningMessage,
1433
+ changeMoment: warningMessage,
1434
+ addProduct: warningMessage,
1435
+ removeProduct: warningMessage,
1436
+ updateProduct: warningMessage,
1437
+ clearCart: warningMessage,
1438
+ applyCoupon: warningMessage,
1439
+ placeCart: warningMessage,
1440
+ confirmCart: warningMessage,
1441
+ setAlert: warningMessage,
1442
+ setConfirm: warningMessage,
1443
+ changeDriverTip: warningMessage,
1444
+ reorder: warningMessage,
1445
+ changePaymethod: warningMessage,
1446
+ setStateValues: warningMessage,
1447
+ getLastOrderHasNoReview: warningMessage
1448
+ }
1449
+ return orderManager || [{}, functionsPlaceholders]
1450
+ }