@lancom/shared 0.0.340 → 0.0.342
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/api/admin.js +3 -0
- package/components/common/client_settings/client-settings.vue +3 -3
- package/components/common/file_uploader.vue +49 -19
- package/components/common/rich-text.vue +69 -3
- package/components/editor/editor_product_details/editor-product-details.scss +41 -15
- package/components/editor/editor_product_details/editor-product-details.vue +3 -2
- package/components/editor/editor_workspace/editor-workspace.scss +4 -4
- package/components/editor/editor_workspace/editor-workspace.vue +64 -8
- package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.scss +9 -4
- package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.vue +13 -19
- package/components/editor/mobile_editor_product_details/mobile-editor-product-details.scss +13 -0
- package/components/editor/mobile_editor_product_details/mobile-editor-product-details.vue +48 -17
- package/components/product/editor_pricing/editor-pricing.vue +7 -1
- package/components/products/product_list_product/product-list-product.vue +2 -2
- package/package.json +1 -1
- package/store/auth.js +2 -2
package/assets/js/api/admin.js
CHANGED
|
@@ -456,6 +456,9 @@ export default {
|
|
|
456
456
|
runGrabber(grabber) {
|
|
457
457
|
return _post(`admin/grabbers/${grabber._id}/run`, grabber);
|
|
458
458
|
},
|
|
459
|
+
getGrabberSKUVariants(grabber) {
|
|
460
|
+
return _post(`admin/grabbers/${grabber._id}/sku-variants`, grabber);
|
|
461
|
+
},
|
|
459
462
|
removeGrabber(id) {
|
|
460
463
|
return _delete(`admin/grabbers/${id}`);
|
|
461
464
|
},
|
|
@@ -109,7 +109,7 @@ export default {
|
|
|
109
109
|
},
|
|
110
110
|
mounted() {
|
|
111
111
|
if (this.country) {
|
|
112
|
-
Cookie.set('country', this.country._id);
|
|
112
|
+
Cookie.set('country', this.country._id, { expires: 365 });
|
|
113
113
|
}
|
|
114
114
|
},
|
|
115
115
|
methods: {
|
|
@@ -123,11 +123,11 @@ export default {
|
|
|
123
123
|
this.visibleCurrencies = !this.visibleCurrencies;
|
|
124
124
|
},
|
|
125
125
|
selectCountry(country) {
|
|
126
|
-
Cookie.set('country', country._id);
|
|
126
|
+
Cookie.set('country', country._id, { expires: 365 });
|
|
127
127
|
window.location.reload();
|
|
128
128
|
},
|
|
129
129
|
selectCurrency(currency) {
|
|
130
|
-
Cookie.set('currency', currency._id);
|
|
130
|
+
Cookie.set('currency', currency._id, { expires: 365 });
|
|
131
131
|
window.location.reload();
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<
|
|
11
|
-
|
|
2
|
+
<div>
|
|
3
|
+
<div
|
|
4
|
+
class="FileUploader__wrapper"
|
|
5
|
+
:class="[error ? 'error' : '', dragging ? 'active' : '']"
|
|
6
|
+
@dragenter="dragging=true"
|
|
7
|
+
@dragend="dragging=false"
|
|
8
|
+
@dragleave="dragging=false"
|
|
9
|
+
@drop="dragging=false">
|
|
10
|
+
<div class="FileUploader__dropzone">
|
|
11
|
+
<slot name="toggle" :uploading="uploading"></slot>
|
|
12
|
+
<slot name="progress" :progress="progress"></slot>
|
|
13
|
+
<input
|
|
14
|
+
ref="fileUploaderField"
|
|
15
|
+
class="FileUploader__input"
|
|
16
|
+
type="file"
|
|
17
|
+
:class="{ disabled: disabled || uploading }"
|
|
18
|
+
:multiple="multiple"
|
|
19
|
+
:accept="accept"
|
|
20
|
+
:required="required"
|
|
21
|
+
:disabled="disabled || uploading"
|
|
22
|
+
@change="fileChange" />
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<div v-if="hasUploadLink">
|
|
12
26
|
<input
|
|
13
|
-
ref="
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
:accept="accept"
|
|
19
|
-
:required="required"
|
|
20
|
-
:disabled="disabled || uploading"
|
|
21
|
-
@change="fileChange" />
|
|
27
|
+
ref="fileLink"
|
|
28
|
+
type="text"
|
|
29
|
+
placeholder="Link"
|
|
30
|
+
class="form-control"
|
|
31
|
+
@change="onPastLink($event)" />
|
|
22
32
|
</div>
|
|
23
33
|
</div>
|
|
24
34
|
</template>
|
|
@@ -35,6 +45,7 @@ export default {
|
|
|
35
45
|
required: { type: Boolean, default: false },
|
|
36
46
|
disabled: { type: Boolean, default: false },
|
|
37
47
|
multiple: { type: Boolean, default: false },
|
|
48
|
+
hasUploadLink: { type: Boolean, default: false },
|
|
38
49
|
hasConversionErrorModal: { type: Boolean, default: true },
|
|
39
50
|
showErrorMessage: { type: Boolean, default: true },
|
|
40
51
|
url: { type: String },
|
|
@@ -52,6 +63,25 @@ export default {
|
|
|
52
63
|
};
|
|
53
64
|
},
|
|
54
65
|
methods: {
|
|
66
|
+
async onPastLink(event) {
|
|
67
|
+
const url = event.target.value?.trim();
|
|
68
|
+
if (!url) return;
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const response = await fetch(url);
|
|
72
|
+
const blob = await response.blob();
|
|
73
|
+
const file = new File([blob], 'image.jpg', { type: blob.type });
|
|
74
|
+
await this.readAndUploadFile(file);
|
|
75
|
+
} catch (e) {
|
|
76
|
+
if (this.showErrorMessage) {
|
|
77
|
+
this.$toastr.e('Failed to load image from URL');
|
|
78
|
+
} else {
|
|
79
|
+
this.$emit('onerror', e);
|
|
80
|
+
}
|
|
81
|
+
} finally {
|
|
82
|
+
event.target.value = '';
|
|
83
|
+
}
|
|
84
|
+
},
|
|
55
85
|
async fileChange(ev) {
|
|
56
86
|
this.uploading = true;
|
|
57
87
|
const files = Array.from(ev.target.files);
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
<div class="RichText__wrapper">
|
|
3
|
+
<div
|
|
4
|
+
ref="text"
|
|
5
|
+
class="RichText__text"
|
|
6
|
+
:class="{ 'RichText__text--short': shortView && !expanded }"
|
|
7
|
+
:style="shortView && !expanded ? `max-height: ${height}px` : ''"
|
|
8
|
+
v-html="text"></div>
|
|
9
|
+
<div
|
|
10
|
+
v-if="shortView && shouldShowMore"
|
|
11
|
+
class="RichText__show-more"
|
|
12
|
+
@click="expanded = !expanded">
|
|
13
|
+
{{ expanded ? 'Hide full' : 'Show full' }}
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
5
16
|
</template>
|
|
6
17
|
|
|
7
18
|
<script>
|
|
@@ -10,7 +21,29 @@ export default {
|
|
|
10
21
|
props: {
|
|
11
22
|
text: {
|
|
12
23
|
type: String
|
|
24
|
+
},
|
|
25
|
+
shortView: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: false
|
|
28
|
+
},
|
|
29
|
+
height: {
|
|
30
|
+
type: Number,
|
|
31
|
+
default: 100
|
|
13
32
|
}
|
|
33
|
+
},
|
|
34
|
+
data() {
|
|
35
|
+
return {
|
|
36
|
+
expanded: false,
|
|
37
|
+
shouldShowMore: false
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
mounted() {
|
|
41
|
+
this.$nextTick(() => {
|
|
42
|
+
if (this.shortView) {
|
|
43
|
+
const textHeight = this.$refs.text.scrollHeight;
|
|
44
|
+
this.shouldShowMore = textHeight > this.height;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
14
47
|
}
|
|
15
48
|
};
|
|
16
49
|
</script>
|
|
@@ -19,11 +52,44 @@ export default {
|
|
|
19
52
|
|
|
20
53
|
.RichText {
|
|
21
54
|
&__wrapper {
|
|
55
|
+
position: relative
|
|
56
|
+
}
|
|
57
|
+
&__text {
|
|
22
58
|
@import "@lancom/shared/assets/scss/normalize";
|
|
23
59
|
letter-spacing: -0.02em !important;
|
|
24
60
|
p {
|
|
25
61
|
margin: 10px 0;
|
|
26
62
|
}
|
|
63
|
+
|
|
64
|
+
&--short {
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
position: relative;
|
|
67
|
+
|
|
68
|
+
&:after {
|
|
69
|
+
content: '';
|
|
70
|
+
position: absolute;
|
|
71
|
+
bottom: 0;
|
|
72
|
+
left: 0;
|
|
73
|
+
width: 100%;
|
|
74
|
+
height: 40px;
|
|
75
|
+
background: linear-gradient(transparent, white);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
&__show-more {
|
|
80
|
+
color: $grey_1;
|
|
81
|
+
cursor: pointer;
|
|
82
|
+
margin-top: 10px;
|
|
83
|
+
display: inline-block;
|
|
84
|
+
border-bottom: 1px dashed $grey_1;
|
|
85
|
+
position: absolute;
|
|
86
|
+
right: 0px;
|
|
87
|
+
bottom: 10px;
|
|
88
|
+
font-size: 12px;
|
|
89
|
+
|
|
90
|
+
&:hover {
|
|
91
|
+
color: $black;
|
|
92
|
+
}
|
|
27
93
|
}
|
|
28
94
|
}
|
|
29
95
|
</style>
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
@import "@/assets/scss/variables";
|
|
2
2
|
|
|
3
3
|
.EditorProductDetails {
|
|
4
|
+
&__name {
|
|
5
|
+
@media (max-width: $bp-extra-small-max) {
|
|
6
|
+
line-height: 30px;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
4
9
|
&__wrapper {
|
|
5
10
|
padding-top: 36px;
|
|
11
|
+
@media (max-width: $bp-extra-small-max) {
|
|
12
|
+
padding-top: 0px;
|
|
13
|
+
margin-top: -10px;
|
|
14
|
+
}
|
|
6
15
|
}
|
|
7
16
|
&__description {
|
|
8
17
|
margin-top: 15px;
|
|
@@ -15,9 +24,14 @@
|
|
|
15
24
|
@media (max-width: $bp-extra-small-max) {
|
|
16
25
|
flex-direction: column;
|
|
17
26
|
align-items: start;
|
|
18
|
-
|
|
27
|
+
padding-left: 155px;
|
|
28
|
+
position: relative;
|
|
29
|
+
margin-bottom: 10px;
|
|
19
30
|
}
|
|
20
31
|
&-logo {
|
|
32
|
+
@media (max-width: $bp-extra-small-max) {
|
|
33
|
+
margin-top: 3px;
|
|
34
|
+
}
|
|
21
35
|
img {
|
|
22
36
|
max-width: 75px;
|
|
23
37
|
max-height: 55px;
|
|
@@ -28,6 +42,7 @@
|
|
|
28
42
|
flex-grow: 1;
|
|
29
43
|
@media (max-width: $bp-extra-small-max) {
|
|
30
44
|
margin-left: 0px;
|
|
45
|
+
margin-top: -5px;
|
|
31
46
|
}
|
|
32
47
|
}
|
|
33
48
|
&-row {
|
|
@@ -106,20 +121,31 @@
|
|
|
106
121
|
padding: 10px;
|
|
107
122
|
cursor: pointer;
|
|
108
123
|
}
|
|
109
|
-
&__quote
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
background-color: $
|
|
122
|
-
|
|
124
|
+
&__quote {
|
|
125
|
+
@media (max-width: $bp-extra-small-max) {
|
|
126
|
+
position: absolute;
|
|
127
|
+
left: 0px;
|
|
128
|
+
top: 0px;
|
|
129
|
+
}
|
|
130
|
+
&-botton {
|
|
131
|
+
font-weight: 800;
|
|
132
|
+
font-size: 14px;
|
|
133
|
+
line-height: 19px;
|
|
134
|
+
text-align: center;
|
|
135
|
+
color: $black;
|
|
136
|
+
background-color: $green;
|
|
137
|
+
text-transform: uppercase;
|
|
138
|
+
padding: 4px 15px;
|
|
139
|
+
margin-top: 7px;
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
@media (max-width: $bp-extra-small-max) {
|
|
142
|
+
padding: 12px 15px;
|
|
143
|
+
margin-top: 5px;
|
|
144
|
+
}
|
|
145
|
+
&:hover {
|
|
146
|
+
background-color: $black;
|
|
147
|
+
color: $white;
|
|
148
|
+
}
|
|
123
149
|
}
|
|
124
150
|
}
|
|
125
151
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="EditorProductDetails__wrapper">
|
|
3
|
-
<h3 class="lc_h3 lc_black">
|
|
3
|
+
<h3 class="lc_h3 lc_black EditorProductDetails__name">
|
|
4
4
|
{{ product.name }}
|
|
5
5
|
</h3>
|
|
6
6
|
<div class="EditorProductDetails__header">
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</span>
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
25
|
-
<div>
|
|
25
|
+
<div class="EditorProductDetails__quote">
|
|
26
26
|
<div
|
|
27
27
|
class="EditorProductDetails__quote-botton"
|
|
28
28
|
@click="showQuoteRequestModal()">
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
class="EditorProductDetails__description">
|
|
103
103
|
<rich-text
|
|
104
104
|
:text="product.description"
|
|
105
|
+
:short-view="true"
|
|
105
106
|
class="EditorProductDetails__description-text" />
|
|
106
107
|
</div>
|
|
107
108
|
<div class="EditorProductDetails__product-image">
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
height: 290px;
|
|
25
25
|
max-width: 100%;
|
|
26
26
|
@media (min-width: $bp-extra-small-min) {
|
|
27
|
-
width:
|
|
28
|
-
height:
|
|
27
|
+
width: 400px;
|
|
28
|
+
height: 400px;
|
|
29
29
|
}
|
|
30
30
|
@media (min-width: $bp-small-min) {
|
|
31
31
|
width: 580px;
|
|
@@ -124,13 +124,13 @@
|
|
|
124
124
|
|
|
125
125
|
&--bottom {
|
|
126
126
|
position: fixed;
|
|
127
|
-
bottom:
|
|
127
|
+
bottom: 130px;
|
|
128
128
|
left: 0;
|
|
129
129
|
right: 0;
|
|
130
130
|
background-color: white;
|
|
131
131
|
width: auto;
|
|
132
132
|
padding: 0 10px;
|
|
133
|
-
z-index:
|
|
133
|
+
z-index: 9999;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -48,8 +48,9 @@
|
|
|
48
48
|
<div
|
|
49
49
|
class="EditorWorkspace__sides-container"
|
|
50
50
|
:class="{
|
|
51
|
-
'EditorWorkspace__sides-container--zoom-in': isZoomIn
|
|
52
|
-
}"
|
|
51
|
+
'EditorWorkspace__sides-container--zoom-in': zoomPrintArea || isZoomIn
|
|
52
|
+
}"
|
|
53
|
+
:style="printAreaZoomInStyles">
|
|
53
54
|
<div
|
|
54
55
|
v-if="editableSide && editableColor"
|
|
55
56
|
class="EditorWorkspace__sides rotate-y-container"
|
|
@@ -66,16 +67,17 @@
|
|
|
66
67
|
:print-area="editablePrintArea"
|
|
67
68
|
:print-area-size="selectedPrintArea"
|
|
68
69
|
:class="editableSide.id"
|
|
69
|
-
:zoom-size="
|
|
70
|
+
:zoom-size="sideZoomSize"
|
|
70
71
|
class="EditorWorkspace__side rotate-y-element"
|
|
71
|
-
@zoom-in="zoomIn()"
|
|
72
|
+
@zoom-in="zoomIn()"
|
|
73
|
+
@workspace="onWorkspaceChange($event)">
|
|
72
74
|
</editor-workspace-side>
|
|
73
75
|
</transition>
|
|
74
76
|
</div>
|
|
75
77
|
<div
|
|
76
78
|
class="EditorWorkspace__sides-toggle"
|
|
77
79
|
:class="{
|
|
78
|
-
'EditorWorkspace__sides-toggle--fixed': isZoomIn
|
|
80
|
+
'EditorWorkspace__sides-toggle--fixed': zoomPrintArea || isZoomIn
|
|
79
81
|
}"
|
|
80
82
|
@click="toggleSide()">
|
|
81
83
|
<i class="icon-rotate-tee"></i>
|
|
@@ -92,7 +94,7 @@
|
|
|
92
94
|
<div
|
|
93
95
|
class="EditorWorkspace__print-area-options"
|
|
94
96
|
:class="{
|
|
95
|
-
'EditorWorkspace__print-area-options--bottom': isZoomIn
|
|
97
|
+
'EditorWorkspace__print-area-options--bottom': zoomPrintArea || isZoomIn
|
|
96
98
|
}">
|
|
97
99
|
<editor-print-area-options
|
|
98
100
|
v-if="productDetailsLoaded"
|
|
@@ -130,6 +132,8 @@ export default {
|
|
|
130
132
|
},
|
|
131
133
|
data() {
|
|
132
134
|
return {
|
|
135
|
+
size: null,
|
|
136
|
+
fabricHelper: null,
|
|
133
137
|
preloading: true,
|
|
134
138
|
isRotating: false,
|
|
135
139
|
zoomSize: null,
|
|
@@ -142,6 +146,12 @@ export default {
|
|
|
142
146
|
]
|
|
143
147
|
};
|
|
144
148
|
},
|
|
149
|
+
props: {
|
|
150
|
+
zoomPrintArea: {
|
|
151
|
+
type: Boolean,
|
|
152
|
+
default: false
|
|
153
|
+
}
|
|
154
|
+
},
|
|
145
155
|
computed: {
|
|
146
156
|
...mapGetters([
|
|
147
157
|
'product',
|
|
@@ -150,10 +160,52 @@ export default {
|
|
|
150
160
|
'editablePrintArea',
|
|
151
161
|
'editableSide',
|
|
152
162
|
'editableColor',
|
|
153
|
-
'editableLayers'
|
|
163
|
+
'editableLayers',
|
|
164
|
+
'editorSize'
|
|
154
165
|
]),
|
|
166
|
+
sideZoomSize() {
|
|
167
|
+
return this.printAreaZoomSize?.width || this.zoomSize;
|
|
168
|
+
},
|
|
155
169
|
isZoomIn() {
|
|
156
170
|
return !!this.zoomSize;
|
|
171
|
+
},
|
|
172
|
+
printAreaZoomInStyles() {
|
|
173
|
+
if (this.fabricHelper && this.zoomPrintArea) {
|
|
174
|
+
return {
|
|
175
|
+
width: `${this.printAreaZoomSize.width}px`,
|
|
176
|
+
height: `${this.printAreaZoomSize.height}px`,
|
|
177
|
+
left: `${this.printAreaZoomSize.left}px`,
|
|
178
|
+
top: `${this.printAreaZoomSize.top}px`
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {};
|
|
183
|
+
},
|
|
184
|
+
printAreaZoomSize() {
|
|
185
|
+
if (this.fabricHelper && this.zoomPrintArea) {
|
|
186
|
+
const { printAreaRect } = this.fabricHelper;
|
|
187
|
+
const printAreaWidth = printAreaRect.width;
|
|
188
|
+
const printAreaHeight = printAreaRect.height;
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
const targetWidth = this.editorSize.width * 0.6;
|
|
192
|
+
const targetHeight = this.editorSize.height * 0.6;
|
|
193
|
+
const scaleX = targetWidth / printAreaWidth;
|
|
194
|
+
const scale = scaleX;
|
|
195
|
+
|
|
196
|
+
const newWidth = this.editorSize.width * scale;
|
|
197
|
+
const newHeight = this.editorSize.height * scale;
|
|
198
|
+
|
|
199
|
+
const left = -printAreaRect.left * scale + (window.innerWidth - printAreaWidth * scale) / 2;
|
|
200
|
+
const top = -printAreaRect.top * scale + (window.innerHeight - 200 - printAreaHeight * scale) / 2;
|
|
201
|
+
return {
|
|
202
|
+
width: newWidth,
|
|
203
|
+
height: newHeight,
|
|
204
|
+
left,
|
|
205
|
+
top
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
157
209
|
}
|
|
158
210
|
},
|
|
159
211
|
mounted() {
|
|
@@ -165,7 +217,11 @@ export default {
|
|
|
165
217
|
'setSelectedPrintArea',
|
|
166
218
|
'setEditablePrintArea'
|
|
167
219
|
]),
|
|
168
|
-
|
|
220
|
+
onWorkspaceChange({ size, fabricHelper }) {
|
|
221
|
+
this.fabricHelper = fabricHelper;
|
|
222
|
+
this.size = size;
|
|
223
|
+
},
|
|
224
|
+
async preloadingEditor() {
|
|
169
225
|
this.preloading = true;
|
|
170
226
|
const sides = ['back', 'front'];
|
|
171
227
|
for (const side of sides) {
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
justify-content: center;
|
|
66
66
|
flex-direction: column;
|
|
67
67
|
|
|
68
|
-
@media (max-width: $bp-extra-small-max) {
|
|
69
|
-
|
|
70
|
-
}
|
|
68
|
+
// @media (max-width: $bp-extra-small-max) {
|
|
69
|
+
// font-size: 10px;
|
|
70
|
+
// }
|
|
71
71
|
|
|
72
72
|
&.tighten {
|
|
73
73
|
font-size: 10px;
|
|
@@ -131,10 +131,11 @@
|
|
|
131
131
|
right: 40px;
|
|
132
132
|
left: 40px;
|
|
133
133
|
z-index: 1;
|
|
134
|
-
|
|
135
134
|
@media (max-width: $bp-extra-small-max) {
|
|
136
135
|
left: 0;
|
|
137
136
|
right: 0;
|
|
137
|
+
top: -30px;
|
|
138
|
+
font-size: 12px;
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
&-warning,
|
|
@@ -144,6 +145,10 @@
|
|
|
144
145
|
border-radius: 5px;
|
|
145
146
|
color: #FFFFFF;
|
|
146
147
|
cursor: pointer;
|
|
148
|
+
@media (max-width: $bp-extra-small-max) {
|
|
149
|
+
font-size: 13px;
|
|
150
|
+
padding: 6px;
|
|
151
|
+
}
|
|
147
152
|
& + & {
|
|
148
153
|
margin-top: 3px;
|
|
149
154
|
}
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
v-if="fabricHelper"
|
|
37
37
|
class="EditorWorkspaceSide__placeholder"
|
|
38
38
|
:class="{
|
|
39
|
-
tighten: printAreaIsSmall,
|
|
39
|
+
tighten: !isZoomed && printAreaIsSmall,
|
|
40
40
|
side: printAreaLayers.length
|
|
41
41
|
}"
|
|
42
42
|
ignore-document-click
|
|
@@ -82,34 +82,27 @@
|
|
|
82
82
|
v-show="isVisibleOverlay"
|
|
83
83
|
class="EditorWorkspaceSide__overlay"
|
|
84
84
|
@mousedown="$emit('zoom-in')"></div>
|
|
85
|
-
<
|
|
86
|
-
name="fade"
|
|
87
|
-
appear
|
|
88
|
-
tag="div"
|
|
89
|
-
class="EditorWorkspaceSide__alert-container">
|
|
85
|
+
<div class="EditorWorkspaceSide__alert-container">
|
|
90
86
|
<div
|
|
91
87
|
v-if="showErrorAboutSmallImage"
|
|
92
|
-
|
|
93
|
-
class="EditorWorkspaceSide__alert-error view-transition"
|
|
88
|
+
class="EditorWorkspaceSide__alert-error"
|
|
94
89
|
@click="adjustSelectedArtDPI">
|
|
95
90
|
<i class="icon-attention-circled"></i>
|
|
96
91
|
Your image doesn't meet our print requirements.
|
|
97
92
|
</div>
|
|
98
93
|
<div
|
|
99
94
|
v-else-if="showRecommendationToUseLargerImage"
|
|
100
|
-
|
|
101
|
-
class="EditorWorkspaceSide__alert-warning view-transition">
|
|
95
|
+
class="EditorWorkspaceSide__alert-warning">
|
|
102
96
|
<i class="icon-info-circled"></i>
|
|
103
97
|
we recommend using a higher quality image.
|
|
104
98
|
</div>
|
|
105
99
|
<div
|
|
106
100
|
v-if="offsetWarningVisible"
|
|
107
|
-
|
|
108
|
-
class="EditorWorkspaceSide__alert-error view-transition">
|
|
101
|
+
class="EditorWorkspaceSide__alert-error">
|
|
109
102
|
<i class="icon-attention-circled"></i>
|
|
110
103
|
Part of your design layer is outside the print area.
|
|
111
104
|
</div>
|
|
112
|
-
</
|
|
105
|
+
</div>
|
|
113
106
|
</div>
|
|
114
107
|
</template>
|
|
115
108
|
|
|
@@ -238,7 +231,7 @@ export default {
|
|
|
238
231
|
return !!this.zoomSize;
|
|
239
232
|
},
|
|
240
233
|
isVisibleOverlay() {
|
|
241
|
-
return !this.isZoomed && this.breakpoints.is
|
|
234
|
+
return !this.isZoomed && [].includes(this.breakpoints.is);
|
|
242
235
|
}
|
|
243
236
|
},
|
|
244
237
|
watch: {
|
|
@@ -302,20 +295,21 @@ export default {
|
|
|
302
295
|
this.setSelectedLayerField({ field: 'scaleY', value: scale });
|
|
303
296
|
this.saveLayersAsImageWithDebounce();
|
|
304
297
|
},
|
|
305
|
-
calcWorkspaceSize() {
|
|
298
|
+
calcWorkspaceSize(skipZoom) {
|
|
306
299
|
const sizes = {
|
|
307
300
|
mini: 290,
|
|
308
|
-
xs:
|
|
301
|
+
xs: 400,
|
|
309
302
|
sm: 580,
|
|
310
303
|
md: 430,
|
|
311
304
|
lg: 600,
|
|
312
305
|
xl: 720
|
|
313
306
|
};
|
|
314
|
-
return this.zoomSize || sizes[this.breakpoints.is] || 430;
|
|
307
|
+
return (!skipZoom && this.zoomSize) || sizes[this.breakpoints.is] || 430;
|
|
315
308
|
},
|
|
316
309
|
handleWorkspaceSize() {
|
|
317
310
|
const size = this.calcWorkspaceSize();
|
|
318
311
|
this.fabricHelper.scaleWorkspace({ width: size, height: size });
|
|
312
|
+
this.$emit('workspace', { size: this.calcWorkspaceSize(true), fabricHelper: this.fabricHelper });
|
|
319
313
|
},
|
|
320
314
|
initEventsListeners() {
|
|
321
315
|
// document.addEventListener('mousedown', this.onDocumentStartClick);
|
|
@@ -434,7 +428,7 @@ export default {
|
|
|
434
428
|
this.offsetWarningVisible = visible;
|
|
435
429
|
},
|
|
436
430
|
toogleBoundBox(state, option) {
|
|
437
|
-
if (!this.fabricHelper || this.breakpoints.is
|
|
431
|
+
if (!this.fabricHelper || ['mini', 'xs'].includes(this.breakpoints.is)) {
|
|
438
432
|
return;
|
|
439
433
|
}
|
|
440
434
|
|
|
@@ -449,6 +443,6 @@ export default {
|
|
|
449
443
|
};
|
|
450
444
|
</script>
|
|
451
445
|
|
|
452
|
-
<style lang="scss"
|
|
446
|
+
<style lang="scss">
|
|
453
447
|
@import 'editor-workspace-side.scss';
|
|
454
448
|
</style>
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
@import "@lancom/shared/assets/scss/ui_kit";
|
|
3
3
|
|
|
4
4
|
.MobileEditorProductDetails {
|
|
5
|
+
&__info {
|
|
6
|
+
position: absolute;
|
|
7
|
+
top: -63px;
|
|
8
|
+
background: white;
|
|
9
|
+
left: 0;
|
|
10
|
+
right: 0;
|
|
11
|
+
}
|
|
5
12
|
&__menu {
|
|
6
13
|
position: fixed;
|
|
7
14
|
// right: 0;
|
|
@@ -36,6 +43,12 @@
|
|
|
36
43
|
color: $white_high_emphasis;
|
|
37
44
|
background-color: $green;
|
|
38
45
|
border-color: $green;
|
|
46
|
+
&.invalidate {
|
|
47
|
+
pointer-events: all !important;
|
|
48
|
+
border-color: $grey_4;
|
|
49
|
+
background-color: $grey_4;
|
|
50
|
+
color: $grey_1;
|
|
51
|
+
}
|
|
39
52
|
}
|
|
40
53
|
|
|
41
54
|
&.cart &-icon {
|
|
@@ -4,9 +4,23 @@
|
|
|
4
4
|
v-if="width"
|
|
5
5
|
class="MobileEditorProductDetails__menu"
|
|
6
6
|
:style="{ width, top }">
|
|
7
|
+
<editor-pricing
|
|
8
|
+
class="MobileEditorProductDetails__info"
|
|
9
|
+
:has-cart-btn="false"
|
|
10
|
+
:has-pricing="false"
|
|
11
|
+
@choose-products="chooseProducts()" />
|
|
7
12
|
<div
|
|
13
|
+
v-if="!!currentTab"
|
|
14
|
+
class="MobileEditorProductDetails__menu-action"
|
|
15
|
+
@click="hide()">
|
|
16
|
+
<i class="icon-blank MobileEditorProductDetails__menu-action-icon"></i>
|
|
17
|
+
<span class="MobileEditorProductDetails__menu-action-label">
|
|
18
|
+
Product
|
|
19
|
+
</span>
|
|
20
|
+
</div>
|
|
21
|
+
<div
|
|
22
|
+
v-if="currentTab !== 'details'"
|
|
8
23
|
class="MobileEditorProductDetails__menu-action"
|
|
9
|
-
:class="{ active: currentTab === 'details' }"
|
|
10
24
|
@click="show('details')">
|
|
11
25
|
<i class="icon-product MobileEditorProductDetails__menu-action-icon"></i>
|
|
12
26
|
<span class="MobileEditorProductDetails__menu-action-label">
|
|
@@ -14,8 +28,8 @@
|
|
|
14
28
|
</span>
|
|
15
29
|
</div>
|
|
16
30
|
<div
|
|
31
|
+
v-if="currentTab !== 'layers'"
|
|
17
32
|
class="MobileEditorProductDetails__menu-action"
|
|
18
|
-
:class="{ active: currentTab === 'layers' }"
|
|
19
33
|
@click="showLayers">
|
|
20
34
|
<i class="icon-edit MobileEditorProductDetails__menu-action-icon"></i>
|
|
21
35
|
<span class="MobileEditorProductDetails__menu-action-label">
|
|
@@ -52,24 +66,23 @@
|
|
|
52
66
|
key="container"
|
|
53
67
|
class="MobileEditorProductDetails__container"
|
|
54
68
|
@close="hide">
|
|
55
|
-
<div class="MobileEditorProductDetails__header">
|
|
56
|
-
<div
|
|
57
|
-
v-if="currentTab === 'details'"
|
|
58
|
-
class="MobileEditorProductDetails__header-title">
|
|
59
|
-
|
|
60
|
-
</div>
|
|
61
|
-
<div
|
|
62
|
-
v-if="currentTab === 'layers'"
|
|
63
|
-
class="MobileEditorProductDetails__header-title">
|
|
69
|
+
<div v-if="currentTab === 'layers'" class="MobileEditorProductDetails__header">
|
|
70
|
+
<div class="MobileEditorProductDetails__header-title">
|
|
64
71
|
Text & Art
|
|
65
72
|
</div>
|
|
66
|
-
<i
|
|
73
|
+
<!-- <i
|
|
67
74
|
class="icon-cancel MobileEditorProductDetails__close"
|
|
68
|
-
@click="hide"></i>
|
|
75
|
+
@click="hide"></i> -->
|
|
69
76
|
</div>
|
|
70
|
-
<div
|
|
71
|
-
|
|
72
|
-
<editor-
|
|
77
|
+
<div
|
|
78
|
+
class="MobileEditorProductDetails__content custom-scrollbar-container">
|
|
79
|
+
<editor-workspace
|
|
80
|
+
v-show="currentTab === 'details'"
|
|
81
|
+
:zoom-print-area="true"
|
|
82
|
+
style="margin-top: 40px;" />
|
|
83
|
+
<editor-layers
|
|
84
|
+
v-show="currentTab === 'layers'"
|
|
85
|
+
:hasPricing="false" />
|
|
73
86
|
</div>
|
|
74
87
|
</div>
|
|
75
88
|
</transition-group>
|
|
@@ -82,6 +95,7 @@ import { EventBus } from '@lancom/shared/assets/js/utils/event-bus';
|
|
|
82
95
|
import addToCartMixin from '@lancom/shared/mixins/add-to-cart';
|
|
83
96
|
import EditorWorkspace from '../editor_workspace/editor-workspace';
|
|
84
97
|
import EditorLayers from '../editor_layers/editor-layers';
|
|
98
|
+
import EditorPricing from '../../product/editor_pricing/editor-pricing';
|
|
85
99
|
|
|
86
100
|
const { mapMutations, mapGetters } = createNamespacedHelpers('product');
|
|
87
101
|
|
|
@@ -90,7 +104,8 @@ export default {
|
|
|
90
104
|
mixins: [addToCartMixin],
|
|
91
105
|
components: {
|
|
92
106
|
EditorWorkspace,
|
|
93
|
-
EditorLayers
|
|
107
|
+
EditorLayers,
|
|
108
|
+
EditorPricing
|
|
94
109
|
},
|
|
95
110
|
data() {
|
|
96
111
|
return {
|
|
@@ -114,6 +129,21 @@ export default {
|
|
|
114
129
|
},
|
|
115
130
|
methods: {
|
|
116
131
|
...mapMutations(['setEditModeSelectedLayer', 'removeTemplateLayer', 'setSelectedLayer']),
|
|
132
|
+
chooseProducts() {
|
|
133
|
+
this.hide();
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
const element = document.getElementById('EditorProductDetails');
|
|
136
|
+
if (element) {
|
|
137
|
+
const offset = 100;
|
|
138
|
+
const elementPosition = element.getBoundingClientRect().top;
|
|
139
|
+
const offsetPosition = elementPosition + window.pageYOffset - offset;
|
|
140
|
+
window.scrollTo({
|
|
141
|
+
top: offsetPosition,
|
|
142
|
+
behavior: 'smooth'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}, 250);
|
|
146
|
+
},
|
|
117
147
|
updateMobileMenuPosition() {
|
|
118
148
|
this.top = `${window.outerHeight - 78}px`;
|
|
119
149
|
this.width = `${window.outerWidth}px`;
|
|
@@ -147,6 +177,7 @@ export default {
|
|
|
147
177
|
},
|
|
148
178
|
async saveToCart() {
|
|
149
179
|
if (this.addToCartDisabled) {
|
|
180
|
+
this.$toastr.e(this.addToCartDisabledMessage);
|
|
150
181
|
return;
|
|
151
182
|
}
|
|
152
183
|
await this.proceedToCard();
|
|
@@ -67,7 +67,9 @@
|
|
|
67
67
|
All good to go!
|
|
68
68
|
</div>
|
|
69
69
|
|
|
70
|
-
<div
|
|
70
|
+
<div
|
|
71
|
+
v-if="hasPricing"
|
|
72
|
+
class="EditorPricing__footer">
|
|
71
73
|
<div class="EditorPricing__footer-section">
|
|
72
74
|
<i class="icon-close-r"></i>
|
|
73
75
|
<div class="EditorPricing__total">
|
|
@@ -128,6 +130,10 @@ export default {
|
|
|
128
130
|
hasCartBtn: {
|
|
129
131
|
type: Boolean,
|
|
130
132
|
default: true
|
|
133
|
+
},
|
|
134
|
+
hasPricing: {
|
|
135
|
+
type: Boolean,
|
|
136
|
+
default: true
|
|
131
137
|
}
|
|
132
138
|
},
|
|
133
139
|
computed: {
|
|
@@ -83,12 +83,12 @@
|
|
|
83
83
|
</div>
|
|
84
84
|
<div
|
|
85
85
|
v-if="minPrice === maxPrice"
|
|
86
|
-
class="ProductListProduct__info-item lc_h4">
|
|
86
|
+
class="ProductListProduct__info-item ProductListProduct__info-price lc_h4">
|
|
87
87
|
{{ minPrice | price(currency) }}
|
|
88
88
|
</div>
|
|
89
89
|
<div
|
|
90
90
|
v-else
|
|
91
|
-
class="ProductListProduct__info-item lc_h4">
|
|
91
|
+
class="ProductListProduct__info-item ProductListProduct__info-price lc_h4">
|
|
92
92
|
{{ minPrice | price(currency) }} - {{ maxPrice | price(currency) }}
|
|
93
93
|
</div>
|
|
94
94
|
<div class="ProductListProduct__info-item mt-2 lc_caption">
|
package/package.json
CHANGED
package/store/auth.js
CHANGED
|
@@ -30,7 +30,7 @@ export const actions = {
|
|
|
30
30
|
const request = customer ? api.authCustomer(customer, shop._id) : api.admin.authUser(user);
|
|
31
31
|
try {
|
|
32
32
|
const { token, user, customer } = await request;
|
|
33
|
-
Cookie.set('auth', token);
|
|
33
|
+
Cookie.set('auth', token, { expires: 365 });
|
|
34
34
|
this.$axios.defaults.headers.authorization = token;
|
|
35
35
|
commit('AUTH_SUCCESS', token, customer || user);
|
|
36
36
|
return customer || user;
|
|
@@ -44,7 +44,7 @@ export const actions = {
|
|
|
44
44
|
Cookie.remove('auth');
|
|
45
45
|
},
|
|
46
46
|
update_user({ commit }, { token, user }) {
|
|
47
|
-
Cookie.set('auth', token);
|
|
47
|
+
Cookie.set('auth', token, { expires: 365 });
|
|
48
48
|
this.$axios.defaults.headers.authorization = token;
|
|
49
49
|
commit('AUTH_SUCCESS', token, user);
|
|
50
50
|
}
|