@lancom/shared 0.0.475 → 0.0.478
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 +14 -2
- package/assets/js/api/index.js +3 -0
- package/assets/js/utils/colors.js +21 -1
- package/assets/js/utils/image.js +1 -1
- package/components/common/lancom-image.vue +12 -5
- package/components/products/products_autocomplete/products-autocomplete.vue +4 -3
- package/components/trade_account_request/trade-account-request.vue +524 -0
- package/mixins/product-preview.js +7 -1
- package/package.json +1 -1
package/assets/js/api/admin.js
CHANGED
|
@@ -296,8 +296,8 @@ export default {
|
|
|
296
296
|
removeUser(id) {
|
|
297
297
|
return _delete(`admin/user/${id}`);
|
|
298
298
|
},
|
|
299
|
-
fetchCustomers() {
|
|
300
|
-
return _get('admin/customers');
|
|
299
|
+
fetchCustomers(params) {
|
|
300
|
+
return _get('admin/customers', params);
|
|
301
301
|
},
|
|
302
302
|
fetchCustomerById(id) {
|
|
303
303
|
return _get(`admin/customer/${id}`);
|
|
@@ -398,6 +398,18 @@ export default {
|
|
|
398
398
|
removeContact(id) {
|
|
399
399
|
return _delete(`admin/contact/${id}`);
|
|
400
400
|
},
|
|
401
|
+
fetchTradeAccountRequests(params) {
|
|
402
|
+
return _get('admin/trade-account', params);
|
|
403
|
+
},
|
|
404
|
+
fetchTradeAccountRequestById(id) {
|
|
405
|
+
return _get(`admin/trade-account/${id}`);
|
|
406
|
+
},
|
|
407
|
+
saveTradeAccountRequest(item) {
|
|
408
|
+
return _put(`admin/trade-account/${item._id}`, item);
|
|
409
|
+
},
|
|
410
|
+
removeTradeAccountRequest(id) {
|
|
411
|
+
return _delete(`admin/trade-account/${id}`);
|
|
412
|
+
},
|
|
401
413
|
fetchLeadById(id) {
|
|
402
414
|
return _get(`admin/lead/${id}`);
|
|
403
415
|
},
|
package/assets/js/api/index.js
CHANGED
|
@@ -147,6 +147,9 @@ const api = {
|
|
|
147
147
|
contactUs(data, shop) {
|
|
148
148
|
return _post(`shop/${shop}/contact`, data);
|
|
149
149
|
},
|
|
150
|
+
requestTradeAccount(data, shop) {
|
|
151
|
+
return _post(`shop/${shop}/trade-account`, data);
|
|
152
|
+
},
|
|
150
153
|
fetchQuoteById(id, params) {
|
|
151
154
|
return _get(`quotes/${id}`, params);
|
|
152
155
|
},
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
|
|
2
2
|
import { staticLink } from './filters';
|
|
3
3
|
import { COLORS_IMAGES_TYPES } from './../constants/colors';
|
|
4
|
+
import { getCloudflareImageSrc } from './image';
|
|
4
5
|
|
|
5
6
|
export const isValidImageType = (i, type) => i.type === type || (i.types || []).includes(type);
|
|
6
7
|
|
|
7
8
|
export const isValidImageTypes = (i, types) => types.some(type => isValidImageType(i, type));
|
|
8
9
|
|
|
9
10
|
export const getColorImage = (product = {}, size = 'small', type, color, allowAnyColor = false, excludeType = []) => {
|
|
11
|
+
const image = getColorImageObject(product, type, color, allowAnyColor, excludeType);
|
|
12
|
+
return image && ((image[size] && staticLink(image[size])) || getCloudflareImageSrc(image.cloudflareImageId, size));
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const getColorImageObject = (product = {}, type, color, allowAnyColor = false, excludeType = []) => {
|
|
10
16
|
const excludeTypes = (excludeType && Array.isArray(excludeType) ? excludeType : [excludeType]) || [];
|
|
11
17
|
const validImages = (product.images || []).filter(i => !excludeTypes.some(type => isValidImageType(i, type)));
|
|
12
18
|
const colorImage = color && validImages.find(i => isValidImageType(i, type || COLORS_IMAGES_TYPES.FRONT) && (color?._id === i.color || color?._id === i.color?._id));
|
|
13
19
|
const image = colorImage || validImages.find(i => isValidImageType(i, type || COLORS_IMAGES_TYPES.FRONT) && (allowAnyColor || !i.color));
|
|
14
|
-
return image
|
|
20
|
+
return image;
|
|
15
21
|
};
|
|
16
22
|
|
|
17
23
|
export const getProductCover = (product = {}, size = 'small', type = COLORS_IMAGES_TYPES.FRONT, color, allowAnyColor = false) => {
|
|
@@ -49,6 +55,20 @@ export const getProductMediumCover = (product, type, color) => getProductCover(p
|
|
|
49
55
|
export const getProductLargeCover = (product, type, color) => getProductCover(product, 'large', type, color);
|
|
50
56
|
export const getProductOriginCover = (product, type, color) => getProductCover(product, 'origin', type, color);
|
|
51
57
|
|
|
58
|
+
export const getProductCoverObject = (product, type = COLORS_IMAGES_TYPES.FRONT, color) =>
|
|
59
|
+
(color && getColorImageObject(product, `catalog_${type}`, color)) ||
|
|
60
|
+
(color && getColorImageObject(product, type, color)) ||
|
|
61
|
+
getColorImageObject(product, `catalog_${type}`, null, true) ||
|
|
62
|
+
getColorImageObject(product, type, color) ||
|
|
63
|
+
getColorImageObject(product, type, null, true) ||
|
|
64
|
+
null;
|
|
65
|
+
|
|
66
|
+
export const getProductHoverCoverObject = (product, currentColor) =>
|
|
67
|
+
getColorImageObject(product, 'catalog_hover', currentColor) ||
|
|
68
|
+
(currentColor && getColorImageObject(product, 'back', currentColor)) ||
|
|
69
|
+
getColorImageObject(product, 'catalog_hover', null, true) ||
|
|
70
|
+
null;
|
|
71
|
+
|
|
52
72
|
export const getBgStyle = img => img && ({ 'background-image': `url("${img}")` });
|
|
53
73
|
|
|
54
74
|
export function getColorBackgroundStyle(color, skipPattern, originBackground) {
|
package/assets/js/utils/image.js
CHANGED
|
@@ -11,7 +11,7 @@ export function getCloudflareImageSrc(cloudflareImageId, variant = IMAGE_VARIANT
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function getCloudflareImageSrcset(cloudflareImageId) {
|
|
14
|
-
const lines = (cloudflareImageId || '').split(
|
|
14
|
+
const lines = (cloudflareImageId || '').split(/\n/g).map(l => l.trim()).filter(Boolean);
|
|
15
15
|
if (lines.length < 2) {
|
|
16
16
|
return null;
|
|
17
17
|
}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
:alt="alt"
|
|
6
6
|
:loading="loading"
|
|
7
7
|
:decoding="decoding"
|
|
8
|
-
:class="imgClass"
|
|
8
|
+
:class="imgClass"
|
|
9
|
+
@load="$emit('load', $event)" />
|
|
9
10
|
</template>
|
|
10
11
|
|
|
11
12
|
<script>
|
|
@@ -45,13 +46,19 @@ export default {
|
|
|
45
46
|
},
|
|
46
47
|
computed: {
|
|
47
48
|
resolvedSrc() {
|
|
48
|
-
if (this.overrideSrc)
|
|
49
|
-
|
|
49
|
+
if (this.overrideSrc) {
|
|
50
|
+
return this.overrideSrc;
|
|
51
|
+
}
|
|
52
|
+
if (!this.image) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
50
55
|
const { large, medium, small, thumb, origin, cloudflareImageId } = this.image;
|
|
51
|
-
return this.image[this.size] || large || medium || small || thumb || origin || getCloudflareImageSrc(cloudflareImageId);
|
|
56
|
+
return this.image[this.size] || large || medium || small || thumb || origin || getCloudflareImageSrc(cloudflareImageId, this.size);
|
|
52
57
|
},
|
|
53
58
|
resolvedSrcset() {
|
|
54
|
-
if (this.overrideSrc)
|
|
59
|
+
if (this.overrideSrc) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
55
62
|
return getCloudflareImageSrcset(this.image?.cloudflareImageId);
|
|
56
63
|
}
|
|
57
64
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
v-model="text"
|
|
6
6
|
:autofocus="autofocus"
|
|
7
7
|
name="search"
|
|
8
|
-
:placeholder="placeholder"
|
|
8
|
+
:placeholder="focused ? '' : placeholder"
|
|
9
9
|
type="text"
|
|
10
10
|
class="form-field no-label tiny-placeholder labelless"
|
|
11
11
|
autocomplete="off"
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
autocapitalize="off"
|
|
14
14
|
spellcheck="false"
|
|
15
15
|
@input="searchWithDebounce"
|
|
16
|
-
@focus="showResults"
|
|
17
|
-
@blur="hideResults"
|
|
16
|
+
@focus="focused = true; showResults()"
|
|
17
|
+
@blur="focused = false; hideResults()"
|
|
18
18
|
@keydown.enter="goToSearch" />
|
|
19
19
|
<i
|
|
20
20
|
v-if="hasSearchIcon"
|
|
@@ -81,6 +81,7 @@ export default {
|
|
|
81
81
|
return {
|
|
82
82
|
searching: false,
|
|
83
83
|
visibleResult: false,
|
|
84
|
+
focused: false,
|
|
84
85
|
text: '',
|
|
85
86
|
products: [],
|
|
86
87
|
searchWithDebounce: debounce(this.search, 1000),
|
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="TradeAccountRequest__wrapper">
|
|
3
|
+
<div
|
|
4
|
+
v-if="!submitted"
|
|
5
|
+
class="TradeAccountRequest__form-container">
|
|
6
|
+
<slot name="header">
|
|
7
|
+
<div class="TradeAccountRequest__header">
|
|
8
|
+
<h1 class="TradeAccountRequest__title">
|
|
9
|
+
Request Trade Account
|
|
10
|
+
</h1>
|
|
11
|
+
<p class="TradeAccountRequest__description">
|
|
12
|
+
For businesses making regular purchases, a 30-day trade account offers a seamless and efficient way to order your workwear and supplies.
|
|
13
|
+
Please complete the form below to apply.
|
|
14
|
+
</p>
|
|
15
|
+
<p class="TradeAccountRequest__note">
|
|
16
|
+
<strong>Please note:</strong> 30-day trade accounts are available for businesses with a minimum monthly spend of $500.
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
</slot>
|
|
20
|
+
|
|
21
|
+
<validation-observer
|
|
22
|
+
ref="form"
|
|
23
|
+
v-slot="{ handleSubmit, errors: submittedErrors }"
|
|
24
|
+
tag="form"
|
|
25
|
+
class="TradeAccountRequest__form">
|
|
26
|
+
<div class="TradeAccountRequest__section-title">
|
|
27
|
+
Contact Details
|
|
28
|
+
</div>
|
|
29
|
+
<div class="row">
|
|
30
|
+
<div class="col-sm-6 col-12">
|
|
31
|
+
<validation-provider
|
|
32
|
+
v-slot="{ errors }"
|
|
33
|
+
tag="div"
|
|
34
|
+
name="First Name"
|
|
35
|
+
rules="required"
|
|
36
|
+
class="form-row">
|
|
37
|
+
<label class="form-label">First Name</label>
|
|
38
|
+
<input
|
|
39
|
+
v-model="form.firstName"
|
|
40
|
+
type="text"
|
|
41
|
+
class="form-field labelless"
|
|
42
|
+
placeholder="First name"
|
|
43
|
+
:class="{ 'is-danger': errors.length, filled: form.firstName }" />
|
|
44
|
+
<span
|
|
45
|
+
v-if="errors.length"
|
|
46
|
+
class="form-help is-danger">
|
|
47
|
+
{{ errors[0] }}
|
|
48
|
+
</span>
|
|
49
|
+
</validation-provider>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="col-sm-6 col-12">
|
|
52
|
+
<validation-provider
|
|
53
|
+
v-slot="{ errors }"
|
|
54
|
+
tag="div"
|
|
55
|
+
name="Last Name"
|
|
56
|
+
rules="required"
|
|
57
|
+
class="form-row">
|
|
58
|
+
<label class="form-label">Last Name</label>
|
|
59
|
+
<input
|
|
60
|
+
v-model="form.lastName"
|
|
61
|
+
type="text"
|
|
62
|
+
class="form-field labelless"
|
|
63
|
+
placeholder="Last name"
|
|
64
|
+
:class="{ 'is-danger': errors.length, filled: form.lastName }" />
|
|
65
|
+
<span
|
|
66
|
+
v-if="errors.length"
|
|
67
|
+
class="form-help is-danger">
|
|
68
|
+
{{ errors[0] }}
|
|
69
|
+
</span>
|
|
70
|
+
</validation-provider>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div class="row">
|
|
75
|
+
<div class="col-sm-6 col-12">
|
|
76
|
+
<validation-provider
|
|
77
|
+
v-slot="{ errors }"
|
|
78
|
+
tag="div"
|
|
79
|
+
name="Phone"
|
|
80
|
+
rules="required"
|
|
81
|
+
class="form-row">
|
|
82
|
+
<label class="form-label">Phone Number</label>
|
|
83
|
+
<input
|
|
84
|
+
v-model="form.phone"
|
|
85
|
+
type="tel"
|
|
86
|
+
class="form-field labelless"
|
|
87
|
+
placeholder="0400 000 000"
|
|
88
|
+
:class="{ 'is-danger': errors.length, filled: form.phone }" />
|
|
89
|
+
<span
|
|
90
|
+
v-if="errors.length"
|
|
91
|
+
class="form-help is-danger">
|
|
92
|
+
{{ errors[0] }}
|
|
93
|
+
</span>
|
|
94
|
+
</validation-provider>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="col-sm-6 col-12">
|
|
97
|
+
<validation-provider
|
|
98
|
+
v-slot="{ errors }"
|
|
99
|
+
tag="div"
|
|
100
|
+
name="Email"
|
|
101
|
+
rules="required|email"
|
|
102
|
+
class="form-row">
|
|
103
|
+
<label class="form-label">Email Address</label>
|
|
104
|
+
<input
|
|
105
|
+
v-model="form.email"
|
|
106
|
+
type="email"
|
|
107
|
+
class="form-field labelless"
|
|
108
|
+
placeholder="your@email.com.au"
|
|
109
|
+
:class="{ 'is-danger': errors.length, filled: form.email }" />
|
|
110
|
+
<span
|
|
111
|
+
v-if="errors.length"
|
|
112
|
+
class="form-help is-danger">
|
|
113
|
+
{{ errors[0] }}
|
|
114
|
+
</span>
|
|
115
|
+
</validation-provider>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<div class="TradeAccountRequest__section-title">
|
|
120
|
+
Business Information
|
|
121
|
+
</div>
|
|
122
|
+
<div class="row">
|
|
123
|
+
<div class="col-sm-6 col-12">
|
|
124
|
+
<validation-provider
|
|
125
|
+
v-slot="{ errors }"
|
|
126
|
+
tag="div"
|
|
127
|
+
name="Company Name"
|
|
128
|
+
rules="required"
|
|
129
|
+
class="form-row">
|
|
130
|
+
<label class="form-label">Company Name</label>
|
|
131
|
+
<input
|
|
132
|
+
v-model="form.businessName"
|
|
133
|
+
type="text"
|
|
134
|
+
class="form-field labelless"
|
|
135
|
+
placeholder="Your company name"
|
|
136
|
+
:class="{ 'is-danger': errors.length, filled: form.businessName }" />
|
|
137
|
+
<span
|
|
138
|
+
v-if="errors.length"
|
|
139
|
+
class="form-help is-danger">
|
|
140
|
+
{{ errors[0] }}
|
|
141
|
+
</span>
|
|
142
|
+
</validation-provider>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="col-sm-6 col-12">
|
|
145
|
+
<validation-provider
|
|
146
|
+
v-slot="{ errors }"
|
|
147
|
+
tag="div"
|
|
148
|
+
name="ABN"
|
|
149
|
+
class="form-row">
|
|
150
|
+
<label class="form-label">ABN</label>
|
|
151
|
+
<input
|
|
152
|
+
v-model="form.abn"
|
|
153
|
+
type="text"
|
|
154
|
+
class="form-field labelless"
|
|
155
|
+
placeholder="Australian Business Number"
|
|
156
|
+
:class="{ 'is-danger': errors.length, filled: form.abn }" />
|
|
157
|
+
<span
|
|
158
|
+
v-if="errors.length"
|
|
159
|
+
class="form-help is-danger">
|
|
160
|
+
{{ errors[0] }}
|
|
161
|
+
</span>
|
|
162
|
+
</validation-provider>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div class="row">
|
|
167
|
+
<div class="col-sm-6 col-12">
|
|
168
|
+
<validation-provider
|
|
169
|
+
v-slot="{ errors }"
|
|
170
|
+
tag="div"
|
|
171
|
+
name="Industry"
|
|
172
|
+
class="form-row">
|
|
173
|
+
<label class="form-label">Industry / Business Type</label>
|
|
174
|
+
<input
|
|
175
|
+
v-model="form.industry"
|
|
176
|
+
type="text"
|
|
177
|
+
class="form-field labelless"
|
|
178
|
+
placeholder="e.g. Construction, Hospitality, Healthcare"
|
|
179
|
+
:class="{ 'is-danger': errors.length, filled: form.industry }" />
|
|
180
|
+
<span
|
|
181
|
+
v-if="errors.length"
|
|
182
|
+
class="form-help is-danger">
|
|
183
|
+
{{ errors[0] }}
|
|
184
|
+
</span>
|
|
185
|
+
</validation-provider>
|
|
186
|
+
</div>
|
|
187
|
+
<div class="col-sm-6 col-12">
|
|
188
|
+
<validation-provider
|
|
189
|
+
v-slot="{ errors }"
|
|
190
|
+
tag="div"
|
|
191
|
+
name="Company Size"
|
|
192
|
+
class="form-row">
|
|
193
|
+
<label class="form-label">Company Size</label>
|
|
194
|
+
<input
|
|
195
|
+
v-model="form.companySize"
|
|
196
|
+
type="text"
|
|
197
|
+
class="form-field labelless"
|
|
198
|
+
placeholder="e.g. 1–10, 11–50, 50+"
|
|
199
|
+
:class="{ 'is-danger': errors.length, filled: form.companySize }" />
|
|
200
|
+
<span
|
|
201
|
+
v-if="errors.length"
|
|
202
|
+
class="form-help is-danger">
|
|
203
|
+
{{ errors[0] }}
|
|
204
|
+
</span>
|
|
205
|
+
</validation-provider>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
<div class="TradeAccountRequest__section-title">
|
|
210
|
+
Delivery Address
|
|
211
|
+
</div>
|
|
212
|
+
<div class="row">
|
|
213
|
+
<div class="col-12">
|
|
214
|
+
<validation-provider
|
|
215
|
+
v-slot="{ errors }"
|
|
216
|
+
tag="div"
|
|
217
|
+
name="Street Address"
|
|
218
|
+
class="form-row">
|
|
219
|
+
<label class="form-label">Street Address</label>
|
|
220
|
+
<input
|
|
221
|
+
v-model="form.streetAddress"
|
|
222
|
+
type="text"
|
|
223
|
+
class="form-field labelless"
|
|
224
|
+
placeholder="Street address"
|
|
225
|
+
:class="{ 'is-danger': errors.length, filled: form.streetAddress }" />
|
|
226
|
+
<span
|
|
227
|
+
v-if="errors.length"
|
|
228
|
+
class="form-help is-danger">
|
|
229
|
+
{{ errors[0] }}
|
|
230
|
+
</span>
|
|
231
|
+
</validation-provider>
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
<div class="row">
|
|
235
|
+
<div class="col-12">
|
|
236
|
+
<div class="form-row">
|
|
237
|
+
<postcode-select
|
|
238
|
+
:suburb="form.suburb"
|
|
239
|
+
:required="false"
|
|
240
|
+
:labelless="true"
|
|
241
|
+
placeholder="Suburb"
|
|
242
|
+
@select="handleSuburbChange" />
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<div class="TradeAccountRequest__section-title">
|
|
248
|
+
Additional Information
|
|
249
|
+
</div>
|
|
250
|
+
<div class="row">
|
|
251
|
+
<div class="col-12">
|
|
252
|
+
<div class="form-row">
|
|
253
|
+
<label class="form-label">Have you purchased from us before?</label>
|
|
254
|
+
<div class="TradeAccountRequest__radio-group">
|
|
255
|
+
<label class="TradeAccountRequest__radio-label">
|
|
256
|
+
<input
|
|
257
|
+
v-model="form.previousCustomer"
|
|
258
|
+
type="radio"
|
|
259
|
+
:value="true" />
|
|
260
|
+
Yes
|
|
261
|
+
</label>
|
|
262
|
+
<label class="TradeAccountRequest__radio-label">
|
|
263
|
+
<input
|
|
264
|
+
v-model="form.previousCustomer"
|
|
265
|
+
type="radio"
|
|
266
|
+
:value="false" />
|
|
267
|
+
No
|
|
268
|
+
</label>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
<div class="row">
|
|
275
|
+
<div class="col-12">
|
|
276
|
+
<validation-provider
|
|
277
|
+
v-slot="{ errors }"
|
|
278
|
+
tag="div"
|
|
279
|
+
name="Credit Line Request"
|
|
280
|
+
class="form-row">
|
|
281
|
+
<label class="form-label">Credit Line Request</label>
|
|
282
|
+
<textarea
|
|
283
|
+
v-model="form.creditLineRequest"
|
|
284
|
+
class="form-field labelless"
|
|
285
|
+
rows="4"
|
|
286
|
+
placeholder="Please describe your credit line requirements and any additional information about your business needs."
|
|
287
|
+
:class="{ 'is-danger': errors.length, filled: form.creditLineRequest }" />
|
|
288
|
+
<span
|
|
289
|
+
v-if="errors.length"
|
|
290
|
+
class="form-help is-danger">
|
|
291
|
+
{{ errors[0] }}
|
|
292
|
+
</span>
|
|
293
|
+
</validation-provider>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
|
|
297
|
+
<div
|
|
298
|
+
v-if="errorMessage"
|
|
299
|
+
class="TradeAccountRequest__error">
|
|
300
|
+
{{ errorMessage }}
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<div class="form-actions full">
|
|
304
|
+
<btn
|
|
305
|
+
btn-class="green"
|
|
306
|
+
btn-label="Submit Application"
|
|
307
|
+
:btn-disabled="submitting"
|
|
308
|
+
:btn-processing="submitting"
|
|
309
|
+
:btn-block="true"
|
|
310
|
+
@onclick="handleSubmit(submit)" />
|
|
311
|
+
</div>
|
|
312
|
+
</validation-observer>
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
<div
|
|
316
|
+
v-else
|
|
317
|
+
class="TradeAccountRequest__success">
|
|
318
|
+
<div class="TradeAccountRequest__success-icon">
|
|
319
|
+
✓
|
|
320
|
+
</div>
|
|
321
|
+
<h2 class="TradeAccountRequest__success-title">
|
|
322
|
+
Received!
|
|
323
|
+
</h2>
|
|
324
|
+
<p class="TradeAccountRequest__success-text">
|
|
325
|
+
Thank you for applying for a trade account. We've received your application
|
|
326
|
+
(ref: <strong>{{ submittedCode }}</strong>) and will be in touch within 1–2 business days.
|
|
327
|
+
</p>
|
|
328
|
+
<btn
|
|
329
|
+
to="/"
|
|
330
|
+
btn-class="green"
|
|
331
|
+
btn-label="Continue Shopping" />
|
|
332
|
+
</div>
|
|
333
|
+
</div>
|
|
334
|
+
</template>
|
|
335
|
+
|
|
336
|
+
<script>
|
|
337
|
+
import { mapGetters } from 'vuex';
|
|
338
|
+
import api from '@lancom/shared/assets/js/api';
|
|
339
|
+
import PostcodeSelect from '@lancom/shared/components/common/postcode_select/postcode-select';
|
|
340
|
+
import Btn from '@lancom/shared/components/common/btn';
|
|
341
|
+
|
|
342
|
+
export default {
|
|
343
|
+
name: 'TradeAccountRequest',
|
|
344
|
+
components: {
|
|
345
|
+
PostcodeSelect,
|
|
346
|
+
Btn
|
|
347
|
+
},
|
|
348
|
+
data() {
|
|
349
|
+
return {
|
|
350
|
+
submitted: false,
|
|
351
|
+
submitting: false,
|
|
352
|
+
submittedCode: null,
|
|
353
|
+
errorMessage: null,
|
|
354
|
+
form: {
|
|
355
|
+
businessName: '',
|
|
356
|
+
firstName: '',
|
|
357
|
+
lastName: '',
|
|
358
|
+
email: '',
|
|
359
|
+
phone: '',
|
|
360
|
+
abn: '',
|
|
361
|
+
industry: '',
|
|
362
|
+
companySize: '',
|
|
363
|
+
streetAddress: '',
|
|
364
|
+
suburb: null,
|
|
365
|
+
state: '',
|
|
366
|
+
postcode: '',
|
|
367
|
+
previousCustomer: null,
|
|
368
|
+
creditLineRequest: ''
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
},
|
|
372
|
+
computed: {
|
|
373
|
+
...mapGetters(['shop'])
|
|
374
|
+
},
|
|
375
|
+
methods: {
|
|
376
|
+
handleSuburbChange(suburb) {
|
|
377
|
+
this.form.suburb = suburb;
|
|
378
|
+
this.form.state = suburb?.state || '';
|
|
379
|
+
this.form.postcode = suburb?.postcode || '';
|
|
380
|
+
},
|
|
381
|
+
async submit() {
|
|
382
|
+
this.errorMessage = null;
|
|
383
|
+
this.submitting = true;
|
|
384
|
+
try {
|
|
385
|
+
let recaptchaToken = null;
|
|
386
|
+
if (this.$recaptcha) {
|
|
387
|
+
recaptchaToken = await this.$recaptcha('trade_account');
|
|
388
|
+
}
|
|
389
|
+
const payload = {
|
|
390
|
+
...this.form,
|
|
391
|
+
suburb: this.form.suburb?.locality || this.form.suburb?.city || '',
|
|
392
|
+
recaptchaToken
|
|
393
|
+
};
|
|
394
|
+
const result = await api.requestTradeAccount(payload, this.shop._id);
|
|
395
|
+
this.submittedCode = result.code;
|
|
396
|
+
this.submitted = true;
|
|
397
|
+
} catch (e) {
|
|
398
|
+
this.errorMessage = 'Something went wrong. Please try again or contact us directly.';
|
|
399
|
+
} finally {
|
|
400
|
+
this.submitting = false;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
</script>
|
|
406
|
+
|
|
407
|
+
<style lang="scss">
|
|
408
|
+
.TradeAccountRequest {
|
|
409
|
+
&__form-container {
|
|
410
|
+
background: #fff;
|
|
411
|
+
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.08);
|
|
412
|
+
border-radius: 8px;
|
|
413
|
+
padding: 48px 40px 56px;
|
|
414
|
+
|
|
415
|
+
@media (max-width: 576px) {
|
|
416
|
+
padding: 32px 20px 40px;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
&__header {
|
|
421
|
+
margin-bottom: 36px;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
&__title {
|
|
425
|
+
font-size: 28px;
|
|
426
|
+
font-weight: 700;
|
|
427
|
+
margin-bottom: 12px;
|
|
428
|
+
text-transform: uppercase;
|
|
429
|
+
letter-spacing: 0.02em;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
&__description {
|
|
433
|
+
font-size: 15px;
|
|
434
|
+
color: #555;
|
|
435
|
+
margin-bottom: 10px;
|
|
436
|
+
line-height: 1.6;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
&__note {
|
|
440
|
+
font-size: 14px;
|
|
441
|
+
color: #777;
|
|
442
|
+
background: #f8f8f8;
|
|
443
|
+
border-left: 3px solid #ccc;
|
|
444
|
+
padding: 10px 14px;
|
|
445
|
+
border-radius: 0 4px 4px 0;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
&__section-title {
|
|
449
|
+
font-size: 13px;
|
|
450
|
+
font-weight: 700;
|
|
451
|
+
text-transform: uppercase;
|
|
452
|
+
letter-spacing: 0.08em;
|
|
453
|
+
color: #999;
|
|
454
|
+
margin: 28px 0 12px;
|
|
455
|
+
padding-bottom: 8px;
|
|
456
|
+
border-bottom: 1px solid #eee;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
&__radio-group {
|
|
460
|
+
display: flex;
|
|
461
|
+
gap: 24px;
|
|
462
|
+
margin-top: 4px;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
&__radio-label {
|
|
466
|
+
display: flex;
|
|
467
|
+
align-items: center;
|
|
468
|
+
gap: 8px;
|
|
469
|
+
font-size: 14px;
|
|
470
|
+
color: #333;
|
|
471
|
+
cursor: pointer;
|
|
472
|
+
|
|
473
|
+
input[type="radio"] {
|
|
474
|
+
margin: 0;
|
|
475
|
+
cursor: pointer;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
&__error {
|
|
480
|
+
margin-top: 16px;
|
|
481
|
+
padding: 12px 16px;
|
|
482
|
+
background: #fff5f5;
|
|
483
|
+
border: 1px solid #f5c6c6;
|
|
484
|
+
border-radius: 4px;
|
|
485
|
+
color: #c0392b;
|
|
486
|
+
font-size: 14px;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
&__success {
|
|
490
|
+
text-align: center;
|
|
491
|
+
padding: 80px 40px;
|
|
492
|
+
background: #fff;
|
|
493
|
+
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.08);
|
|
494
|
+
border-radius: 8px;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
&__success-icon {
|
|
498
|
+
width: 72px;
|
|
499
|
+
height: 72px;
|
|
500
|
+
border-radius: 50%;
|
|
501
|
+
background: #38c88d;
|
|
502
|
+
color: #fff;
|
|
503
|
+
font-size: 36px;
|
|
504
|
+
line-height: 72px;
|
|
505
|
+
margin: 0 auto 24px;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
&__success-title {
|
|
509
|
+
font-size: 26px;
|
|
510
|
+
font-weight: 700;
|
|
511
|
+
margin-bottom: 16px;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
&__success-text {
|
|
515
|
+
font-size: 15px;
|
|
516
|
+
color: #555;
|
|
517
|
+
margin-bottom: 32px;
|
|
518
|
+
line-height: 1.6;
|
|
519
|
+
max-width: 500px;
|
|
520
|
+
margin-left: auto;
|
|
521
|
+
margin-right: auto;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mapGetters } from 'vuex';
|
|
2
|
-
import { getColorBackgroundStyle, getProductMediumCover, getBgStyle, getProductHoverCover } from '@lancom/shared/assets/js/utils/colors';
|
|
2
|
+
import { getColorBackgroundStyle, getProductMediumCover, getBgStyle, getProductHoverCover, getProductCoverObject, getProductHoverCoverObject } from '@lancom/shared/assets/js/utils/colors';
|
|
3
3
|
import { staticLink } from '@lancom/shared/assets/js/utils/filters';
|
|
4
4
|
import { generateProductLink } from '@lancom/shared/assets/js/utils/product';
|
|
5
5
|
import { sortSizes } from '@lancom/shared/assets/js/utils/sizes';
|
|
@@ -99,6 +99,12 @@ const productPreview = {
|
|
|
99
99
|
productСoverHover() {
|
|
100
100
|
return getProductHoverCover(this.product, this.currentColor) || getProductMediumCover(this.product, 'back', this.currentColor);
|
|
101
101
|
},
|
|
102
|
+
productСoverImage() {
|
|
103
|
+
return getProductCoverObject(this.product, 'front', this.currentColor);
|
|
104
|
+
},
|
|
105
|
+
productСoverHoverImage() {
|
|
106
|
+
return getProductHoverCoverObject(this.product, this.currentColor);
|
|
107
|
+
},
|
|
102
108
|
productСoverBg() {
|
|
103
109
|
return getBgStyle(this.productСover);
|
|
104
110
|
},
|