@lancom/shared 0.0.266 → 0.0.268

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.
@@ -97,6 +97,7 @@ export default {
97
97
  },
98
98
  onProgress(progress) {
99
99
  // const duration = progress ? 0.1 : 0;
100
+ this.progress = progress;
100
101
  // this.timelineLite.to(this, duration, { progress, ease: Power3.easeIn });
101
102
  },
102
103
  toggle() {
@@ -15,35 +15,37 @@
15
15
  ::v-deep .slick-list {
16
16
  min-height: 205px;
17
17
  }
18
- ::v-deep .slick-arrow.slick-prev,
19
- ::v-deep .slick-arrow.slick-next {
18
+
19
+ ::v-deep .slick-arrow {
20
20
  position: absolute;
21
- bottom: 25px;
22
- right: 0;
23
- background-color: black;
24
- border: 1px solid white;
25
- background-image: url(./../../../static/icons/arrow-left.svg);
21
+ color: white;
22
+ top: 120px;
23
+ background-color: $gray;
24
+ background-image: url(./../../../static/icons/arrow-right.svg);
26
25
  background-position: center;
27
26
  background-repeat: no-repeat;
28
- background-size: 15px 15px;
29
- width: 41px;
30
- height: 41px;
27
+ background-size: 25px 25px;
28
+ width: 31px;
29
+ height: 47px;
30
+ margin-top: -45px;
31
31
  text-indent: -9999px;
32
+ border: none;
32
33
  cursor: pointer;
33
34
  z-index: 2;
34
35
 
36
+ &.slick-prev {
37
+ left: 0;
38
+ transform: rotate(180deg);
39
+ }
40
+ &.slick-next {
41
+ right: 0;
42
+ }
35
43
  &:hover {
36
44
  box-shadow: 0 0 3px $grey_2;
37
45
  }
38
- }
39
- ::v-deep .slick-arrow.slick-prev {
40
- transform: rotateZ(180deg);
41
- left: 0;
42
- right: auto;
43
- }
44
- ::v-deep .slick-arrow.slick-prev:focus,
45
- ::v-deep .slick-arrow.slick-next:focus {
46
- outline: none;
46
+ &:focus {
47
+ outline: none;
48
+ }
47
49
  }
48
50
  }
49
51
  &__items {
@@ -56,5 +58,13 @@
56
58
  height: 200px;
57
59
  max-width: 300px;
58
60
  flex-grow: 1;
61
+ &--active {
62
+ .elevation2 {
63
+ box-shadow: 0px 1px 5px $green !important;
64
+ }
65
+ ::v-deep .ProductMultipack__price {
66
+ background-color: $green !important;
67
+ }
68
+ }
59
69
  }
60
70
  }
@@ -4,11 +4,15 @@
4
4
  <div
5
5
  v-for="multipack in visibleMultipacks"
6
6
  :key="multipack._id"
7
- class="ProductMultipacksCarousel__item">
7
+ class="ProductMultipacksCarousel__item"
8
+ :class="{
9
+ 'ProductMultipacksCarousel__item--active': multipack === selectedMultipack
10
+ }">
8
11
  <product-multipack
9
12
  :multipack="multipack"
10
13
  :simple-products="simpleProducts"
11
- class="elevation2" />
14
+ class="elevation2"
15
+ @selected="toggleMultipack(multipack)" />
12
16
  </div>
13
17
  </div>
14
18
  <button
@@ -27,6 +31,8 @@
27
31
  </template>
28
32
 
29
33
  <script>
34
+ import { mapMutations } from 'vuex';
35
+ import { inRange } from '@lancom/shared/assets/js/utils/filters';
30
36
  import ProductMultipack from './product_multipack/product-multipack';
31
37
 
