@lancom/shared 0.0.336 → 0.0.337

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.
Files changed (32) hide show
  1. package/assets/js/utils/colors.js +3 -3
  2. package/assets/js/utils/fabric/selection-style.js +2 -1
  3. package/assets/js/utils/prints.js +1 -1
  4. package/components/checkout/cart/cart.vue +2 -2
  5. package/components/checkout/cart/cart_entity/cart_entity_color_simple_products/cart-entity-color-simple-products.vue +2 -0
  6. package/components/checkout/order/order-success/order-success.vue +1 -1
  7. package/components/common/client_settings/client-settings.scss +4 -4
  8. package/components/common/client_settings/client-settings.vue +5 -1
  9. package/components/common/pricing_table/pricing-table.scss +3 -0
  10. package/components/common/product_side_with_print/product-side-with-print.scss +3 -0
  11. package/components/common/product_side_with_print/product-side-with-print.vue +5 -1
  12. package/components/customer/customer_menu/customer-menu.scss +9 -3
  13. package/components/customer/customer_menu/customer-menu.vue +26 -3
  14. package/components/editor/editor.vue +7 -0
  15. package/components/editor/editor_layers/editor-layers.vue +2 -1
  16. package/components/editor/editor_product_details/editor-product-details.scss +4 -1
  17. package/components/editor/editor_product_details/editor-product-details.vue +1 -0
  18. package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.scss +35 -10
  19. package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.vue +50 -2
  20. package/components/errors/404.vue +1 -1
  21. package/components/errors/500.vue +1 -1
  22. package/components/product/editor_pricing/editor-pricing.scss +3 -0
  23. package/components/product/editor_pricing/editor-pricing.vue +13 -9
  24. package/components/products/brands/brands.scss +90 -0
  25. package/components/products/brands/brands.vue +65 -0
  26. package/components/products/products_autocomplete/products-autocomplete.scss +3 -0
  27. package/components/products/products_autocomplete/products-autocomplete.vue +7 -7
  28. package/components/subscribe/subscribe.vue +1 -1
  29. package/mixins/add-to-cart.js +3 -0
  30. package/package.json +1 -1
  31. package/store/product.js +2 -2
  32. package/store/products.js +1 -1
