ordering-ui-admin-external 1.28.0 → 1.29.0

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 (169) hide show
  1. package/_bundles/main.css +294 -26
  2. package/_bundles/{ordering-ui-admin.88341b2ec95c8949082e.js → ordering-ui-admin.452c5996b9b7ebdf8016.js} +2 -2
  3. package/_bundles/{ordering-ui-admin.88341b2ec95c8949082e.js.LICENSE.txt → ordering-ui-admin.452c5996b9b7ebdf8016.js.LICENSE.txt} +8 -0
  4. package/_modules/components/Delivery/AddressForm/styles.js +2 -2
  5. package/_modules/components/Delivery/AddressList/index.js +9 -56
  6. package/_modules/components/Delivery/AddressList/styles.js +1 -1
  7. package/_modules/components/Delivery/DriversGroupLogs/index.js +5 -2
  8. package/_modules/components/Delivery/UserAddForm/index.js +16 -4
  9. package/_modules/components/Delivery/UserFormDetails/index.js +17 -5
  10. package/_modules/components/Home/HomePage/index.js +5 -1
  11. package/_modules/components/MyProducts/OrderingWebsite/index.js +5 -1
  12. package/_modules/components/OrderingProducts/SiteTheme/index.js +1 -1
  13. package/_modules/components/Orders/CreateCustomOrder/CardForm/index.js +96 -0
  14. package/_modules/components/Orders/CreateCustomOrder/CardForm/styles.js +35 -0
  15. package/_modules/components/Orders/CreateCustomOrder/CardFormCustom/cardUtils.js +102 -0
  16. package/_modules/components/Orders/CreateCustomOrder/CardFormCustom/index.js +148 -0
  17. package/_modules/components/Orders/CreateCustomOrder/CardFormCustom/styles.js +16 -0
  18. package/_modules/components/Orders/CreateCustomOrder/CartBill/index.js +275 -0
  19. package/_modules/components/Orders/CreateCustomOrder/CartBill/styles.js +23 -0
  20. package/_modules/components/Orders/CreateCustomOrder/Checkout/index.js +498 -0
  21. package/_modules/components/Orders/CreateCustomOrder/Checkout/styles.js +31 -0
  22. package/_modules/components/Orders/CreateCustomOrder/CouponControl/index.js +100 -0
  23. package/_modules/components/Orders/CreateCustomOrder/CouponControl/styles.js +17 -0
  24. package/_modules/components/Orders/CreateCustomOrder/CustomOrderDetails/index.js +139 -0
  25. package/_modules/components/Orders/CreateCustomOrder/CustomOrderDetails/styles.js +17 -0
  26. package/_modules/components/Orders/CreateCustomOrder/DriverTips/index.js +101 -0
  27. package/_modules/components/Orders/CreateCustomOrder/DriverTips/styles.js +37 -0
  28. package/_modules/components/Orders/CreateCustomOrder/Map/index.js +131 -0
  29. package/_modules/components/Orders/CreateCustomOrder/Map/styles.js +12 -0
  30. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionCard/index.js +83 -0
  31. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionCash/index.js +81 -0
  32. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionCash/styles.js +23 -0
  33. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionPaypal/index.js +45 -0
  34. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionPaypal/styles.js +12 -0
  35. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionSquare/index.js +112 -0
  36. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionSquare/styles.js +21 -0
  37. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionStripe/index.js +259 -0
  38. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionStripe/styles.js +66 -0
  39. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionWallet/index.js +173 -0
  40. package/_modules/components/Orders/CreateCustomOrder/PaymentOptionWallet/styles.js +26 -0
  41. package/_modules/components/Orders/CreateCustomOrder/PaymentOptions/index.js +400 -0
  42. package/_modules/components/Orders/CreateCustomOrder/PaymentOptions/styles.js +40 -0
  43. package/_modules/components/Orders/CreateCustomOrder/ProductForm/index.js +613 -0
  44. package/_modules/components/Orders/CreateCustomOrder/ProductForm/styles.js +109 -0
  45. package/_modules/components/Orders/CreateCustomOrder/ProductIngredient/index.js +39 -0
  46. package/_modules/components/Orders/CreateCustomOrder/ProductIngredient/styles.js +23 -0
  47. package/_modules/components/Orders/CreateCustomOrder/ProductOption/index.js +51 -0
  48. package/_modules/components/Orders/CreateCustomOrder/ProductOption/styles.js +29 -0
  49. package/_modules/components/Orders/CreateCustomOrder/ProductOptionSubOption/index.js +148 -0
  50. package/_modules/components/Orders/CreateCustomOrder/ProductOptionSubOption/styles.js +79 -0
  51. package/_modules/components/Orders/CreateCustomOrder/SelectBusinesses/index.js +82 -0
  52. package/_modules/components/Orders/CreateCustomOrder/SelectBusinesses/styles.js +21 -0
  53. package/_modules/components/Orders/CreateCustomOrder/SelectCustomer/index.js +191 -0
  54. package/_modules/components/Orders/CreateCustomOrder/SelectCustomer/styles.js +68 -0
  55. package/_modules/components/Orders/CreateCustomOrder/SelectProducts/index.js +234 -0
  56. package/_modules/components/Orders/CreateCustomOrder/SelectProducts/styles.js +54 -0
  57. package/_modules/components/Orders/CreateCustomOrder/SingleProductCard/index.js +99 -0
  58. package/_modules/components/Orders/CreateCustomOrder/SingleProductCard/styles.js +131 -0
  59. package/_modules/components/Orders/CreateCustomOrder/StripeElementsForm/index.js +73 -0
  60. package/_modules/components/Orders/CreateCustomOrder/StripeElementsForm/styles.js +17 -0
  61. package/_modules/components/Orders/CreateCustomOrder/StripeMethodForm/index.js +124 -0
  62. package/_modules/components/Orders/CreateCustomOrder/StripeMethodForm/styles.js +12 -0
  63. package/_modules/components/Orders/CreateCustomOrder/StripeRedirectForm/index.js +83 -0
  64. package/_modules/components/Orders/CreateCustomOrder/StripeRedirectForm/styles.js +21 -0
  65. package/_modules/components/Orders/CreateCustomOrder/TaxInformation/index.js +48 -0
  66. package/_modules/components/Orders/CreateCustomOrder/TaxInformation/styles.js +14 -0
  67. package/_modules/components/Orders/CreateCustomOrder/index.js +59 -0
  68. package/_modules/components/Orders/OrderToPrintTicket/index.js +2 -2
  69. package/_modules/components/Orders/OrdersDashboardControls/index.js +6 -2
  70. package/_modules/components/Orders/OrdersDashboardControls/styles.js +3 -3
  71. package/_modules/components/Orders/OrdersExportCSV/styles.js +14 -8
  72. package/_modules/components/Orders/OrdersManager/index.js +6 -4
  73. package/_modules/components/Orders/OrdersManager/styles.js +1 -1
  74. package/_modules/components/Shared/AutoScroll/index.js +1 -0
  75. package/_modules/components/Shared/LinkableText/index.js +22 -0
  76. package/_modules/components/Shared/Tabs/index.js +32 -0
  77. package/_modules/components/Shared/index.js +20 -0
  78. package/_modules/components/SidebarMenu/index.js +2 -1
  79. package/_modules/components/Stores/BusinessProductsListing/index.js +7 -3
  80. package/_modules/components/Stores/BusinessQRCodeOption/index.js +6 -2
  81. package/_modules/components/Stores/BusinessSummary/index.js +7 -3
  82. package/_modules/components/Users/UserAddForm/index.js +13 -5
  83. package/_modules/components/Users/UserAddForm/styles.js +1 -1
  84. package/_modules/styles/Selects/index.js +1 -1
  85. package/_modules/utils/index.js +9 -2
  86. package/index-template.js +1 -1
  87. package/package.json +6 -4
  88. package/src/components/Delivery/AddressForm/styles.js +3 -3
  89. package/src/components/Delivery/AddressList/index.js +6 -61
  90. package/src/components/Delivery/AddressList/styles.js +1 -1
  91. package/src/components/Delivery/DriversGroupLogs/index.js +8 -2
  92. package/src/components/Delivery/UserAddForm/index.js +32 -13
  93. package/src/components/Delivery/UserFormDetails/index.js +30 -13
  94. package/src/components/Home/HomePage/index.js +3 -2
  95. package/src/components/MyProducts/OrderingWebsite/index.js +9 -8
  96. package/src/components/OrderingProducts/SiteTheme/index.js +1 -1
  97. package/src/components/Orders/CreateCustomOrder/CardForm/index.js +135 -0
  98. package/src/components/Orders/CreateCustomOrder/CardForm/styles.js +135 -0
  99. package/src/components/Orders/CreateCustomOrder/CardFormCustom/cardUtils.js +111 -0
  100. package/src/components/Orders/CreateCustomOrder/CardFormCustom/index.js +161 -0
  101. package/src/components/Orders/CreateCustomOrder/CardFormCustom/styles.js +20 -0
  102. package/src/components/Orders/CreateCustomOrder/CartBill/index.js +267 -0
  103. package/src/components/Orders/CreateCustomOrder/CartBill/styles.js +67 -0
  104. package/src/components/Orders/CreateCustomOrder/Checkout/index.js +519 -0
  105. package/src/components/Orders/CreateCustomOrder/Checkout/styles.js +85 -0
  106. package/src/components/Orders/CreateCustomOrder/CouponControl/index.js +90 -0
  107. package/src/components/Orders/CreateCustomOrder/CouponControl/styles.js +22 -0
  108. package/src/components/Orders/CreateCustomOrder/CustomOrderDetails/index.js +132 -0
  109. package/src/components/Orders/CreateCustomOrder/CustomOrderDetails/styles.js +28 -0
  110. package/src/components/Orders/CreateCustomOrder/DriverTips/index.js +113 -0
  111. package/src/components/Orders/CreateCustomOrder/DriverTips/styles.js +91 -0
  112. package/src/components/Orders/CreateCustomOrder/Map/index.js +115 -0
  113. package/src/components/Orders/CreateCustomOrder/Map/styles.js +10 -0
  114. package/src/components/Orders/CreateCustomOrder/PaymentOptionCard/index.js +70 -0
  115. package/src/components/Orders/CreateCustomOrder/PaymentOptionCash/index.js +83 -0
  116. package/src/components/Orders/CreateCustomOrder/PaymentOptionCash/styles.js +50 -0
  117. package/src/components/Orders/CreateCustomOrder/PaymentOptionPaypal/index.js +43 -0
  118. package/src/components/Orders/CreateCustomOrder/PaymentOptionPaypal/styles.js +5 -0
  119. package/src/components/Orders/CreateCustomOrder/PaymentOptionSquare/index.js +105 -0
  120. package/src/components/Orders/CreateCustomOrder/PaymentOptionSquare/styles.js +27 -0
  121. package/src/components/Orders/CreateCustomOrder/PaymentOptionStripe/index.js +261 -0
  122. package/src/components/Orders/CreateCustomOrder/PaymentOptionStripe/styles.js +159 -0
  123. package/src/components/Orders/CreateCustomOrder/PaymentOptionWallet/index.js +172 -0
  124. package/src/components/Orders/CreateCustomOrder/PaymentOptionWallet/styles.js +33 -0
  125. package/src/components/Orders/CreateCustomOrder/PaymentOptions/index.js +440 -0
  126. package/src/components/Orders/CreateCustomOrder/PaymentOptions/styles.js +132 -0
  127. package/src/components/Orders/CreateCustomOrder/ProductForm/index.js +701 -0
  128. package/src/components/Orders/CreateCustomOrder/ProductForm/styles.js +540 -0
  129. package/src/components/Orders/CreateCustomOrder/ProductIngredient/index.js +43 -0
  130. package/src/components/Orders/CreateCustomOrder/ProductIngredient/styles.js +29 -0
  131. package/src/components/Orders/CreateCustomOrder/ProductOption/index.js +58 -0
  132. package/src/components/Orders/CreateCustomOrder/ProductOption/styles.js +76 -0
  133. package/src/components/Orders/CreateCustomOrder/ProductOptionSubOption/index.js +182 -0
  134. package/src/components/Orders/CreateCustomOrder/ProductOptionSubOption/styles.js +195 -0
  135. package/src/components/Orders/CreateCustomOrder/SelectBusinesses/index.js +67 -0
  136. package/src/components/Orders/CreateCustomOrder/SelectBusinesses/styles.js +63 -0
  137. package/src/components/Orders/CreateCustomOrder/SelectCustomer/index.js +241 -0
  138. package/src/components/Orders/CreateCustomOrder/SelectCustomer/styles.js +235 -0
  139. package/src/components/Orders/CreateCustomOrder/SelectProducts/index.js +237 -0
  140. package/src/components/Orders/CreateCustomOrder/SelectProducts/styles.js +161 -0
  141. package/src/components/Orders/CreateCustomOrder/SingleProductCard/index.js +105 -0
  142. package/src/components/Orders/CreateCustomOrder/SingleProductCard/styles.js +314 -0
  143. package/src/components/Orders/CreateCustomOrder/StripeElementsForm/index.js +71 -0
  144. package/src/components/Orders/CreateCustomOrder/StripeElementsForm/styles.js +13 -0
  145. package/src/components/Orders/CreateCustomOrder/StripeMethodForm/index.js +90 -0
  146. package/src/components/Orders/CreateCustomOrder/StripeMethodForm/styles.js +9 -0
  147. package/src/components/Orders/CreateCustomOrder/StripeRedirectForm/index.js +96 -0
  148. package/src/components/Orders/CreateCustomOrder/StripeRedirectForm/styles.js +73 -0
  149. package/src/components/Orders/CreateCustomOrder/TaxInformation/index.js +69 -0
  150. package/src/components/Orders/CreateCustomOrder/TaxInformation/styles.js +25 -0
  151. package/src/components/Orders/CreateCustomOrder/index.js +45 -0
  152. package/src/components/Orders/OrderToPrintTicket/index.js +1 -1
  153. package/src/components/Orders/OrdersDashboardControls/index.js +4 -1
  154. package/src/components/Orders/OrdersDashboardControls/styles.js +13 -11
  155. package/src/components/Orders/OrdersExportCSV/styles.js +16 -0
  156. package/src/components/Orders/OrdersManager/index.js +5 -1
  157. package/src/components/Orders/OrdersManager/styles.js +2 -0
  158. package/src/components/Shared/AutoScroll/index.js +1 -0
  159. package/src/components/Shared/LinkableText/index.js +17 -0
  160. package/src/components/Shared/Tabs/index.js +28 -0
  161. package/src/components/Shared/index.js +5 -0
  162. package/src/components/SidebarMenu/index.js +1 -1
  163. package/src/components/Stores/BusinessProductsListing/index.js +6 -3
  164. package/src/components/Stores/BusinessQRCodeOption/index.js +5 -3
  165. package/src/components/Stores/BusinessSummary/index.js +6 -4
  166. package/src/components/Users/UserAddForm/index.js +12 -3
  167. package/src/components/Users/UserAddForm/styles.js +2 -2
  168. package/src/styles/Selects/index.js +1 -1
  169. package/src/utils/index.js +5 -0