32
38
  export default {
@@ -36,7 +42,8 @@ export default {
36
42
  },
37
43
  data() {
38
44
  return {
39
- thumbsPage: 0
45
+ thumbsPage: 0,
46
+ selectedMultipack: null
40
47
  };
41
48
  },
42
49
  props: {
@@ -65,6 +72,38 @@ export default {
65
72
  }
66
73
  },
67
74
  methods: {
75
+ toggleMultipack(multipack) {
76
+ this.selectedMultipack = this.selectedMultipack === multipack ? null : multipack;
77
+ this.clearSimpleProductsAmount();
78
+ if (this.selectedMultipack) {
79
+ this.buyMultipack()
80
+ }
81
+ },
82
+ ...mapMutations('product', ['setSimpleProductAmount', 'clearSimpleProductsAmount']),
83
+ buyMultipack() {
84
+ const sizes = [
85
+ { size: 'S', percent: 0.15 },
86
+ { size: 'M', percent: 0.2 },
87
+ { size: 'XL', percent: 0.3 },
88
+ { size: '2XL', percent: 0.05 },
89
+ { size: 'L' }
90
+ ];
91
+ let leftQty = this.selectedMultipack.qty;
92
+ sizes.forEach(s => {
93
+ const simpleProduct = this.simpleProducts.find(simpleProduct => simpleProduct.size.shortName === s.size);
94
+ if (simpleProduct) {
95
+ const qty = s.percent ? +(s.percent * this.selectedMultipack.qty).toFixed(0) : leftQty;
96
+ const amount = inRange(qty, 0, simpleProduct.quantityStock || 999);
97
+ leftQty -= amount;
98
+ this.setSimpleProductAmount({
99
+ colorId: simpleProduct.color._id,
100
+ sizeId: simpleProduct.size._id,
101
+ amount
102
+ });
103
+ }
104
+ });
105
+
106
+ },
68
107
  goToPrevPage() {
69
108
  this.thumbsPage = Math.max(0, this.thumbsPage - 1);
70
109
  },
@@ -2,11 +2,21 @@
2
2
 
3
3
  .ProductMultipack {
4
4
  &__price {
5
- padding: 15px;
5
+ padding: 10px;
6
6
  text-align: center;
7
7
  font-size: 14px;
8
8
  font-weight: bold;
9
9
  background-color: $gray;
10
+ span {
11
+ text-align: center;
12
+ padding: 6px;
13
+ background-color: $orange;
14
+ color: $white;
15
+ display: inline-block;
16
+ font-weight: bold;
17
+ font-size: 15px;
18
+ margin-left: 14px;
19
+ }
10
20
  }
11
21
  &__image {
12
22
  position: absolute;
@@ -16,28 +26,18 @@
16
26
  bottom: 0;
17
27
  background-position: left top;
18
28
  background-repeat: no-repeat;
19
- background-size: contain;
29
+ background-size: cover;
20
30
  }
21
31
  &__banner {
22
32
  position: relative;
23
33
  height: 140px;
24
34
  &-info {
25
35
  position: absolute;
26
- top: 20px;
27
- right: 10px;
36
+ top: 0px;
37
+ right: 0px;
28
38
  display: flex;
29
39
  flex-direction: column;
30
40
  align-items: end;
31
- &-item span {
32
- margin-bottom: 10px;
33
- text-align: center;
34
- padding: 6px;
35
- background-color: $orange;
36
- color: $white;
37
- display: inline-block;
38
- font-weight: bold;
39
- font-size: 15px;
40
- }
41
41
  }
42
42
  }
43
43
  }
@@ -1,12 +1,13 @@
1
1
  <template>
2
2
  <div
3
3
  :id="`product-multipack-${multipack._id}`"
4
- class="ProductMultipack__wrapper">
4
+ class="ProductMultipack__wrapper"
5
+ @click="buyMultipack()">
5
6
  <div class="ProductMultipack__banner">
6
7
  <div
7
8
  class="ProductMultipack__image"
8
9
  :style="{
9
- 'background-image': multipack.image ? `url('${multipack.image.small}'` : null
10
+ 'background-image': bannerImage ? `url('${bannerImage}'` : null
10
11
  }">
11
12
  </div>
12
13
  <div class="ProductMultipack__banner-info">
@@ -14,27 +15,22 @@
14
15
  <btn
15
16
  style="padding: 10px; height: 35px; margin-bottom: 10px;"
16
17
  btn-class="green"
17
- btn-label="BUY"
18
+ :btn-label="`BUY ${multipack.qty}`"
18
19
  size="sm"
19
20
  @onclick="buyMultipack()" />
20
21
  </div>
21
- <div class="ProductMultipack__banner-info-item">
22
- <span>{{ multipack.qty }}</span>
23
- </div>
24
- <div class="ProductMultipack__banner-info-item">
25
- <span>{{ totalPrice | priceWithTax(pricingSettings, currency) }}</span>
26
- </div>
27
22
  </div>
28
23
  </div>
29
24
  <div class="ProductMultipack__price">
30
- Only {{ oneItemPrice | priceWithTax(pricingSettings, currency) }} each
25
+ {{ oneItemPrice | priceWithTax(pricingSettings, currency) }} each
26
+ <span>{{ totalPrice | priceWithTax(pricingSettings, currency) }}</span>
31
27
  </div>
32
28
  </div>
33
29
  </template>
34
30
 
35
31
  <script>
36
- import { mapGetters, mapMutations } from 'vuex';
37
- import { priceWithTax, inRange } from '@lancom/shared/assets/js/utils/filters';
32
+ import { mapGetters } from 'vuex';
33
+ import { priceWithTax } from '@lancom/shared/assets/js/utils/filters';
38
34
 
39
35
  export default {
40
36
  name: 'LancomProductMultipack',
@@ -53,6 +49,10 @@ export default {
53
49
  },
54
50
  computed: {
55
51
  ...mapGetters(['pricingSettings', 'currency']),
52
+ bannerImage() {
53
+ const banner = this.multipack.banner?.editorImage || this.multipack.banner;
54
+ return banner?.origin;
55
+ },
56
56
  simpleProduct() {
57
57
  return (this.simpleProducts || []).find(sp => sp.SKU === this.multipack.SKU);
58
58
  },
@@ -64,13 +64,8 @@ export default {
64
64
  }
65
65
  },
66
66
  methods: {
67
- ...mapMutations('product', ['setSimpleProductAmount']),
68
67
  buyMultipack() {
69
- this.setSimpleProductAmount({
70
- colorId: this.simpleProduct.color._id,
71
- sizeId: this.simpleProduct.size._id,
72
- amount: inRange(this.multipack.qty, 0, this.simpleProduct.quantityStock || 999)
73
- });
68
+ this.$emit('selected', this.multipack);
74
69
  }
75
70
  }
76
71
  };
@@ -96,10 +96,10 @@ async function googleShoppingFeed(axios, config, availableStores) {
96
96
  }
97
97
  if (product.volume) {
98
98
  if (product.volume.length) {
99
- info['g:shipping_length'] = { _text: `${parseInt(product.volume.length * (sp.multipackQty || 1))} cm` };
99
+ info['g:shipping_length'] = { _text: `${parseInt(product.volume.length)} cm` };
100
100
  }
101
101
  if (product.volume.width) {
102
- info['g:shipping_width'] = { _text: `${parseInt(product.volume.width * (sp.multipackQty || 1))} cm` };
102
+ info['g:shipping_width'] = { _text: `${parseInt(product.volume.width)} cm` };
103
103
  }
104
104
  if (product.volume.height) {
105
105
  info['g:shipping_height'] = { _text: `${parseInt(product.volume.height * (sp.multipackQty || 1))} cm` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.266",
3
+ "version": "0.0.268",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
package/store/product.js CHANGED
@@ -67,6 +67,7 @@ export const getters = {
67
67
  hasLayers: ({ template }) => (template.layers || []).length > 0,
68
68
  visibleSteps: ({ template }) => template.visibleSteps,
69
69
  simpleProducts: ({ template }) => template.simpleProducts || [],
70
+ editableColorSimpleProducts: ({ template, editableColor }) => (template.simpleProducts || []).filter(sp => sp.color._id === editableColor._id),
70
71
  usedSimpleProducts: ({ template }) => (template.simpleProducts || []).filter(p => p.amount > 0),
71
72
  usedSimpleProductsQuantity: ({ template }) => (template.simpleProducts || []).filter(p => p.amount > 0).reduce((sum, { amount }) => sum + amount, 0),
72
73
  usedBigSizeSimpleProductsQuantity: (state, { usedSimpleProducts }) => filterBigSize(usedSimpleProducts).reduce((sum, { amount }) => sum + amount, 0),
@@ -410,6 +411,12 @@ export const mutations = {
410
411
  Vue.set(state.template.simpleProducts, index, simpleProduct);
411
412
  }
412
413
  },
414
+ clearSimpleProductsAmount(state) {
415
+ state.template.simpleProducts.forEach((simpleProduct, index) => {
416
+ Vue.set(simpleProduct, 'amount', 0);
417
+ Vue.set(state.template.simpleProducts, index, simpleProduct);
418
+ })
419
+ },
413
420
  setProductPricing(state, price) {
414
421
  state.productPricing = price;
415
422
  },