@lancom/shared 0.0.410 → 0.0.411

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.
@@ -1,3 +1,4 @@
1
+
1
2
  import { _get, _post, _put, _delete, _patch } from './helpers';
2
3
  import adminApi from './admin';
3
4
  import { unminifySimpleProducts } from './utils/simple-products';
@@ -19,9 +20,6 @@ const api = {
19
20
  saveCustomer(customer, shop) {
20
21
  return customer._id ? _patch(`shop/${shop}/customer/${customer.accessToken}`, customer) : _post(`shop/${shop}/customer`, customer);
21
22
  },
22
- fetchCustomer(accessToken, shop) {
23
- return _get(`shop/${shop}/customer/${accessToken}`);
24
- },
25
23
  authCustomer(customer, shop) {
26
24
  return _post(`shop/${shop}/customer/login`, customer);
27
25
  },
@@ -74,7 +74,7 @@
74
74
  <div
75
75
  v-else
76
76
  class="lc_caption form-help is-danger">
77
- Invalid coupon: Min Order for Coupon: {{ minOrderValue | price(currency) }}
77
+ Invalid coupon: Min Order for Coupon: {{ value.minOrderValue | price(currency) }}
78
78
  </div>
79
79
  <div v-if="hasQualifyingProducts" class="lc_caption mb-10">
80
80
  <div v-if="noQualifyingProductsInCart">
@@ -129,18 +129,8 @@ export default {
129
129
  hasQualifyingProductsInCart() {
130
130
  return this.sumQualifyingProductsInCart > 0;
131
131
  },
132
- minOrderValue() {
133
- const value = [
134
- this.value,
135
- ...(this.value?.values || [])
136
- ]
137
- .filter(v => v?.minOrderValue > 0)
138
- .sort((a, b) => a.minOrderValue - b.minOrderValue)[0];
139
-
140
- return value?.minOrderValue || 0;
141
- },
142
132
  isValidPricing() {
143
- return !this.minOrderValue || this.pricing.coupon;
133
+ return !this.value?.minOrderValue || this.pricing.coupon;
144
134
  },
145
135
  model: {
146
136
  get() {
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
  <div>
3
- <div :class="containerClassname">
3
+ <div class="form-row">
4
4
  <label
5
5
  v-if="labelless"
6
- :class="labelClassname"
6
+ class="form-label"
7
7
  @click="$refs.phone.$el.focus()">
8
8
  {{ displayLabelText }}
9
9
  </label>
@@ -31,8 +31,8 @@
31
31
  :disabled="disabled"
32
32
  :name="'phone' + uniqueKey"
33
33
  type="text"
34
+ class="form-field"
34
35
  :class="{
35
- [inputClassname]: true,
36
36
  'is-danger': errors.length,
37
37
  filled: model,
38
38
  labelless
@@ -115,18 +115,6 @@ export default {
115
115
  namePrefix: {
116
116
  type: String,
117
117
  default: ''
118
- },
119
- containerClassname: {
120
- type: String,
121
- default: 'form-row'
122
- },
123
- labelClassname: {
124
- type: String,
125
- default: 'form-label'
126
- },
127
- inputClassname: {
128
- type: String,
129
- default: 'form-field'
130
118
  }
131
119
  },
132
120
  data() {
@@ -15,12 +15,6 @@
15
15
  <script>
16
16
  export default {
17
17
  name: 'CustomerMenu',
18
- props: {
19
- activeMenuItem: {
20
- type: String,
21
- required: true
22
- }
23
- },
24
18
  data() {
25
19
  return {
26
20
  menuItems: [{
@@ -35,12 +29,14 @@ export default {
35
29
  label: 'Coupons',
36
30
  key: 'coupons',
37
31
  url: '/customer/coupons'
38
- }, {
39
- label: 'Preferences',
40
- key: 'preferences',
41
- url: '/customer/preferences'
42
32
  }]
43
33
  };
34
+ },
35
+ props: {
36
+ activeMenuItem: {
37
+ type: String,
38
+ required: true
39
+ }
44
40
  }
45
41
  };
46
42
  </script>
@@ -72,5 +68,5 @@ export default {
72
68
  background-color: $green;
73
69
  }
74
70
  }
75
- }
71
+ }
76
72
  </style>
@@ -43,11 +43,6 @@ export default {
43
43
  components: {
44
44
  ProductMultipack
45
45
  },
46
- data() {
47
- return {
48
- thumbsPage: 0
49
- };
50
- },
51
46
  props: {
52
47
  product: {
53
48
  type: Object,
@@ -70,8 +65,10 @@ export default {
70
65
  default: 3
71
66
  }
72
67
  },
73
- created() {
74
- console.log('LancomProductMultipacks...')
68
+ data() {
69
+ return {
70
+ thumbsPage: 0
71
+ };
75
72
  },
76
73
  computed: {
77
74
  ...mapGetters(['currency']),
@@ -25,7 +25,7 @@
25
25
  </div>
26
26
  </div>
27
27
  <div class="ProductMultipack__price">
28
- {{ oneItemPrice | price(currency) }} each
28
+ {{ oneItemPrice | price(currency) }} each
29
29
  <span>{{ totalPrice | price(currency) }}</span>
30
30
  </div>
31
31
  </div>
@@ -79,7 +79,9 @@ export default {
79
79
  return simpleProducts.find(sp => sp.size?.shortName === simpleProduct?.size?.shortName) || simpleProducts[0];
80
80
  },
81
81
  totalPrice() {
82
- return this.oneItemPrice * this.multipack.qty;
82
+ const itemPrice = priceFromRange(this.multipack.qty, this.simpleProduct?.pricing);
83
+ const price = itemPrice * this.multipack.qty;
84
+ return this.withGst ? tax(price, this.gstTax) : price;
83
85
  },
84
86
  oneItemPrice() {
85
87
  const price = priceFromRange(this.multipack.qty, this.simpleProduct?.pricing);
@@ -126,10 +126,10 @@
126
126
  return 'product';
127
127
  },
128
128
  pageItemImage() {
129
- const images = this.products.reduce((images, product) => {
129
+ const images = this.products?.reduce((images, product) => {
130
130
  const image = getProductLargeCover(product, 'front') || getProductMediumCover(product, 'front');
131
131
  return image ? [...images, image] : images;
132
- }, []);
132
+ }, []) || [];
133
133
  return images.slice(0, 1);
134
134
  },
135
135
  currentBrand() {
@@ -42,7 +42,7 @@ export default (IS_PRODUCT_PRESET_PRINT_PRICING, isEditor = false) => ({
42
42
  const redirectUrl = generateProductLink(product, data.defaultColor, isEditor);
43
43
  return redirect(301, redirectUrl);
44
44
  }
45
-
45
+
46
46
  if (params.sku && params.sku !== product?.SKU?.toLowerCase()) {
47
47
  return error({ statusCode: 404, message: 'Product not found' });
48
48
  }
@@ -58,6 +58,11 @@ export default (IS_PRODUCT_PRESET_PRINT_PRICING, isEditor = false) => ({
58
58
  if (query.price) {
59
59
  store.commit('product/setPriceIncludeGST', query.price === 'IT');
60
60
  }
61
+ if (query.multipack) {
62
+ const multipackQty = +query.multipack.split('-multipack-')[1];
63
+ const multipack = product.multipacks?.find(m => m.qty === multipackQty);
64
+ store.commit('product/setMultipack', multipack);
65
+ }
61
66
  } catch (e) {
62
67
  console.log(e);
63
68
  }
@@ -179,7 +184,7 @@ export default (IS_PRODUCT_PRESET_PRINT_PRICING, isEditor = false) => ({
179
184
  }
180
185
  } catch (e) {
181
186
  }
182
-
187
+
183
188
  this.fillBreadcrumbs();
184
189
  const { multipack } = this.$route.query;
185
190
  if (multipack) {
@@ -277,7 +282,7 @@ export default (IS_PRODUCT_PRESET_PRINT_PRICING, isEditor = false) => ({
277
282
  const maxPrice = this.printsPrice ? spMaxPrice + this.printsPrice : spMaxPrice;
278
283
  const availability = sp.quantityStock > 0 ? 'InStock' : 'OutOfStock';
279
284
  const name = `${this.product.name} | ${sp.size?.shortName || ''} ${sp.color?.name || ''}`;
280
-
285
+
281
286
  const offer = {
282
287
  '@type': 'Offer',
283
288
  name,
@@ -309,7 +314,7 @@ export default (IS_PRODUCT_PRESET_PRINT_PRICING, isEditor = false) => ({
309
314
  // if (sp.quantityStock > 0) {
310
315
  // }
311
316
  }
312
-
317
+
313
318
  offer.shippingDetails = { "@id": "#shipping_policy" };
314
319
  offer.hasMerchantReturnPolicy = { "@id": "#return_policy" };
315
320
 
@@ -422,4 +427,4 @@ export default (IS_PRODUCT_PRESET_PRINT_PRICING, isEditor = false) => ({
422
427
  this.$store.state.shop?.shippingPolicySchema
423
428
  ].filter(s => !!s);
424
429
  }
425
- });
430
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.410",
3
+ "version": "0.0.411",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
package/routes/index.js CHANGED
@@ -122,11 +122,6 @@ module.exports = function(routes, resolve, config) {
122
122
  path: '/customer/coupons',
123
123
  component: resolve('@lancom/shared/pages/customer/coupons.vue'),
124
124
  chunkName: 'pages/customer/coupons'
125
- }, {
126
- name: 'customer-preferences',
127
- path: '/customer/preferences',
128
- component: resolve('@lancom/shared/pages/customer/preferences.vue'),
129
- chunkName: 'pages/customer/preferences'
130
125
  }, {
131
126
  name: 'customer-recovery',
132
127
  path: '/customer/recovery',
@@ -142,11 +137,6 @@ module.exports = function(routes, resolve, config) {
142
137
  path: '/customer/password/:token',
143
138
  component: resolve('@lancom/shared/pages/customer/password/_token.vue'),
144
139
  chunkName: 'pages/customer/password/reset'
145
- }, {
146
- name: 'customer-preferences',
147
- path: '/customer/preferences',
148
- component: resolve('@lancom/shared/pages/customer/preferences.vue'),
149
- chunkName: 'pages/customer/preferences'
150
140
  }, {
151
141
  name: 'checkout-cart',
152
142
  path: '/checkout/cart',
@@ -1,12 +0,0 @@
1
- @import "@/assets/scss/variables";
2
-
3
- .CustomerPreferencesForm {
4
- &__error {
5
- font-weight: bold;
6
- font-size: 14px;
7
- padding: 18px 10px;
8
- text-align: center;
9
- color: $white;
10
- background: #EA3434;
11
- }
12
- }
@@ -1,87 +0,0 @@
1
- <template>
2
- <div class="form__wrapper CustomerFrom__wrapper">
3
- <validation-observer ref="form">
4
- <div class="mt-10">
5
- <div
6
- class="row"
7
- style="margin-top: -20px">
8
- <div class="col-12">
9
- <div class="form-row">
10
- <label class="form-label">
11
- <checkbox v-model="customer.signUpForNewsletter" />
12
- <span class="lc_regular12 lc__grey1">
13
- Sign up for newsletter
14
- </span>
15
- </label>
16
- </div>
17
- </div>
18
- </div>
19
- </div>
20
- <div class="form__footer mt-5">
21
- <div
22
- v-if="errorMessage"
23
- class="CustomerForm__error">
24
- {{ errorMessage }}
25
- </div>
26
- <div class="form-actions full">
27
- <btn
28
- class="btn btn-black"
29
- :btn-processing="processing"
30
- :btn-disabled="processing"
31
- :btn-label="customer._id ? 'Save' : 'Create Account'"
32
- @onclick="submit()">
33
- </btn>
34
- </div>
35
- </div>
36
- </validation-observer>
37
- </div>
38
- </template>
39
-
40
- <script>
41
- import { mapGetters } from 'vuex';
42
- import api from '@lancom/shared/assets/js/api';
43
-
44
- export default {
45
- name: 'CustomerPreferencesForm',
46
- props: {
47
- customer: {
48
- type: Object,
49
- required: true
50
- }
51
- },
52
- data() {
53
- return {
54
- errorMessage: null,
55
- processing: false
56
- };
57
- },
58
- computed: {
59
- ...mapGetters(['shop'])
60
- },
61
- methods: {
62
- async submit() {
63
- this.errorMessage = null;
64
-
65
- const isValid = await this.$refs.form.validate();
66
- if (!isValid) {
67
- return;
68
- }
69
-
70
- try {
71
- this.processing = true;
72
- const result = await api.saveCustomer(this.customer, this.shop._id);
73
- this.$emit('save', result);
74
- } catch ({ response }) {
75
- const { data } = response || {};
76
- this.errorMessage = data && data.error;
77
- } finally {
78
- this.processing = false;
79
- }
80
- }
81
- }
82
- };
83
- </script>
84
-
85
- <style lang="scss" scoped>
86
- @import 'customer-preferences-form.scss';
87
- </style>
@@ -1,79 +0,0 @@
1
- <template>
2
- <div class="CustomerPreferences__wrapper">
3
- <customer-preferences-form
4
- v-if="customer"
5
- ref="customerForm"
6
- :customer="customer"
7
- @save="onSave"
8
- @customer-loaded="onCustomerLoaded" />
9
- </div>
10
- </template>
11
-
12
- <script>
13
- import api from '@lancom/shared/assets/js/api';
14
- import { mapGetters, mapActions } from 'vuex';
15
- import CustomerPreferencesForm from '@lancom/shared/components/customer/customer_preferences_form/customer-preferences-form';
16
-
17
- export default {
18
- name: 'CustomerPreferences',
19
- components: {
20
- CustomerPreferencesForm
21
- },
22
- data() {
23
- return {
24
- customer: null,
25
- loading: false,
26
- error: null
27
- };
28
- },
29
- computed: {
30
- ...mapGetters(['shop']),
31
- ...mapGetters('auth', ['user'])
32
- },
33
- async created() {
34
- await this.loadCustomerData();
35
- },
36
- methods: {
37
- ...mapActions('auth', ['update_user']),
38
- async loadCustomerData() {
39
- try {
40
- this.processing = true;
41
- const customer = await api.fetchCustomer(this.user.accessToken, this.shop._id);
42
- console.log('customer: ', customer);
43
- this.customer = customer;
44
- } catch (e) {
45
- console.log(e);
46
- const errorMessage = e?.response?.data?.error;
47
- this.$toastr.e(errorMessage || 'Customer failed to load');
48
- } finally {
49
- this.processing = false;
50
- }
51
- },
52
- onSave({ customer: user, token }) {
53
- this.$toastr.s('Customer successfully saved');
54
- this.update_user({ user, token });
55
- },
56
- onCustomerLoaded(customer) {
57
- this.customer = customer;
58
- }
59
- }
60
- };
61
- </script>
62
-
63
- <style lang="scss" scoped>
64
- .loading-message {
65
- text-align: center;
66
- padding: 2rem;
67
- font-size: 1.1rem;
68
- color: #666;
69
- }
70
-
71
- .error-message {
72
- text-align: center;
73
- padding: 2rem;
74
- color: #d32f2f;
75
- background-color: #ffebee;
76
- border-radius: 4px;
77
- margin: 1rem 0;
78
- }
79
- </style>
@@ -1,33 +0,0 @@
1
- <template>
2
- <div
3
- :data-aos="aosFadeLeft"
4
- class="CustomerPreferencesPage__wrapper">
5
- <customer-preferences />
6
- </div>
7
- </template>
8
-
9
- <script>
10
- import metaInfo from '@lancom/shared/mixins/meta-info';
11
-
12
- export default {
13
- name: 'CustomerPreferencesPage',
14
- components: {
15
- CustomerPreferences: () => import('@lancom/shared/components/pages/customer/preferences/preferences')
16
- },
17
- mixins: [metaInfo]
18
- };
19
- </script>
20
-
21
- <style lang="scss" scoped>
22
- @import "@/assets/scss/variables";
23
-
24
- .CustomerPreferencesPage {
25
- &__wrapper {
26
- margin: 100px auto;
27
- width: 500px;
28
- @media (max-width: $bp-extra-small-max) {
29
- width: auto;
30
- }
31
- }
32
- }
33
- </style>