@ecomplus/storefront-components 1.0.0-beta.19 → 1.0.0-beta.191
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/.version +0 -0
- package/CHANGELOG.md +1333 -135
- package/all.js +3 -1
- package/dist/1.storefront-components.min.js +2 -0
- package/dist/1.storefront-components.min.js.map +1 -0
- package/dist/2.storefront-components.min.js +5 -0
- package/dist/2.storefront-components.min.js.map +1 -0
- package/dist/3.storefront-components.min.js +5 -0
- package/dist/3.storefront-components.min.js.map +1 -0
- package/dist/storefront-components.min.js +33 -12
- package/dist/storefront-components.min.js.map +1 -1
- package/package.json +17 -12
- package/src/APagination.vue +2 -0
- package/src/AShare.vue +2 -0
- package/src/AccountAddresses.vue +3 -0
- package/src/AccountForm.vue +3 -0
- package/src/AccountPoints.vue +3 -0
- package/src/BuyTogether.vue +3 -0
- package/src/EarnPointsProgress.vue +3 -0
- package/src/ItemCustomizations.vue +2 -0
- package/src/KitProductVariations.vue +3 -0
- package/src/PointsApplier.vue +2 -0
- package/src/ProductQuickview.vue +3 -0
- package/src/QuantitySelector.vue +3 -0
- package/src/RecommendedItems.vue +3 -0
- package/src/ShippingLine.vue +1 -0
- package/src/TheCart.vue +3 -0
- package/src/html/APagination.html +90 -0
- package/src/html/APrices.html +24 -4
- package/src/html/AShare.html +31 -0
- package/src/html/AccountAddresses.html +90 -0
- package/src/html/AccountForm.html +269 -0
- package/src/html/AccountPoints.html +39 -0
- package/src/html/AddressForm.html +9 -7
- package/src/html/BuyTogether.html +60 -0
- package/src/html/CartItem.html +86 -38
- package/src/html/CartQuickview.html +28 -5
- package/src/html/DiscountApplier.html +3 -3
- package/src/html/EarnPointsProgress.html +28 -0
- package/src/html/InputDate.html +1 -1
- package/src/html/InputDocNumber.html +1 -0
- package/src/html/InputPhone.html +1 -1
- package/src/html/InstantSearch.html +3 -3
- package/src/html/ItemCustomizations.html +14 -0
- package/src/html/KitProductVariations.html +92 -0
- package/src/html/LoginBlock.html +34 -32
- package/src/html/LoginModal.html +9 -4
- package/src/html/PaymentOption.html +7 -5
- package/src/html/PointsApplier.html +26 -0
- package/src/html/ProductCard.html +68 -8
- package/src/html/ProductGallery.html +21 -3
- package/src/html/ProductQuickview.html +64 -0
- package/src/html/ProductVariations.html +30 -3
- package/src/html/QuantitySelector.html +85 -0
- package/src/html/RecommendedItems.html +48 -0
- package/src/html/SearchEngine.html +101 -24
- package/src/html/ShippingCalculator.html +84 -3
- package/src/html/ShippingLine.html +5 -2
- package/src/html/TheAccount.html +43 -9
- package/src/html/TheCart.html +156 -0
- package/src/html/TheProduct.html +416 -138
- package/src/js/APagination.js +74 -0
- package/src/js/APicture.js +27 -7
- package/src/js/APrices.js +80 -41
- package/src/js/AShare.js +83 -0
- package/src/js/AccountAddresses.js +201 -0
- package/src/js/AccountForm.js +312 -0
- package/src/js/AccountPoints.js +63 -0
- package/src/js/AddressForm.js +80 -35
- package/src/js/BuyTogether.js +246 -0
- package/src/js/CartItem.js +67 -14
- package/src/js/CartQuickview.js +20 -1
- package/src/js/DiscountApplier.js +181 -50
- package/src/js/EarnPointsProgress.js +77 -0
- package/src/js/InputDate.js +8 -8
- package/src/js/InputDocNumber.js +20 -0
- package/src/js/ItemCustomizations.js +10 -0
- package/src/js/KitProductVariations.js +218 -0
- package/src/js/LoginBlock.js +47 -6
- package/src/js/LoginModal.js +18 -10
- package/src/js/PaymentOption.js +28 -1
- package/src/js/PointsApplier.js +110 -0
- package/src/js/ProductCard.js +115 -11
- package/src/js/ProductGallery.js +32 -12
- package/src/js/ProductQuickview.js +72 -0
- package/src/js/ProductVariations.js +76 -19
- package/src/js/QuantitySelector.js +175 -0
- package/src/js/RecommendedItems.js +178 -0
- package/src/js/SearchEngine.js +185 -55
- package/src/js/ShippingCalculator.js +176 -35
- package/src/js/ShippingLine.js +44 -5
- package/src/js/TheAccount.js +97 -6
- package/src/js/TheCart.js +146 -0
- package/src/js/TheProduct.js +387 -43
- package/src/js/helpers/add-idle-callback.js +7 -0
- package/src/js/helpers/check-form-validity.js +3 -0
- package/src/js/helpers/favorite-products.js +24 -0
- package/src/js/helpers/scroll-to-element.js +10 -0
- package/src/js/helpers/sort-apps.js +14 -0
- package/src/js/helpers/wait-storefront-info.js +21 -0
- package/src/scss/APicture.scss +2 -0
- package/src/scss/APrices.scss +13 -1
- package/src/scss/AccountAddresses.scss +27 -0
- package/src/scss/AccountForm.scss +5 -0
- package/src/scss/AccountPoints.scss +17 -0
- package/src/scss/BuyTogether.scss +38 -0
- package/src/scss/CartItem.scss +17 -1
- package/src/scss/EarnPointsProgress.scss +6 -0
- package/src/scss/InstantSearch.scss +1 -0
- package/src/scss/KitProductVariations.scss +72 -0
- package/src/scss/LoginBlock.scss +5 -0
- package/src/scss/PaymentOption.scss +10 -1
- package/src/scss/ProductCard.scss +63 -25
- package/src/scss/ProductGallery.scss +4 -2
- package/src/scss/ProductQuickview.scss +36 -0
- package/src/scss/ProductVariations.scss +20 -4
- package/src/scss/QuantitySelector.scss +39 -0
- package/src/scss/RecommendedItems.scss +28 -0
- package/src/scss/SearchEngine.scss +9 -5
- package/src/scss/ShippingCalculator.scss +42 -1
- package/src/scss/ShippingLine.scss +24 -0
- package/src/scss/TheAccount.scss +4 -0
- package/src/scss/TheCart.scss +54 -0
- package/src/scss/TheProduct.scss +146 -1
- package/webpack.config.js +20 -6
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
i19add$1ToEarn,
|
|
2
3
|
i19calculateShipping,
|
|
4
|
+
i19freeShipping,
|
|
3
5
|
i19zipCode
|
|
4
6
|
} from '@ecomplus/i18n'
|
|
5
7
|
|
|
@@ -11,11 +13,13 @@ import {
|
|
|
11
13
|
} from '@ecomplus/utils'
|
|
12
14
|
|
|
13
15
|
import { modules } from '@ecomplus/client'
|
|
16
|
+
import sortApps from './helpers/sort-apps'
|
|
14
17
|
import CleaveInput from 'vue-cleave-component'
|
|
15
18
|
import ShippingLine from '../ShippingLine.vue'
|
|
16
19
|
|
|
17
20
|
const localStorage = typeof window === 'object' && window.localStorage
|
|
18
21
|
const zipStorageKey = 'shipping-to-zip'
|
|
22
|
+
const globalOpts = (typeof window === 'object' && window.propsShippingCalculator) || {}
|
|
19
23
|
|
|
20
24
|
const reduceItemBody = itemOrProduct => {
|
|
21
25
|
const shippedItem = {}
|
|
@@ -25,6 +29,7 @@ const reduceItemBody = itemOrProduct => {
|
|
|
25
29
|
'sku',
|
|
26
30
|
'name',
|
|
27
31
|
'quantity',
|
|
32
|
+
'inventory',
|
|
28
33
|
'currency_id',
|
|
29
34
|
'currency_symbol',
|
|
30
35
|
'price',
|
|
@@ -50,9 +55,17 @@ export default {
|
|
|
50
55
|
props: {
|
|
51
56
|
zipCode: String,
|
|
52
57
|
canSelectServices: Boolean,
|
|
58
|
+
canAutoSelectService: {
|
|
59
|
+
type: Boolean,
|
|
60
|
+
default: typeof globalOpts.canAutoSelectService === 'boolean'
|
|
61
|
+
? globalOpts.canAutoSelectService
|
|
62
|
+
: true
|
|
63
|
+
},
|
|
53
64
|
canInputZip: {
|
|
54
65
|
type: Boolean,
|
|
55
|
-
default:
|
|
66
|
+
default: typeof globalOpts.canInputZip === 'boolean'
|
|
67
|
+
? globalOpts.canInputZip
|
|
68
|
+
: true
|
|
56
69
|
},
|
|
57
70
|
countryCode: {
|
|
58
71
|
type: String,
|
|
@@ -75,26 +88,66 @@ export default {
|
|
|
75
88
|
default () {
|
|
76
89
|
return {}
|
|
77
90
|
}
|
|
91
|
+
},
|
|
92
|
+
skipAppIds: Array,
|
|
93
|
+
shippingAppsSort: {
|
|
94
|
+
type: Array,
|
|
95
|
+
default () {
|
|
96
|
+
return window.ecomShippingApps || []
|
|
97
|
+
}
|
|
78
98
|
}
|
|
79
99
|
},
|
|
80
100
|
|
|
81
101
|
data () {
|
|
82
102
|
return {
|
|
83
103
|
localZipCode: null,
|
|
104
|
+
localShippedItems: [],
|
|
105
|
+
amountSubtotal: null,
|
|
84
106
|
shippingServices: [],
|
|
85
107
|
selectedService: null,
|
|
86
|
-
|
|
108
|
+
hasPaidOption: false,
|
|
109
|
+
freeFromValue: null,
|
|
110
|
+
isScheduled: false,
|
|
111
|
+
retryTimer: null,
|
|
112
|
+
isWaiting: false,
|
|
113
|
+
hasCalculated: false
|
|
87
114
|
}
|
|
88
115
|
},
|
|
89
116
|
|
|
90
117
|
computed: {
|
|
118
|
+
i19add$1ToEarn: () => i18n(i19add$1ToEarn),
|
|
91
119
|
i19calculateShipping: () => i18n(i19calculateShipping),
|
|
92
120
|
i19zipCode: () => i18n(i19zipCode),
|
|
121
|
+
i19freeShipping: () => i18n(i19freeShipping).toLowerCase(),
|
|
122
|
+
i19selectShippingMsg: () => i18n({
|
|
123
|
+
pt_br: 'Selecione uma forma de envio abaixo',
|
|
124
|
+
en_us: 'Select a shipping method below'
|
|
125
|
+
}),
|
|
93
126
|
|
|
94
127
|
cleaveOptions () {
|
|
95
128
|
return this.countryCode === 'BR'
|
|
96
129
|
? { blocks: [5, 3], delimiter: '-' }
|
|
97
130
|
: { blocks: [30] }
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
freeFromPercentage () {
|
|
134
|
+
return this.hasPaidOption && this.amountSubtotal < this.freeFromValue
|
|
135
|
+
? Math.round(this.amountSubtotal * 100 / this.freeFromValue)
|
|
136
|
+
: null
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
productionDeadline () {
|
|
140
|
+
let maxDeadline = 0
|
|
141
|
+
this.shippedItems.forEach(item => {
|
|
142
|
+
if (item.quantity && item.production_time) {
|
|
143
|
+
const { days, cumulative } = item.production_time
|
|
144
|
+
const itemDeadline = cumulative ? days * item.quantity : days
|
|
145
|
+
if (itemDeadline > maxDeadline) {
|
|
146
|
+
maxDeadline = itemDeadline
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
return maxDeadline
|
|
98
151
|
}
|
|
99
152
|
},
|
|
100
153
|
|
|
@@ -105,56 +158,119 @@ export default {
|
|
|
105
158
|
this.$emit('update:zip-code', this.localZipCode)
|
|
106
159
|
},
|
|
107
160
|
|
|
108
|
-
parseShippingOptions (shippingResult = [], isRetry) {
|
|
161
|
+
parseShippingOptions (shippingResult = [], isRetry = false) {
|
|
162
|
+
this.freeFromValue = null
|
|
109
163
|
this.shippingServices = []
|
|
110
|
-
let canRetry
|
|
111
164
|
if (shippingResult.length) {
|
|
112
165
|
shippingResult.forEach(appResult => {
|
|
113
166
|
const { validated, error, response } = appResult
|
|
114
|
-
if (validated
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
167
|
+
if (!validated || error) {
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
if (
|
|
171
|
+
this.skipAppIds &&
|
|
172
|
+
this.skipAppIds.includes(appResult.app_id) &&
|
|
173
|
+
shippingResult.filter(({ app_id: appId }) => !this.skipAppIds.includes(appId)).length
|
|
174
|
+
) {
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
response.shipping_services.forEach(service => {
|
|
178
|
+
this.shippingServices.push({
|
|
179
|
+
app_id: appResult.app_id,
|
|
180
|
+
...service
|
|
120
181
|
})
|
|
121
|
-
}
|
|
122
|
-
|
|
182
|
+
})
|
|
183
|
+
const freeShippingFromValue = response.free_shipping_from_value
|
|
184
|
+
if (
|
|
185
|
+
freeShippingFromValue &&
|
|
186
|
+
(!this.freeFromValue || this.freeFromValue > freeShippingFromValue)
|
|
187
|
+
) {
|
|
188
|
+
this.freeFromValue = freeShippingFromValue
|
|
123
189
|
}
|
|
124
190
|
})
|
|
125
191
|
if (!this.shippingServices.length) {
|
|
126
|
-
if (
|
|
192
|
+
if (!isRetry) {
|
|
127
193
|
this.fetchShippingServices(true)
|
|
194
|
+
} else {
|
|
195
|
+
this.scheduleRetry()
|
|
128
196
|
}
|
|
129
197
|
} else {
|
|
130
|
-
this.
|
|
198
|
+
this.shippingServices = this.shippingServices.sort((a, b) => {
|
|
199
|
+
const priceDiff = a.shipping_line.total_price - b.shipping_line.total_price
|
|
200
|
+
return priceDiff < 0
|
|
201
|
+
? -1
|
|
202
|
+
: priceDiff > 0
|
|
203
|
+
? 1
|
|
204
|
+
: a.shipping_line.delivery_time && b.shipping_line.delivery_time &&
|
|
205
|
+
a.shipping_line.delivery_time.days < b.shipping_line.delivery_time.days
|
|
206
|
+
? -1
|
|
207
|
+
: 1
|
|
208
|
+
})
|
|
209
|
+
if (this.canAutoSelectService) {
|
|
210
|
+
this.setSelectedService(0)
|
|
211
|
+
} else {
|
|
212
|
+
this.selectedService = null
|
|
213
|
+
}
|
|
214
|
+
this.hasPaidOption = Boolean(this.shippingServices.find(service => {
|
|
215
|
+
return service.shipping_line.total_price || service.shipping_line.price
|
|
216
|
+
}))
|
|
217
|
+
if (Array.isArray(this.shippingAppsSort) && this.shippingAppsSort.length) {
|
|
218
|
+
this.shippingServices = sortApps(this.shippingServices, this.shippingAppsSort)
|
|
219
|
+
}
|
|
131
220
|
}
|
|
132
221
|
}
|
|
133
222
|
},
|
|
134
223
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
...this.shippingData,
|
|
141
|
-
to: {
|
|
142
|
-
zip: this.localZipCode,
|
|
143
|
-
...this.shippingData.to
|
|
224
|
+
scheduleRetry (timeout = 10000) {
|
|
225
|
+
clearTimeout(this.retryTimer)
|
|
226
|
+
this.retryTimer = setTimeout(() => {
|
|
227
|
+
if (this.localZipCode && !this.shippingServices.length && this.shippedItems.length) {
|
|
228
|
+
this.fetchShippingServices(true)
|
|
144
229
|
}
|
|
230
|
+
}, timeout)
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
fetchShippingServices (isRetry) {
|
|
234
|
+
if (!this.isScheduled) {
|
|
235
|
+
this.isScheduled = true
|
|
236
|
+
setTimeout(() => {
|
|
237
|
+
this.isScheduled = false
|
|
238
|
+
const { storeId } = this
|
|
239
|
+
let url = '/calculate_shipping.json'
|
|
240
|
+
if (this.skipAppIds && this.skipAppIds.length) {
|
|
241
|
+
url += '?skip_ids='
|
|
242
|
+
this.skipAppIds.forEach((appId, i) => {
|
|
243
|
+
if (i > 0) url += ','
|
|
244
|
+
url += `${appId}`
|
|
245
|
+
})
|
|
246
|
+
}
|
|
247
|
+
const method = 'POST'
|
|
248
|
+
const data = {
|
|
249
|
+
...this.shippingData,
|
|
250
|
+
to: {
|
|
251
|
+
zip: this.localZipCode,
|
|
252
|
+
...this.shippingData.to
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (this.localShippedItems.length) {
|
|
256
|
+
data.items = this.localShippedItems
|
|
257
|
+
data.subtotal = this.amountSubtotal
|
|
258
|
+
}
|
|
259
|
+
this.isWaiting = true
|
|
260
|
+
modules({ url, method, storeId, data })
|
|
261
|
+
.then(({ data }) => this.parseShippingOptions(data.result, isRetry))
|
|
262
|
+
.catch(err => {
|
|
263
|
+
if (!isRetry) {
|
|
264
|
+
this.scheduleRetry(4000)
|
|
265
|
+
}
|
|
266
|
+
console.error(err)
|
|
267
|
+
})
|
|
268
|
+
.finally(() => {
|
|
269
|
+
this.hasCalculated = true
|
|
270
|
+
this.isWaiting = false
|
|
271
|
+
})
|
|
272
|
+
}, this.hasCalculated ? 150 : 50)
|
|
145
273
|
}
|
|
146
|
-
if (this.shippedItems.length) {
|
|
147
|
-
data.items = this.shippedItems.map(reduceItemBody)
|
|
148
|
-
const itemsToSubtotal = (subtotal, item) => subtotal + getPrice(item) * item.quantity
|
|
149
|
-
data.subtotal = data.items.reduce(itemsToSubtotal, 0)
|
|
150
|
-
}
|
|
151
|
-
this.isWaiting = true
|
|
152
|
-
modules({ url, method, storeId, data })
|
|
153
|
-
.then(({ data }) => this.parseShippingOptions(data.result, isRetry))
|
|
154
|
-
.catch(console.error)
|
|
155
|
-
.finally(() => {
|
|
156
|
-
this.isWaiting = false
|
|
157
|
-
})
|
|
158
274
|
},
|
|
159
275
|
|
|
160
276
|
submitZipCode () {
|
|
@@ -174,6 +290,27 @@ export default {
|
|
|
174
290
|
},
|
|
175
291
|
|
|
176
292
|
watch: {
|
|
293
|
+
shippedItems: {
|
|
294
|
+
handler () {
|
|
295
|
+
setTimeout(() => {
|
|
296
|
+
this.localShippedItems = this.shippedItems.map(reduceItemBody)
|
|
297
|
+
const { amountSubtotal } = this
|
|
298
|
+
this.amountSubtotal = this.shippedItems.reduce((subtotal, item) => {
|
|
299
|
+
return subtotal + getPrice(item) * item.quantity
|
|
300
|
+
}, 0)
|
|
301
|
+
if (
|
|
302
|
+
this.hasCalculated &&
|
|
303
|
+
(this.canSelectServices || amountSubtotal !== this.amountSubtotal ||
|
|
304
|
+
(!this.shippingServices.length && !this.isWaiting))
|
|
305
|
+
) {
|
|
306
|
+
this.fetchShippingServices()
|
|
307
|
+
}
|
|
308
|
+
}, 50)
|
|
309
|
+
},
|
|
310
|
+
deep: true,
|
|
311
|
+
immediate: true
|
|
312
|
+
},
|
|
313
|
+
|
|
177
314
|
localZipCode (zipCode) {
|
|
178
315
|
if (this.countryCode === 'BR' && zipCode.replace(/\D/g, '').length === 8) {
|
|
179
316
|
this.submitZipCode()
|
|
@@ -189,6 +326,10 @@ export default {
|
|
|
189
326
|
immediate: true
|
|
190
327
|
},
|
|
191
328
|
|
|
329
|
+
skipAppIds () {
|
|
330
|
+
this.fetchShippingServices()
|
|
331
|
+
},
|
|
332
|
+
|
|
192
333
|
shippingResult: {
|
|
193
334
|
handler (result) {
|
|
194
335
|
if (result.length) {
|
package/src/js/ShippingLine.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
i19days,
|
|
3
|
+
i19free,
|
|
3
4
|
i19freeShipping,
|
|
5
|
+
i19pickUpToday,
|
|
6
|
+
i19receiveToday,
|
|
7
|
+
i19untilTomorrow,
|
|
4
8
|
i19upTo,
|
|
5
9
|
i19workingDays
|
|
6
10
|
} from '@ecomplus/i18n'
|
|
@@ -10,6 +14,8 @@ import {
|
|
|
10
14
|
formatMoney
|
|
11
15
|
} from '@ecomplus/utils'
|
|
12
16
|
|
|
17
|
+
const globalOpts = (typeof window === 'object' && window.propsShippingLine) || {}
|
|
18
|
+
|
|
13
19
|
export default {
|
|
14
20
|
name: 'ShippingLine',
|
|
15
21
|
|
|
@@ -17,10 +23,23 @@ export default {
|
|
|
17
23
|
shippingLine: {
|
|
18
24
|
type: Object,
|
|
19
25
|
required: true
|
|
26
|
+
},
|
|
27
|
+
productionDeadline: {
|
|
28
|
+
type: Number,
|
|
29
|
+
default: 0
|
|
30
|
+
},
|
|
31
|
+
getDeadlineStr: {
|
|
32
|
+
type: Function,
|
|
33
|
+
default: globalOpts.getDeadlineStr
|
|
20
34
|
}
|
|
21
35
|
},
|
|
22
36
|
|
|
23
37
|
computed: {
|
|
38
|
+
i19workingDay: () => i18n({
|
|
39
|
+
en_us: 'Working day',
|
|
40
|
+
pt_br: 'Dia útil'
|
|
41
|
+
}),
|
|
42
|
+
|
|
24
43
|
deadlineStr () {
|
|
25
44
|
const shipping = this.shippingLine
|
|
26
45
|
const isWorkingDays = (shipping.posting_deadline && shipping.posting_deadline.working_days) ||
|
|
@@ -29,17 +48,37 @@ export default {
|
|
|
29
48
|
if (shipping.delivery_time) {
|
|
30
49
|
days += shipping.delivery_time.days
|
|
31
50
|
}
|
|
32
|
-
|
|
51
|
+
days += this.productionDeadline
|
|
52
|
+
if (this.getDeadlineStr) {
|
|
53
|
+
const str = this.getDeadlineStr({
|
|
54
|
+
days,
|
|
55
|
+
isWorkingDays,
|
|
56
|
+
shippingLine: this.shippingLine
|
|
57
|
+
})
|
|
58
|
+
if (str) return str
|
|
59
|
+
}
|
|
60
|
+
if (days > 1) {
|
|
61
|
+
return `${i18n(i19upTo)} ${days} ` +
|
|
62
|
+
i18n(isWorkingDays ? i19workingDays : i19days).toLowerCase()
|
|
63
|
+
}
|
|
64
|
+
if (days === 1) {
|
|
65
|
+
if (isWorkingDays) {
|
|
66
|
+
return `${i18n(i19upTo)} 1 ` + i18n(this.i19workingDay).toLowerCase()
|
|
67
|
+
}
|
|
68
|
+
return i19untilTomorrow
|
|
69
|
+
}
|
|
70
|
+
return shipping.pick_up ? i19pickUpToday : i19receiveToday
|
|
33
71
|
},
|
|
34
72
|
|
|
35
73
|
freightValueStr () {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
74
|
+
const { shippingLine } = this
|
|
75
|
+
const freight = typeof shippingLine.total_price === 'number'
|
|
76
|
+
? shippingLine.total_price
|
|
77
|
+
: shippingLine.price
|
|
39
78
|
if (freight) {
|
|
40
79
|
return formatMoney(freight)
|
|
41
80
|
} else {
|
|
42
|
-
return i18n(i19freeShipping)
|
|
81
|
+
return i18n(shippingLine.pick_up ? i19free : i19freeShipping)
|
|
43
82
|
}
|
|
44
83
|
}
|
|
45
84
|
}
|
package/src/js/TheAccount.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
i19addresses,
|
|
3
|
+
i19favorites,
|
|
3
4
|
i19hello,
|
|
4
5
|
i19isNotYou,
|
|
5
6
|
i19logout,
|
|
7
|
+
i19noSavedFavoritesMsg,
|
|
6
8
|
i19orders,
|
|
7
|
-
i19registration
|
|
9
|
+
i19registration,
|
|
10
|
+
i19subscriptions
|
|
8
11
|
} from '@ecomplus/i18n'
|
|
9
12
|
|
|
10
13
|
import {
|
|
@@ -14,12 +17,14 @@ import {
|
|
|
14
17
|
|
|
15
18
|
import ecomPassport from '@ecomplus/passport-client'
|
|
16
19
|
import LoginBlock from '../LoginBlock.vue'
|
|
20
|
+
import RecommendedItems from '../RecommendedItems.vue'
|
|
17
21
|
|
|
18
22
|
export default {
|
|
19
23
|
name: 'TheAccount',
|
|
20
24
|
|
|
21
25
|
components: {
|
|
22
|
-
LoginBlock
|
|
26
|
+
LoginBlock,
|
|
27
|
+
RecommendedItems
|
|
23
28
|
},
|
|
24
29
|
|
|
25
30
|
props: {
|
|
@@ -29,7 +34,18 @@ export default {
|
|
|
29
34
|
return {}
|
|
30
35
|
}
|
|
31
36
|
},
|
|
32
|
-
|
|
37
|
+
currentTab: {
|
|
38
|
+
type: String,
|
|
39
|
+
validator: function (value) {
|
|
40
|
+
return ['orders', 'favorites', 'subscriptions', 'points', 'account'].includes(value)
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
isExternalAuth: {
|
|
44
|
+
type: Boolean,
|
|
45
|
+
default () {
|
|
46
|
+
return Boolean(window.$firebaseConfig && window.$firebaseConfig.authDomain)
|
|
47
|
+
}
|
|
48
|
+
},
|
|
33
49
|
ecomPassport: {
|
|
34
50
|
type: Object,
|
|
35
51
|
default () {
|
|
@@ -38,20 +54,30 @@ export default {
|
|
|
38
54
|
}
|
|
39
55
|
},
|
|
40
56
|
|
|
57
|
+
data () {
|
|
58
|
+
return {
|
|
59
|
+
favoriteIds: [],
|
|
60
|
+
navTabs: []
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
|
|
41
64
|
computed: {
|
|
42
65
|
i19addresses: () => i18n(i19addresses),
|
|
66
|
+
i19favorites: () => i18n(i19favorites),
|
|
43
67
|
i19hello: () => i18n(i19hello),
|
|
44
68
|
i19isNotYou: () => i18n(i19isNotYou),
|
|
45
69
|
i19logout: () => i18n(i19logout),
|
|
70
|
+
i19noSavedFavoritesMsg: () => i18n(i19noSavedFavoritesMsg),
|
|
46
71
|
i19orders: () => i18n(i19orders),
|
|
72
|
+
i19subscriptions: () => i18n(i19subscriptions),
|
|
47
73
|
i19registration: () => i18n(i19registration),
|
|
48
74
|
|
|
49
75
|
activeTab: {
|
|
50
76
|
get () {
|
|
51
|
-
return this.
|
|
77
|
+
return this.currentTab || 'account'
|
|
52
78
|
},
|
|
53
|
-
set (
|
|
54
|
-
this.$emit('update:
|
|
79
|
+
set (tab) {
|
|
80
|
+
this.$emit('update:current-tab', tab)
|
|
55
81
|
}
|
|
56
82
|
},
|
|
57
83
|
|
|
@@ -70,6 +96,27 @@ export default {
|
|
|
70
96
|
},
|
|
71
97
|
|
|
72
98
|
methods: {
|
|
99
|
+
hasTab (tabValue) {
|
|
100
|
+
return this.navTabs.some(tab => tab.value === tabValue)
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
insertSubscriptionTab () {
|
|
104
|
+
const hasSubscriptions = this.hasTab('subscriptions')
|
|
105
|
+
if (this.ecomPassport.checkAuthorization() && !hasSubscriptions) {
|
|
106
|
+
this.ecomPassport.requestApi('/orders.json?transactions.type=recurrence&limit=1&fields=_id')
|
|
107
|
+
.then(({ data }) => {
|
|
108
|
+
const { result } = data
|
|
109
|
+
if (result.length) {
|
|
110
|
+
this.navTabs.push({
|
|
111
|
+
label: this.i19subscriptions,
|
|
112
|
+
value: 'subscriptions'
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
.catch(console.error)
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
73
120
|
login (ecomPassport) {
|
|
74
121
|
if (ecomPassport.checkAuthorization()) {
|
|
75
122
|
this.localCustomer = ecomPassport.getCustomer()
|
|
@@ -83,5 +130,49 @@ export default {
|
|
|
83
130
|
this.$emit('logout')
|
|
84
131
|
}
|
|
85
132
|
}
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
watch: {
|
|
136
|
+
customer: {
|
|
137
|
+
handler (customer) {
|
|
138
|
+
const hasPoints = this.hasTab('points')
|
|
139
|
+
if (Array.isArray(customer.loyalty_points_entries) && customer.loyalty_points_entries.length && !hasPoints) {
|
|
140
|
+
this.navTabs.push({
|
|
141
|
+
label: 'Cashback',
|
|
142
|
+
value: 'points'
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
immediate: true,
|
|
147
|
+
deep: true
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
created () {
|
|
152
|
+
if (this.isExternalAuth && !this.ecomPassport.checkAuthorization()) {
|
|
153
|
+
window.location.href = '/app/account'
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
this.navTabs = [
|
|
157
|
+
{
|
|
158
|
+
label: this.i19registration,
|
|
159
|
+
value: 'account'
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
label: this.i19orders,
|
|
163
|
+
value: 'orders'
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
label: this.i19favorites,
|
|
167
|
+
value: 'favorites'
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
const { favorites } = this.ecomPassport.getCustomer()
|
|
171
|
+
this.favoriteIds = favorites || []
|
|
172
|
+
this.insertSubscriptionTab()
|
|
173
|
+
this.ecomPassport.on('login', this.insertSubscriptionTab)
|
|
174
|
+
this.$once('hook:beforeDestroy', () => {
|
|
175
|
+
this.ecomPassport.off('login', this.insertSubscriptionTab)
|
|
176
|
+
})
|
|
86
177
|
}
|
|
87
178
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import {
|
|
2
|
+
i19checkout,
|
|
3
|
+
i19continueShopping,
|
|
4
|
+
i19discount,
|
|
5
|
+
i19emptyCart
|
|
6
|
+
} from '@ecomplus/i18n'
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
i18n,
|
|
10
|
+
formatMoney
|
|
11
|
+
} from '@ecomplus/utils'
|
|
12
|
+
|
|
13
|
+
import ecomCart from '@ecomplus/shopping-cart'
|
|
14
|
+
import APrices from './../APrices.vue'
|
|
15
|
+
import CartItem from './../CartItem.vue'
|
|
16
|
+
import DiscountApplier from './../DiscountApplier.vue'
|
|
17
|
+
import ShippingCalculator from './../ShippingCalculator.vue'
|
|
18
|
+
import EarnPointsProgress from './../EarnPointsProgress.vue'
|
|
19
|
+
import RecommendedItems from './../RecommendedItems.vue'
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
name: 'TheCart',
|
|
23
|
+
|
|
24
|
+
components: {
|
|
25
|
+
APrices,
|
|
26
|
+
CartItem,
|
|
27
|
+
DiscountApplier,
|
|
28
|
+
ShippingCalculator,
|
|
29
|
+
EarnPointsProgress,
|
|
30
|
+
RecommendedItems
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
props: {
|
|
34
|
+
amount: {
|
|
35
|
+
type: Object,
|
|
36
|
+
default () {
|
|
37
|
+
return {}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
checkoutUrl: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: '/app/#/checkout'
|
|
43
|
+
},
|
|
44
|
+
zipCode: String,
|
|
45
|
+
discountCoupon: String,
|
|
46
|
+
modulesPayload: Object,
|
|
47
|
+
ecomCart: {
|
|
48
|
+
type: Object,
|
|
49
|
+
default () {
|
|
50
|
+
return ecomCart
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
data () {
|
|
56
|
+
return {
|
|
57
|
+
localZipCode: this.zipCode,
|
|
58
|
+
canApplyDiscount: false,
|
|
59
|
+
isCouponApplied: false
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
computed: {
|
|
64
|
+
i19checkout: () => i18n(i19checkout),
|
|
65
|
+
i19continueShopping: () => i18n(i19continueShopping),
|
|
66
|
+
i19discount: () => i18n(i19discount),
|
|
67
|
+
i19emptyCart: () => i18n(i19emptyCart),
|
|
68
|
+
|
|
69
|
+
cart () {
|
|
70
|
+
return this.ecomCart.data
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
isValidCart () {
|
|
74
|
+
return this.ecomCart.data.items.find(({ quantity }) => quantity)
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
localDiscountCoupon: {
|
|
78
|
+
get () {
|
|
79
|
+
return this.discountCoupon
|
|
80
|
+
},
|
|
81
|
+
set (couponCode) {
|
|
82
|
+
this.$emit('update:discount-coupon', couponCode)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
methods: {
|
|
88
|
+
formatMoney,
|
|
89
|
+
|
|
90
|
+
selectShippingService (service) {
|
|
91
|
+
this.$emit('select-shipping', service)
|
|
92
|
+
this.$nextTick(() => {
|
|
93
|
+
this.canApplyDiscount = true
|
|
94
|
+
})
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
setDiscountRule (discountRule) {
|
|
98
|
+
this.$emit('set-discount-rule', discountRule)
|
|
99
|
+
this.$nextTick(() => {
|
|
100
|
+
this.isCouponApplied = Boolean(this.discountCoupon && this.amount.discount)
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
watch: {
|
|
106
|
+
localZipCode (zipCode) {
|
|
107
|
+
this.$emit('update:zip-code', zipCode)
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
canApplyDiscount (canApplyDiscount) {
|
|
111
|
+
if (!canApplyDiscount) {
|
|
112
|
+
this.isCouponApplied = false
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
mounted () {
|
|
118
|
+
this.$nextTick(() => {
|
|
119
|
+
this.canApplyDiscount = !this.localZipCode
|
|
120
|
+
})
|
|
121
|
+
const { ecomCart } = this
|
|
122
|
+
const getNumItems = () => ecomCart.data.items.reduce((numItems, { flags, quantity }) => {
|
|
123
|
+
if (!flags || !flags.includes('freebie')) {
|
|
124
|
+
numItems += quantity
|
|
125
|
+
}
|
|
126
|
+
return numItems
|
|
127
|
+
}, 0)
|
|
128
|
+
let oldNumItems = getNumItems()
|
|
129
|
+
const cartWatcher = () => {
|
|
130
|
+
this.canApplyDiscount = !this.localZipCode
|
|
131
|
+
const numItems = getNumItems()
|
|
132
|
+
if (oldNumItems !== numItems) {
|
|
133
|
+
ecomCart.data.items.forEach(({ _id, quantity, flags }) => {
|
|
134
|
+
if (Array.isArray(flags) && flags.includes('freebie') && quantity === 1) {
|
|
135
|
+
ecomCart.removeItem(_id)
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
oldNumItems = numItems
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
ecomCart.on('change', cartWatcher)
|
|
142
|
+
this.$once('hook:beforeDestroy', () => {
|
|
143
|
+
ecomCart.off('change', cartWatcher)
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
}
|