@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.
- package/assets/js/utils/colors.js +3 -3
- package/assets/js/utils/fabric/selection-style.js +2 -1
- package/assets/js/utils/prints.js +1 -1
- package/components/checkout/cart/cart.vue +2 -2
- package/components/checkout/cart/cart_entity/cart_entity_color_simple_products/cart-entity-color-simple-products.vue +2 -0
- package/components/checkout/order/order-success/order-success.vue +1 -1
- package/components/common/client_settings/client-settings.scss +4 -4
- package/components/common/client_settings/client-settings.vue +5 -1
- package/components/common/pricing_table/pricing-table.scss +3 -0
- package/components/common/product_side_with_print/product-side-with-print.scss +3 -0
- package/components/common/product_side_with_print/product-side-with-print.vue +5 -1
- package/components/customer/customer_menu/customer-menu.scss +9 -3
- package/components/customer/customer_menu/customer-menu.vue +26 -3
- package/components/editor/editor.vue +7 -0
- package/components/editor/editor_layers/editor-layers.vue +2 -1
- package/components/editor/editor_product_details/editor-product-details.scss +4 -1
- package/components/editor/editor_product_details/editor-product-details.vue +1 -0
- package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.scss +35 -10
- package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.vue +50 -2
- package/components/errors/404.vue +1 -1
- package/components/errors/500.vue +1 -1
- package/components/product/editor_pricing/editor-pricing.scss +3 -0
- package/components/product/editor_pricing/editor-pricing.vue +13 -9
- package/components/products/brands/brands.scss +90 -0
- package/components/products/brands/brands.vue +65 -0
- package/components/products/products_autocomplete/products-autocomplete.scss +3 -0
- package/components/products/products_autocomplete/products-autocomplete.vue +7 -7
- package/components/subscribe/subscribe.vue +1 -1
- package/mixins/add-to-cart.js +3 -0
- package/package.json +1 -1
- package/store/product.js +2 -2
- 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(
|
|
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>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
min-width: 72px;
|
|
9
9
|
width: 33%;
|
|
10
10
|
height: 100%;
|
|
11
|
-
border-radius:
|
|
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:
|
|
56
|
-
width:
|
|
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:
|
|
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
|
},
|
|
@@ -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:
|
|
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:
|
|
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: $
|
|
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
|
|
27
|
+
<a
|
|
28
|
+
href="/customer/settings"
|
|
29
|
+
class="CustomerMenu__field-item">
|
|
30
|
+
Settings
|
|
31
|
+
</a>
|
|
27
32
|
</div>
|
|
28
33
|
<div>
|
|
29
|
-
<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 }"
|
|
@@ -58,13 +58,16 @@
|
|
|
58
58
|
display: inline-block;
|
|
59
59
|
}
|
|
60
60
|
&__prints-table {
|
|
61
|
-
width:
|
|
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;
|
|
@@ -58,28 +58,27 @@
|
|
|
58
58
|
}
|
|
59
59
|
&__placeholder {
|
|
60
60
|
position: absolute;
|
|
61
|
-
cursor: pointer;
|
|
62
61
|
z-index: 999;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
background-repeat: no-repeat;
|
|
66
|
-
background-position: center;
|
|
67
|
-
|
|
62
|
+
text-align: center;
|
|
63
|
+
|
|
68
64
|
--placeholder-width: 140px;
|
|
69
|
-
--placeholder-height:
|
|
65
|
+
--placeholder-height: 100px;
|
|
70
66
|
|
|
71
67
|
@media (max-width: $bp-extra-small-max) {
|
|
72
68
|
--placeholder-width: 70px;
|
|
73
|
-
--placeholder-height:
|
|
69
|
+
--placeholder-height: 50px;
|
|
70
|
+
font-size: 10px;
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
&.tighten {
|
|
77
74
|
--placeholder-width: 70px;
|
|
78
|
-
--placeholder-height:
|
|
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:
|
|
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
|
-
|
|
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
|
},
|
|
@@ -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
|
-
|
|
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,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
|
|
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>
|
package/mixins/add-to-cart.js
CHANGED
|
@@ -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
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
|
|
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
|
|
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:
|
|
41
|
+
const brands = await api.fetchProductsBrands(shop, { limit: 100 });
|
|
42
42
|
commit('setBrands', brands);
|
|
43
43
|
},
|
|
44
44
|
async fetchTypes({ commit }, shop) {
|