ordering-ui-external 2.6.7 → 2.7.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.0a58ae9fc1a4bce64c6e.js +1 -0
- package/_bundles/{1.ordering-ui.fd1dc326de89a8eb39f9.js → 1.ordering-ui.0a58ae9fc1a4bce64c6e.js} +1 -1
- package/_bundles/4.ordering-ui.0a58ae9fc1a4bce64c6e.js +1 -0
- package/_bundles/{5.ordering-ui.fd1dc326de89a8eb39f9.js → 5.ordering-ui.0a58ae9fc1a4bce64c6e.js} +1 -1
- package/_bundles/{6.ordering-ui.fd1dc326de89a8eb39f9.js → 6.ordering-ui.0a58ae9fc1a4bce64c6e.js} +1 -1
- package/_bundles/{7.ordering-ui.fd1dc326de89a8eb39f9.js → 7.ordering-ui.0a58ae9fc1a4bce64c6e.js} +2 -2
- package/_bundles/ordering-ui.0a58ae9fc1a4bce64c6e.js +2 -0
- package/_modules/components/LanguageSelector/index.js +1 -0
- package/_modules/components/OrderTypeSelectorHeader/index.js +3 -1
- package/_modules/components/SmartAppBanner/index.js +5 -2
- package/_modules/contexts/ThemeContext/index.js +1 -1
- package/_modules/styles/Select/index.js +14 -2
- package/_modules/styles/Selects/index.js +11 -8
- package/_modules/themes/five/index.js +21 -0
- package/_modules/themes/five/src/components/BusinessBasicInformation/BusinessInfoComponent.js +168 -0
- package/_modules/themes/five/src/components/BusinessBasicInformation/SearchComponent.js +39 -0
- package/_modules/themes/five/src/components/BusinessBasicInformation/SocialNetWork.js +19 -0
- package/_modules/themes/five/src/components/BusinessBasicInformation/index.js +35 -156
- package/_modules/themes/five/src/components/BusinessBasicInformation/styles.js +45 -35
- package/_modules/themes/five/src/components/BusinessController/index.js +6 -2
- package/_modules/themes/five/src/components/BusinessProductsCategories/index.js +1 -1
- package/_modules/themes/five/src/components/BusinessProductsListing/index.js +5 -4
- package/_modules/themes/five/src/components/CardForm/index.js +16 -3
- package/_modules/themes/five/src/components/CardForm/styles.js +13 -9
- package/_modules/themes/five/src/components/CardFormCustom/cardUtils.js +102 -0
- package/_modules/themes/five/src/components/CardFormCustom/index.js +148 -0
- package/_modules/themes/five/src/components/CardFormCustom/styles.js +16 -0
- package/_modules/themes/five/src/components/Cart/index.js +1 -1
- package/_modules/themes/five/src/components/CartPopover/styles.js +1 -1
- package/_modules/themes/five/src/components/Checkout/index.js +41 -27
- package/_modules/themes/five/src/components/Header/index.js +10 -4
- package/_modules/themes/five/src/components/LanguageSelector/index.js +4 -1
- package/_modules/themes/five/src/components/LoginForm/index.js +11 -8
- package/_modules/themes/five/src/components/Modal/styles.js +1 -1
- package/_modules/themes/five/src/components/OrderContextUI/index.js +13 -1
- package/_modules/themes/five/src/components/OrderDetails/OrderBillSection.js +1 -1
- package/_modules/themes/five/src/components/OrderDetails/OrderEta.js +18 -8
- package/_modules/themes/five/src/components/OrderDetails/OrderHistory.js +7 -3
- package/_modules/themes/five/src/components/OrderDetails/index.js +4 -2
- package/_modules/themes/five/src/components/PaymentOptionCard/index.js +84 -0
- package/_modules/themes/five/src/components/PaymentOptionStripe/index.js +48 -22
- package/_modules/themes/five/src/components/PaymentOptionStripe/styles.js +3 -1
- package/_modules/themes/five/src/components/PaymentOptions/index.js +46 -24
- package/_modules/themes/five/src/components/ProductForm/styles.js +1 -1
- package/_modules/themes/five/src/components/RenderProductsLayout/index.js +2 -2
- package/_modules/themes/five/src/components/SearchProducts/styles.js +1 -1
- package/_modules/themes/five/src/components/UserDetails/index.js +1 -1
- package/_modules/themes/five/src/components/UserPopover/styles.js +1 -1
- package/_modules/themes/five/src/styles/Select/index.js +4 -2
- package/_modules/themes/five/src/styles/Selects/index.js +7 -4
- package/_modules/themes/pwa/src/components/MomentPopover/styles.js +1 -1
- package/index.html +1 -1
- package/package.json +4 -2
- package/src/components/LanguageSelector/index.js +1 -0
- package/src/components/OrderTypeSelectorHeader/index.js +3 -1
- package/src/components/SmartAppBanner/index.js +4 -2
- package/src/contexts/ThemeContext/index.js +1 -1
- package/src/styles/Select/index.js +11 -2
- package/src/styles/Selects/index.js +1 -1
- package/src/themes/five/index.js +6 -0
- package/src/themes/five/src/components/BusinessBasicInformation/BusinessInfoComponent.js +230 -0
- package/src/themes/five/src/components/BusinessBasicInformation/SearchComponent.js +40 -0
- package/src/themes/five/src/components/BusinessBasicInformation/SocialNetWork.js +10 -0
- package/src/themes/five/src/components/BusinessBasicInformation/index.js +39 -247
- package/src/themes/five/src/components/BusinessBasicInformation/styles.js +14 -4
- package/src/themes/five/src/components/BusinessController/index.js +2 -2
- package/src/themes/five/src/components/BusinessProductsCategories/index.js +1 -1
- package/src/themes/five/src/components/BusinessProductsListing/index.js +5 -4
- package/src/themes/five/src/components/CardForm/index.js +25 -4
- package/src/themes/five/src/components/CardForm/styles.js +35 -0
- package/src/themes/five/src/components/CardFormCustom/cardUtils.js +111 -0
- package/src/themes/five/src/components/CardFormCustom/index.js +161 -0
- package/src/themes/five/src/components/CardFormCustom/styles.js +20 -0
- package/src/themes/five/src/components/Cart/index.js +1 -1
- package/src/themes/five/src/components/CartPopover/styles.js +1 -1
- package/src/themes/five/src/components/Checkout/index.js +42 -30
- package/src/themes/five/src/components/Header/index.js +9 -4
- package/src/themes/five/src/components/LanguageSelector/index.js +2 -1
- package/src/themes/five/src/components/LoginForm/index.js +6 -4
- package/src/themes/five/src/components/Modal/styles.js +1 -0
- package/src/themes/five/src/components/OrderContextUI/index.js +10 -3
- package/src/themes/five/src/components/OrderDetails/OrderBillSection.js +1 -1
- package/src/themes/five/src/components/OrderDetails/OrderEta.js +21 -9
- package/src/themes/five/src/components/OrderDetails/OrderHistory.js +4 -3
- package/src/themes/five/src/components/OrderDetails/index.js +1 -1
- package/src/themes/five/src/components/PaymentOptionCard/index.js +70 -0
- package/src/themes/five/src/components/PaymentOptionStripe/index.js +46 -20
- package/src/themes/five/src/components/PaymentOptionStripe/styles.js +6 -1
- package/src/themes/five/src/components/PaymentOptions/index.js +28 -3
- package/src/themes/five/src/components/ProductForm/index.js +0 -1
- package/src/themes/five/src/components/ProductForm/styles.js +1 -1
- package/src/themes/five/src/components/RenderProductsLayout/index.js +2 -2
- package/src/themes/five/src/components/SearchProducts/styles.js +1 -1
- package/src/themes/five/src/components/UserDetails/index.js +1 -1
- package/src/themes/five/src/components/UserPopover/styles.js +1 -1
- package/src/themes/five/src/styles/Select/index.js +3 -2
- package/src/themes/five/src/styles/Selects/index.js +1 -1
- package/src/themes/pwa/src/components/MomentPopover/styles.js +4 -1
- package/template/app.js +13 -7
- package/template/pages/BusinessProductsList/index.js +4 -3
- package/template/pages/BusinessesList/index.js +2 -1
- package/template/pages/Checkout/index.js +1 -0
- package/template/pages/MyOrders/index.js +1 -0
- package/template/theme.json +3 -1
- package/_bundles/0.ordering-ui.fd1dc326de89a8eb39f9.js +0 -1
- package/_bundles/4.ordering-ui.fd1dc326de89a8eb39f9.js +0 -1
- package/_bundles/ordering-ui.fd1dc326de89a8eb39f9.js +0 -2
- /package/_bundles/{2.ordering-ui.fd1dc326de89a8eb39f9.js → 2.ordering-ui.0a58ae9fc1a4bce64c6e.js} +0 -0
- /package/_bundles/{7.ordering-ui.fd1dc326de89a8eb39f9.js.LICENSE.txt → 7.ordering-ui.0a58ae9fc1a4bce64c6e.js.LICENSE.txt} +0 -0
- /package/_bundles/{8.ordering-ui.fd1dc326de89a8eb39f9.js → 8.ordering-ui.0a58ae9fc1a4bce64c6e.js} +0 -0
- /package/_bundles/{9.ordering-ui.fd1dc326de89a8eb39f9.js → 9.ordering-ui.0a58ae9fc1a4bce64c6e.js} +0 -0
- /package/_bundles/{ordering-ui.fd1dc326de89a8eb39f9.js.LICENSE.txt → ordering-ui.0a58ae9fc1a4bce64c6e.js.LICENSE.txt} +0 -0
|
@@ -95,8 +95,8 @@ const BusinessControllerUI = (props) => {
|
|
|
95
95
|
|
|
96
96
|
const handleBusinessClick = (e) => {
|
|
97
97
|
if (favoriteRef?.current?.contains(e.target)) return
|
|
98
|
-
|
|
99
|
-
if (onPreorderBusiness && !isBusinessOpen) onPreorderBusiness(business)
|
|
98
|
+
const hasMenu = business?.menus?.filter(menu => menu?.enabled && menu?.products?.length > 0).length
|
|
99
|
+
if (onPreorderBusiness && (!isBusinessOpen || !hasMenu)) onPreorderBusiness(business)
|
|
100
100
|
else handleClick(business)
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -83,7 +83,8 @@ const BusinessProductsListingUI = (props) => {
|
|
|
83
83
|
onBusinessClick,
|
|
84
84
|
handleChangePriceFilterValues,
|
|
85
85
|
priceFilterValues,
|
|
86
|
-
handleUpdateProfessionals
|
|
86
|
+
handleUpdateProfessionals,
|
|
87
|
+
isCustomLayout
|
|
87
88
|
} = props
|
|
88
89
|
|
|
89
90
|
const { business, loading, error } = businessState
|
|
@@ -224,7 +225,7 @@ const BusinessProductsListingUI = (props) => {
|
|
|
224
225
|
}
|
|
225
226
|
const adjustBusiness = async (adjustBusinessId) => {
|
|
226
227
|
const _carts = carts?.[adjustBusinessId]
|
|
227
|
-
const products = carts?.[adjustBusinessId]?.products
|
|
228
|
+
const products = carts?.[adjustBusinessId]?.products || []
|
|
228
229
|
const unavailableProducts = products.filter(product => product.valid !== true)
|
|
229
230
|
const alreadyRemoved = sessionStorage.getItem('already-removed')
|
|
230
231
|
sessionStorage.removeItem('already-removed')
|
|
@@ -327,7 +328,7 @@ const BusinessProductsListingUI = (props) => {
|
|
|
327
328
|
<ProductsContainer>
|
|
328
329
|
{!props.useKioskApp && (
|
|
329
330
|
<HeaderContent>
|
|
330
|
-
{!location.pathname.includes('/marketplace') && (
|
|
331
|
+
{!isCustomLayout && !location.pathname.includes('/marketplace') && (
|
|
331
332
|
<div id='back-arrow'>
|
|
332
333
|
<ArrowLeft className='back-arrow' onClick={() => handleGoToBusinessList()} />
|
|
333
334
|
</div>
|
|
@@ -352,8 +353,8 @@ const BusinessProductsListingUI = (props) => {
|
|
|
352
353
|
businessState={businessState}
|
|
353
354
|
sortByOptions={sortByOptions}
|
|
354
355
|
categoryState={categoryState}
|
|
356
|
+
isCustomLayout={isCustomLayout}
|
|
355
357
|
categoriesState={props.categoriesState}
|
|
356
|
-
isCustomLayout={props.isCustomLayout}
|
|
357
358
|
useKioskApp={props.useKioskApp}
|
|
358
359
|
categorySelected={categorySelected}
|
|
359
360
|
openCategories={openCategories}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { CardCvcElement, CardElement, CardExpiryElement, CardNumberElement } from '@stripe/react-stripe-js'
|
|
3
|
-
import { CardForm as CardFormController, useLanguage } from 'ordering-components-external'
|
|
4
|
-
|
|
3
|
+
import { CardForm as CardFormController, useLanguage, useValidationFields } from 'ordering-components-external'
|
|
5
4
|
import {
|
|
6
5
|
FormStripe,
|
|
7
6
|
FormRow,
|
|
@@ -10,7 +9,9 @@ import {
|
|
|
10
9
|
CardNumberField,
|
|
11
10
|
CardExpiryCvcField,
|
|
12
11
|
CardExpiryField,
|
|
13
|
-
CardCvcField
|
|
12
|
+
CardCvcField,
|
|
13
|
+
CardZipcodeField,
|
|
14
|
+
ZipcodeField
|
|
14
15
|
} from './styles'
|
|
15
16
|
|
|
16
17
|
import { Button } from '../../styles/Buttons'
|
|
@@ -43,10 +44,14 @@ const CardFormUI = (props) => {
|
|
|
43
44
|
handleChange,
|
|
44
45
|
isSplitForm,
|
|
45
46
|
handleChangeExpiry,
|
|
46
|
-
handleChangeCvc
|
|
47
|
+
handleChangeCvc,
|
|
48
|
+
errorZipcode
|
|
47
49
|
} = props
|
|
48
50
|
|
|
49
51
|
const [, t] = useLanguage()
|
|
52
|
+
const [validationFields] = useValidationFields()
|
|
53
|
+
const zipCodeEnabled = validationFields?.fields?.card?.zipcode?.enabled
|
|
54
|
+
const zipCodeRequired = validationFields?.fields?.card?.zipcode?.required
|
|
50
55
|
|
|
51
56
|
return (
|
|
52
57
|
<>
|
|
@@ -93,6 +98,22 @@ const CardFormUI = (props) => {
|
|
|
93
98
|
<ErrorMessage>{errorCvc}</ErrorMessage>
|
|
94
99
|
</CardCvcField>
|
|
95
100
|
</CardExpiryCvcField>
|
|
101
|
+
{zipCodeEnabled && (
|
|
102
|
+
<CardZipcodeField>
|
|
103
|
+
<label>{t('ZIPCODE', 'Zipcode')}</label>
|
|
104
|
+
<ZipcodeField
|
|
105
|
+
name='zipcode'
|
|
106
|
+
placeholder={`${t('ZIPCODE', 'Zipcode')}${zipCodeRequired ? '*' : ''}`}
|
|
107
|
+
options={CARD_ELEMENT_OPTIONS}
|
|
108
|
+
onChange={handleChange}
|
|
109
|
+
pattern='[0-9]'
|
|
110
|
+
type='number'
|
|
111
|
+
/>
|
|
112
|
+
{errorZipcode && (
|
|
113
|
+
<ErrorMessage>{t('ZIPCODE_IS_INCOMPLETED', 'The zipcode is incompleted.')}</ErrorMessage>
|
|
114
|
+
)}
|
|
115
|
+
</CardZipcodeField>
|
|
116
|
+
)}
|
|
96
117
|
</>
|
|
97
118
|
}
|
|
98
119
|
</FormRow>
|
|
@@ -40,6 +40,10 @@ export const CardCvcField = styled.div`
|
|
|
40
40
|
color: #ADB2B9;
|
|
41
41
|
`
|
|
42
42
|
|
|
43
|
+
export const CardZipcodeField = styled.div`
|
|
44
|
+
color: #ADB2B9;
|
|
45
|
+
`
|
|
46
|
+
|
|
43
47
|
export const CardNumberField = styled.div`
|
|
44
48
|
width: 100%;
|
|
45
49
|
color: #ADB2B9;
|
|
@@ -98,3 +102,34 @@ export const FormActions = styled.div`
|
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
`
|
|
105
|
+
|
|
106
|
+
export const ZipcodeField = styled.input`
|
|
107
|
+
font-weight: 500;
|
|
108
|
+
font-size: 16px;
|
|
109
|
+
box-sizing: border-box;
|
|
110
|
+
width: 100% !important;
|
|
111
|
+
&:-webkit-autofill {
|
|
112
|
+
color: '#fce883'
|
|
113
|
+
}
|
|
114
|
+
&::placeholder {
|
|
115
|
+
font-weight: 500
|
|
116
|
+
}
|
|
117
|
+
&:focus(){
|
|
118
|
+
box-shadow: rgba(50, 50, 93, 0.109804) 0px 4px 6px,
|
|
119
|
+
rgba(0, 0, 0, 0.0784314) 0px 1px 3px;
|
|
120
|
+
-webkit-transition: all 150ms ease;
|
|
121
|
+
transition: all 150ms ease;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
&::-webkit-outer-spin-button,
|
|
125
|
+
&::-webkit-inner-spin-button {
|
|
126
|
+
-webkit-appearance: none;
|
|
127
|
+
margin: 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Firefox */
|
|
131
|
+
&[type=number] {
|
|
132
|
+
-moz-appearance: textfield;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
`
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import Payment from 'payment'
|
|
2
|
+
|
|
3
|
+
const clearNumber = (value = '') => {
|
|
4
|
+
return value.replace(/\D+/g, '')
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const formatCreditCardNumber = (value) => {
|
|
8
|
+
if (!value) {
|
|
9
|
+
return value
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const issuer = Payment.fns.cardType(value)
|
|
13
|
+
const clearValue = clearNumber(value)
|
|
14
|
+
let nextValue
|
|
15
|
+
|
|
16
|
+
switch (issuer) {
|
|
17
|
+
case 'amex':
|
|
18
|
+
nextValue = `${clearValue.slice(0, 4)} ${clearValue.slice(
|
|
19
|
+
4,
|
|
20
|
+
10
|
|
21
|
+
)} ${clearValue.slice(10, 15)}`
|
|
22
|
+
break
|
|
23
|
+
case 'dinersclub':
|
|
24
|
+
nextValue = `${clearValue.slice(0, 4)} ${clearValue.slice(
|
|
25
|
+
4,
|
|
26
|
+
10
|
|
27
|
+
)} ${clearValue.slice(10, 14)}`
|
|
28
|
+
break
|
|
29
|
+
default:
|
|
30
|
+
nextValue = `${clearValue.slice(0, 4)} ${clearValue.slice(
|
|
31
|
+
4,
|
|
32
|
+
8
|
|
33
|
+
)} ${clearValue.slice(8, 12)} ${clearValue.slice(12, 19)}`
|
|
34
|
+
break
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return nextValue.trim()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const formatCVC = (value, prevValue, allValues = {}) => {
|
|
41
|
+
const clearValue = clearNumber(value)
|
|
42
|
+
let maxLength = 4
|
|
43
|
+
|
|
44
|
+
if (allValues.number) {
|
|
45
|
+
const issuer = Payment.fns.cardType(allValues.number)
|
|
46
|
+
maxLength = issuer === 'amex' ? 4 : 3
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return clearValue.slice(0, maxLength)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const formatExpirationDate = (value) => {
|
|
53
|
+
const clearValue = clearNumber(value)
|
|
54
|
+
|
|
55
|
+
if (clearValue.length >= 3) {
|
|
56
|
+
return `${clearValue.slice(0, 2)}/${clearValue.slice(2, 4)}`
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return clearValue
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const getCardType = (number) => {
|
|
63
|
+
// visa
|
|
64
|
+
var re = new RegExp('^4')
|
|
65
|
+
if (number.match(re) != null) {
|
|
66
|
+
return 'Visa'
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Mastercard
|
|
70
|
+
// Updated for Mastercard 2017 BINs expansion
|
|
71
|
+
if (/^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/.test(number)) {
|
|
72
|
+
return 'Mastercard'
|
|
73
|
+
}
|
|
74
|
+
// AMEX
|
|
75
|
+
re = new RegExp('^3[47]')
|
|
76
|
+
if (number.match(re) != null) {
|
|
77
|
+
return 'AMEX'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Discover
|
|
81
|
+
re = new RegExp('^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)')
|
|
82
|
+
if (number.match(re) != null) {
|
|
83
|
+
return 'Discover'
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Diners
|
|
87
|
+
re = new RegExp('^36')
|
|
88
|
+
if (number.match(re) != null) {
|
|
89
|
+
return 'Diners'
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Diners - Carte Blanche
|
|
93
|
+
re = new RegExp('^30[0-5]')
|
|
94
|
+
if (number.match(re) != null) {
|
|
95
|
+
return 'Diners - Carte Blanche'
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// JCB
|
|
99
|
+
re = new RegExp('^35(2[89]|[3-8][0-9])')
|
|
100
|
+
if (number.match(re) != null) {
|
|
101
|
+
return 'JCB'
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Visa Electron
|
|
105
|
+
re = new RegExp('^(4026|417500|4508|4844|491(3|7))')
|
|
106
|
+
if (number.match(re) != null) {
|
|
107
|
+
return 'Visa Electron'
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return ''
|
|
111
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import Card from 'react-credit-cards-2'
|
|
3
|
+
import 'react-credit-cards-2/es/styles-compiled.css'
|
|
4
|
+
import {
|
|
5
|
+
formatCreditCardNumber,
|
|
6
|
+
formatCVC,
|
|
7
|
+
formatExpirationDate,
|
|
8
|
+
getCardType
|
|
9
|
+
} from './cardUtils'
|
|
10
|
+
import { useForm } from 'react-hook-form'
|
|
11
|
+
import { Input } from '../../styles/Inputs'
|
|
12
|
+
import { useLanguage } from 'ordering-components-external'
|
|
13
|
+
import Button from '../../styles/Buttons'
|
|
14
|
+
import { FormContainer, InputContainer } from './styles'
|
|
15
|
+
|
|
16
|
+
export const CardFormCustom = (props) => {
|
|
17
|
+
const {
|
|
18
|
+
handleNewCard,
|
|
19
|
+
setAddCardOpen
|
|
20
|
+
} = props
|
|
21
|
+
|
|
22
|
+
const [, t] = useLanguage()
|
|
23
|
+
const [formState, setFormState] = useState({
|
|
24
|
+
cvc: '',
|
|
25
|
+
expiry: '',
|
|
26
|
+
focus: '',
|
|
27
|
+
name: '',
|
|
28
|
+
number: ''
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const formMethods = useForm()
|
|
32
|
+
|
|
33
|
+
const handleInputFocus = (e) => {
|
|
34
|
+
setFormState({
|
|
35
|
+
...formState,
|
|
36
|
+
focus: e.target.name
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const handleInputChange = ({ target }) => {
|
|
41
|
+
if (target.name === 'number') {
|
|
42
|
+
target.value = formatCreditCardNumber(target.value)
|
|
43
|
+
} else if (target.name === 'expiry') {
|
|
44
|
+
target.value = formatExpirationDate(target.value)
|
|
45
|
+
} else if (target.name === 'cvc') {
|
|
46
|
+
target.value = formatCVC(target.value)
|
|
47
|
+
}
|
|
48
|
+
setFormState({
|
|
49
|
+
...formState,
|
|
50
|
+
[target.name]: target.value
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const onSubmit = (values) => {
|
|
55
|
+
const cardBrand = getCardType(values?.number)
|
|
56
|
+
const lastFourDigits = values?.number.substr(-4)
|
|
57
|
+
const card = {
|
|
58
|
+
type: 'card',
|
|
59
|
+
brand: cardBrand,
|
|
60
|
+
last4: lastFourDigits,
|
|
61
|
+
ccnumber: values?.number?.replace(/\s/g, ''),
|
|
62
|
+
ccexp: values?.expiry?.replace('/', ''),
|
|
63
|
+
cvv: values?.cvc
|
|
64
|
+
}
|
|
65
|
+
handleNewCard(card)
|
|
66
|
+
setAddCardOpen(false)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<FormContainer id='PaymentForm'>
|
|
71
|
+
<Card
|
|
72
|
+
cvc={formState.cvc}
|
|
73
|
+
expiry={formState.expiry}
|
|
74
|
+
focused={formState.focus}
|
|
75
|
+
name={formState.name}
|
|
76
|
+
number={formState.number}
|
|
77
|
+
placeholders={{
|
|
78
|
+
name: t('YOUR_NAME_HERE', 'Your name here')
|
|
79
|
+
}}
|
|
80
|
+
/>
|
|
81
|
+
<form
|
|
82
|
+
onSubmit={formMethods.handleSubmit(onSubmit)}
|
|
83
|
+
>
|
|
84
|
+
<InputContainer>
|
|
85
|
+
<Input
|
|
86
|
+
type='tel'
|
|
87
|
+
name='number'
|
|
88
|
+
placeholder={t('CARD_NUMBER', 'Card number')}
|
|
89
|
+
inputMode='numeric'
|
|
90
|
+
onChange={handleInputChange}
|
|
91
|
+
onFocus={handleInputFocus}
|
|
92
|
+
pattern='[\d| ]{16,22}'
|
|
93
|
+
format={formatCreditCardNumber}
|
|
94
|
+
maxLength={19}
|
|
95
|
+
ref={
|
|
96
|
+
formMethods.register({
|
|
97
|
+
required: t('CARD_NUMBER_REQUIRED', 'Card number is required'),
|
|
98
|
+
pattern: /^[\d| ]{16,22}$/i
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
isError={formMethods.errors.number}
|
|
102
|
+
/>
|
|
103
|
+
</InputContainer>
|
|
104
|
+
<InputContainer>
|
|
105
|
+
<Input
|
|
106
|
+
type='text'
|
|
107
|
+
name='name'
|
|
108
|
+
placeholder={t('NAME', 'Name')}
|
|
109
|
+
onChange={handleInputChange}
|
|
110
|
+
onFocus={handleInputFocus}
|
|
111
|
+
ref={
|
|
112
|
+
formMethods.register({
|
|
113
|
+
required: t('NAME_REQUIRED', 'Name is required'),
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
isError={formMethods.errors.name}
|
|
117
|
+
/>
|
|
118
|
+
</InputContainer>
|
|
119
|
+
<InputContainer>
|
|
120
|
+
<Input
|
|
121
|
+
type='text'
|
|
122
|
+
name='expiry'
|
|
123
|
+
pattern='\d\d/\d\d'
|
|
124
|
+
placeholder={t('EXPIRY', 'Expiry')}
|
|
125
|
+
onChange={handleInputChange}
|
|
126
|
+
onFocus={handleInputFocus}
|
|
127
|
+
format={formatExpirationDate}
|
|
128
|
+
ref={
|
|
129
|
+
formMethods.register({
|
|
130
|
+
required: t('EXPIRY_DATE_REQUIRED', 'Expiry date required')
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
isError={formMethods.errors.expiry}
|
|
134
|
+
/>
|
|
135
|
+
<Input
|
|
136
|
+
type='text'
|
|
137
|
+
name='cvc'
|
|
138
|
+
placeholder={t('CVC', 'CVC')}
|
|
139
|
+
pattern='\d{3,4}'
|
|
140
|
+
onChange={handleInputChange}
|
|
141
|
+
onFocus={handleInputFocus}
|
|
142
|
+
format={formatCVC}
|
|
143
|
+
ref={
|
|
144
|
+
formMethods.register({
|
|
145
|
+
required: t('CVC_REQUIRED', 'CVC is required')
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
isError={formMethods.errors.cvc}
|
|
149
|
+
/>
|
|
150
|
+
</InputContainer>
|
|
151
|
+
<Button
|
|
152
|
+
type='submit'
|
|
153
|
+
color='primary'
|
|
154
|
+
disabled={Object.keys(formMethods.errors)?.length > 0}
|
|
155
|
+
>
|
|
156
|
+
{t('SAVE', 'Save')}
|
|
157
|
+
</Button>
|
|
158
|
+
</form>
|
|
159
|
+
</FormContainer>
|
|
160
|
+
)
|
|
161
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components'
|
|
2
|
+
|
|
3
|
+
export const InputContainer = styled.div`
|
|
4
|
+
width: 100%;
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: space-between;
|
|
7
|
+
|
|
8
|
+
input{
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
width: 100%;
|
|
11
|
+
margin: 10px;
|
|
12
|
+
}
|
|
13
|
+
`
|
|
14
|
+
|
|
15
|
+
export const FormContainer = styled.div`
|
|
16
|
+
button{
|
|
17
|
+
width: 100%;
|
|
18
|
+
margin: 10px;
|
|
19
|
+
}
|
|
20
|
+
`
|
|
@@ -421,7 +421,7 @@ const CartUI = (props) => {
|
|
|
421
421
|
</tr>
|
|
422
422
|
))
|
|
423
423
|
}
|
|
424
|
-
{orderState?.options?.type === 1 &&
|
|
424
|
+
{orderState?.options?.type === 1 && !hideDeliveryFee && (
|
|
425
425
|
<tr>
|
|
426
426
|
<td>{t('DELIVERY_FEE', 'Delivery Fee')}</td>
|
|
427
427
|
<td>{parsePrice(cart?.delivery_price_with_discount)}</td>
|
|
@@ -21,7 +21,6 @@ import { UpsellingPage } from '../UpsellingPage'
|
|
|
21
21
|
import parsePhoneNumber from 'libphonenumber-js'
|
|
22
22
|
import { useHistory } from 'react-router-dom'
|
|
23
23
|
import { ArrowLeft } from 'react-bootstrap-icons'
|
|
24
|
-
|
|
25
24
|
import {
|
|
26
25
|
Container,
|
|
27
26
|
WrapperLeftContainer,
|
|
@@ -129,7 +128,7 @@ const CheckoutUI = (props) => {
|
|
|
129
128
|
const [openModal, setOpenModal] = useState({ login: false, signup: false })
|
|
130
129
|
const [allowedGuest, setAllowedGuest] = useState(false)
|
|
131
130
|
const [cardList, setCardList] = useState([])
|
|
132
|
-
|
|
131
|
+
const cardsMethods = ['stripe', 'credomatic']
|
|
133
132
|
const businessConfigs = businessDetails?.business?.configs ?? []
|
|
134
133
|
const isTableNumberEnabled = configs?.table_numer_enabled?.value
|
|
135
134
|
const isWalletCashEnabled = businessConfigs.find(config => config.key === 'wallet_cash_enabled')?.value === '1'
|
|
@@ -147,7 +146,7 @@ const CheckoutUI = (props) => {
|
|
|
147
146
|
|
|
148
147
|
const isDisablePlaceOrderButton = !cart?.valid ||
|
|
149
148
|
(!paymethodSelected && cart?.balance > 0) ||
|
|
150
|
-
(paymethodSelected?.gateway
|
|
149
|
+
(cardsMethods.includes(paymethodSelected?.gateway) && cardList?.cards?.length === 0) ||
|
|
151
150
|
placing ||
|
|
152
151
|
errorCash ||
|
|
153
152
|
loading ||
|
|
@@ -246,7 +245,7 @@ const CheckoutUI = (props) => {
|
|
|
246
245
|
if (userSelected && userSelected?.cellphone) {
|
|
247
246
|
if (userSelected?.country_phone_code) {
|
|
248
247
|
let phone = null
|
|
249
|
-
phone = `+${userSelected?.country_phone_code}${userSelected?.cellphone}`
|
|
248
|
+
phone = `+${userSelected?.country_phone_code}${userSelected?.cellphone.replace(`+${userSelected?.country_phone_code}`, '')}`
|
|
250
249
|
const phoneNumber = parsePhoneNumber(phone)
|
|
251
250
|
if (!phoneNumber?.isValid()) {
|
|
252
251
|
errors.push(t('VALIDATION_ERROR_MOBILE_PHONE_INVALID', 'The field Phone number is invalid.'))
|
|
@@ -526,24 +525,24 @@ const CheckoutUI = (props) => {
|
|
|
526
525
|
|
|
527
526
|
{
|
|
528
527
|
!!(!isMultiDriverTips && driverTipsField) &&
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
528
|
+
<>
|
|
529
|
+
<DriverTipContainer>
|
|
530
|
+
<h1>{t('DRIVER_TIPS', 'Driver Tips')}</h1>
|
|
531
|
+
<p>{t('100%_OF_THE_TIP_YOUR_DRIVER', '100% of the tip goes to your driver')}</p>
|
|
532
|
+
<DriverTips
|
|
533
|
+
businessId={cart?.business_id}
|
|
534
|
+
driverTipsOptions={driverTipsOptions}
|
|
535
|
+
isFixedPrice={parseInt(configs?.driver_tip_type?.value, 10) === 1}
|
|
536
|
+
isDriverTipUseCustom={!!parseInt(configs?.driver_tip_use_custom?.value, 10)}
|
|
537
|
+
driverTip={parseInt(configs?.driver_tip_type?.value, 10) === 1
|
|
538
|
+
? cart?.driver_tip
|
|
539
|
+
: cart?.driver_tip_rate}
|
|
540
|
+
cart={cart}
|
|
541
|
+
useOrderContext
|
|
542
|
+
/>
|
|
543
|
+
</DriverTipContainer>
|
|
544
|
+
<DriverTipDivider />
|
|
545
|
+
</>
|
|
547
546
|
}
|
|
548
547
|
{!cartState.loading && placeSpotsEnabled && cart?.business_id && (
|
|
549
548
|
<SelectSpotContainer>
|
|
@@ -576,7 +575,7 @@ const CheckoutUI = (props) => {
|
|
|
576
575
|
businessConfigs={businessConfigs}
|
|
577
576
|
loyaltyRewardRate={
|
|
578
577
|
creditPointPlanOnBusiness?.accumulation_rate ??
|
|
579
|
-
|
|
578
|
+
(!!creditPointPlanOnBusiness && creditPointPlan?.accumulation_rate) ?? 0
|
|
580
579
|
}
|
|
581
580
|
/>
|
|
582
581
|
</CartContainer>
|
|
@@ -756,7 +755,8 @@ export const Checkout = (props) => {
|
|
|
756
755
|
handleOrderRedirect,
|
|
757
756
|
handleCheckoutRedirect,
|
|
758
757
|
handleSearchRedirect,
|
|
759
|
-
handleCheckoutListRedirect
|
|
758
|
+
handleCheckoutListRedirect,
|
|
759
|
+
businessSlug
|
|
760
760
|
} = props
|
|
761
761
|
|
|
762
762
|
const [orderState, { confirmCart }] = useOrder()
|
|
@@ -773,7 +773,9 @@ export const Checkout = (props) => {
|
|
|
773
773
|
const [isResetPaymethod, setIsResetPaymethod] = useState(false)
|
|
774
774
|
|
|
775
775
|
const cartsWithProducts = orderState?.carts && (Object.values(orderState?.carts)?.filter(cart => cart?.products && cart?.products?.length) || null)
|
|
776
|
-
|
|
776
|
+
const carts = businessSlug
|
|
777
|
+
? cartsWithProducts.filter((cart) => cart?.business?.slug === businessSlug || businessSlug === cart?.business_id)
|
|
778
|
+
: cartsWithProducts
|
|
777
779
|
const closeAlert = () => {
|
|
778
780
|
setAlertState({
|
|
779
781
|
open: false,
|
|
@@ -813,7 +815,7 @@ export const Checkout = (props) => {
|
|
|
813
815
|
const getOrder = async (cartId) => {
|
|
814
816
|
try {
|
|
815
817
|
let result = {}
|
|
816
|
-
const cart =
|
|
818
|
+
const cart = carts.find(cart => cart.uuid === cartId)
|
|
817
819
|
const userCustomer = JSON.parse(window.localStorage.getItem('user-customer'))
|
|
818
820
|
if (cart && !userCustomer) {
|
|
819
821
|
result = { ...cart }
|
|
@@ -838,8 +840,18 @@ export const Checkout = (props) => {
|
|
|
838
840
|
handleOrderRedirect(result.order.uuid)
|
|
839
841
|
setCartState({ ...cartState, loading: false })
|
|
840
842
|
} else if (result.status === 2) {
|
|
843
|
+
let credomaticData = null
|
|
844
|
+
if (result?.paymethod_data?.gateway === 'credomatic') {
|
|
845
|
+
const urlParams = new URLSearchParams(window.location.search)
|
|
846
|
+
const paramsObj = Object.fromEntries(urlParams.entries())
|
|
847
|
+
credomaticData = {
|
|
848
|
+
credomatic: {
|
|
849
|
+
...paramsObj
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
841
853
|
try {
|
|
842
|
-
const confirmCartRes = await confirmCart(cartUuid)
|
|
854
|
+
const confirmCartRes = await confirmCart(cartUuid, credomaticData)
|
|
843
855
|
if (confirmCartRes.error) {
|
|
844
856
|
setAlertState({
|
|
845
857
|
open: true,
|
|
@@ -911,17 +923,17 @@ export const Checkout = (props) => {
|
|
|
911
923
|
|
|
912
924
|
return (
|
|
913
925
|
<>
|
|
914
|
-
{!cartUuid && orderState.carts &&
|
|
926
|
+
{!cartUuid && orderState.carts && carts && carts?.length === 0 && (
|
|
915
927
|
<NotFoundSource
|
|
916
928
|
content={t('NOT_FOUND_CARTS', 'Sorry, You don\'t seem to have any carts.')}
|
|
917
929
|
btnTitle={t('SEARCH_REDIRECT', 'Go to Businesses')}
|
|
918
930
|
onClickButton={handleSearchRedirect}
|
|
919
931
|
/>
|
|
920
932
|
)}
|
|
921
|
-
{!cartUuid && orderState.carts &&
|
|
933
|
+
{!cartUuid && orderState.carts && carts && carts?.length > 0 && (
|
|
922
934
|
<CartsList>
|
|
923
935
|
<CartContent
|
|
924
|
-
carts={
|
|
936
|
+
carts={carts}
|
|
925
937
|
isOrderStateCarts={!!orderState.carts}
|
|
926
938
|
isForceOpenCart
|
|
927
939
|
/>
|
|
@@ -59,7 +59,9 @@ export const Header = (props) => {
|
|
|
59
59
|
isHideSignup,
|
|
60
60
|
isCustomerMode,
|
|
61
61
|
searchValue,
|
|
62
|
-
setSearchValue
|
|
62
|
+
setSearchValue,
|
|
63
|
+
businessSlug,
|
|
64
|
+
notificationState
|
|
63
65
|
} = props
|
|
64
66
|
|
|
65
67
|
const { pathname } = useLocation()
|
|
@@ -90,6 +92,9 @@ export const Header = (props) => {
|
|
|
90
92
|
const isMulticheckoutPage = window.location.pathname?.includes('/multi-checkout')
|
|
91
93
|
|
|
92
94
|
const cartsWithProducts = (orderState?.carts && Object.values(orderState?.carts).filter(cart => cart.products && cart.products?.length > 0)) || null
|
|
95
|
+
const carts = businessSlug
|
|
96
|
+
? cartsWithProducts.filter((cart) => cart?.business?.slug === businessSlug || businessSlug === cart?.business_id)
|
|
97
|
+
: cartsWithProducts
|
|
93
98
|
|
|
94
99
|
const windowSize = useWindowSize()
|
|
95
100
|
const onlineStatus = useOnlineStatus()
|
|
@@ -367,7 +372,7 @@ export const Header = (props) => {
|
|
|
367
372
|
{!isMulticheckoutPage ? (
|
|
368
373
|
<CartPopover
|
|
369
374
|
open={openPopover.cart}
|
|
370
|
-
carts={
|
|
375
|
+
carts={carts}
|
|
371
376
|
onClick={() => handleTogglePopover('cart')}
|
|
372
377
|
onClose={() => handleClosePopover('cart')}
|
|
373
378
|
auth={auth}
|
|
@@ -380,7 +385,7 @@ export const Header = (props) => {
|
|
|
380
385
|
) : (
|
|
381
386
|
<HeaderOption
|
|
382
387
|
variant='cart'
|
|
383
|
-
totalCarts={
|
|
388
|
+
totalCarts={carts?.length}
|
|
384
389
|
onClick={(variant) => openModal(variant)}
|
|
385
390
|
/>
|
|
386
391
|
)
|
|
@@ -469,7 +474,7 @@ export const Header = (props) => {
|
|
|
469
474
|
>
|
|
470
475
|
{modalSelected === 'cart' && (
|
|
471
476
|
<CartContent
|
|
472
|
-
carts={
|
|
477
|
+
carts={carts}
|
|
473
478
|
isOrderStateCarts={!!orderState.carts}
|
|
474
479
|
onClose={() => setModalIsOpen(false)}
|
|
475
480
|
/>
|