@lancom/shared 0.0.287 → 0.0.288

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.
@@ -0,0 +1,24 @@
1
+ export function getShopCountrySettings(shop, country) {
2
+ const countrySettings = (shop.countries || []).find(c => c.country?._id === country?._id) || { settings: [] };
3
+ const countrySetting = (countrySettings?.settings || [])[0];
4
+
5
+ return {
6
+ ...shop.settings,
7
+ contacts: {
8
+ ...shop.settings.contacts,
9
+ ...settingsValues(countrySetting?.settings?.contacts)
10
+ },
11
+ depositInfo: {
12
+ ...shop.settings.depositInfo,
13
+ ...settingsValues(countrySetting?.settings?.depositInfo)
14
+ },
15
+ pricing: {
16
+ ...shop.settings.pricing,
17
+ ...settingsValues(countrySetting?.settings?.pricing)
18
+ }
19
+ };
20
+ }
21
+
22
+ function settingsValues(settings) {
23
+ return Object.keys(settings || {}).reduce((s, key) => (!!settings[key] ? { ...s, [key]: settings[key] } : s), {});
24
+ }
@@ -26,6 +26,7 @@
26
26
  <postcode-select
27
27
  :suburb="suburb"
28
28
  :labelless="true"
29
+ :only-postcode="true"
29
30
  :placeholder="postcodeLabel"
30
31
  :label-text="postcodeInfoLabel"
31
32
  @select="handleSuburbChange" />
@@ -14,6 +14,7 @@
14
14
  min="0"
15
15
  class="form-field centered CartEntitiesGroupSizeCell__field"
16
16
  :class="{ empty: !model }"
17
+ @wheel="onWheel"
17
18
  @focus="onFocus()"
18
19
  @blur="onBlur()" />
19
20
  <div
@@ -76,6 +77,9 @@ export default {
76
77
  },
77
78
  methods: {
78
79
  ...mapActions('cart', ['setEntityAmount']),
80
+ onWheel(e) {
81
+ e.target.blur();
82
+ },
79
83
  onFocus() {
80
84
  this.defaultValue = '';
81
85
  },
@@ -20,6 +20,7 @@
20
20
  empty: !model,
21
21
  error: model > simpleProduct.quantityStock
22
22
  }"
23
+ @wheel="onWheel"
23
24
  @change="onChange()"
24
25
  @focus="onFocus()"
25
26
  @blur="onBlur()" />
@@ -119,6 +120,9 @@ export default {
119
120
  },
