ordering-ui-external 2.2.1 → 2.3.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.
- package/_bundles/{0.ordering-ui.95882a524750766186cd.js → 0.ordering-ui.c46aca08b04b2755b967.js} +1 -1
- package/_bundles/{1.ordering-ui.95882a524750766186cd.js → 1.ordering-ui.c46aca08b04b2755b967.js} +1 -1
- package/_bundles/{2.ordering-ui.95882a524750766186cd.js → 2.ordering-ui.c46aca08b04b2755b967.js} +1 -1
- package/_bundles/{4.ordering-ui.95882a524750766186cd.js → 4.ordering-ui.c46aca08b04b2755b967.js} +1 -1
- package/_bundles/{5.ordering-ui.95882a524750766186cd.js → 5.ordering-ui.c46aca08b04b2755b967.js} +1 -1
- package/_bundles/{6.ordering-ui.95882a524750766186cd.js → 6.ordering-ui.c46aca08b04b2755b967.js} +1 -1
- package/_bundles/{7.ordering-ui.95882a524750766186cd.js → 7.ordering-ui.c46aca08b04b2755b967.js} +2 -2
- package/_bundles/{7.ordering-ui.95882a524750766186cd.js.LICENSE.txt → 7.ordering-ui.c46aca08b04b2755b967.js.LICENSE.txt} +0 -0
- package/_bundles/{8.ordering-ui.95882a524750766186cd.js → 8.ordering-ui.c46aca08b04b2755b967.js} +1 -1
- package/_bundles/{9.ordering-ui.95882a524750766186cd.js → 9.ordering-ui.c46aca08b04b2755b967.js} +1 -1
- package/_bundles/ordering-ui.c46aca08b04b2755b967.js +2 -0
- package/_bundles/{ordering-ui.95882a524750766186cd.js.LICENSE.txt → ordering-ui.c46aca08b04b2755b967.js.LICENSE.txt} +0 -0
- package/_modules/components/PaymentOptions/index.js +42 -2
- package/_modules/index.js +7 -0
- package/_modules/themes/five/index.js +7 -0
- package/_modules/themes/five/src/components/BusinessProductsListing/index.js +1 -4
- package/_modules/themes/five/src/components/Cart/index.js +6 -2
- package/_modules/themes/five/src/components/Cart/styles.js +1 -1
- package/_modules/themes/five/src/components/Checkout/index.js +142 -42
- package/_modules/themes/five/src/components/Checkout/styles.js +5 -3
- package/_modules/themes/five/src/components/Header/index.js +3 -3
- package/_modules/themes/five/src/components/InputPhoneNumber/index.js +10 -21
- package/_modules/themes/five/src/components/LoginForm/index.js +29 -13
- package/_modules/themes/five/src/components/MultiCheckout/index.js +5 -1
- package/_modules/themes/five/src/components/QueryLoginSpoonity/index.js +37 -0
- package/_modules/themes/five/src/components/SignUpForm/index.js +15 -7
- package/_modules/themes/five/src/styles/Buttons/index.js +32 -2
- package/package.json +2 -2
- package/src/components/PaymentOptions/index.js +35 -2
- package/src/index.js +2 -0
- package/src/themes/five/index.js +2 -1
- package/src/themes/five/src/components/BusinessProductsListing/index.js +3 -2
- package/src/themes/five/src/components/Cart/index.js +10 -1
- package/src/themes/five/src/components/Cart/styles.js +5 -0
- package/src/themes/five/src/components/Checkout/index.js +141 -54
- package/src/themes/five/src/components/Checkout/styles.js +15 -0
- package/src/themes/five/src/components/Header/index.js +2 -2
- package/src/themes/five/src/components/InputPhoneNumber/index.js +33 -38
- package/src/themes/five/src/components/LoginForm/index.js +27 -10
- package/src/themes/five/src/components/MultiCheckout/index.js +11 -2
- package/src/themes/five/src/components/QueryLoginSpoonity/index.js +19 -0
- package/src/themes/five/src/components/SignUpForm/index.js +9 -1
- package/src/themes/five/src/styles/Buttons/index.js +24 -0
- package/template/app.js +22 -7
- package/_bundles/ordering-ui.95882a524750766186cd.js +0 -2
package/src/index.js
CHANGED
|
@@ -98,6 +98,7 @@ import { SearchProducts } from './components/RenderProductsLayout/SearchProducts
|
|
|
98
98
|
import { ThemeContext, ThemeProvider, useTheme } from './contexts/ThemeContext'
|
|
99
99
|
import { useOnlineStatus } from './hooks/useOnlineStatus'
|
|
100
100
|
import { useWindowSize } from './hooks/useWindowSize'
|
|
101
|
+
import { useRecaptcha } from './hooks/useRecaptcha'
|
|
101
102
|
import { useCountdownTimer } from './hooks/useCountdownTimer'
|
|
102
103
|
import { useIntersectionObserver } from './hooks/useIntersectionObserver'
|
|
103
104
|
import { useIsMounted } from './hooks/useIsMounted'
|
|
@@ -241,6 +242,7 @@ export {
|
|
|
241
242
|
// Hooks
|
|
242
243
|
useOnlineStatus,
|
|
243
244
|
useWindowSize,
|
|
245
|
+
useRecaptcha,
|
|
244
246
|
useCountdownTimer,
|
|
245
247
|
useIntersectionObserver,
|
|
246
248
|
useIsMounted,
|
package/src/themes/five/index.js
CHANGED
|
@@ -114,6 +114,7 @@ import { OrderPreferencesSection } from './src/components/OrderDetails/OrderPref
|
|
|
114
114
|
import { ActionsSection } from './src/components/OrderDetails/ActionsSection'
|
|
115
115
|
import { ProductShare } from './src/components/ProductShare'
|
|
116
116
|
import { MultiCart } from './src/components/MultiCart'
|
|
117
|
+
import { QueryLoginSpoonity } from './src/components/QueryLoginSpoonity'
|
|
117
118
|
|
|
118
119
|
import { Button } from './src/styles/Buttons'
|
|
119
120
|
import { Input, TextArea } from './src/styles/Inputs'
|
|
@@ -239,7 +240,7 @@ export {
|
|
|
239
240
|
ActionsSection,
|
|
240
241
|
ProductShare,
|
|
241
242
|
MultiCart,
|
|
242
|
-
|
|
243
|
+
QueryLoginSpoonity,
|
|
243
244
|
// styles
|
|
244
245
|
Button,
|
|
245
246
|
Input,
|
|
@@ -298,9 +298,10 @@ const BusinessProductsListingUI = (props) => {
|
|
|
298
298
|
<>
|
|
299
299
|
<ProductsContainer>
|
|
300
300
|
{!props.useKioskApp && (
|
|
301
|
-
// <ArrowLeft onClick={() => handleGoToBusinessList()} />
|
|
302
301
|
<HeaderContent>
|
|
303
|
-
|
|
302
|
+
{!location.pathname.includes('/marketplace') &&
|
|
303
|
+
<ArrowLeft className='back-arrow' onClick={() => handleGoToBusinessList()} />
|
|
304
|
+
}
|
|
304
305
|
{windowSize?.width < 576 && (
|
|
305
306
|
<OrderContextUIWrapper>
|
|
306
307
|
<OrderContextUI isCheckOut />
|
|
@@ -71,7 +71,8 @@ const CartUI = (props) => {
|
|
|
71
71
|
hideDeliveryFee,
|
|
72
72
|
hideDriverTip,
|
|
73
73
|
hideCouponInput,
|
|
74
|
-
businessConfigs
|
|
74
|
+
businessConfigs,
|
|
75
|
+
loyaltyRewardRate
|
|
75
76
|
} = props
|
|
76
77
|
|
|
77
78
|
const theme = useTheme()
|
|
@@ -128,6 +129,8 @@ const CartUI = (props) => {
|
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
const loyaltyRewardValue = Math.round(cart?.subtotal / loyaltyRewardRate)
|
|
133
|
+
|
|
131
134
|
const momentFormatted = !orderState?.option?.moment
|
|
132
135
|
? t('RIGHT_NOW', 'Right Now')
|
|
133
136
|
: parseDate(orderState?.option?.moment, { outputFormat: 'YYYY-MM-DD HH:mm' })
|
|
@@ -515,6 +518,12 @@ const CartUI = (props) => {
|
|
|
515
518
|
<td>{t('TOTAL', 'Total')}</td>
|
|
516
519
|
<td>{parsePrice(cart?.total >= 0 ? cart?.total : 0)}</td>
|
|
517
520
|
</tr>
|
|
521
|
+
{!!loyaltyRewardValue && isFinite(loyaltyRewardValue) && (
|
|
522
|
+
<tr>
|
|
523
|
+
<td> </td>
|
|
524
|
+
<td id='loyalty'>{t('REWARD_LOYALTY_POINT', 'Reward :amount: on loyalty points').replace(':amount:', loyaltyRewardValue)}</td>
|
|
525
|
+
</tr>
|
|
526
|
+
)}
|
|
518
527
|
</tbody>
|
|
519
528
|
</table>
|
|
520
529
|
{cart?.status !== 2 && !hideCartComments && (
|
|
@@ -46,7 +46,8 @@ import {
|
|
|
46
46
|
WrapperActionsInput,
|
|
47
47
|
MobileWrapperPlaceOrderButton,
|
|
48
48
|
OrderContextUIWrapper,
|
|
49
|
-
HeaderContent
|
|
49
|
+
HeaderContent,
|
|
50
|
+
AuthButtonList
|
|
50
51
|
} from './styles'
|
|
51
52
|
|
|
52
53
|
import { Button } from '../../styles/Buttons'
|
|
@@ -65,6 +66,8 @@ import { CartContent } from '../CartContent'
|
|
|
65
66
|
import { Select } from '../../styles/Select'
|
|
66
67
|
import { PlaceSpot } from '../PlaceSpot'
|
|
67
68
|
import { OrderContextUI } from '../OrderContextUI'
|
|
69
|
+
import { SignUpForm } from '../SignUpForm'
|
|
70
|
+
import { LoginForm } from '../LoginForm'
|
|
68
71
|
|
|
69
72
|
const mapConfigs = {
|
|
70
73
|
mapZoom: 16,
|
|
@@ -81,6 +84,7 @@ const CheckoutUI = (props) => {
|
|
|
81
84
|
placing,
|
|
82
85
|
cartState,
|
|
83
86
|
useKioskApp,
|
|
87
|
+
loyaltyPlansState,
|
|
84
88
|
businessDetails,
|
|
85
89
|
paymethodSelected,
|
|
86
90
|
handlePaymethodChange,
|
|
@@ -104,7 +108,7 @@ const CheckoutUI = (props) => {
|
|
|
104
108
|
const [{ options, loading }] = useOrder()
|
|
105
109
|
const [, t] = useLanguage()
|
|
106
110
|
const [{ parsePrice }] = useUtils()
|
|
107
|
-
const [{ user }] = useSession()
|
|
111
|
+
const [{ user }, { login }] = useSession()
|
|
108
112
|
const [{ configs }] = useConfig()
|
|
109
113
|
const [customerState] = useCustomer()
|
|
110
114
|
const [events] = useEvent()
|
|
@@ -120,6 +124,9 @@ const CheckoutUI = (props) => {
|
|
|
120
124
|
const [isOpen, setIsOpen] = useState(false)
|
|
121
125
|
const [requiredFields, setRequiredFields] = useState([])
|
|
122
126
|
const [isSuccess, setIsSuccess] = useState(false)
|
|
127
|
+
const [openModal, setOpenModal] = useState({ login: false, signup: false })
|
|
128
|
+
const [allowedGuest, setAllowedGuest] = useState(false)
|
|
129
|
+
const [cardList, setCardList] = useState([])
|
|
123
130
|
|
|
124
131
|
const businessConfigs = businessDetails?.business?.configs ?? []
|
|
125
132
|
const isTableNumberEnabled = configs?.table_numer_enabled?.value
|
|
@@ -135,6 +142,7 @@ const CheckoutUI = (props) => {
|
|
|
135
142
|
|
|
136
143
|
const isDisablePlaceOrderButton = !cart?.valid ||
|
|
137
144
|
(!paymethodSelected && cart?.balance > 0) ||
|
|
145
|
+
(paymethodSelected?.gateway === 'stripe' && cardList?.cards?.length === 0) ||
|
|
138
146
|
placing ||
|
|
139
147
|
errorCash ||
|
|
140
148
|
loading ||
|
|
@@ -164,7 +172,7 @@ const CheckoutUI = (props) => {
|
|
|
164
172
|
const driverTipsField = !cartState.loading && cart && cart?.business_id && options.type === 1 && cart?.status !== 2 && validationFields?.fields?.checkout?.driver_tip?.enabled && driverTipsOptions.length > 0 && !useKioskApp
|
|
165
173
|
|
|
166
174
|
const handlePlaceOrder = () => {
|
|
167
|
-
if (!userErrors.length && !requiredFields?.length) {
|
|
175
|
+
if (!userErrors.length && (!requiredFields?.length || allowedGuest)) {
|
|
168
176
|
const body = {}
|
|
169
177
|
if (behalfName) {
|
|
170
178
|
body.on_behalf_of = behalfName
|
|
@@ -183,6 +191,15 @@ const CheckoutUI = (props) => {
|
|
|
183
191
|
setIsUserDetailsEdit(true)
|
|
184
192
|
}
|
|
185
193
|
|
|
194
|
+
const handlePlaceOrderAsGuest = () => {
|
|
195
|
+
setIsOpen(false)
|
|
196
|
+
const body = {}
|
|
197
|
+
if (behalfName) {
|
|
198
|
+
body.on_behalf_of = behalfName
|
|
199
|
+
}
|
|
200
|
+
handlerClickPlaceOrder && handlerClickPlaceOrder(null, body)
|
|
201
|
+
}
|
|
202
|
+
|
|
186
203
|
const closeAlert = () => {
|
|
187
204
|
setAlertState({
|
|
188
205
|
open: false,
|
|
@@ -233,6 +250,18 @@ const CheckoutUI = (props) => {
|
|
|
233
250
|
setUserErrors(errors)
|
|
234
251
|
}
|
|
235
252
|
|
|
253
|
+
const handleSuccessSignup = (user) => {
|
|
254
|
+
login({
|
|
255
|
+
user,
|
|
256
|
+
token: user?.session?.access_token
|
|
257
|
+
})
|
|
258
|
+
setOpenModal({ ...openModal, signup: false })
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const handleSuccessLogin = (user) => {
|
|
262
|
+
if (user) setOpenModal({ ...openModal, login: false })
|
|
263
|
+
}
|
|
264
|
+
|
|
236
265
|
const handleScrollTo = () => {
|
|
237
266
|
if (!((!paymethodSelected && cart?.balance > 0) && cart?.status !== 2)) return
|
|
238
267
|
const scrollElement = document.querySelector('.paymentsContainer')
|
|
@@ -299,7 +328,7 @@ const CheckoutUI = (props) => {
|
|
|
299
328
|
|
|
300
329
|
{!useKioskApp ? (
|
|
301
330
|
<>
|
|
302
|
-
{cart?.business_id && (
|
|
331
|
+
{cart?.business_id && !hideBusinessMap && (
|
|
303
332
|
<>
|
|
304
333
|
{(businessDetails?.loading || cartState.loading) ? (
|
|
305
334
|
<div style={{ width: '100%', marginBottom: '20px' }}>
|
|
@@ -319,34 +348,51 @@ const CheckoutUI = (props) => {
|
|
|
319
348
|
)}
|
|
320
349
|
</>
|
|
321
350
|
)}
|
|
322
|
-
|
|
323
|
-
<
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
<
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
351
|
+
{!hideCustomerDetails && (
|
|
352
|
+
<UserDetailsContainer>
|
|
353
|
+
<WrapperUserDetails>
|
|
354
|
+
{cartState.loading || (isCustomerMode && !customerState?.user?.id) ? (
|
|
355
|
+
<div>
|
|
356
|
+
<Skeleton height={35} style={{ marginBottom: '10px' }} />
|
|
357
|
+
<Skeleton height={35} style={{ marginBottom: '10px' }} />
|
|
358
|
+
<Skeleton height={35} style={{ marginBottom: '10px' }} />
|
|
359
|
+
<Skeleton height={35} style={{ marginBottom: '10px' }} />
|
|
360
|
+
<Skeleton height={35} style={{ marginBottom: '10px' }} />
|
|
361
|
+
</div>
|
|
362
|
+
) : (
|
|
363
|
+
(user?.guest_id && !allowedGuest) ? (
|
|
364
|
+
<AuthButtonList>
|
|
365
|
+
<h2>{t('CUSTOMER_DETAILS', 'Customer details')}</h2>
|
|
366
|
+
<Button color='primary' onClick={() => setOpenModal({ ...openModal, signup: true })}>
|
|
367
|
+
{t('SIGN_UP', 'Sign up')}
|
|
368
|
+
</Button>
|
|
369
|
+
<Button color='primary' outline onClick={() => setOpenModal({ ...openModal, login: true })}>
|
|
370
|
+
{t('LOGIN', 'Login')}
|
|
371
|
+
</Button>
|
|
372
|
+
<Button color='black' outline onClick={() => setAllowedGuest(true)}>
|
|
373
|
+
{t('CONTINUE_AS_GUEST', 'Continue as guest')}
|
|
374
|
+
</Button>
|
|
375
|
+
</AuthButtonList>
|
|
376
|
+
) : (
|
|
377
|
+
<UserDetails
|
|
378
|
+
isUserDetailsEdit={isUserDetailsEdit}
|
|
379
|
+
cartStatus={cart?.status}
|
|
380
|
+
businessId={cart?.business_id}
|
|
381
|
+
useValidationFields
|
|
382
|
+
useDefualtSessionManager
|
|
383
|
+
useSessionUser={!isCustomerMode}
|
|
384
|
+
isCustomerMode={isCustomerMode}
|
|
385
|
+
userData={isCustomerMode && customerState.user}
|
|
386
|
+
userId={isCustomerMode && customerState?.user?.id}
|
|
387
|
+
isSuccess={isSuccess}
|
|
388
|
+
isCheckout
|
|
389
|
+
/>
|
|
390
|
+
)
|
|
391
|
+
)}
|
|
392
|
+
</WrapperUserDetails>
|
|
393
|
+
</UserDetailsContainer>
|
|
394
|
+
)}
|
|
395
|
+
{cart?.business_id && !hideBusinessDetails && (
|
|
350
396
|
<BusinessDetailsContainer>
|
|
351
397
|
{(businessDetails?.loading || cartState.loading) && !businessDetails?.error && (
|
|
352
398
|
<div>
|
|
@@ -363,7 +409,9 @@ const CheckoutUI = (props) => {
|
|
|
363
409
|
<div>
|
|
364
410
|
<h1>{t('BUSINESS_DETAILS', 'Business Details')}</h1>
|
|
365
411
|
<div>
|
|
366
|
-
|
|
412
|
+
{!hideBusinessAddress && (
|
|
413
|
+
<p>{businessDetails?.business?.address}</p>
|
|
414
|
+
)}
|
|
367
415
|
<p>{businessDetails?.business?.name}</p>
|
|
368
416
|
<p>{businessDetails?.business?.email}</p>
|
|
369
417
|
<p>{businessDetails?.business?.cellphone}</p>
|
|
@@ -446,6 +494,7 @@ const CheckoutUI = (props) => {
|
|
|
446
494
|
paySelected={paymethodSelected}
|
|
447
495
|
handlePlaceOrder={handlePlaceOrder}
|
|
448
496
|
onPlaceOrderClick={onPlaceOrderClick}
|
|
497
|
+
setCardList={setCardList}
|
|
449
498
|
/>
|
|
450
499
|
</PaymentMethodContainer>
|
|
451
500
|
)}
|
|
@@ -454,6 +503,7 @@ const CheckoutUI = (props) => {
|
|
|
454
503
|
<WalletPaymentOptionContainer>
|
|
455
504
|
<PaymentOptionWallet
|
|
456
505
|
cart={cart}
|
|
506
|
+
loyaltyPlansState={loyaltyPlansState}
|
|
457
507
|
businessConfigs={businessDetails?.business?.configs}
|
|
458
508
|
/>
|
|
459
509
|
</WalletPaymentOptionContainer>
|
|
@@ -464,24 +514,24 @@ const CheckoutUI = (props) => {
|
|
|
464
514
|
|
|
465
515
|
{
|
|
466
516
|
!!(!isMultiDriverTips && driverTipsField) &&
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
517
|
+
<>
|
|
518
|
+
<DriverTipContainer>
|
|
519
|
+
<h1>{t('DRIVER_TIPS', 'Driver Tips')}</h1>
|
|
520
|
+
<p>{t('100%_OF_THE_TIP_YOUR_DRIVER', '100% of the tip goes to your driver')}</p>
|
|
521
|
+
<DriverTips
|
|
522
|
+
businessId={cart?.business_id}
|
|
523
|
+
driverTipsOptions={driverTipsOptions}
|
|
524
|
+
isFixedPrice={parseInt(configs?.driver_tip_type?.value, 10) === 1}
|
|
525
|
+
isDriverTipUseCustom={!!parseInt(configs?.driver_tip_use_custom?.value, 10)}
|
|
526
|
+
driverTip={parseInt(configs?.driver_tip_type?.value, 10) === 1
|
|
527
|
+
? cart?.driver_tip
|
|
528
|
+
: cart?.driver_tip_rate}
|
|
529
|
+
cart={cart}
|
|
530
|
+
useOrderContext
|
|
531
|
+
/>
|
|
532
|
+
</DriverTipContainer>
|
|
533
|
+
<DriverTipDivider />
|
|
534
|
+
</>
|
|
485
535
|
}
|
|
486
536
|
{!cartState.loading && placeSpotsEnabled && cart?.business_id && (
|
|
487
537
|
<SelectSpotContainer>
|
|
@@ -510,6 +560,9 @@ const CheckoutUI = (props) => {
|
|
|
510
560
|
useKioskApp={useKioskApp}
|
|
511
561
|
isCheckout
|
|
512
562
|
isProducts={cart?.products?.length || 0}
|
|
563
|
+
viewString='checkout'
|
|
564
|
+
businessConfigs={businessConfigs}
|
|
565
|
+
loyaltyRewardRate={loyaltyPlansState?.result?.find(loyal => loyal.type === 'credit_point')?.accumulation_rate ?? 0}
|
|
513
566
|
/>
|
|
514
567
|
</CartContainer>
|
|
515
568
|
)}
|
|
@@ -578,9 +631,15 @@ const CheckoutUI = (props) => {
|
|
|
578
631
|
validationFields?.fields?.checkout?.driver_tip?.enabled &&
|
|
579
632
|
validationFields?.fields?.checkout?.driver_tip?.required &&
|
|
580
633
|
(Number(cart?.driver_tip) <= 0) &&
|
|
581
|
-
|
|
634
|
+
(
|
|
635
|
+
<WarningText>
|
|
636
|
+
{t('WARNING_INVALID_DRIVER_TIP', 'Driver Tip is required.')}
|
|
637
|
+
</WarningText>
|
|
638
|
+
)}
|
|
639
|
+
|
|
640
|
+
{!cart?.valid_preorder && (
|
|
582
641
|
<WarningText>
|
|
583
|
-
{t('
|
|
642
|
+
{t('INVALID_CART_MOMENT', 'Selected schedule time is invalid, please select a schedule into the business schedule interval.')}
|
|
584
643
|
</WarningText>
|
|
585
644
|
)}
|
|
586
645
|
</WrapperRightContainer>
|
|
@@ -630,12 +689,39 @@ const CheckoutUI = (props) => {
|
|
|
630
689
|
isCheckout
|
|
631
690
|
isEdit
|
|
632
691
|
isModal
|
|
692
|
+
handlePlaceOrderAsGuest={handlePlaceOrderAsGuest}
|
|
633
693
|
onClose={() => {
|
|
634
694
|
setIsOpen(false)
|
|
635
695
|
handlePlaceOrder()
|
|
636
696
|
}}
|
|
637
697
|
/>
|
|
638
698
|
</Modal>
|
|
699
|
+
<Modal
|
|
700
|
+
open={openModal.signup}
|
|
701
|
+
width='760px'
|
|
702
|
+
padding='30px'
|
|
703
|
+
onClose={() => setOpenModal({ ...openModal, signup: false })}
|
|
704
|
+
>
|
|
705
|
+
<SignUpForm
|
|
706
|
+
useLoginByCellphone
|
|
707
|
+
useChekoutFileds
|
|
708
|
+
handleSuccessSignup={handleSuccessSignup}
|
|
709
|
+
isPopup
|
|
710
|
+
isGuest
|
|
711
|
+
/>
|
|
712
|
+
</Modal>
|
|
713
|
+
<Modal
|
|
714
|
+
open={openModal.login}
|
|
715
|
+
width='760px'
|
|
716
|
+
padding='30px'
|
|
717
|
+
onClose={() => setOpenModal({ ...openModal, login: false })}
|
|
718
|
+
>
|
|
719
|
+
<LoginForm
|
|
720
|
+
handleSuccessLogin={handleSuccessLogin}
|
|
721
|
+
isPopup
|
|
722
|
+
isGuest
|
|
723
|
+
/>
|
|
724
|
+
</Modal>
|
|
639
725
|
</Container>
|
|
640
726
|
)
|
|
641
727
|
}
|
|
@@ -719,7 +805,8 @@ export const Checkout = (props) => {
|
|
|
719
805
|
method: 'GET',
|
|
720
806
|
headers: {
|
|
721
807
|
'Content-Type': 'application/json',
|
|
722
|
-
Authorization: `Bearer ${token}
|
|
808
|
+
Authorization: `Bearer ${token}`,
|
|
809
|
+
'X-App-X': ordering.appId
|
|
723
810
|
}
|
|
724
811
|
})
|
|
725
812
|
const content = await response.json()
|
|
@@ -334,3 +334,18 @@ export const HeaderContent = styled.div`
|
|
|
334
334
|
cursor: pointer;
|
|
335
335
|
}
|
|
336
336
|
`
|
|
337
|
+
|
|
338
|
+
export const AuthButtonList = styled.div`
|
|
339
|
+
display: flex;
|
|
340
|
+
flex-direction: column;
|
|
341
|
+
h2 {
|
|
342
|
+
font-weight: 600;
|
|
343
|
+
font-size: 20px;
|
|
344
|
+
margin-bottom: 3px;
|
|
345
|
+
}
|
|
346
|
+
button {
|
|
347
|
+
width: 100%;
|
|
348
|
+
height: 44px;
|
|
349
|
+
margin-top: 22px;
|
|
350
|
+
}
|
|
351
|
+
`
|
|
@@ -224,8 +224,8 @@ export const Header = (props) => {
|
|
|
224
224
|
onClick={() => handleGoToPage({ page: orderState?.options?.address?.location && !isCustomerMode ? 'search' : 'home' })}
|
|
225
225
|
isChew={isChew}
|
|
226
226
|
>
|
|
227
|
-
<img alt='Logotype' width='170px' height={isChew ? '35px' : '45px'} src={isChew ? theme?.images?.logos?.chewLogo : orderingTheme?.my_products?.components?.images?.components?.logo?.components?.image || theme?.images?.logos?.logotype} loading='lazy' />
|
|
228
|
-
<img alt='Isotype' width={isChew ? '70px' : '35px'} height={isChew ? '20px' : '45px'} src={isChew ? theme?.images?.logos?.chewLogo : orderingTheme?.my_products?.components?.images?.components?.logo?.components?.image || (isHome ? theme?.images?.logos?.isotypeInvert : theme?.images?.logos?.isotype)} loading='lazy' />
|
|
227
|
+
<img alt='Logotype' width='170px' height={isChew ? '35px' : '45px'} src={isChew ? theme?.images?.logos?.chewLogo : orderingTheme?.theme?.my_products?.components?.images?.components?.logo?.components?.image || theme?.images?.logos?.logotype} loading='lazy' />
|
|
228
|
+
<img alt='Isotype' width={isChew ? '70px' : '35px'} height={isChew ? '20px' : '45px'} src={isChew ? theme?.images?.logos?.chewLogo : orderingTheme?.theme?.my_products?.components?.images?.components?.logo?.components?.image || (isHome ? theme?.images?.logos?.isotypeInvert : theme?.images?.logos?.isotype)} loading='lazy' />
|
|
229
229
|
</LogoHeader>
|
|
230
230
|
</LeftHeader>
|
|
231
231
|
{isShowOrderOptions && !props.isCustomLayout && windowSize.width >= 576 && (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect } from 'react'
|
|
1
|
+
import React, { useEffect, useRef } from 'react'
|
|
2
2
|
import parsePhoneNumber from 'libphonenumber-js'
|
|
3
3
|
import PhoneInput from 'react-phone-number-input'
|
|
4
4
|
import BsPhone from '@meronex/icons/bs/BsPhone'
|
|
@@ -13,13 +13,17 @@ export const InputPhoneNumber = (props) => {
|
|
|
13
13
|
setValue,
|
|
14
14
|
handleIsValid,
|
|
15
15
|
disabled,
|
|
16
|
-
isError
|
|
16
|
+
isError,
|
|
17
|
+
currentCountryCode,
|
|
18
|
+
setCurrentPhoneNumber
|
|
17
19
|
} = props
|
|
18
20
|
|
|
19
21
|
const [, t] = useLanguage()
|
|
20
22
|
const [{ auth }] = useSession()
|
|
21
23
|
const [{ configs }] = useConfig()
|
|
22
24
|
|
|
25
|
+
const phoneRef = useRef(null)
|
|
26
|
+
|
|
23
27
|
const isValidPhoneNumber = (number) => {
|
|
24
28
|
if (!number) return
|
|
25
29
|
if (!parseInt(configs?.validation_phone_number_lib?.value ?? 1, 10)) {
|
|
@@ -31,49 +35,40 @@ export const InputPhoneNumber = (props) => {
|
|
|
31
35
|
|
|
32
36
|
useEffect(() => {
|
|
33
37
|
if (value) {
|
|
38
|
+
setCurrentPhoneNumber &&
|
|
39
|
+
setCurrentPhoneNumber(
|
|
40
|
+
`+${currentCountryCode} ${phoneRef?.current?.defaultValue?.replace(/ /g, '')}`
|
|
41
|
+
)
|
|
34
42
|
handleIsValid && handleIsValid(isValidPhoneNumber(value))
|
|
35
43
|
}
|
|
36
44
|
}, [value])
|
|
37
45
|
|
|
38
46
|
return (
|
|
39
47
|
<Container className='phone_number' disabled={disabled} isValid={value ? isValidPhoneNumber(value) : true} isError={isError}>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/>
|
|
59
|
-
{value && !isValidPhoneNumber(value) && !disabled && (
|
|
60
|
-
<>
|
|
61
|
-
{((auth && user?.country_phone_code) || !auth || value.includes('+')) && (
|
|
62
|
-
<ErrorMsg>{t('INVALID_ERROR_PHONE_NUMBER', 'The Phone Number field is invalid')}</ErrorMsg>
|
|
63
|
-
)}
|
|
48
|
+
<InputBeforeIconWrapper>
|
|
49
|
+
<BsPhone />
|
|
50
|
+
</InputBeforeIconWrapper>
|
|
51
|
+
<PhoneInput
|
|
52
|
+
ref={phoneRef}
|
|
53
|
+
disabled={disabled}
|
|
54
|
+
placeholder={t('PHONE_NUMBER', 'Phone number')}
|
|
55
|
+
defaultCountry={configs?.default_country_code?.value}
|
|
56
|
+
value={value}
|
|
57
|
+
name='telefono'
|
|
58
|
+
displayInitialValueAsLocalNumber
|
|
59
|
+
onChange={(val) => setValue && setValue(val, isValidPhoneNumber(val))}
|
|
60
|
+
/>
|
|
61
|
+
{value && !isValidPhoneNumber(value) && !disabled && (
|
|
62
|
+
<>
|
|
63
|
+
{((auth && user?.country_phone_code) || !auth || value.includes('+')) && (
|
|
64
|
+
<ErrorMsg>{t('INVALID_ERROR_PHONE_NUMBER', 'The Phone Number field is invalid')}</ErrorMsg>
|
|
65
|
+
)}
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
{props.afterComponents?.map((AfterComponent, i) => (
|
|
71
|
-
<AfterComponent key={i} {...props} />))}
|
|
72
|
-
{props.afterElements?.map((AfterElement, i) => (
|
|
73
|
-
<React.Fragment key={i}>
|
|
74
|
-
{AfterElement}
|
|
75
|
-
</React.Fragment>))}
|
|
76
|
-
</>
|
|
67
|
+
{auth && !user?.country_phone_code && !value.includes('+') && (
|
|
68
|
+
<ErrorMsg>{t('INVALID_ERROR_COUNTRY_CODE_PHONE_NUMBER', 'The country code of the phone number is invalid')}</ErrorMsg>
|
|
69
|
+
)}
|
|
70
|
+
</>
|
|
71
|
+
)}
|
|
77
72
|
</Container>
|
|
78
73
|
)
|
|
79
74
|
}
|
|
@@ -86,7 +86,9 @@ const LoginFormUI = (props) => {
|
|
|
86
86
|
otpState,
|
|
87
87
|
setOtpState,
|
|
88
88
|
useLoginOtpEmail,
|
|
89
|
-
useLoginOtpCellphone
|
|
89
|
+
useLoginOtpCellphone,
|
|
90
|
+
handleLoginSpoonity,
|
|
91
|
+
useLoginSpoonity
|
|
90
92
|
} = props
|
|
91
93
|
const numOtpInputs = loginTab === 'otp' ? 6 : 4
|
|
92
94
|
const [ordering, { setOrdering }] = useApi()
|
|
@@ -120,6 +122,8 @@ const LoginFormUI = (props) => {
|
|
|
120
122
|
const facebookLoginEnabled = configs?.facebook_login_enabled?.value === '1' || !configs?.facebook_login_enabled?.enabled
|
|
121
123
|
const appleLoginEnabled = configs?.apple_login_enabled?.value === '1' || !configs?.apple_login_enabled?.enabled
|
|
122
124
|
|
|
125
|
+
const spoonityTitle = configs?.spoonity_title?.value
|
|
126
|
+
|
|
123
127
|
const hasSocialLogin = (
|
|
124
128
|
(configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') && configs?.facebook_id?.value) ||
|
|
125
129
|
(configs?.google_login_client_id?.value && configs?.google_login_auth_domain?.value && configs?.google_login_api_key?.value && googleLoginEnabled) ||
|
|
@@ -154,6 +158,10 @@ const LoginFormUI = (props) => {
|
|
|
154
158
|
setSubmitted(true)
|
|
155
159
|
return
|
|
156
160
|
}
|
|
161
|
+
if (loginTab === 'spoonity') {
|
|
162
|
+
handleLoginSpoonity()
|
|
163
|
+
return
|
|
164
|
+
}
|
|
157
165
|
handleButtonLoginClick()
|
|
158
166
|
}
|
|
159
167
|
}
|
|
@@ -243,6 +251,12 @@ const LoginFormUI = (props) => {
|
|
|
243
251
|
setOtpType(type)
|
|
244
252
|
}
|
|
245
253
|
|
|
254
|
+
const preventWhiteSpaceOnKeyDown = (e) => {
|
|
255
|
+
if (e.key === ' ') {
|
|
256
|
+
e.preventDefault()
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
246
260
|
useEffect(() => {
|
|
247
261
|
if (!formState.loading && formState.result?.error) {
|
|
248
262
|
if (formState.result?.result?.[0] === 'ERROR_AUTH_VERIFICATION_CODE') {
|
|
@@ -346,12 +360,6 @@ const LoginFormUI = (props) => {
|
|
|
346
360
|
}
|
|
347
361
|
}, [recaptchaConfig])
|
|
348
362
|
|
|
349
|
-
const preventWhiteSpaceOnKeyDown = (e) => {
|
|
350
|
-
if (e.key === " ") {
|
|
351
|
-
e.preventDefault()
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
363
|
return (
|
|
356
364
|
<>
|
|
357
365
|
{props.beforeElements?.map((BeforeElement, i) => (
|
|
@@ -375,7 +383,7 @@ const LoginFormUI = (props) => {
|
|
|
375
383
|
<Title>{t('LOGIN', 'Login')}</Title>
|
|
376
384
|
)}
|
|
377
385
|
|
|
378
|
-
{((Number(useLoginByEmail) + Number(useLoginByCellphone) + Number(useLoginOtpEmail) + Number(useLoginOtpCellphone) > 1) && !loginWithOtpState && !willVerifyOtpState) && (
|
|
386
|
+
{((Number(useLoginByEmail) + Number(useLoginByCellphone) + Number(useLoginOtpEmail) + Number(useLoginOtpCellphone) + Number(useLoginSpoonity) > 1) && !loginWithOtpState && !willVerifyOtpState) && (
|
|
379
387
|
<LoginWith isPopup={isPopup}>
|
|
380
388
|
<Tabs variant='primary'>
|
|
381
389
|
{useLoginByEmail && (
|
|
@@ -414,6 +422,15 @@ const LoginFormUI = (props) => {
|
|
|
414
422
|
{t('BY_OTP_CELLPHONE', 'by Otp Cellphone')}
|
|
415
423
|
</Tab>
|
|
416
424
|
)}
|
|
425
|
+
{useLoginSpoonity && (
|
|
426
|
+
<Tab
|
|
427
|
+
onClick={() => handleChangeTab('spoonity')}
|
|
428
|
+
active={loginTab === 'spoonity'}
|
|
429
|
+
borderBottom={loginTab === 'spoonity'}
|
|
430
|
+
>
|
|
431
|
+
{spoonityTitle || t('BY_SPOONITY', 'by Spoonity')}
|
|
432
|
+
</Tab>
|
|
433
|
+
)}
|
|
417
434
|
</Tabs>
|
|
418
435
|
</LoginWith>
|
|
419
436
|
)}
|
|
@@ -455,7 +472,7 @@ const LoginFormUI = (props) => {
|
|
|
455
472
|
</InputBeforeIcon>
|
|
456
473
|
</InputWrapper>
|
|
457
474
|
)}
|
|
458
|
-
{(((useLoginByEmail && loginTab === 'email') || (loginTab === 'otp' && otpType === 'email')) && !willVerifyOtpState) && (
|
|
475
|
+
{(((useLoginByEmail && loginTab === 'email') || (loginTab === 'otp' && otpType === 'email') || (useLoginSpoonity && loginTab === 'spoonity')) && !willVerifyOtpState) && (
|
|
459
476
|
<>
|
|
460
477
|
{formMethods?.errors?.email?.type === 'required' && (
|
|
461
478
|
<ValidationText>
|
|
@@ -474,7 +491,7 @@ const LoginFormUI = (props) => {
|
|
|
474
491
|
aria-label='email'
|
|
475
492
|
placeholder={t('EMAIL', 'Email')}
|
|
476
493
|
ref={formMethods.register({
|
|
477
|
-
required: loginTab === 'email'
|
|
494
|
+
required: loginTab === 'email' || loginTab === 'spoonity'
|
|
478
495
|
? t('VALIDATION_ERROR_EMAIL_REQUIRED', 'The field Email is required').replace('_attribute_', t('EMAIL', 'Email'))
|
|
479
496
|
: null,
|
|
480
497
|
pattern: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i
|