@@ -0,0 +1,519 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import {
3
+ Checkout as CheckoutController,
4
+ useOrder,
5
+ useSession,
6
+ useApi,
7
+ useLanguage,
8
+ useValidationFields,
9
+ useUtils,
10
+ useConfig,
11
+ useCustomer
12
+ } from 'ordering-components-admin-external'
13
+ import parsePhoneNumber from 'libphonenumber-js'
14
+ import VscWarning from '@meronex/icons/vsc/VscWarning'
15
+
16
+ import { PaymentOptions } from '../PaymentOptions'
17
+ import { PaymentOptionWallet } from '../PaymentOptionWallet'
18
+ import { DriverTips } from '../DriverTips'
19
+ import { CartBill } from '../CartBill'
20
+
21
+ import { Alert, NotFoundSource } from '../../../Shared'
22
+ import { Button } from '../../../../styles'
23
+
24
+ import {
25
+ Conatiner,
26
+ WarningMessage,
27
+ PaymentMethodContainer,
28
+ SectionTitleContainer,
29
+ Flag,
30
+ WarningText,
31
+ WrapperPlaceOrderButton
32
+ } from './styles'
33
+
34
+ const CheckoutUI = (props) => {
35
+ const {
36
+ cart,
37
+ errors,
38
+ placing,
39
+ cartState,
40
+ loyaltyPlansState,
41
+ businessDetails,
42
+ paymethodSelected,
43
+ handlePaymethodChange,
44
+ handlerClickPlaceOrder,
45
+ handleOrderRedirect,
46
+ isCustomerMode,
47
+ isResetPaymethod,
48
+ setIsResetPaymethod,
49
+ onPlaceOrderClick,
50
+ placeSpotNumber
51
+ } = props
52
+
53
+ const [validationFields] = useValidationFields()
54
+ const [{ options, loading }] = useOrder()
55
+ const [, t] = useLanguage()
56
+ const [{ parsePrice }] = useUtils()
57
+ const [{ user }] = useSession()
58
+ const [{ configs }] = useConfig()
59
+ const [customerState] = useCustomer()
60
+
61
+ const [errorCash, setErrorCash] = useState(false)
62
+ const [userErrors, setUserErrors] = useState([])
63
+ const [alertState, setAlertState] = useState({ open: false, content: [] })
64
+ const [requiredFields, setRequiredFields] = useState([])
65
+ const [cardList, setCardList] = useState([])
66
+ const [paymethodClicked, setPaymethodClicked] = useState(null)
67
+ const cardsMethods = ['stripe', 'credomatic']
68
+ const businessConfigs = businessDetails?.business?.configs ?? []
69
+ const isTableNumberEnabled = configs?.table_numer_enabled?.value
70
+ const isWalletCashEnabled = businessConfigs.find(config => config.key === 'wallet_cash_enabled')?.value === '1'
71
+ const isWalletCreditPointsEnabled = businessConfigs.find(config => config.key === 'wallet_credit_point_enabled')?.value === '1'
72
+ const isWalletEnabled = configs?.cash_wallet?.value && configs?.wallet_enabled?.value === '1' &&
73
+ (isWalletCashEnabled || isWalletCreditPointsEnabled) && !isCustomerMode
74
+
75
+ const isGiftCardCart = !cart?.business_id
76
+
77
+ const validateCommentsCartField = validationFields?.fields?.checkout?.comments?.enabled && validationFields?.fields?.checkout?.comments?.required && (cart?.comment === null || cart?.comment?.trim().length === 0)
78
+
79
+ const validateZipcodeCard =
80
+ validationFields?.fields?.card?.zipcode?.enabled && validationFields?.fields?.card?.zipcode?.required && paymethodSelected?.gateway === 'stripe' && paymethodSelected?.data?.card && !paymethodSelected?.data?.card?.zipcode
81
+
82
+ const isDisablePlaceOrderButton = !cart?.valid ||
83
+ (!paymethodSelected && cart?.balance > 0) ||
84
+ (cardsMethods.includes(paymethodSelected?.gateway) && cardList?.cards?.length === 0) ||
85
+ placing ||
86
+ errorCash ||
87
+ loading ||
88
+ (isTableNumberEnabled === '1' && (options?.type === 3 && !(cartState?.cart?.spot_number || cart?.spot_number || placeSpotNumber))) ||
89
+ !cart?.valid_maximum ||
90
+ (!cart?.valid_minimum && !(cart?.discount_type === 1 && cart?.discount_rate === 100)) ||
91
+ (options.type === 1 &&
92
+ validationFields?.fields?.checkout?.driver_tip?.enabled &&
93
+ validationFields?.fields?.checkout?.driver_tip?.required &&
94
+ (Number(cart?.driver_tip) <= 0)) ||
95
+ (validateCommentsCartField) ||
96
+ validateZipcodeCard
97
+
98
+ const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
99
+ ? JSON.parse(configs?.driver_tip_options?.value) || []
100
+ : configs?.driver_tip_options?.value || []
101
+
102
+ const driverTipsField = !cartState.loading && cart && cart?.business_id && options.type === 1 && cart?.status !== 2 && validationFields?.fields?.checkout?.driver_tip?.enabled && driverTipsOptions.length > 0
103
+
104
+ const handlePlaceOrder = () => {
105
+ if (!userErrors.length && (!requiredFields?.length ||
106
+ ((paymethodSelected?.gateway === 'cash' || paymethodSelected?.gateway === 'card_delivery')))) {
107
+ const body = {}
108
+ handlerClickPlaceOrder && handlerClickPlaceOrder(null, body)
109
+ return
110
+ }
111
+ setAlertState({
112
+ open: true,
113
+ content: Object.values(userErrors).map(error => error)
114
+ })
115
+ }
116
+
117
+ const checkValidationFields = () => {
118
+ setUserErrors([])
119
+ const errors = []
120
+ const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes', 'comments']
121
+ const userSelected = isCustomerMode ? customerState.user : user
122
+ const _requiredFields = []
123
+
124
+ Object.values(validationFields?.fields?.checkout).map(field => {
125
+ if (field?.enabled && field?.required && !notFields.includes(field.code)) {
126
+ if (userSelected && !userSelected[field?.code]) {
127
+ _requiredFields.push(field?.code)
128
+ }
129
+ }
130
+ })
131
+
132
+ if (
133
+ userSelected &&
134
+ !userSelected?.cellphone &&
135
+ ((validationFields?.fields?.checkout?.cellphone?.enabled &&
136
+ validationFields?.fields?.checkout?.cellphone?.required) ||
137
+ configs?.verification_phone_required?.value === '1')
138
+ ) {
139
+ _requiredFields.push('cellphone')
140
+ }
141
+ setRequiredFields(_requiredFields)
142
+
143
+ if (userSelected && userSelected?.cellphone) {
144
+ if (userSelected?.country_phone_code) {
145
+ let phone = null
146
+ phone = `+${userSelected?.country_phone_code}${userSelected?.cellphone.replace(`+${userSelected?.country_phone_code}`, '')}`
147
+ const phoneNumber = parsePhoneNumber(phone)
148
+ if (!phoneNumber?.isValid()) {
149
+ errors.push(t('VALIDATION_ERROR_MOBILE_PHONE_INVALID', 'The field Phone number is invalid.'))
150
+ }
151
+ } else {
152
+ errors.push(t('INVALID_ERROR_COUNTRY_CODE_PHONE_NUMBER', 'The country code of the phone number is invalid'))
153
+ }
154
+ }
155
+
156
+ setUserErrors(errors)
157
+ }
158
+
159
+ useEffect(() => {
160
+ if (validationFields && validationFields?.fields?.checkout) {
161
+ checkValidationFields()
162
+ }
163
+ }, [validationFields, user, customerState])
164
+
165
+ useEffect(() => {
166
+ if (errors) {
167
+ setAlertState({
168
+ open: true,
169
+ content: errors
170
+ })
171
+ }
172
+ }, [errors])
173
+
174
+ useEffect(() => {
175
+ if (isResetPaymethod) {
176
+ handlePaymethodChange(null)
177
+ setIsResetPaymethod(true)
178
+ }
179
+ }, [isResetPaymethod])
180
+
181
+ return (
182
+ <Conatiner>
183
+ {!cartState.loading && cart?.status === 2 && (
184
+ <WarningMessage>
185
+ <VscWarning />
186
+ <h1>
187
+ {t('CART_STATUS_PENDING_MESSAGE', 'Your order is being processed, please wait a little more. if you\'ve been waiting too long, please reload the page')}
188
+ </h1>
189
+ </WarningMessage>
190
+ )}
191
+
192
+ {!cartState.loading && cart && (
193
+ <PaymentMethodContainer className='paymentsContainer'>
194
+ <SectionTitleContainer>
195
+ <h3>{t('PAYMENT_METHODS', 'Payment Methods')}</h3>
196
+ <Flag>{t('REQUIRED', 'Required')}</Flag>
197
+ </SectionTitleContainer>
198
+ {!cartState.loading && cart?.status === 4 && (
199
+ <WarningMessage style={{ marginTop: 20 }}>
200
+ <VscWarning />
201
+ <h1>
202
+ {t('CART_STATUS_CANCEL_MESSAGE', 'The payment has not been successful, please try again')}
203
+ </h1>
204
+ </WarningMessage>
205
+ )}
206
+ <PaymentOptions
207
+ cart={cart}
208
+ isDisabled={cart?.status === 2}
209
+ businessId={!isGiftCardCart ? businessDetails?.business?.id : -1}
210
+ isLoading={!isGiftCardCart ? businessDetails.loading : false}
211
+ paymethods={businessDetails?.business?.paymethods}
212
+ onPaymentChange={handlePaymethodChange}
213
+ errorCash={errorCash}
214
+ setErrorCash={setErrorCash}
215
+ handleOrderRedirect={handleOrderRedirect}
216
+ isCustomerMode={isCustomerMode}
217
+ paySelected={paymethodSelected}
218
+ handlePlaceOrder={handlePlaceOrder}
219
+ onPlaceOrderClick={onPlaceOrderClick}
220
+ setCardList={setCardList}
221
+ requiredFields={requiredFields}
222
+ paymethodClicked={paymethodClicked}
223
+ setPaymethodClicked={setPaymethodClicked}
224
+ />
225
+ </PaymentMethodContainer>
226
+ )}
227
+
228
+ {isWalletEnabled && !businessDetails?.loading && (
229
+ <PaymentOptionWallet
230
+ cart={cart}
231
+ loyaltyPlansState={loyaltyPlansState}
232
+ businessConfigs={businessDetails?.business?.configs}
233
+ />
234
+ )}
235
+
236
+ {driverTipsField && (
237
+ <DriverTips
238
+ businessId={cart?.business_id}
239
+ driverTipsOptions={driverTipsOptions}
240
+ isFixedPrice={parseInt(configs?.driver_tip_type?.value, 10) === 1}
241
+ isDriverTipUseCustom={!!parseInt(configs?.driver_tip_use_custom?.value, 10)}
242
+ driverTip={parseInt(configs?.driver_tip_type?.value, 10) === 1
243
+ ? cart?.driver_tip
244
+ : cart?.driver_tip_rate}
245
+ cart={cart}
246
+ useOrderContext
247
+ />
248
+ )}
249
+ {!cartState.loading && cart && <CartBill cart={cart} />}
250
+
251
+ {!cartState.loading && cart && cart?.status !== 2 && (
252
+ <WrapperPlaceOrderButton>
253
+ <Button
254
+ color={(!cart?.valid_maximum || (!cart?.valid_minimum && !(cart?.discount_type === 1 && cart?.discount_rate === 100))) ? 'secundary' : 'primary'}
255
+ disabled={isDisablePlaceOrderButton}
256
+ onClick={() => handlePlaceOrder()}
257
+ >
258
+ {!cart?.valid_maximum ? (
259
+ `${t('MAXIMUM_SUBTOTAL_ORDER', 'Maximum subtotal order')}: ${parsePrice(cart?.maximum)}`
260
+ ) : (!cart?.valid_minimum && !(cart?.discount_type === 1 && cart?.discount_rate === 100)) ? (
261
+ `${t('MINIMUN_SUBTOTAL_ORDER', 'Minimum subtotal order:')} ${parsePrice(cart?.minimum)}`
262
+ ) : placing ? t('PLACING', 'Placing') : t('PLACE_ORDER', 'Place Order')}
263
+ </Button>
264
+ </WrapperPlaceOrderButton>
265
+ )}
266
+
267
+ {!cart?.valid_address && cart?.status !== 2 && (
268
+ <WarningText>
269
+ {t('INVALID_CART_ADDRESS', 'Selected address is invalid, please select a closer address.')}
270
+ </WarningText>
271
+ )}
272
+
273
+ {(!paymethodSelected && cart?.balance > 0) && cart?.status !== 2 && (
274
+ <WarningText>
275
+ {t('WARNING_NOT_PAYMENT_SELECTED', 'Please, select a payment method to place order.')}
276
+ </WarningText>
277
+ )}
278
+
279
+ {!cart?.valid_products && cart?.status !== 2 && (
280
+ <WarningText>
281
+ {t('WARNING_INVALID_PRODUCTS', 'Some products are invalid, please check them.')}
282
+ </WarningText>
283
+ )}
284
+
285
+ {isTableNumberEnabled === '1' && (options?.type === 3 && !(cart?.spot_number || placeSpotNumber)) && (
286
+ <WarningText>
287
+ {t('WARNING_PLACE_SPOT', 'Please, select your spot to place order.')}
288
+ </WarningText>
289
+ )}
290
+
291
+ {options.type === 1 &&
292
+ validationFields?.fields?.checkout?.driver_tip?.enabled &&
293
+ validationFields?.fields?.checkout?.driver_tip?.required &&
294
+ (Number(cart?.driver_tip) <= 0) &&
295
+ (
296
+ <WarningText>
297
+ {t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
298
+ </WarningText>
299
+ )}
300
+
301
+ {validateCommentsCartField && (
302
+ <WarningText>
303
+ {t('WARNING_INVALID_CART_COMMENTS', 'Cart comments is required.')}
304
+ </WarningText>
305
+ )}
306
+
307
+ {validateZipcodeCard && (
308
+ <WarningText>
309
+ {t('WARNING_CARD_ZIPCODE_REQUIRED', 'Your card selected has not zipcode')}
310
+ </WarningText>
311
+ )}
312
+ {cart?.valid_preorder !== undefined && !cart?.valid_preorder && (
313
+ <WarningText>
314
+ {t('INVALID_CART_MOMENT', 'Selected schedule time is invalid, please select a schedule into the business schedule interval.')}
315
+ </WarningText>
316
+ )}
317
+
318
+ <Alert
319
+ title={t('CUSTOMER_DETAILS', 'Customer Details')}
320
+ content={alertState.content}
321
+ acceptText={t('ACCEPT', 'Accept')}
322
+ open={alertState.open}
323
+ onClose={() => setAlertState({ open: false, content: [] })}
324
+ onAccept={() => setAlertState({ open: false, content: [] })}
325
+ closeOnBackdrop={false}
326
+ />
327
+ </Conatiner>
328
+ )
329
+ }
330
+
331
+ export const Checkout = (props) => {
332
+ const {
333
+ errors,
334
+ clearErrors,
335
+ cartUuid,
336
+ handleOrderRedirect,
337
+ handleSearchRedirect,
338
+ handleCheckoutListRedirect,
339
+ businessSlug
340
+ } = props
341
+
342
+ const [orderState, { confirmCart }] = useOrder()
343
+ const [{ token }] = useSession()
344
+ const [ordering] = useApi()
345
+ const [, t] = useLanguage()
346
+
347
+ const [cartState, setCartState] = useState({ loading: true, error: null, cart: null })
348
+
349
+ const [currentCart, setCurrentCart] = useState(null)
350
+ const [alertState, setAlertState] = useState({ open: false, content: [] })
351
+ const [isResetPaymethod, setIsResetPaymethod] = useState(false)
352
+
353
+ const cartsWithProducts = orderState?.carts && (Object.values(orderState?.carts)?.filter(cart => cart?.products && cart?.products?.length) || null)
354
+ const carts = businessSlug
355
+ ? cartsWithProducts.filter((cart) => cart?.business?.slug === businessSlug || businessSlug === cart?.business_id)
356
+ : cartsWithProducts
357
+ const closeAlert = () => {
358
+ setAlertState({
359
+ open: false,
360
+ content: []
361
+ })
362
+ clearErrors && clearErrors()
363
+ }
364
+
365
+ useEffect(() => {
366
+ if (!orderState.loading && currentCart?.business_id) {
367
+ setCurrentCart(...Object.values(orderState.carts)?.filter(cart => cart?.business_id === currentCart?.business_id))
368
+ }
369
+ }, [orderState.loading])
370
+
371
+ useEffect(() => {
372
+ if (errors?.length) {
373
+ setAlertState({
374
+ open: true,
375
+ content: errors
376
+ })
377
+ }
378
+ }, [errors])
379
+
380
+ const getOrder = async (cartId) => {
381
+ try {
382
+ let result = {}
383
+ const cart = carts.find(cart => cart.uuid === cartId)
384
+ const userCustomer = JSON.parse(window.localStorage.getItem('user-customer'))
385
+ if (cart && !userCustomer) {
386
+ result = JSON.parse(JSON.stringify(cart))
387
+ } else {
388
+ setCartState({ ...cartState, loading: true })
389
+ const url = userCustomer
390
+ ? `${ordering.root}/carts/${cartId}?user_id=${userCustomer?.id}`
391
+ : `${ordering.root}/carts/${cartId}`
392
+ const response = await fetch(url, {
393
+ method: 'GET',
394
+ headers: {
395
+ 'Content-Type': 'application/json',
396
+ Authorization: `Bearer ${token}`,
397
+ 'X-App-X': ordering.appId
398
+ }
399
+ })
400
+ const content = await response.json()
401
+ result = content.result
402
+ }
403
+
404
+ if (result.status === 1 && result.order?.uuid) {
405
+ handleOrderRedirect(result.order.uuid)
406
+ setCartState({ ...cartState, loading: false })
407
+ } else if (result.status === 2) {
408
+ let credomaticData = null
409
+ if (result?.paymethod_data?.gateway === 'credomatic') {
410
+ const urlParams = new URLSearchParams(window.location.search)
411
+ const paramsObj = Object.fromEntries(urlParams.entries())
412
+ credomaticData = {
413
+ credomatic: {
414
+ ...paramsObj
415
+ }
416
+ }
417
+ }
418
+ try {
419
+ const confirmCartRes = await confirmCart(cartUuid, credomaticData)
420
+ if (confirmCartRes.error) {
421
+ setAlertState({
422
+ open: true,
423
+ content: typeof confirmCartRes.result === 'string'
424
+ ? [confirmCartRes.result]
425
+ : confirmCartRes.result
426
+ })
427
+ setIsResetPaymethod(true)
428
+ }
429
+ if (confirmCartRes.result.order?.uuid) {
430
+ handleOrderRedirect(confirmCartRes.result.order.uuid)
431
+ }
432
+ setCartState({
433
+ ...cartState,
434
+ loading: false,
435
+ cart: result
436
+ })
437
+ } catch (error) {
438
+ setAlertState({
439
+ open: true,
440
+ content: [error.message]
441
+ })
442
+ }
443
+ } else {
444
+ let _cart = Array.isArray(result) ? null : JSON.parse(JSON.stringify(result))
445
+ const spotNumberFromStorage = window.localStorage.getItem('table_number')
446
+ if (spotNumberFromStorage) {
447
+ const spotNumber = JSON.parse(spotNumberFromStorage)?.tableNumber
448
+ const slug = JSON.parse(spotNumberFromStorage)?.slug
449
+ if (_cart?.business?.slug === slug) {
450
+ _cart = {
451
+ ..._cart,
452
+ spot_number: parseInt(spotNumber, 10)
453
+ }
454
+ }
455
+ }
456
+ setCartState({
457
+ loading: false,
458
+ cart: _cart,
459
+ error: _cart ? null : result
460
+ })
461
+ }
462
+ } catch (e) {
463
+ setCartState({
464
+ ...cartState,
465
+ loading: false,
466
+ error: [e.toString()]
467
+ })
468
+ }
469
+ }
470
+
471
+ useEffect(() => {
472
+ if (token && cartUuid) {
473
+ getOrder(cartUuid)
474
+ } else {
475
+ setCartState({ ...cartState, loading: false })
476
+ }
477
+ }, [token, cartUuid])
478
+
479
+ const checkoutProps = {
480
+ ...props,
481
+ UIComponent: CheckoutUI,
482
+ cartState,
483
+ uuid: cartUuid,
484
+ isResetPaymethod,
485
+ setIsResetPaymethod
486
+ }
487
+
488
+ return (
489
+ <>
490
+ {!cartUuid && orderState.carts && carts && carts?.length === 0 && (
491
+ <NotFoundSource
492
+ content={t('NOT_FOUND_CARTS', 'Sorry, You don\'t seem to have any carts.')}
493
+ btnTitle={t('SEARCH_REDIRECT', 'Go to Businesses')}
494
+ onClickButton={handleSearchRedirect}
495
+ />
496
+ )}
497
+
498
+ {cartUuid && cartState.error && cartState.error?.length > 0 && (
499
+ <NotFoundSource
500
+ content={t('ERROR_CART_SELECTED', 'Sorry, the selected cart was not found.')}
501
+ btnTitle={t('CHECKOUT_REDIRECT', 'Go to Checkout list')}
502
+ onClickButton={handleCheckoutListRedirect}
503
+ />
504
+ )}
505
+
506
+ {cartUuid && cartState.cart && cartState.cart?.status !== 1 && <CheckoutController {...checkoutProps} />}
507
+
508
+ <Alert
509
+ title={t('CHECKOUT ', 'Checkout')}
510
+ content={alertState.content}
511
+ acceptText={t('ACCEPT', 'Accept')}
512
+ open={alertState.open}
513
+ onClose={() => closeAlert()}
514
+ onAccept={() => closeAlert()}
515
+ closeOnBackdrop={false}
516
+ />
517
+ </>
518
+ )
519
+ }
@@ -0,0 +1,85 @@
1
+ import styled, { css } from 'styled-components'
2
+
3
+ export const Conatiner = styled.div`
4
+
5
+ `
6
+
7
+ export const WarningMessage = styled.div`
8
+ width: 100%;
9
+ height: fit-content;
10
+ max-height: fit-content;
11
+ min-height: 150px;
12
+ background-color: #F2BB40;
13
+ display: flex;
14
+ justify-content: center;
15
+ align-items: center;
16
+ opacity: 0.8;
17
+ border-radius: 10px;
18
+ position: relative;
19
+
20
+ svg {
21
+ position: absolute;
22
+ font-size: 30px;
23
+ top: 0;
24
+ left: 0;
25
+ margin: 11px;
26
+ ${props => props.theme?.rtl && css`
27
+ right: 0;
28
+ left: initial;
29
+ `}
30
+ }
31
+
32
+ h1 {
33
+ font-size: 20px;
34
+ margin: 0px 60px;
35
+ text-align: center;
36
+ }
37
+ `
38
+ export const Flag = styled.span`
39
+ font-size: 13px;
40
+ margin: 0px;
41
+ text-transform: capitalize;
42
+ color: #E63757;
43
+ font-weight: 500;
44
+
45
+ @media (min-width: 381px) {
46
+ font-size: 14px;
47
+ }
48
+ `
49
+ export const SectionTitleContainer = styled.div`
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: space-between;
53
+ `
54
+ export const PaymentMethodContainer = styled.div`
55
+ display: flex;
56
+ flex-direction: column;
57
+ margin: 50px 0px 0px;
58
+ `
59
+ export const WarningText = styled.p`
60
+ margin: 10px auto;
61
+ text-align: center;
62
+ color: ${props => props.theme.colors.primary};
63
+ `
64
+ export const WrapperPlaceOrderButton = styled.div`
65
+ padding: 15px 0px;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: space-between;
69
+ box-sizing: border-box;
70
+
71
+ span {
72
+ font-weight: 600;
73
+ font-size: 16px;
74
+
75
+ @media (min-width: 1200px) {
76
+ font-size: 18px;
77
+ padding-left: 20px;
78
+ }
79
+ }
80
+
81
+ button {
82
+ min-height: 44px;
83
+ border-radius: 7.6px;
84
+ }
85
+ `
@@ -0,0 +1,90 @@
1
+ import React from 'react'
2
+ import { useLanguage, useOrder, CouponControl as CouponController } from 'ordering-components-admin-external'
3
+ import { Button, Input } from '../../../../styles'
4
+ import { Confirm } from '../../../Shared'
5
+
6
+ import {
7
+ CouponContainer
8
+ } from './styles'
9
+
10
+ const CouponControlUI = (props) => {
11
+ const {
12
+ couponDefault,
13
+ couponInput,
14
+ handleButtonApplyClick,
15
+ handleRemoveCouponClick,
16
+ onChangeInputCoupon,
17
+ confirm,
18
+ setConfirm
19
+ } = props
20
+
21
+ const [, t] = useLanguage()
22
+ const [orderState] = useOrder()
23
+
24
+ const onRemoveCoupon = () => {
25
+ setConfirm({
26
+ open: true,
27
+ content: t('QUESTION_DELETE_COUPON', 'Are you sure that you want to delete the coupon?')
28
+ })
29
+ }
30
+
31
+ const handleOnAccept = () => {
32
+ if (!confirm.error) {
33
+ handleRemoveCouponClick && handleRemoveCouponClick()
34
+ }
35
+ setConfirm({ ...confirm, open: false, error: false })
36
+ onChangeInputCoupon('')
37
+ }
38
+
39
+ const handleClose = () => {
40
+ setConfirm({ ...confirm, open: false, error: false })
41
+ onChangeInputCoupon('')
42
+ }
43
+
44
+ return (
45
+ <CouponContainer>
46
+ {couponDefault ? (
47
+ <Button onClick={() => onRemoveCoupon()}>
48
+ {t('REMOVE_COUPON', 'Remove Coupon')} {couponDefault}
49
+ </Button>
50
+ ) : (
51
+ <>
52
+ <Input
53
+ value={couponInput ?? ''}
54
+ placeholder={t('DISCOUNT_COUPON', 'Discount coupon')}
55
+ onChange={(e) => onChangeInputCoupon(e.target.value)}
56
+ autoComplete='off'
57
+ />
58
+ <Button
59
+ borderRadius='8px'
60
+ color='primary'
61
+ disabled={!couponInput || orderState.loading}
62
+ onClick={handleButtonApplyClick}
63
+ >
64
+ {t('APPLY', 'Apply')}
65
+ </Button>
66
+ </>
67
+ )}
68
+ <Confirm
69
+ title={t('COUPON', 'Coupon')}
70
+ content={confirm?.content}
71
+ acceptText={t('ACCEPT', 'Accept')}
72
+ open={confirm?.open}
73
+ onClose={handleClose}
74
+ onCancel={!confirm?.error ? () => setConfirm({ ...confirm, open: false, error: false }) : null}
75
+ onAccept={handleOnAccept}
76
+ closeOnBackdrop={false}
77
+ />
78
+ </CouponContainer>
79
+ )
80
+ }
81
+
82
+ export const CouponControl = (props) => {
83
+ const couponProp = {
84
+ ...props,
85
+ UIComponent: CouponControlUI
86
+ }
87
+ return (
88
+ <CouponController {...couponProp} />
89
+ )
90
+ }