120
121
  methods: {
121
122
  ...mapActions('cart', ['setSimpleProductAmount']),
123
+ onWheel(e) {
124
+ e.target.blur();
125
+ },
122
126
  onChange() {
123
127
  if (this.$refs.input) {
124
128
  this.$refs.input.blur();
@@ -110,6 +110,10 @@ export default {
110
110
  type: Boolean,
111
111
  default: false
112
112
  },
113
+ onlyPostcode: {
114
+ type: Boolean,
115
+ default: false
116
+ },
113
117
  disabled: {
114
118
  type: Boolean,
115
119
  default: false
@@ -154,7 +158,14 @@ export default {
154
158
  this.isLoading = true;
155
159
  const country = this.codeCountry || this.country;
156
160
  const countryName = country ? (country.isoCode === 'GB' ? 'England' : (country.name || country)) : 'Australia';
157
- this.suburbs = await api.fetchSuburbs({ query: query.trim(), country: countryName }, this.shop?._id);
161
+ const params = {
162
+ query: query.trim(),
163
+ country: countryName
164
+ };
165
+ if (this.onlyPostcode) {
166
+ params.onlyPostcode = true;
167
+ }
168
+ this.suburbs = await api.fetchSuburbs(params, this.shop?._id);
158
169
  this.options = this.suburbs.map(this.createOptionFromSuburb);
159
170
  this.isLoading = false;
160
171
  } else {
@@ -163,9 +174,9 @@ export default {
163
174
  },
164
175
  createOptionFromSuburb({ locality, state, postcode, city, _id, address, id }) {
165
176
  return {
166
- label: address || [locality || city, state, postcode].filter(i => !!i).join(', '),
177
+ label: this.onlyPostcode ? postcode : (address || [locality || city, state, postcode].filter(i => !!i).join(', ')),
167
178
  value: postcode,
168
- _id: id || _id
179
+ _id: id || _id || postcode
169
180
  };
170
181
  },
171
182
  async updatePostcode(option) {
@@ -29,9 +29,7 @@
29
29
  </template>
30
30
  </v-popover>
31
31
  </span>
32
- <span
33
- v-if="isPrintPricing"
34
- class="lc_regular16 lc_grey1 ml-6">
32
+ <span class="lc_regular16 lc_grey1 ml-6">
35
33
  +
36
34
  <v-popover
37
35
  ref="popover"
@@ -1,4 +1,6 @@
1
+ import { mapGetters } from 'vuex';
1
2
  import { price, shortDate, tax } from '@lancom/shared/assets/js/utils/filters';
3
+ import { getShopCountrySettings } from '@lancom/shared/assets/js/utils/shop';
2
4
 
3
5
  export default {
4
6
  filters: {
@@ -22,6 +24,7 @@ export default {
22
24
  },
23
25
  },
24
26
  computed: {
27
+ ...mapGetters(['MESSAGES']),
25
28
  couponTotal() {
26
29
  return Math.abs(this.order.couponTotal || 0);
27
30
  },
@@ -34,11 +37,14 @@ export default {
34
37
  orderId() {
35
38
  return `${this.order.code}`.replace('ORDER', '');
36
39
  },
40
+ settings() {
41
+ return getShopCountrySettings(this.order.shop, this.order.country);
42
+ },
37
43
  shopContacts() {
38
- return this.order.shop.settings?.contacts || {};
44
+ return this.settings?.contacts || {};
39
45
  },
40
46
  depositInfo() {
41
- return this.order.shop.settings?.depositInfo || {};
47
+ return this.settings?.depositInfo || {};
42
48
  },
43
49
  fullName() {
44
50
  return this.invoice?.address?.fullName || this.order.shippingAddress.fullName;
@@ -69,10 +75,31 @@ export default {
69
75
  ].filter(i => !!i).join(', ');
70
76
  },
71
77
  gstTax() {
72
- return this.order.shop.settings?.pricing?.gstTax || 0;
78
+ return this.settings?.pricing?.gstTax || 0;
73
79
  },
74
80
  gstTotal() {
75
81
  return tax(this.model.total, this.gstTax) - this.model.total;
82
+ },
83
+ taxName() {
84
+ return this.settings?.pricing?.taxName || 'GST'
85
+ },
86
+ paymentCard() {
87
+ if (this.model.charge?.card) {
88
+ return {
89
+ number: this.model.charge.card.display_number,
90
+ scheme: this.model.charge.card.scheme
91
+ };
92
+ } else if (this.model.charge) {
93
+ return {
94
+ number: `XXXX-XXXX-XXXX-${this.model.charge.payment_method_details?.card?.last4 || 'XXXX'}`,
95
+ scheme: this.model.charge.payment_method_details?.card?.brand
96
+ };
97
+ }
76
98
  }
99
+ },
100
+ mounted() {
101
+ console.log('');
102
+ console.log('this.settings: ', this.settings);
103
+ console.log('this.order: ', this.order);
77
104
  }
78
105
  };
@@ -27,6 +27,13 @@
27
27
  </h5>
28
28
  </div>
29
29
  </div>
30
+ <div
31
+ v-if="depositInfo.vatNumber"
32
+ class="OrderView__info">
33
+ <h5 class="text-secondary lc_h5">
34
+ VAT Number: {{ depositInfo.vatNumber }}
35
+ </h5>
36
+ </div>
30
37
  <div class="OrderView__info">
31
38
  <div v-if="shopContacts">
32
39
  <div class="lc_regular16">
@@ -86,12 +93,12 @@
86
93
  <div class="lc_regular16">
87
94
  <b>PAID VIA CREDIT CARD</b>
88
95
  </div>
89
- <div v-if="model.charge && model.charge.card">
96
+ <div v-if="paymentCard">
90
97
  <div class="lc_regular16">
91
- Card: {{ model.charge.card.display_number }}
98
+ Card: {{ paymentCard.number }}
92
99
  </div>
93
100
  <div class="lc_regular16">
94
- Scheme: {{ model.charge.card.scheme }}
101
+ Scheme: {{ paymentCard.scheme }}
95
102
  </div>
96
103
  </div>
97
104
  </td>
@@ -99,7 +106,7 @@
99
106
  v-else
100
107
  class="w-33">
101
108
  <div class="lc_regular16">
102
- <b>DIRECT DEPOSIT DETAILS</b>
109
+ <b>{{ MESSAGES.DIRECT_DEPOSIT_DETAILS || 'DIRECT DEPOSIT DETAILS'}}</b>
103
110
  </div>
104
111
  <div class="lc_regular16">
105
112
  Bank: {{ depositInfo.bank }}
@@ -198,7 +205,6 @@
198
205
  </template>
199
206
 
200
207
  <script>
201
- import { mapGetters } from 'vuex';
202
208
  import OrderViewMixin from './order-view.mixin';
203
209
  import OrderViewProduct from './order_view_product/order-view-product';
204
210
 
@@ -213,9 +219,6 @@ export default {
213
219
  type: Boolean,
214
220
  default: true
215
221
  }
216
- },
217
- computed: {
218
- ...mapGetters(['taxName'])
219
222
  }
220
223
  };
221
224
  </script>
@@ -19,11 +19,14 @@
19
19
  <product-main-info :product="product" />
20
20
  </section>
21
21
  <section class="Product__section">
22
- <product-colors-selector v-if="productDetails" />
22
+ <wizard-editor />
23
23
  </section>
24
- <section class="Product__section">
24
+ <!-- <section class="Product__section">
25
+ <product-colors-selector v-if="productDetails" />
26
+ </section> -->
27
+ <!-- <section class="Product__section">
25
28
  <product-tier-prices :product="product" />
26
- </section>
29
+ </section> -->
27
30
  <section class="Product__section">
28
31
  <product-fabric-and-size-info :product="product" />
29
32
  </section>
@@ -50,6 +53,8 @@ import ProductModelMeasurements from './layouts/product_model_measurements/produ
50
53
  import ProductSizeTable from './layouts/product_size_table/product-size-table';
51
54
  import RelatedProducts from '@lancom/shared/components/product/related_products/related-products';
52
55
  import Gallery from '@lancom/shared/components/product/gallery/gallery';
56
+ import WizardEditor from './wizard-editor/wizard-editor.vue';
57
+
53
58
 
54
59
  // import ProductLabelsCustomization from './layouts/product_labels_customization/product-labels-customization';
55
60
 
@@ -64,7 +69,8 @@ export default {
64
69
  ProductModelMeasurements,
65
70
  ProductSizeTable,
66
71
  RelatedProducts,
67
- Gallery
72
+ Gallery,
73
+ WizardEditor
68
74
  // ProductLabelsCustomization
69
75
  },
70
76
  computed: {
@@ -27,6 +27,7 @@
27
27
  :class="{ invalidate: disabled, empty: !model }"
28
28
  :aria-label="size.name"
29
29
  :disabled="disabled"
30
+ @wheel="onWheel"
30
31
  @focus="onFocus()"
31
32
  @blur="onBlur()" />
32
33
  <div
@@ -117,6 +118,9 @@ export default {
117
118
  },
118
119
  methods: {
119
120
  ...mapMutations('product', ['setSimpleProductAmount']),
121
+ onWheel(e) {
122
+ e.target.blur();
123
+ },
120
124
  onFocus() {
121
125
  this.defaultValue = '';
122
126
  },
@@ -0,0 +1,30 @@
1
+ <template>
2
+ <div class="EditorAsync__wrapper">
3
+ <placeholder
4
+ v-if="!isLoadedComponent"
5
+ style="height: 500px" />
6
+ <wizard-editor
7
+ v-else
8
+ v-bind="$attrs" />
9
+ </div>
10
+ </template>
11
+
12
+ <script>
13
+ import Vue from 'vue';
14
+ import ComponentAsyncMixin from '@lancom/shared/mixins/component-async';
15
+ import Placeholder from '@lancom/shared/components/placeholder/placeholder';
16
+
17
+ export default {
18
+ name: 'EditorAsync',
19
+ components: {
20
+ Placeholder
21
+ },
22
+ mixins: [ComponentAsyncMixin],
23
+ methods: {
24
+ async importComponents() {
25
+ const component = await import('./wizard-editor');
26
+ Vue.component('wizard-editor', component.default);
27
+ }
28
+ }
29
+ };
30
+ </script>
@@ -0,0 +1,37 @@
1
+ @import '@/assets/scss/variables';
2
+
3
+ .Editor {
4
+ &__section {
5
+ margin-bottom: 20px;
6
+ position: relative;
7
+ }
8
+ &__colors-selector {
9
+ &--disabled {
10
+ opacity: 0.5;
11
+ pointer-events: none;
12
+ }
13
+ }
14
+ &__tooltip-message {
15
+ width: 250px;
16
+ font-size: 14px;
17
+ padding: 20px;
18
+ background: $green;
19
+ color: $black;
20
+ position: absolute;
21
+ top: 150px;
22
+ left: 50%;
23
+ width: 272px;
24
+ font-size: 14px;
25
+ padding: 10px;
26
+ line-height: 23px;
27
+ border-radius: 4px;
28
+ text-align: center;
29
+ font-weight: bold;
30
+ z-index: 2;
31
+ margin-left: -125px;
32
+ span {
33
+ text-decoration: underline;
34
+ cursor: pointer;
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <div class="Editor__wrapper">
3
+ <div>
4
+ <div
5
+ v-if="productDetailsLoaded"
6
+ class="Editor__wizard">
7
+ <div class="Editor__section">
8
+ <wizard
9
+ ref="wizard"
10
+ v-show="visibleWizard" />
11
+ </div>
12
+ <div
13
+ v-if="editableColor"
14
+ class="Editor__section">
15
+ <product-multipacks-carousel
16
+ :key="editableColor._id"
17
+ :product="product"
18
+ :color="editableColor"
19
+ :simple-products="simpleProducts"
20
+ :with-gst="priceIncludeGST" />
21
+ </div>
22
+ <div
23
+ class="Editor__section"
24
+ @mouseenter="onColorsSelectorMouseenter"
25
+ @mouseleave="onColorsSelectorMouseleave"
26
+ @mousemove="onColorsSelectorMousemoveWithThrottle">
27
+ <product-colors-selector
28
+ class="Editor__colors-selector"
29
+ :class="{
30
+ 'Editor__colors-selector--disabled': disabledProductsSelector
31
+ }" />
32
+ <div
33
+ v-show="disabledProductsSelector"
34
+ ref="message"
35
+ class="Editor__tooltip-message">
36
+ You must complete the print details above, or <span @click="hideWizard()">cancel</span> the print
37
+ </div>
38
+ </div>
39
+ <div class="Editor__section">
40
+ <editor-pricing />
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </template>
46
+
47
+ <script>
48
+ import { mapGetters } from 'vuex';
49
+ import throttle from 'lodash.throttle';
50
+ import ProductMultipacksCarousel from '@lancom/shared/components/product/product_multipacks_carousel/product-multipacks-carousel';
51
+ import Wizard from '@lancom/shared/components/product/wizard/wizard';
52
+ import ProductColorsSelector from '@lancom/shared/components/product/product_colors_selector/product-colors-selector';
53
+ import EditorPricing from '@lancom/shared/components/product/editor_pricing/editor-pricing';
54
+
55
+ export default {
56
+ name: 'Editor',
57
+ components: {
58
+ ProductColorsSelector,
59
+ ProductMultipacksCarousel,
60
+ Wizard,
61
+ EditorPricing
62
+ },
63
+ data() {
64
+ return {
65
+ isVisibleMessage: false,
66
+ onColorsSelectorMousemoveWithThrottle: throttle(this.onColorsSelectorMousemove, 20)
67
+ };
68
+ },
69
+ computed: {
70
+ ...mapGetters('product', [
71
+ 'product',
72
+ 'simpleProducts',
73
+ 'editableColorSimpleProducts',
74
+ 'editableColor',
75
+ 'productDetailsLoaded',
76
+ 'hasLayers',
77
+ 'isPrintPricing',
78
+ 'priceIncludeGST'
79
+ ]),
80
+ visibleWizard() {
81
+ return (this.product.printTypes || []).length > 0;
82
+ },
83
+ disabledProductsSelector() {
84
+ return this.isPrintPricing && !this.hasLayers;
85
+ }
86
+ },
87
+ destroyed() {
88
+ if (this.$refs.message) {
89
+ document.body.removeChild(this.$refs.message);
90
+ }
91
+ },
92
+ methods: {
93
+ onColorsSelectorMouseenter() {
94
+ // this.isVisibleMessage = this.disabledProductsSelector;
95
+ },
96
+ onColorsSelectorMousemove({ clientX, clientY }) {
97
+ // if (this.isVisibleMessage && this.$refs.message) {
98
+ // document.body.appendChild(this.$refs.message);
99
+ // this.$refs.message.style.display = 'block';
100
+ // this.$refs.message.style.top = `${clientY}px`;
101
+ // this.$refs.message.style.left = ('ontouchstart' in window) ? '50%' : `${clientX}px`;
102
+ // }
103
+ },
104
+ onColorsSelectorMouseleave() {
105
+ // if (this.isVisibleMessage && this.$refs.message) {
106
+ // document.body.removeChild(this.$refs.message);
107
+ // }
108
+ // this.isVisibleMessage = false;
109
+ // this.$refs.message.style.display = 'none';
110
+ },
111
+ hideWizard() {
112
+ this.$refs.wizard.toggleVisible();
113
+ }
114
+ }
115
+ };
116
+ </script>
117
+
118
+ <style lang="scss">
119
+ @import 'wizard-editor';
120
+ </style>
@@ -38,7 +38,7 @@
38
38
  <products-autocomplete-item
39
39
  v-for="product of products"
40
40
  :key="product._id"
41
- :to-editor="false"
41
+ :to-editor="toEditor"
42
42
  :product="product"
43
43
  class="ProductsAutocomplete__result-item"
44
44
  @select="$emit('select', product)" />
@@ -71,6 +71,10 @@ export default {
71
71
  placeholder: {
72
72
  type: String,
73
73
  default: 'Search products'
74
+ },
75
+ toEditor: {
76
+ type: Boolean,
77
+ default: false
74
78
  }
75
79
  },
76
80
  data() {
@@ -34,7 +34,7 @@ export default (IS_PRODUCT_PRESET_PRINT_PRICING) => ({
34
34
  if (IS_PRODUCT_PRESET_PRINT_PRICING) {
35
35
  const printType = product.printTypes[0];
36
36
  store.commit('product/setSelectedPrintType', printType);
37
- store.commit('product/setIsPrintPricing', true);
37
+ // store.commit('product/setIsPrintPricing', true);
38
38
  }
39
39
 
40
40
  if (query.store) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.287",
3
+ "version": "0.0.288",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
package/store/index.js CHANGED
@@ -3,7 +3,7 @@ import { saveStatePlugin, loadState } from '@lancom/shared/plugins/save-state';
3
3
  import { MESSAGES, COUNTRIES_MESSAGES } from '@/messages';
4
4
  const cookieparser = process.server ? require('cookieparser') : undefined;
5
5
  const CLOSED_NOTIFICATION = 'lancom-closed-notification-1.0';
6
-
6
+ import { getShopCountrySettings } from '@lancom/shared/assets/js/utils/shop';
7
7
 
8
8
  export const state = () => ({
9
9
  country: null,
@@ -50,7 +50,6 @@ export const actions = {
50
50
  const menus = await api.fetchMenus(shop._id);
51
51
  commit('setMenus', menus);
52
52
  commit('setShop', shop);
53
- commit('setSettings', shop.settings);
54
53
  // if (req.headers.cookie) {
55
54
  const { country, currency } = (req.headers.cookie && cookieparser.parse(req.headers.cookie)) || {};
56
55
  const headers = (req && req.headers) ? Object.assign({}, req.headers) : {};
@@ -59,14 +58,16 @@ export const actions = {
59
58
  commit('setCountry', settings.country);
60
59
  commit('setCurrency', settings.currency);
61
60
 
62
- const countrySettings = (shop.countries || []).find(c => c.country?._id === settings.country?._id) || { settings: [] };
63
-
61
+ const countrySetting = getShopCountrySettings(shop, settings.country);
62
+ commit('setSettings', countrySetting);
63
+
64
64
  if (process.env.PINPAYMENT_PUBLISHABLE_API_KEY) {
65
65
  commit('setPayment', {
66
66
  type: 'pinpayment',
67
67
  clientKey: process.env.PINPAYMENT_PUBLISHABLE_API_KEY
68
68
  });
69
69
  } else {
70
+ const countrySettings = (shop.countries || []).find(c => c.country?._id === settings.country?._id) || { settings: [] };
70
71
  const countrySetting = (countrySettings?.settings || []).find(s => !!s.settings.app.STRIPE_PUBLIC_KEY);
71
72
  if (countrySetting) {
72
73
  commit('setPayment', {
@@ -76,13 +77,6 @@ export const actions = {
76
77
  }
77
78
  }
78
79
 
79
-
80
- const pricingSetting = (countrySettings?.settings || []).find(s => !!s.settings.pricing);
81
- commit('setPricing', {
82
- ...shop.settings.pricing,
83
- ...(pricingSetting?.settings?.pricing || {})
84
- });
85
-
86
80
  // }
87
81
  try {
88
82
  if (req.headers.cookie) {
@@ -142,12 +136,13 @@ export const mutations = {
142
136
  setCurrency(state, currency) {
143
137
  state.currency = currency;
144
138
  },
145
- setSettings(state, { contacts, notificationBar, discountPopup, order, depositInfo }) {
139
+ setSettings(state, { contacts, notificationBar, discountPopup, order, depositInfo, pricing }) {
146
140
  state.contacts = contacts;
147
141
  state.orderInfo = order;
148
142
  state.notificationBar = notificationBar;
149
143
  state.discountPopup = discountPopup;
150
144
  state.depositInfo = depositInfo;
145
+ state.pricing = pricing;
151
146
  },
152
147
  setShop(state, shop) {
153
148
  state.shop = shop;
package/store/product.js CHANGED
@@ -364,8 +364,8 @@ export const mutations = {
364
364
  ];
365
365
  Vue.set(state.template, 'layers', layers);
366
366
  if (layers.length === 1 && !state.product.printOnly) {
367
- const printType = state.product.printTypes[0];
368
- state.selectedPrintType = printType;
367
+ // const printType = state.product.printTypes[0];
368
+ // state.selectedPrintType = printType;
369
369
  state.isPrintPricing = true;
370
370
  }
371
371
  },
@@ -376,7 +376,7 @@ export const mutations = {
376
376
  state.selectedLayer = null;
377
377
  }
378
378
  if (state.template.layers.length === 0 && !state.product.printOnly) {
379
- state.selectedPrintType = null;
379
+ // state.selectedPrintType = null;
380
380
  state.isPrintPricing = false;
381
381
  }
382
382
  },