@@ -49,12 +49,12 @@ export const getProductOriginCover = (product, type, color) => getProductCover(p
49
49
 
50
50
  export const getBgStyle = img => img && ({ 'background-image': `url("${img}")` });
51
51
 
52
- export function getColorBackgroundStyle(color, skipPattern) {
53
- const { rgb, pattern, name } = color || {};
52
+ export function getColorBackgroundStyle(color, skipPattern, originBackground) {
53
+ const { rgb, pattern, patternOrigin, name } = color || {};
54
54
 
55
55
  if (pattern && !skipPattern) {
56
56
  return {
57
- 'background-image': `url("${staticLink(pattern)}")`
57
+ 'background-image': `url("${staticLink((originBackground && patternOrigin) || pattern)}")`
58
58
  };
59
59
  }
60
60
 
@@ -1,10 +1,11 @@
1
1
  import { fabric } from 'fabric';
2
+ import { staticLink } from '@lancom/shared/assets/js/utils/filters';
2
3
 
3
4
  let rotate;
4
5
 
5
6
  export function loadRotateImage(cb = Function.prototype) {
6
7
  const image = new Image();
7
- image.src = '/icons/rotate.png';
8
+ image.src = staticLink('/icons/rotate.png');
8
9
  image.onload = () => {
9
10
  rotate = image;
10
11
  cb();
@@ -61,7 +61,7 @@ export function getPrintsFromLayers(layers, product) {
61
61
  prints.set(printAreaKey, data);
62
62
  layer.printGuid = data.guid;
63
63
  } else {
64
- const print = prints.get(printArea);
64
+ const print = prints.get(printAreaKey);
65
65
  layer.printGuid = print.guid;
66
66
  print.layers.push(generatePrintLayer(layer));
67
67
  prints.set(printAreaKey, print);
@@ -92,10 +92,10 @@ export default {
92
92
  filters: { price },
93
93
  mixins: [CartMixin],
94
94
  computed: {
95
- ...mapGetters(['MESSAGES', 'SETTINGS', 'currency']),
95
+ ...mapGetters(['MESSAGES', 'SETTINGS', 'currency', 'country']),
96
96
  ...mapGetters('cart', ['isEmpty', 'cartPricingError', 'cartPricing', 'cartPricingCalculating', 'entities']),
97
97
  onlyPostcode() {
98
- return !!this.SETTINGS.CART_ONLY_POSTCODE;
98
+ return !!this.SETTINGS.CART_ONLY_POSTCODE && this.country?.isoCode === 'UK';
99
99
  },
100
100
  postcodeLabel() {
101
101
  return this.onlyPostcode ? 'Postcode' : (this.MESSAGES.CART_POSTCODE || 'Postcode');
@@ -6,6 +6,7 @@
6
6
  @click="showImage(images, 0)">
7
7
  <product-side-with-print
8
8
  :product="group"
9
+ :fill-background="true"
9
10
  :default-preview="defaultPreview"
10
11
  side="front"
11
12
  size="medium" />
@@ -17,6 +18,7 @@
17
18
  <product-side-with-print
18
19
  :product="group"
19
20
  :default-preview="defaultPreview"
21
+ :fill-background="true"
20
22
  side="back"
21
23
  size="medium" />
22
24
  </div>
@@ -2,7 +2,7 @@
2
2
  <div class="OrderSuccess__wrapper">
3
3
  <div class="OrderSuccess__card">
4
4
  <div class="OrderSuccess__card-icon">
5
- <img src="/images/success.svg" />
5
+ <img src="~static/images/success.svg" />
6
6
  </div>
7
7
  <div class="OrderSuccess__card-head">
8
8
  RECEIVED!
@@ -8,7 +8,7 @@
8
8
  min-width: 72px;
9
9
  width: 33%;
10
10
  height: 100%;
11
- border-radius: 2px;
11
+ border-radius: 5px;
12
12
  box-shadow: $elevation1;
13
13
  }
14
14
  &__value {
@@ -52,15 +52,15 @@
52
52
  &__dropdown {
53
53
  position: absolute;
54
54
  z-index: 101;
55
- top: 40px;
56
- width: 220px;
55
+ top: 35px;
56
+ width: 250px;
57
57
  margin-top: 20px;
58
58
  margin-left: -55px;
59
59
  // transform: translateY(-50%);
60
60
  padding: 15px;
61
61
  box-shadow: 0px 4px 121px 0px rgba(145, 136, 188, 0.34);
62
62
  background-color: white;
63
- border-radius: 12px;
63
+ border-radius: 5px;
64
64
  }
65
65
  &__backdrop {
66
66
  top: 0;
@@ -18,7 +18,8 @@
18
18
  </div>
19
19
  <div
20
20
  v-if="isOpen"
21
- class="ClientSettings__dropdown">
21
+ class="ClientSettings__dropdown"
22
+ v-click-outside="close">
22
23
  <div>
23
24
  <div
24
25
  class="ClientSettings__field"
@@ -112,6 +113,9 @@ export default {
112
113
  }
113
114
  },
114
115
  methods: {
116
+ close() {
117
+ this.isOpen = false;
118
+ },
115
119
  toggleVisibleCountries() {
116
120
  this.visibleCountries = !this.visibleCountries;
117
121
  },
@@ -3,4 +3,7 @@
3
3
  table {
4
4
  min-width: 200px;
5
5
  background-color: $white;
6
+ tr th {
7
+ overflow: hidden;
8
+ }
6
9
  }
@@ -2,6 +2,9 @@
2
2
  position: relative;
3
3
  width: 100%;
4
4
  height: 100%;
5
+ background-position: center;
6
+ background-size: contain;
7
+ background-repeat: no-repeat;
5
8
  &.preview {
6
9
  cursor: pointer;
7
10
  }
@@ -49,6 +49,10 @@ export default {
49
49
  type: Boolean,
50
50
  default: false
51
51
  },
52
+ originBackground: {
53
+ type: Boolean,
54
+ default: false
55
+ },
52
56
  priviewProducts: {
53
57
  type: Array,
54
58
  default: null
@@ -76,7 +80,7 @@ export default {
76
80
  return [...this.priviewProducts.reduce(predicate, new Map()).values()];
77
81
  },
78
82
  colorBackground() {
79
- return this.fillBackground && getColorBackgroundStyle(this.product.color);
83
+ return this.fillBackground && getColorBackgroundStyle(this.product.color, false, this.originBackground);
80
84
  },
81
85
  imageBackground() {
82
86
  return this.image && this.getImageBackground(this.image);
@@ -3,6 +3,11 @@
3
3
  .CustomerMenu {
4
4
  &__wrapper {
5
5
  position: relative;
6
+ .Btn {
7
+ &__wrapper {
8
+ height: 43px;
9
+ }
10
+ }
6
11
  }
7
12
  &__inner {
8
13
  min-width: 72px;
@@ -18,7 +23,7 @@
18
23
  display: flex;
19
24
  align-items: center;
20
25
  background-color: rgba(125, 106, 239, 0.07);
21
- padding: 10px 10px 5px 10px;
26
+ padding: 4px;
22
27
  border-radius: 20px;
23
28
  &--divider {
24
29
  display: block;
@@ -60,7 +65,7 @@
60
65
  padding: 15px;
61
66
  box-shadow: 0px 4px 121px 0px rgba(145, 136, 188, 0.34);
62
67
  background-color: white;
63
- border-radius: 12px;
68
+ border-radius: 5px;
64
69
  }
65
70
  &__backdrop {
66
71
  top: 0;
@@ -95,7 +100,8 @@
95
100
  display: flex;
96
101
  align-items: center;
97
102
  font-size: 16px;
98
- color: $purple;
103
+ color: $black;
104
+ text-decoration: none !important;
99
105
 
100
106
  &-checked {
101
107
  margin-right: 10px;
@@ -21,24 +21,47 @@
21
21
  </div>
22
22
  <div
23
23
  v-if="isOpen"
24
- class="CustomerMenu__dropdown">
24
+ class="CustomerMenu__dropdown"
25
+ v-click-outside="close">
25
26
  <div>
26
- <a href="/customer/settings" class="CustomerMenu__field-item">Settings</a>
27
+ <a
28
+ href="/customer/settings"
29
+ class="CustomerMenu__field-item">
30
+ Settings
31
+ </a>
27
32
  </div>
28
33
  <div>
29
- <a href="/customer/orders" class="CustomerMenu__field-item">Orders</a>
34
+ <a
35
+ href="/customer/orders"
36
+ class="CustomerMenu__field-item">
37
+ Orders
38
+ </a>
39
+ </div>
40
+ <div>
41
+ <a
42
+ href="#"
43
+ class="CustomerMenu__field-item"
44
+ @click="auth_logout">Logout</a>
30
45
  </div>
31
46
  </div>
32
47
  </div>
33
48
  </template>
34
49
 
35
50
  <script>
51
+ import { mapActions } from 'vuex';
52
+
36
53
  export default {
37
54
  name: 'CustomerMenu',
38
55
  data() {
39
56
  return {
40
57
  isOpen: false,
41
58
  };
59
+ },
60
+ methods: {
61
+ ...mapActions('auth', ['auth_logout']),
62
+ close() {
63
+ this.isOpen = false;
64
+ }
42
65
  }
43
66
  };
44
67
  </script>
@@ -14,6 +14,7 @@
14
14
  <template v-slot:default="{ currentTab }">
15
15
  <component
16
16
  :is="editorCurrentTabComponent(currentTab)"
17
+ @choose-products="selectTab('product')"
17
18
  v-if="currentTab">
18
19
  </component>
19
20
  </template>
@@ -25,7 +26,13 @@
25
26
  btn-label="Start again"
26
27
  btn-class="white"
27
28
  @onclick="showResetAllConfirm" />
29
+ <btn
30
+ v-if="isValidPrintOnly && needToAddProducts"
31
+ btn-label="Enter products"
32
+ btn-class="green"
33
+ @onclick="selectTab('product')" />
28
34
  <v-popover
35
+ v-else
29
36
  ref="popover"
30
37
  trigger="hover"
31
38
  :delay="{ hide: 400, show: 400 }"
@@ -79,7 +79,8 @@
79
79
  <editor-pricing
80
80
  v-if="hasPricing"
81
81
  class="EditorLayers__pricing"
82
- :has-cart-btn="false" />
82
+ :has-cart-btn="false"
83
+ @choose-products="$emit('choose-products')" />
83
84
  </div>
84
85
  </template>
85
86
 
@@ -58,13 +58,16 @@
58
58
  display: inline-block;
59
59
  }
60
60
  &__prints-table {
61
- width: 400px;
61
+ width: 450px;
62
62
 
63
63
  thead tr,
64
64
  tbody td:first-child {
65
65
  background-color: $grey_4 !important;
66
66
  text-align: center;
67
67
  }
68
+ tr th {
69
+ font-size: 12px;
70
+ }
68
71
  }
69
72
  &__available-warning {
70
73
  background-color: $error;
@@ -111,6 +111,7 @@
111
111
  :side="side"
112
112
  :default-preview="false"
113
113
  :fill-background="true"
114
+ :origin-background="true"
114
115
  size="large" />
115
116
  <div
116
117
  class="EditorProductDetails__product-sides-toggle"
@@ -58,28 +58,27 @@
58
58
  }
59
59
  &__placeholder {
60
60
  position: absolute;
61
- cursor: pointer;
62
61
  z-index: 999;
63
- background-image: url(../../../../static/images/type_here.png);
64
- background-size: contain;
65
- background-repeat: no-repeat;
66
- background-position: center;
67
-
62
+ text-align: center;
63
+
68
64
  --placeholder-width: 140px;
69
- --placeholder-height: 50px;
65
+ --placeholder-height: 100px;
70
66
 
71
67
  @media (max-width: $bp-extra-small-max) {
72
68
  --placeholder-width: 70px;
73
- --placeholder-height: 25px;
69
+ --placeholder-height: 50px;
70
+ font-size: 10px;
74
71
  }
75
72
 
76
73
  &.tighten {
77
74
  --placeholder-width: 70px;
78
- --placeholder-height: 25px;
75
+ --placeholder-height: 50px;
76
+ font-size: 10px;
79
77
 
80
78
  @media (max-width: $bp-extra-small-max) {
81
79
  --placeholder-width: 35px;
82
- --placeholder-height: 12.5px;
80
+ --placeholder-height: 25px;
81
+ font-size: 8px;
83
82
  }
84
83
  }
85
84
 
@@ -87,6 +86,32 @@
87
86
  height: var(--placeholder-height);
88
87
  margin-left: calc(var(--placeholder-width) / 2 * (-1));
89
88
  margin-top: calc(var(--placeholder-height) / 2 * (-1));
89
+ letter-spacing: -0.5px;
90
+ &-option {
91
+ cursor: pointer;
92
+ margin: 5px 0;
93
+ text-transform: uppercase;
94
+ }
95
+ &-divider {
96
+ color: $grey_1;
97
+ }
98
+ &-progress {
99
+ position: absolute;
100
+ top: 0;
101
+ left: 0;
102
+ width: 100%;
103
+ height: 100%;
104
+ background-color: $white_high_emphasis;
105
+ opacity: .7;
106
+ &-indicator {
107
+ position: absolute;
108
+ top: 0;
109
+ left: 0;
110
+ width: 0;
111
+ height: 100%;
112
+ background-color: $green;
113
+ }
114
+ }
90
115
  }
91
116
  &__alert {
92
117
  &-container {
@@ -5,6 +5,7 @@
5
5
  :class="{
6
6
  'EditorWorkspaceSide__wrapper--zoom-in': isZoomed
7
7
  }"
8
+ v-click-outside="onOutsideClick"
8
9
  @mouseover="toogleBoundBox(true)"
9
10
  @mouseleave="toogleBoundBox(false)">
10
11
  <div
@@ -36,8 +37,37 @@
36
37
  class="EditorWorkspaceSide__placeholder"
37
38
  :class="{ tighten: printAreaIsSmall }"
38
39
  ignore-document-click
39
- :style="positionPlaceholder"
40
- @click="createTextLayer">
40
+ :style="positionPlaceholder">
41
+ <div
42
+ @click="createTextLayer"
43
+ class="EditorWorkspaceSide__placeholder-option">
44
+ Type here
45
+ </div>
46
+ <div class="EditorWorkspaceSide__placeholder-divider">
47
+ or
48
+ </div>
49
+ <div>
50
+ <file-uploader
51
+ :multiple="false"
52
+ :url="`image/editor/${shop._id}/${product._id}`"
53
+ @onuploaded="handleUploaded">
54
+ <template #toggle>
55
+ <div class="EditorWorkspaceSide__placeholder-option">
56
+ <i class="icon-picture"></i> Add art
57
+ </div>
58
+ </template>
59
+ <template v-slot:progress="{ progress }">
60
+ <div
61
+ v-if="progress"
62
+ class="EditorWorkspaceSide__placeholder-progress">
63
+ <div
64
+ :style="{ width: `${progress}%`}"
65
+ class="EditorWorkspaceSide__placeholder-progress-indicator"></div>
66
+ <spinner v-if="progress >= 100" background="white" style="margin-top: 50px" />
67
+ </div>
68
+ </template>
69
+ </file-uploader>
70
+ </div>
41
71
  </div>
42
72
  <div
43
73
  v-show="isVisibleOverlay"
@@ -85,9 +115,13 @@ import FabricHelper from '@lancom/shared/assets/js/utils/fabric-helper';
85
115
  import { findParentByPredicate } from '@lancom/shared/assets/js/utils/dom';
86
116
  import Breakpoints from '@lancom/shared/assets/js/utils/breakpoints';
87
117
  import { getColorBackgroundStyle } from '@lancom/shared/assets/js/utils/colors';
118
+ import FileUploader from '@lancom/shared/components/common/file_uploader';
88
119
 
89
120
  export default {
90
121
  name: 'EditorWorkspaceSide',
122
+ components: {
123
+ FileUploader
124
+ },
91
125
  props: {
92
126
  side: {
93
127
  type: String,
@@ -105,6 +139,7 @@ export default {
105
139
  },
106
140
  data() {
107
141
  return {
142
+ addedFromCanvas: false,
108
143
  visibleWireframe: false,
109
144
  fabricHelper: null,
110
145
  redrawWithThrottle: throttle(this.redraw, 100, { trailing: false }),
@@ -120,6 +155,7 @@ export default {
120
155
  };
121
156
  },
122
157
  computed: {
158
+ ...mapGetters(['shop']),
123
159
  ...mapGetters('product', [
124
160
  'product',
125
161
  'layers',
@@ -355,15 +391,27 @@ export default {
355
391
  removeSelected() {
356
392
  this.removeTemplateLayer(this.selectedLayer);
357
393
  },
394
+ onOutsideClick() {
395
+ if (this.addedFromCanvas && this.selectedLayer?.type === 'text' && !this.selectedLayer.copy) {
396
+ this.removeTemplateLayer(this.selectedLayer);
397
+ }
398
+ this.addedFromCanvas = false;
399
+ },
358
400
  saveLayersAsImage() {
359
401
  const image = this.fabricHelper.getLayersAsImage();
360
402
  this.setLayersThumbnail({ side: this.side, value: image });
361
403
  },
362
404
  createTextLayer() {
405
+ this.addedFromCanvas = true;
363
406
  window.scrollTo(0, 0);
364
407
  this.createLayer({ type: 'text', isEditMode: true });
365
408
  this.visibleWireframe = true;
366
409
  },
410
+ async handleUploaded({ url, size, fileName }) {
411
+ window.scrollTo(0, 0);
412
+ await this.createLayer({ type: 'art', url, size, fileName });
413
+ this.visibleWireframe = true;
414
+ },
367
415
  setDeleteButtonPosition(pos) {
368
416
  this.deleteButtonPos = pos;
369
417
  },
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="error-404">
3
3
  <div class="mt-10 mb-10 image">
4
- <img src="/images/tee.svg" width="250px" />
4
+ <img src="~static/images/tee.svg" width="250px" />
5
5
  <div class="code">
6
6
  404
7
7
  </div>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="error-500">
3
3
  <div class="mt-10 mb-10 image">
4
- <img src="/images/tee.svg" width="250px" />
4
+ <img src="~static/images/tee.svg" width="250px" />
5
5
  <div class="code">
6
6
  500
7
7
  </div>
@@ -19,6 +19,9 @@
19
19
  img {
20
20
  margin-right: 10px;
21
21
  }
22
+ a {
23
+ color: $gray_main;
24
+ }
22
25
  }
23
26
  }
24
27
  &__footer {
@@ -10,56 +10,60 @@
10
10
  <div
11
11
  v-if="addedToCart"
12
12
  class="EditorPricing__main-alert">
13
- <img src="/images/smile.svg" />
13
+ <img src="~static/images/smile.svg" />
14
14
  Products have been added to cart
15
15
  </div>
16
16
 
17
17
  <div
18
18
  v-else-if="!hasUsedSimpleProducts && (!layers.length && isPrintPricing)"
19
19
  class="EditorPricing__main-alert">
20
- <img src="/images/sad.svg" />
20
+ <img src="~static/images/sad.svg" />
21
21
  No products selected and no prints defined
22
22
  </div>
23
23
 
24
24
  <div
25
25
  v-else-if="hasUsedSimpleProducts && ((!isValidPrintOnly || !layers.length && isPrintPricing))"
26
26
  class="EditorPricing__main-alert">
27
- <img src="/images/sad.svg" />
27
+ <img src="~static/images/sad.svg" />
28
28
  No prints defined
29
29
  </div>
30
30
 
31
31
  <div
32
32
  v-else-if="!hasUsedSimpleProducts && layers.length"
33
33
  class="EditorPricing__main-alert">
34
- <img src="/images/sad.svg" />
35
- No products selected to view price
34
+ <img src="~static/images/sad.svg" />
35
+ <a
36
+ href="#"
37
+ @click.prevent.stop="$emit('choose-products')">
38
+ Choose products here to continue
39
+ </a>
36
40
  </div>
37
41
 
38
42
  <div
39
43
  v-else-if="!isValidMiltipackOrderQuantity"
40
44
  class="EditorPricing__main-alert">
41
- <img src="/images/sad.svg" />
45
+ <img src="~static/images/sad.svg" />
42
46
  bulk pack {{ multipack.qty }} - add more x {{ multipack.qty - usedSimpleProductsQuantity }}
43
47
  </div>
44
48
 
45
49
  <div
46
50
  v-else-if="!isValidOrderQuantity && isValidBigSizeOrderQuantity && minimumOrderQuantity > 1"
47
51
  class="EditorPricing__main-alert">
48
- <img src="/images/sad.svg" />
52
+ <img src="~static/images/sad.svg" />
49
53
  Minimum order of these items must be {{ minimumOrderQuantity }} or more
50
54
  </div>
51
55
 
52
56
  <div
53
57
  v-else-if="!isValidBigSizeOrderQuantity"
54
58
  class="EditorPricing__main-alert">
55
- <img src="/images/sad.svg" />
59
+ <img src="~static/images/sad.svg" />
56
60
  Minimum order of 5XL-7XL should be 50%
57
61
  </div>
58
62
 
59
63
  <div
60
64
  v-else-if="isValidOrderQuantity"
61
65
  class="EditorPricing__main-alert">
62
- <img src="/images/smile.svg" />
66
+ <img src="~static/images/smile.svg" />
63
67
  All good to go!
64
68
  </div>
65
69
 
@@ -0,0 +1,90 @@
1
+ @import "@/assets/scss/variables";
2
+
3
+ .Brands {
4
+ &__main {
5
+ position: relative;
6
+ display: flex;
7
+ justify-content: space-between;
8
+ @media (max-width: $bp-extra-small-max) {
9
+ margin-top: 40px;
10
+ }
11
+ @media (max-width: $bp-small-max) {
12
+ flex-direction: column;
13
+ align-items: center;
14
+ }
15
+ }
16
+ &__items {
17
+ display: flex;
18
+ flex-wrap: wrap;
19
+ justify-content: space-between;
20
+ margin-top: 40px;
21
+ @media (max-width: $bp-medium-max) {
22
+ margin-top: 20px;
23
+ }
24
+ @media (max-width: $bp-extra-small-max) {
25
+ justify-content: space-around;
26
+ }
27
+ }
28
+ &__brand-item {
29
+ width: 280px;
30
+ height: 160px;
31
+ @media (max-width: $bp-medium-max) {
32
+ width: 240px;
33
+ height: 140px;
34
+ }
35
+ @media (max-width: $bp-small-max) {
36
+ width: 200px;
37
+ height: 120px;
38
+ }
39
+ @media (max-width: $bp-extra-small-max) {
40
+ width: 180px;
41
+ height: 90px;
42
+ }
43
+ @media (max-width: $bp-mini-max) {
44
+ width: 155px;
45
+ }
46
+ background-color: rgba(242, 242, 247, 1);
47
+ margin: 8px 0;
48
+ text-indent: -9999px;
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ &-logo {
53
+ display: block;
54
+ width: 153px;
55
+ height: 100px;
56
+ @media (max-width: $bp-extra-small-max) {
57
+ width: 123px;
58
+ height: 70px;
59
+ }
60
+ background-position: center;
61
+ background-repeat: no-repeat;
62
+ background-size: contain;
63
+ }
64
+ }
65
+ &__control {
66
+ margin-top: 10px;
67
+ position: absolute;
68
+ top: 0;
69
+ right: 0;
70
+ a {
71
+ font-size: 24px;
72
+ font-weight: 700;
73
+ line-height: 31.2px;
74
+ letter-spacing: -0.005em;
75
+ color: $purple;
76
+ }
77
+ }
78
+ &__brands-image {
79
+ margin-top: 80px;
80
+ @media (max-width: $bp-medium-max) {
81
+ margin-top: 70px;
82
+ }
83
+ @media (max-width: $bp-small-max) {
84
+ margin-bottom: 70px;
85
+ }
86
+ img {
87
+ width: 100%;
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <div class="Brands__wrapper content-inner">
3
+ <div class="Brands__main">
4
+ <div
5
+ data-aos="fade-left"
6
+ class="Brands__items-wrapper Brands__brands">
7
+ <div class="Brands__title lc_h2">
8
+ Brands
9
+ </div>
10
+ <div class="Brands__items">
11
+ <nuxt-link
12
+ v-for="brand in brands"
13
+ :key="brand._id"
14
+ :to="brandLink(brand)"
15
+ :title="brand.name"
16
+ class="Brands__brand-item">
17
+ <span
18
+ class="Brands__brand-item-logo"
19
+ :style="{
20
+ 'background-image': brandBackgroundImage(brand)
21
+ }">
22
+ </span>
23
+ </nuxt-link>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <script>
31
+ import { mapActions, mapGetters } from 'vuex';
32
+ import { generateProductsLink } from '@lancom/shared/assets/js/utils/product';
33
+ import { staticLink } from '@lancom/shared/assets/js/utils/filters';
34
+
35
+ export default {
36
+ name: 'Brands',
37
+ fetch() {
38
+ return Promise.all([
39
+ this.fetchBrands(this.shop._id)
40
+ ]);
41
+ },
42
+ computed: {
43
+ ...mapGetters(['shop']),
44
+ ...mapGetters('products', [
45
+ 'brands'
46
+ ])
47
+ },
48
+ methods: {
49
+ ...mapActions('products', [
50
+ 'fetchBrands'
51
+ ]),
52
+ brandLink({ alias: brand }) {
53
+ return generateProductsLink(null, { brand });
54
+ },
55
+ brandBackgroundImage(brand) {
56
+ const link = staticLink(brand.logo);
57
+ return link ? `url("${link}")` : null;
58
+ }
59
+ }
60
+ };
61
+ </script>
62
+
63
+ <style lang="scss" scoped>
64
+ @import 'brands';
65
+ </style>
@@ -28,6 +28,9 @@
28
28
  font-size: 13px;
29
29
  text-decoration: none;
30
30
  }
31
+ a:hover {
32
+ font-weight: bold;
33
+ }
31
34
  }
32
35
  &-all {
33
36
  border-top: 1px solid $gray_main;
@@ -28,13 +28,6 @@
28
28
  <spinner v-if="searching" />
29
29
  </div>
30
30
  <div v-if="hasProducts">
31
- <div class="ProductsAutocomplete__result-item">
32
- <a
33
- class="ProductsAutocomplete__result-item-all"
34
- :href="fullSearchLink">
35
- click to see all results
36
- </a>
37
- </div>
38
31
  <products-autocomplete-item
39
32
  v-for="product of products"
40
33
  :key="product._id"
@@ -42,6 +35,13 @@
42
35
  :product="product"
43
36
  class="ProductsAutocomplete__result-item"
44
37
  @select="$emit('select', product)" />
38
+ <div class="ProductsAutocomplete__result-item">
39
+ <a
40
+ class="ProductsAutocomplete__result-item-all"
41
+ :href="fullSearchLink">
42
+ more
43
+ </a>
44
+ </div>
45
45
  </div>
46
46
  </div>
47
47
  </div>
@@ -10,7 +10,7 @@
10
10
  </slot>
11
11
  <slot name="description">
12
12
  <div class="Subscribe__description lc_regular16">
13
- Sign up for new product relesses, free design rescurrces, and a chance to win 36 free custom printed shirts.
13
+ Sign up for new product releases, free design resources, tips to grow your brand and promo sale events
14
14
  </div>
15
15
  </slot>
16
16
  </div>
@@ -38,6 +38,9 @@ export default {
38
38
  isValidMiltipackOrderQuantity() {
39
39
  return !this.multipack || this.multipack.qty <= this.usedSimpleProductsQuantity;
40
40
  },
41
+ needToAddProducts() {
42
+ return !this.usedSimpleProducts.length;
43
+ },
41
44
  addToCartDisabled() {
42
45
  return !((this.template.layers.length || !this.isPrintPricing) && this.usedSimpleProducts.length) || this.calculatingPrice || !this.isValidOrderQuantity || !this.isValidPrintOnly;
43
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.336",
3
+ "version": "0.0.337",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
package/store/product.js CHANGED
@@ -370,7 +370,7 @@ export const mutations = {
370
370
  layer
371
371
  ];
372
372
  state.template = { ...state.template, layers };
373
- if (layers.length === 1 && !state.product.printOnly) {
373
+ if (layers.length >= 1) {
374
374
  // const printType = state.product.printTypes[0];
375
375
  // state.selectedPrintType = printType;
376
376
  state.isPrintPricing = true;
@@ -382,7 +382,7 @@ export const mutations = {
382
382
  if (state.selectedLayer && state.selectedLayer.createdAt === layer.createdAt) {
383
383
  state.selectedLayer = null;
384
384
  }
385
- if (state.template.layers.length === 0 && !state.product.printOnly) {
385
+ if (state.template.layers.length === 0) {
386
386
  // state.selectedPrintType = null;
387
387
  state.isPrintPricing = false;
388
388
  }
package/store/products.js CHANGED
@@ -38,7 +38,7 @@ export const getters = {
38
38
 
39
39
  export const actions = {
40
40
  async fetchBrands({ commit }, shop) {
41
- const brands = await api.fetchProductsBrands(shop, { limit: 10 });
41
+ const brands = await api.fetchProductsBrands(shop, { limit: 100 });
42
42
  commit('setBrands', brands);
43
43
  },
44
44
  async fetchTypes({ commit }, shop) {