@lancom/shared 0.0.399 → 0.0.401
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/components/checkout/cart/cart_entity/cart-entity.scss +8 -0
- package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart-coupon-free-products.scss +10 -2
- package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart-coupon-free-products.vue +18 -1
- package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart_coupon_free_product/cart-coupon-free-product.scss +7 -1
- package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart_coupon_free_product/cart-coupon-free-product.vue +10 -1
- package/components/common/coupon_select/coupon-select.scss +5 -0
- package/components/common/coupon_select/coupon-select.vue +18 -0
- package/components/faq/faq.vue +13 -0
- package/components/products_kit/products_kit/products_kit_options/products_kit_option/products_kit_option_products/products-kit-option-products.scss +18 -0
- package/components/products_kit/products_kit/products_kit_options/products_kit_option/products_kit_option_products/products-kit-option-products.vue +10 -1
- package/components/products_kit/products_kit/products_kit_options/products_kit_option/products_kit_option_products/products_kit_option_product/products-kit-option-product.scss +15 -13
- package/components/products_kit/products_kit/products_kit_options/products_kit_option/products_kit_option_products/products_kit_option_product/products-kit-option-product.vue +3 -0
- package/mixins/product-preview.js +12 -0
- package/package.json +1 -1
- package/store/cart.js +7 -0
- package/store/productsKit.js +16 -6
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
.CartCouponFreeProducts {
|
|
4
4
|
&__label {
|
|
5
|
-
font-
|
|
6
|
-
font-
|
|
5
|
+
font-weight: 700;
|
|
6
|
+
font-size: 1.1em;
|
|
7
|
+
margin: 0 0 8px 0;
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: 12px;
|
|
7
11
|
}
|
|
8
12
|
&__product {
|
|
9
13
|
margin-top: 5px;
|
|
10
14
|
}
|
|
15
|
+
&__main-product {
|
|
16
|
+
padding-left: 36px;
|
|
17
|
+
font-size: 12px;
|
|
18
|
+
}
|
|
11
19
|
}
|
package/components/checkout/cart/cart_entity/cart_coupon_free_products/cart-coupon-free-products.vue
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="CartCouponFreeProducts__wrapper">
|
|
3
3
|
<div class="CartCouponFreeProducts__label">
|
|
4
|
-
|
|
4
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-gift">
|
|
5
|
+
<polyline points="20 12 20 22 4 22 4 12"></polyline>
|
|
6
|
+
<rect x="2" y="7" width="20" height="5"></rect>
|
|
7
|
+
<line x1="12" y1="22" x2="12" y2="7"></line>
|
|
8
|
+
<path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"></path>
|
|
9
|
+
<path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"></path>
|
|
10
|
+
</svg>
|
|
11
|
+
<span>You've Unlocked Free Gifts!</span>
|
|
12
|
+
</div>
|
|
13
|
+
<div
|
|
14
|
+
v-if="entity.product"
|
|
15
|
+
class="CartCouponFreeProducts__main-product">
|
|
16
|
+
{{ entity.product.name }} x {{ qty }}
|
|
5
17
|
</div>
|
|
6
18
|
<cart-coupon-free-product
|
|
7
19
|
v-for="freeProduct in freeProducts"
|
|
@@ -29,6 +41,11 @@ export default {
|
|
|
29
41
|
type: Object,
|
|
30
42
|
required: true
|
|
31
43
|
}
|
|
44
|
+
},
|
|
45
|
+
computed: {
|
|
46
|
+
qty() {
|
|
47
|
+
return this.entity.simpleProducts?.reduce((qty, sp) => qty + (sp.amount || 0), 0) || 0;
|
|
48
|
+
}
|
|
32
49
|
}
|
|
33
50
|
};
|
|
34
51
|
</script>
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="CartCouponFreeProduct__wrapper">
|
|
3
|
-
|
|
3
|
+
<a
|
|
4
|
+
:href="productLink"
|
|
5
|
+
target="_blank">
|
|
6
|
+
FREE {{ freeProduct.name }} x {{ qty }}
|
|
7
|
+
</a>
|
|
4
8
|
</div>
|
|
5
9
|
</template>
|
|
6
10
|
|
|
7
11
|
<script>
|
|
12
|
+
import { generateProductLink } from '@lancom/shared/assets/js/utils/product';
|
|
13
|
+
|
|
8
14
|
export default {
|
|
9
15
|
name: 'CartCouponFreeProduct',
|
|
10
16
|
props: {
|
|
@@ -18,6 +24,9 @@ export default {
|
|
|
18
24
|
}
|
|
19
25
|
},
|
|
20
26
|
computed: {
|
|
27
|
+
productLink() {
|
|
28
|
+
return generateProductLink(this.freeProduct);
|
|
29
|
+
},
|
|
21
30
|
qty() {
|
|
22
31
|
return this.entity.simpleProducts?.reduce((qty, sp) => qty + (sp.amount || 0), 0) || 0;
|
|
23
32
|
}
|
|
@@ -76,6 +76,14 @@
|
|
|
76
76
|
class="lc_caption form-help is-danger">
|
|
77
77
|
Invalid coupon: Min Order for Coupon: {{ value.minOrderValue | price(currency) }}
|
|
78
78
|
</div>
|
|
79
|
+
<div v-if="hasQualifyingProducts" class="lc_caption">
|
|
80
|
+
<div v-if="noQualifyingProductsInCart">
|
|
81
|
+
There are no qualifying products in your cart. See here for more information: <a href="/faq/other#entity-684640df5ce4d102f04974d1">EOFY Beanie offer</a>
|
|
82
|
+
</div>
|
|
83
|
+
<div v-if="hasQualifyingProductsInCart">
|
|
84
|
+
The coupon has been applied to '{{ sumQualifyingProductsInCart }}' qualifying products. See here for more information: <a href="/faq/other#entity-684640df5ce4d102f04974d1">EOFY Beanie offer</a>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
79
87
|
</div>
|
|
80
88
|
</div>
|
|
81
89
|
</template>
|
|
@@ -111,6 +119,16 @@ export default {
|
|
|
111
119
|
},
|
|
112
120
|
computed: {
|
|
113
121
|
...mapGetters(['shop']),
|
|
122
|
+
...mapGetters('cart', ['sumQualifyingProductsInCart']),
|
|
123
|
+
hasQualifyingProducts() {
|
|
124
|
+
return true;
|
|
125
|
+
},
|
|
126
|
+
noQualifyingProductsInCart() {
|
|
127
|
+
return this.sumQualifyingProductsInCart === 0;
|
|
128
|
+
},
|
|
129
|
+
hasQualifyingProductsInCart() {
|
|
130
|
+
return this.sumQualifyingProductsInCart > 0;
|
|
131
|
+
},
|
|
114
132
|
isValidPricing() {
|
|
115
133
|
return !this.value?.minOrderValue || this.pricing.coupon;
|
|
116
134
|
},
|
package/components/faq/faq.vue
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
class="FAQ__group-content">
|
|
37
37
|
<div
|
|
38
38
|
v-for="entity in group.entities"
|
|
39
|
+
:id="`entity-${entity._id}`"
|
|
39
40
|
:key="entity._id"
|
|
40
41
|
:ref="entity._id"
|
|
41
42
|
class="FAQ__entity">
|
|
@@ -64,6 +65,8 @@
|
|
|
64
65
|
</template>
|
|
65
66
|
|
|
66
67
|
<script>
|
|
68
|
+
import { scrollToElement } from '@lancom/shared/assets/js/utils/scroll';
|
|
69
|
+
|
|
67
70
|
export default {
|
|
68
71
|
name: 'FAQ',
|
|
69
72
|
props: {
|
|
@@ -89,6 +92,12 @@ export default {
|
|
|
89
92
|
openedEntities: groups.reduce((items, { entities }) => [...items, ...entities.map(({ _id }) => _id)], [])
|
|
90
93
|
};
|
|
91
94
|
},
|
|
95
|
+
mounted() {
|
|
96
|
+
const hash = window.location.hash;
|
|
97
|
+
if (hash.startsWith('#entity-')) {
|
|
98
|
+
scrollToElement(hash.substring(1), 200);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
92
101
|
methods: {
|
|
93
102
|
toggleGroup({ type }) {
|
|
94
103
|
const index = this.openedGroups.indexOf(type);
|
|
@@ -221,6 +230,10 @@ $types: delivery, general, other, printing, garments;
|
|
|
221
230
|
color: $grey_1;
|
|
222
231
|
overflow: hidden;
|
|
223
232
|
@import "@lancom/shared/assets/scss/normalize";
|
|
233
|
+
|
|
234
|
+
a {
|
|
235
|
+
color: #2196f3;
|
|
236
|
+
}
|
|
224
237
|
}
|
|
225
238
|
}
|
|
226
239
|
}
|
|
@@ -3,5 +3,23 @@
|
|
|
3
3
|
.ProductsKitOptionProducts {
|
|
4
4
|
&__wrapper {
|
|
5
5
|
display: flex;
|
|
6
|
+
position: relative;
|
|
7
|
+
}
|
|
8
|
+
&__product {
|
|
9
|
+
margin: 3px;
|
|
10
|
+
z-index: 0;
|
|
11
|
+
}
|
|
12
|
+
&__loading {
|
|
13
|
+
position: absolute;
|
|
14
|
+
top: 0;
|
|
15
|
+
right: 0;
|
|
16
|
+
bottom: 0;
|
|
17
|
+
left: 0;
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
background-color: white;
|
|
22
|
+
opacity: 0.6;
|
|
23
|
+
z-index: 1;
|
|
6
24
|
}
|
|
7
25
|
}
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
:option="option"
|
|
8
8
|
:product="product"
|
|
9
9
|
class="ProductsKitOptionProducts__product" />
|
|
10
|
+
<div
|
|
11
|
+
v-if="isLoading"
|
|
12
|
+
class="ProductsKitOptionProducts__loading">
|
|
13
|
+
<spinner />
|
|
14
|
+
</div>
|
|
10
15
|
</div>
|
|
11
16
|
</template>
|
|
12
17
|
|
|
@@ -34,7 +39,11 @@ export default {
|
|
|
34
39
|
'country',
|
|
35
40
|
'currency',
|
|
36
41
|
'stockCountry'
|
|
37
|
-
])
|
|
42
|
+
]),
|
|
43
|
+
...mapGetters('productsKit', ['loadingOptions']),
|
|
44
|
+
isLoading() {
|
|
45
|
+
return this.loadingOptions[this.option._id];
|
|
46
|
+
}
|
|
38
47
|
},
|
|
39
48
|
mounted() {
|
|
40
49
|
if (this.option.required && this.option.products?.length === 1) {
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
.ProductsKitOptionProduct {
|
|
4
4
|
&__wrapper {
|
|
5
|
-
border:
|
|
5
|
+
border: 2px solid $gray;
|
|
6
6
|
&--active {
|
|
7
|
-
border:
|
|
7
|
+
border: 2px solid #aac145;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
&__preview {
|
|
11
11
|
width: 175px;
|
|
12
|
-
height:
|
|
12
|
+
height: 340px;
|
|
13
13
|
margin: 7px;
|
|
14
14
|
position: relative;
|
|
15
15
|
z-index: 1;
|
|
@@ -42,30 +42,32 @@
|
|
|
42
42
|
::v-deep {
|
|
43
43
|
.ProductPreview {
|
|
44
44
|
&__link {
|
|
45
|
-
height: 175px;
|
|
45
|
+
height: 175px !important;
|
|
46
46
|
&-cover,
|
|
47
47
|
&-cover-hover {
|
|
48
|
-
height: 175px;
|
|
49
|
-
top: 10px;
|
|
48
|
+
height: 175px !important;
|
|
49
|
+
top: 10px !important;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
&__sku {
|
|
53
|
-
font-size: 13px;
|
|
53
|
+
font-size: 13px !important;
|
|
54
|
+
text-decoration: underline;
|
|
54
55
|
}
|
|
55
56
|
&__name {
|
|
56
|
-
font-size: 15px;
|
|
57
|
-
line-height: 20px;
|
|
57
|
+
font-size: 15px !important;
|
|
58
|
+
line-height: 20px !important;
|
|
58
59
|
margin-top: 1px;
|
|
59
|
-
min-height: 35px;
|
|
60
|
+
min-height: 35px !important;
|
|
61
|
+
text-decoration: underline;
|
|
60
62
|
}
|
|
61
63
|
&__prices-printed-price {
|
|
62
|
-
font-size: 16px;
|
|
63
|
-
line-height: 20px;
|
|
64
|
+
font-size: 16px !important;
|
|
65
|
+
line-height: 20px !important;
|
|
64
66
|
}
|
|
65
67
|
&__slogan-item {
|
|
66
68
|
span {
|
|
67
69
|
padding: 2px 3px;
|
|
68
|
-
font-size: 8px;
|
|
70
|
+
font-size: 8px !important;
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
&__content {
|
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
:product="product"
|
|
15
15
|
:to-editor="false"
|
|
16
16
|
:visible-color-thumbs="false"
|
|
17
|
+
:visible-info="false"
|
|
18
|
+
:visible-brand="false"
|
|
17
19
|
:visible-prices="!option.required"
|
|
20
|
+
link-target="_blank"
|
|
18
21
|
@preview="onPreviewProduct($event)"
|
|
19
22
|
@color="onProductSelectColor($event)" />
|
|
20
23
|
</div>
|
|
@@ -33,6 +33,18 @@ const productPreview = {
|
|
|
33
33
|
visibleColorThumbs: {
|
|
34
34
|
type: Boolean,
|
|
35
35
|
default: true
|
|
36
|
+
},
|
|
37
|
+
visibleInfo: {
|
|
38
|
+
type: Boolean,
|
|
39
|
+
default: true
|
|
40
|
+
},
|
|
41
|
+
visibleBrand: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
default: true
|
|
44
|
+
},
|
|
45
|
+
linkTarget: {
|
|
46
|
+
type: String,
|
|
47
|
+
default: '_self'
|
|
36
48
|
}
|
|
37
49
|
},
|
|
38
50
|
data() {
|
package/package.json
CHANGED
package/store/cart.js
CHANGED
|
@@ -95,6 +95,13 @@ export const getters = {
|
|
|
95
95
|
];
|
|
96
96
|
}, []);
|
|
97
97
|
},
|
|
98
|
+
sumQualifyingProductsInCart: ({ entities, coupon }) => {
|
|
99
|
+
return entities.reduce((sum, entity) => {
|
|
100
|
+
const amount = entity.simpleProducts?.reduce((count, sp) => count + +(sp.amount || 0), 0) || 0;
|
|
101
|
+
const freeProducts = getCouponFreeProducts(coupon, entity.product);
|
|
102
|
+
return freeProducts.length > 0 ? sum + amount : sum;
|
|
103
|
+
}, 0);
|
|
104
|
+
},
|
|
98
105
|
coupon: ({ coupon }) => coupon,
|
|
99
106
|
needToPickup: ({ needToPickup }) => needToPickup,
|
|
100
107
|
needToPickupWithoutErrors: (state, { notValidProductsPickup }) => state.needToPickup && notValidProductsPickup?.length === 0,
|
package/store/productsKit.js
CHANGED
|
@@ -8,6 +8,7 @@ export const state = () => ({
|
|
|
8
8
|
amount: 0,
|
|
9
9
|
productsKit: null,
|
|
10
10
|
loadError: null,
|
|
11
|
+
loadingOptions: {},
|
|
11
12
|
selectedOptionsProducts: {},
|
|
12
13
|
selectedOptionsSimpleProducts: {},
|
|
13
14
|
selectedOptionsColors: {},
|
|
@@ -35,6 +36,7 @@ export const getters = {
|
|
|
35
36
|
loadError: ({ loadError }) => loadError,
|
|
36
37
|
amount: ({ amount }) => amount,
|
|
37
38
|
productsKitPricing: ({ productsKitPricing }) => productsKitPricing,
|
|
39
|
+
loadingOptions: ({ loadingOptions }) => loadingOptions,
|
|
38
40
|
selectedOptionsProducts: ({ selectedOptionsProducts }) => selectedOptionsProducts,
|
|
39
41
|
selectedOptionsSimpleProducts: ({ selectedOptionsSimpleProducts }) => selectedOptionsSimpleProducts,
|
|
40
42
|
selectedOptionsColors: ({ selectedOptionsColors }) => selectedOptionsColors,
|
|
@@ -97,12 +99,17 @@ export const actions = {
|
|
|
97
99
|
},
|
|
98
100
|
async selectOptionProduct({ commit }, { option, product, country, currency, stockCountry }) {
|
|
99
101
|
const params = { country, currency, stockCountry };
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
try {
|
|
103
|
+
commit('setLoadingOption', { option, loading: true });
|
|
104
|
+
const simpleProducts = product ? (await api.fetchProductDetails(null, product.alias, params)) : [];
|
|
105
|
+
commit('setSelectedOptionProduct', { option, product });
|
|
106
|
+
commit('setSelectedOptionSimpleProducts', { option, simpleProducts });
|
|
107
|
+
commit('setSelectedOptionColor', { option, color: null });
|
|
108
|
+
commit('setSelectedOptionSize', { option, size: null });
|
|
109
|
+
} catch (e) {
|
|
110
|
+
} finally {
|
|
111
|
+
commit('setLoadingOption', { option, loading: false });
|
|
112
|
+
}
|
|
106
113
|
},
|
|
107
114
|
selectOptionColor({ commit }, { option, color }) {
|
|
108
115
|
commit('setSelectedOptionColor', { option, color });
|
|
@@ -168,6 +175,9 @@ export const mutations = {
|
|
|
168
175
|
setSelectedOptionSimpleProducts(state, { option, simpleProducts }) {
|
|
169
176
|
Vue.set(state.selectedOptionsSimpleProducts, option._id, simpleProducts);
|
|
170
177
|
},
|
|
178
|
+
setLoadingOption(state, { option, loading }) {
|
|
179
|
+
Vue.set(state.loadingOptions, option._id, loading);
|
|
180
|
+
},
|
|
171
181
|
setLoadError(state, error) {
|
|
172
182
|
state.loadError = error;
|
|
173
183
|
},
|