@lancom/shared 0.0.91 → 0.0.95

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.
Files changed (34) hide show
  1. package/assets/js/api/admin.js +12 -0
  2. package/assets/js/api/helpers.js +2 -1
  3. package/assets/js/utils/filters.js +6 -2
  4. package/assets/js/utils/product.js +3 -2
  5. package/components/checkout/cart/cart.mixin.js +3 -3
  6. package/components/checkout/cart/cart_entity/cart-entity.vue +8 -0
  7. package/components/checkout/cart/cart_price_info/cart-price-info.scss +10 -0
  8. package/components/checkout/cart/cart_price_info/cart-price-info.vue +9 -3
  9. package/components/checkout/cart/cart_shipments_pricing/cart-shipments-pricing.scss +54 -0
  10. package/components/checkout/cart/cart_shipments_pricing/cart-shipments-pricing.vue +110 -0
  11. package/components/checkout/order/address-form/address-form.vue +1 -1
  12. package/components/checkout/order/order-billing-information/order-billing-information.vue +0 -8
  13. package/components/checkout/order/order-shipping-method/order-shipping-method.vue +1 -1
  14. package/components/common/progress_steps/progress-steps.scss +1 -1
  15. package/components/editor/editor.vue +0 -8
  16. package/components/editor/editor_layers/editor_layer_forms/editor_layer_common_fields/editor-layer-common-fields.vue +0 -49
  17. package/components/editor/editor_layers/editor_layer_forms/editor_layer_form_art/editor-layer-form-art.vue +0 -6
  18. package/components/editor/editor_pricing/editor-pricing.vue +2 -4
  19. package/components/editor/editor_workspace/editor_workspace_side/editor-workspace-side.vue +0 -3
  20. package/components/modals/order_modal/order-modal.vue +1 -1
  21. package/components/order/order_payment/order-payment.vue +0 -4
  22. package/components/order/order_status/order-status.vue +0 -18
  23. package/components/product/layouts/product_model_measurements/product-model-measurements.vue +0 -5
  24. package/components/product/product.vue +0 -7
  25. package/components/products/products_attributes/products-attributes.vue +0 -3
  26. package/components/products/products_brands/products-brands.vue +2 -2
  27. package/components/products/products_colors/products-colors.scss +2 -1
  28. package/components/products/products_filters/products-filters.vue +0 -17
  29. package/components/quotes/quote_request/quote-request.vue +0 -6
  30. package/nuxt.config.js +3 -3
  31. package/package.json +1 -1
  32. package/store/auth.js +1 -0
  33. package/store/cart.js +86 -32
  34. package/store/order.js +1 -0
@@ -188,6 +188,18 @@ export default {
188
188
  removeSupplier(id) {
189
189
  return _delete(`admin/suppliers/${id}`);
190
190
  },
191
+ async fetchWarehouses(params) {
192
+ return sortByName(await _get('admin/warehouse', params));
193
+ },
194
+ fetchWarehouseById(id) {
195
+ return _get(`admin/warehouse/${id}`);
196
+ },
197
+ saveWarehouse(brand) {
198
+ return brand._id ? _put(`admin/warehouse/${brand._id}`, brand) : _post('admin/warehouse', brand);
199
+ },
200
+ removeWarehouse(id) {
201
+ return _delete(`admin/warehouse/${id}`);
202
+ },
191
203
  async fetchBanners(params) {
192
204
  return sortByName(await _get('admin/banners', params));
193
205
  },
@@ -17,7 +17,8 @@ if (process.client) {
17
17
  });
18
18
  }
19
19
 
20
- export const buildPath = path => `${process.env.API_URL}/${path}`;
20
+ const API_URL = process.client ? process.env.API_URL : process.env.LOCAL_API_URL;
21
+ export const buildPath = path => `${API_URL}/${path}`;
21
22
 
22
23
  export const prepareHeaders = method => {
23
24
  const headers = {};
@@ -16,7 +16,7 @@ export const number = (value, digits = 0) => {
16
16
  return fixed.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
17
17
  };
18
18
 
19
- export const decimal = value => number(value || 0, 2);
19
+ export const decimal = (value, digits = 2) => number(value || 0, digits);
20
20
 
21
21
  export const price = (value = 0, currency = 'USD') => {
22
22
  const amount = number(value, 2);
@@ -56,8 +56,12 @@ export const print = type => printsLabels[type];
56
56
 
57
57
  export const side = type => SIDE_TYPES[type];
58
58
 
59
+ export const commaArray = (list = []) => {
60
+ return list.join(', ');
61
+ };
62
+
59
63
  export const printsRange = (prints = []) => {
60
- return prints.join(', ');
64
+ return commaArray(prints);
61
65
  };
62
66
 
63
67
  export const highlight = (string = '', query) => {
@@ -11,11 +11,12 @@ export function getProductsForCalculatePricing(mainProduct, simpleProducts, laye
11
11
  _id: mainProduct._id,
12
12
  prints: hasPrints ? prints.map(p => isCLearPrintsLayers ? ({ ...p, layers: null }) : p) : null,
13
13
  printSurcharge: mainProduct.printSurcharge || 0,
14
- simpleProducts: simpleProducts.map(({ _id, amount, pricing, unprintedPricing, weight }) => ({
14
+ simpleProducts: simpleProducts.map(({ _id, amount, pricing, unprintedPricing, weight, volume }) => ({
15
15
  _id,
16
16
  amount,
17
17
  pricing: hasPrints ? pricing : unprintedPricing,
18
- weight: weight || mainProduct.weight
18
+ weight: weight || mainProduct.weight,
19
+ volume: volume || mainProduct.volume
19
20
  }))
20
21
  }];
21
22
  }
@@ -28,11 +28,11 @@ export default {
28
28
  },
29
29
  watch: {
30
30
  entities() {
31
- this.calculateCartPrice(this.shop);
31
+ this.calculateCartPrice({ shop: this.shop });
32
32
  }
33
33
  },
34
34
  mounted() {
35
- this.calculateCartPrice(this.shop);
35
+ this.calculateCartPrice({ shop: this.shop });
36
36
  if (!this.suburb && this.user?.suburb) {
37
37
  this.handleSuburbChange(this.user.suburb);
38
38
  }
@@ -47,7 +47,7 @@ export default {
47
47
  ]),
48
48
  handleSuburbChange(suburb) {
49
49
  this.setSuburb(suburb);
50
- this.calculateCartPrice(this.shop);
50
+ this.calculateCartPrice({ shop: this.shop });
51
51
  },
52
52
  async removeSimpleProducts(simpleProducts) {
53
53
  const message = 'This will delete all items in this row, Press OK to continue or Cancel';
@@ -17,6 +17,14 @@
17
17
  {{ product.SKU }}
18
18
  </div>
19
19
  </div>
20
+ <div class="CartEntity__feature">
21
+ <div class="lc_title-small">
22
+ Brand:
23
+ </div>
24
+ <div class="lc_body-small">
25
+ {{ product.brand.name }}
26
+ </div>
27
+ </div>
20
28
  </div>
21
29
  <div>
22
30
  <cart-entity-color-simple-products
@@ -0,0 +1,10 @@
1
+ @import '@/assets/scss/variables';
2
+
3
+ .CartPriceInfo {
4
+ &__error {
5
+ padding: 10px;
6
+ font-size: 12px;
7
+ color: $white;
8
+ background-color: $error;
9
+ }
10
+ }
@@ -1,11 +1,16 @@
1
1
  <template>
2
- <div>
2
+ <div class="CartPriceInfo__wrapper">
3
3
  <slot name="cart-pricing" v-bind="{ cartPricing, itemsLabel }">
4
4
  <product-total-pricing
5
5
  v-if="cartPricing && cartPricing.amount"
6
6
  :pricing="cartPricing"
7
7
  :items-label="itemsLabel" />
8
8
  </slot>
9
+ <div
10
+ v-if="cartPricingError"
11
+ class="CartPriceInfo__error">
12
+ {{ cartPricingError }}
13
+ </div>
9
14
  </div>
10
15
  </template>
11
16
 
@@ -39,7 +44,8 @@ export default {
39
44
  ...mapGetters(['shop']),
40
45
  ...mapGetters('cart', [
41
46
  'entities',
42
- 'cartPricing'
47
+ 'cartPricing',
48
+ 'cartPricingError'
43
49
  ])
44
50
  },
45
51
  watch: {
@@ -55,7 +61,7 @@ export default {
55
61
  'calculateCartPrice'
56
62
  ]),
57
63
  calculatePrice() {
58
- this.calculateCartPrice(this.shop);
64
+ this.calculateCartPrice({ shop: this.shop });
59
65
  }
60
66
  }
61
67
  };
@@ -0,0 +1,54 @@
1
+ @import '@/assets/scss/variables';
2
+
3
+ .CartShipmentsPricing {
4
+ &__title {
5
+ padding-top: 15px;
6
+ padding-bottom: 5px;
7
+ display: flex;
8
+ justify-content: space-between;
9
+ a {
10
+ color: $black
11
+ }
12
+ }
13
+ &__supplier {
14
+ padding: 15px 10px 15px 10px;
15
+ border-bottom: 1px solid #e3e3e3;
16
+ &:last-child {
17
+ border-bottom: none;
18
+ }
19
+ &-info {
20
+ display: flex;
21
+ justify-content: space-between;
22
+ font-weight: bold;
23
+ font-size: 16px;
24
+ }
25
+ &-brands {
26
+ display: flex;
27
+ i {
28
+ margin-left: -2px;
29
+ margin-right: 8px;
30
+ cursor: pointer;
31
+ }
32
+ }
33
+ }
34
+ &__rate {
35
+ cursor: pointer;
36
+ display: flex;
37
+ justify-content: space-between;
38
+ align-items: center;
39
+ margin-top: 10px;
40
+ font-size: 16px;
41
+ &--disabled {
42
+ pointer-events: none !important;
43
+ opacity: 0.6;
44
+ cursor: default;
45
+ }
46
+ &-icon {
47
+ margin-right: 10px;
48
+ }
49
+ &-info {
50
+ display: flex;
51
+ align-items: center;
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <div class="CartShipmentsPricing__wrapper">
3
+ <div v-if="hasSuppliersWithRates">
4
+ <div class="CartShipmentsPricing__title">
5
+ <div class="lc_body-large lc_gray-main">Delivery</div>
6
+ <a
7
+ href="/info/shipping-info"
8
+ target="_blank">
9
+ Learn more <i class="icon-target"></i>
10
+ </a>
11
+ </div>
12
+ <div
13
+ v-for="(supplier, index) of suppliersWithRates"
14
+ :key="index"
15
+ class="CartShipmentsPricing__supplier">
16
+ <div class="CartShipmentsPricing__supplier-info">
17
+ <div class="CartShipmentsPricing__supplier-brands">
18
+ <div @click="removeSupplierConfirm(supplier)">
19
+ <i class="icon-delete"></i>
20
+ </div>
21
+ <div>
22
+ {{ supplier.brands.map(b => b.name) | commaArray }}
23
+ </div>
24
+ </div>
25
+ <div>
26
+ {{ supplier | selectedRatePrice | price }}
27
+ </div>
28
+ </div>
29
+ <div
30
+ v-for="(rate, i) of supplier.rates"
31
+ :key="`rate-${i}`"
32
+ class="CartShipmentsPricing__rate"
33
+ :class="{
34
+ 'CartShipmentsPricing__rate--disabled': rate.disabled
35
+ }"
36
+ @click="selectRate({ supplier, rate, shop })">
37
+ <div class="CartShipmentsPricing__rate-info">
38
+ <div class="CartShipmentsPricing__rate-icon">
39
+ <checked-icon :checked="rate.selected" />
40
+ </div>
41
+ <div class="CartShipmentsPricing__rate-name">
42
+ <div>{{ rate.name }}</div>
43
+ <div
44
+ v-if="rate.note"
45
+ class="lc_regular10">
46
+ {{ rate.note }}
47
+ </div>
48
+ </div>
49
+ </div>
50
+ <div class="CartShipmentsPricing__rate-price">
51
+ {{ rate.totalPriceWithoutTax | price }}
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </template>
58
+
59
+ <script>
60
+ import { mapGetters, mapActions } from 'vuex';
61
+ import { price, commaArray } from '@lancom/shared/assets/js/utils/filters';
62
+ import CheckedIcon from '@lancom/shared/components/common/checked-icon';
63
+ import confirm from '@lancom/shared/mixins/confirm';
64
+
65
+ export default {
66
+ name: 'LancomCartShipmentsPricing',
67
+ components: {
68
+ CheckedIcon
69
+ },
70
+ filters: {
71
+ price,
72
+ commaArray,
73
+ selectedRatePrice(supplier) {
74
+ const { totalPriceWithoutTax = 0 } = supplier.rates.find(r => r.selected) || {};
75
+ return totalPriceWithoutTax;
76
+ }
77
+ },
78
+ mixins: [confirm],
79
+ computed: {
80
+ ...mapGetters(['shop']),
81
+ ...mapGetters('cart', [
82
+ 'cartPricing'
83
+ ]),
84
+ hasSuppliersWithRates() {
85
+ return this.suppliersWithRates.length > 0;
86
+ },
87
+ suppliersWithRates() {
88
+ return this.cartPricing?.shipping?.suppliersWithRates || [];
89
+ }
90
+ },
91
+ methods: {
92
+ ...mapActions('cart', [
93
+ 'selectRate',
94
+ 'removeSupplier'
95
+ ]),
96
+ async removeSupplierConfirm(supplier) {
97
+ const message = `Will be removed all products related to brands: ${commaArray(supplier.brands.map(b => b.name))}. Are you sure?`;
98
+ const reset = await this.showConfirmationModal(message);
99
+
100
+ if (reset) {
101
+ this.removeSupplier({ supplier, shop: this.shop });
102
+ }
103
+ }
104
+ }
105
+ };
106
+ </script>
107
+
108
+ <style lang="scss" scoped>
109
+ @import 'cart-shipments-pricing.scss';
110
+ </style>
@@ -295,7 +295,7 @@ export default {
295
295
  handleSuburbChange(suburb) {
296
296
  this.setAddressSuburb(suburb);
297
297
  this.setSuburb(suburb);
298
- this.calculateCartPrice(this.shop);
298
+ this.calculateCartPrice({ shop: this.shop });
299
299
  }
300
300
  }
301
301
  };
@@ -11,14 +11,6 @@
11
11
  <address-form
12
12
  :address="order.shippingAddress"
13
13
  :without-additional-info="true" />
14
- <!-- <div class="form-row mt-10">
15
- <label class="form-label">
16
- <checkbox v-model="copyToShippingAddress" />
17
- <span class="lc_regular14 lc__grey1">
18
- Ship to this address
19
- </span>
20
- </label>
21
- </div> -->
22
14
  </div>
23
15
  <progress-steps-controls
24
16
  :disabled-next="invalid || !order.shippingAddress.postcode"
@@ -53,7 +53,7 @@ export default {
53
53
  },
54
54
  mounted() {
55
55
  if (!this.shippingPricing) {
56
- this.calculateCartPrice(this.shop);
56
+ this.calculateCartPrice({ shop: this.shop });
57
57
  }
58
58
  },
59
59
  methods: {
@@ -25,7 +25,7 @@
25
25
  &__content-wrapper {
26
26
  padding: 51px;
27
27
  position: relative;
28
- @media (max-width: $bp-extra-small-max) {
28
+ @media (max-width: $bp-large-max) {
29
29
  padding: 15px;
30
30
  }
31
31
  }
@@ -1,13 +1,5 @@
1
1
  <template>
2
2
  <div class="Editor__wrapper">
3
- <!-- <div class="Editor__header">
4
- <nuxt-link
5
- to="/"
6
- class="lc_link">
7
- <i class="icon-left"></i>
8
- Go to all models
9
- </nuxt-link>
10
- </div> -->
11
3
  <div class="Editor__content row">
12
4
  <breakpoint
13
5
  name="md"
@@ -20,55 +20,6 @@
20
20
  </div>
21
21
  </div>
22
22
  </div>
23
- <!-- <div class="form-row">
24
- <div class="form-label">
25
- Align:
26
- </div>
27
- <div class="EditorLayerCommonFields__align-options">
28
- <div
29
- v-tooltip="'Center vertically'"
30
- class="EditorLayerCommonFields__align-option ripple"
31
- :class="{ active: alignVertically === 'center' }"
32
- @click="alignVertically = 'center'">
33
- <i class="icon-vertical-align-center"></i>
34
- </div>
35
- <div
36
- v-tooltip="'Center horizontally'"
37
- class="EditorLayerCommonFields__align-option ripple"
38
- :class="{ active: alignHorizontally === 'center' }"
39
- @click="alignHorizontally = 'center'">
40
- <i class="icon-horizonal-align-center"></i>
41
- </div>
42
- <div
43
- v-tooltip="'Left'"
44
- class="EditorLayerCommonFields__align-option ripple"
45
- :class="{ active: alignHorizontally === 'left' }"
46
- @click="alignHorizontally = 'left'">
47
- <i class="icon-horizonal-align-left"></i>
48
- </div>
49
- <div
50
- v-tooltip="'Right'"
51
- class="EditorLayerCommonFields__align-option ripple"
52
- :class="{ active: alignHorizontally === 'right' }"
53
- @click="alignHorizontally = 'right'">
54
- <i class="icon-horizonal-align-right"></i>
55
- </div>
56
- <div
57
- v-tooltip="'Top'"
58
- class="EditorLayerCommonFields__align-option ripple"
59
- :class="{ active: alignVertically === 'top' }"
60
- @click="alignVertically = 'top'">
61
- <i class="icon-vertical-align-top"></i>
62
- </div>
63
- <div
64
- v-tooltip="'Bottom'"
65
- class="EditorLayerCommonFields__align-option ripple"
66
- :class="{ active: alignVertically === 'bottom' }"
67
- @click="alignVertically = 'bottom'">
68
- <i class="icon-vertical-align-bottom"></i>
69
- </div>
70
- </div>
71
- </div> -->
72
23
  </fragment>
73
24
  </template>
74
25
 
@@ -5,12 +5,6 @@
5
5
  name="header"
6
6
  :invalid="invalid">
7
7
  </slot>
8
- <!-- <div class="EditorLayerFormArt__content">
9
- <input
10
- v-model="url"
11
- readonly
12
- class="form-field" />
13
- </div> -->
14
8
  <editor-layer-common-fields
15
9
  :layer="layer"
16
10
  @set-layer-field="data => $emit('set-layer-field', data)">
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <div class="EditorPricing__wrapper">
3
3
  <div class="EditorPricing__main">
4
- <!-- no qty, no layers -->
5
4
  <fragment v-if="!hasUsedSimpleProducts && !layers.length">
6
5
  <div class="EditorPricing__main-alert">
7
6
  <i class="icon-attention-circled"></i>
@@ -17,7 +16,6 @@
17
16
  </div>
18
17
  </fragment>
19
18
 
20
- <!-- has qty, no layers -->
21
19
  <fragment v-else-if="hasUsedSimpleProducts && !layers.length">
22
20
  <div class="EditorPricing__main-alert">
23
21
  <i class="icon-attention-circled"></i>
@@ -36,7 +34,7 @@
36
34
  </div>
37
35
  </div>
38
36
  </fragment>
39
- <!-- no qty, has layers -->
37
+
40
38
  <fragment v-else-if="!hasUsedSimpleProducts && layers.length">
41
39
  <div class="EditorPricing__main-alert">
42
40
  <i class="icon-attention-circled"></i>
@@ -55,7 +53,7 @@
55
53
  </div>
56
54
  </div>
57
55
  </fragment>
58
- <!-- has qty, has layers -->
56
+
59
57
  <fragment v-else>
60
58
  <div class="EditorPricing__main-row">
61
59
  <div class="lc_regular14 EditorPricing__main-col">
@@ -62,9 +62,6 @@
62
62
  class="EditorWorkspaceSide__alert-error view-transition">
63
63
  <i class="icon-attention-circled"></i>
64
64
  Part of your design layer is outside the print area.
65
- <!-- <i
66
- class="icon-cancel EditorWorkspaceSide__offset-warning-close"
67
- @click="offsetWarningVisible = false"></i> -->
68
65
  </div>
69
66
  </transition-group>
70
67
  </div>
@@ -331,7 +331,7 @@ export default {
331
331
  handleSuburbChange(suburb) {
332
332
  this.form.suburb = suburb;
333
333
  this.setSuburb(suburb);
334
- this.calculateCartPrice(this.shop);
334
+ this.calculateCartPrice({ shop: this.shop });
335
335
  },
336
336
  back() {
337
337
  this.switchModal('showCartModal');
@@ -12,10 +12,6 @@
12
12
  btn-class="green PaymentSuccess__btn"
13
13
  btn-label="GO HOME"
14
14
  to="/" />
15
- <!-- <btn
16
- btn-class="green PaymentSuccess__btn"
17
- btn-label="VIEW ORDER"
18
- :to="`/order/${order.token}`" /> -->
19
15
  </div>
20
16
  </template>
21
17
  </payment-success>
@@ -18,24 +18,6 @@
18
18
  {{ order.status }}
19
19
  </div>
20
20
  </div>
21
- <!-- <h4 class="lc_h4">
22
- Special
23
- </h4>
24
- <div class="OrderStatus__value">
25
- <div v-if="isEditable">
26
- <label class="form-label PaymentModal__label-with-checkbox">
27
- <checkbox v-model="order.special" @change="changeStatus" />
28
- <span class="lc_regular14 lc__grey1">
29
- Special Order
30
- </span>
31
- </label>
32
- </div>
33
- <div
34
- v-else
35
- class="OrderStatus__status">
36
- {{ order.special ? 'Yes' : 'No' }}
37
- </div>
38
- </div> -->
39
21
  </div>
40
22
  </template>
41
23
 
@@ -9,11 +9,6 @@
9
9
  src="~static/images/measurements_model.svg"
10
10
  class="ProductModelMeasurements__icon" />
11
11
  <div class="form-actions center">
12
- <!-- <btn
13
- btn-class="green-link"
14
- btn-label="Show model image"
15
- @click="showModel">
16
- </btn> -->
17
12
  </div>
18
13
  </td>
19
14
  <td>
@@ -30,13 +30,6 @@
30
30
  </section>
31
31
  </div>
32
32
  </div>
33
- <!-- <div class="row Product__section-row">
34
- <div class="col-12">
35
- <section class="Product__section">
36
- <product-labels-customization />
37
- </section>
38
- </div>
39
- </div> -->
40
33
  </div>
41
34
  </template>
42
35
 
@@ -2,7 +2,6 @@
2
2
  <div
3
3
  v-if="attributes.length"
4
4
  class="ProductsAttributes__wrapper">
5
- <!-- <toggle-content label="Attributes"> -->
6
5
  <div
7
6
  v-for="attribute in attributes"
8
7
  :key="attribute._id"
@@ -11,13 +10,11 @@
11
10
  :attribute="attribute"
12
11
  :has-selected-icon="hasSelectedIcon" />
13
12
  </div>
14
- <!-- </toggle-content> -->
15
13
  </div>
16
14
  </template>
17
15
 
18
16
  <script>
19
17
  import { mapGetters } from 'vuex';
20
- // import ToggleContent from '@lancom/shared/components/common/toggle-content';
21
18
  import ProductsAttribute from './products_attribute/products-attribute';
22
19
 
23
20
  export default {
@@ -43,8 +43,8 @@ export default {
43
43
  computed: {
44
44
  ...mapGetters('products', ['brands', 'types']),
45
45
  list() {
46
- const type = this.types.find(type => type.alias === this.$route.params.type);
47
- return type ? this.brands.filter(({ productTypes = [] }) => productTypes.some(t => type._id === t)) : this.brands;
46
+ // const type = this.types.find(type => type.alias === this.$route.params.type);
47
+ return this.brands;
48
48
  },
49
49
  currentBrand() {
50
50
  return this.$route.params.brand;
@@ -12,7 +12,8 @@
12
12
  &__selected-item {
13
13
  display: flex;
14
14
  align-items: center;
15
- font-size: 18px;
15
+ font-size: 12px;
16
+ font-weight: bold;
16
17
  margin: 12px 0;
17
18
  padding-top: 4px;
18
19
  color: $grey_1;
@@ -20,23 +20,6 @@
20
20
  class="icon-filter ProductsFilters__menu-toggle"
21
21
  @click="$emit('open')"></i>
22
22
  </div>
23
- <!-- <div class="ProductsFilters__search hidden-sm-and-down">
24
- <input
25
- v-model="search"
26
- name="search"
27
- placeholder="Search"
28
- type="text"
29
- class="form-field no-label tiny-placeholder labelless"
30
- @change="goToTextSearch" />
31
- <i class="icon-search"></i>
32
- </div> -->
33
- <!-- <multiselect
34
- v-model="sortBy"
35
- :options="sortByOptions"
36
- :option-height="35"
37
- value="value"
38
- label="label"
39
- class="labelless" /> -->
40
23
  </div>
41
24
  </template>
42
25
 
@@ -1,11 +1,5 @@
1
1
  <template>
2
2
  <div class="QuoteRequest__wrapper">
3
- <!-- <div class="QuoteRequest__title">
4
- Quick Quote
5
- </div>
6
- <div class="QuoteRequest__info">
7
- Fill our the form below and one of our team members will respond with a Quote ASAP!
8
- </div> -->
9
3
  <div class="QuoteRequest__content">
10
4
  <validation-observer
11
5
  v-slot="{ invalid, handleSubmit, errors: submittedErrors }"
package/nuxt.config.js CHANGED
@@ -32,7 +32,7 @@ module.exports = (config, axios) => ({
32
32
  '/customer/**'
33
33
  ],
34
34
  routes: async () => {
35
- const { data } = await axios.get(`${config.API_URL}/feed/sitemap?host=${config.HOST_NAME}`);
35
+ const { data } = await axios.get(`${config.LOCAL_API_URL}/feed/sitemap?host=${config.HOST_NAME}`);
36
36
  return data.map(url => ({ url, priority: 0.8 }));
37
37
  }
38
38
  },
@@ -82,7 +82,7 @@ module.exports = (config, axios) => ({
82
82
  feed: [{
83
83
  path: '/google-shopping.xml',
84
84
  async get() {
85
- const { data } = await axios.get(`${config.API_URL}/feed/products?host=${config.HOST_NAME}`);
85
+ const { data } = await axios.get(`${config.LOCAL_API_URL}/feed/products?host=${config.HOST_NAME}`);
86
86
  const spliceFirstImage = images => (images || []).splice(0, 1)[0];
87
87
  const getImages = images => (images || []).length > 0 ? images : null;
88
88
  return {
@@ -100,7 +100,7 @@ module.exports = (config, axios) => ({
100
100
  const image = spliceFirstImage(feedImages) || spliceFirstImage(frontImages) || spliceFirstImage(catalogFrontImages) || spliceFirstImage(backImages) || {};
101
101
  const images = getImages(backImages) || getImages(frontImages) || [];
102
102
  const info = {
103
- title: { _text: `${product.name} ${sp.color.name}-${sp.size.name}` },
103
+ title: { _text: `${product.name} ${sp.color.name}` },
104
104
  description: { _text: product.description || product.fabricInfoShort || product.name },
105
105
  link: { _text: `https://${config.HOST_NAME}/${product.brand.alias}/${product.productType.alias}/${product.alias}?color=${sp.color.alias}` },
106
106
  'g:id': { _text: sp.SKU },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.91",
3
+ "version": "0.0.95",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
package/store/auth.js CHANGED
@@ -18,6 +18,7 @@ export const getters = {
18
18
  isGuestUser: state => !state.token,
19
19
  isAdmin: state => checkRoles(state.user, ['admin']),
20
20
  isContentEditor: state => checkRoles(state.user, ['admin', 'content-editor']),
21
+ isWarehouse: state => checkRoles(state.user, ['admin', 'warehouse']),
21
22
  user: state => state.user,
22
23
  authStatus: state => state.status,
23
24
  stateError: state => state.err
package/store/cart.js CHANGED
@@ -6,7 +6,8 @@ export const state = () => ({
6
6
  id: null,
7
7
  entities: [],
8
8
  suburb: null,
9
- cartPricing: null
9
+ cartPricing: null,
10
+ cartPricingError: null
10
11
  });
11
12
 
12
13
  const getSimpleProductsQuantity = simpleProducts => {
@@ -56,6 +57,7 @@ export const getters = {
56
57
  notValidPrintsQuantities(state, { quantities }) {
57
58
  return (quantities?.prints || []).filter(({ minQuantity, quantity }) => quantity < minQuantity);
58
59
  },
60
+ cartPricingError: ({ cartPricingError }) => cartPricingError
59
61
  };
60
62
 
61
63
  export const actions = {
@@ -96,37 +98,24 @@ export const actions = {
96
98
  await api.saveCart(payload, shop._id);
97
99
  commit('setEntities', entities);
98
100
  },
99
- async calculateCartPrice({ state: { suburb, entities }, commit }, shop) {
100
- const getSimpleObj = i => i && ({ _id: i._id, name: i.name });
101
- const payload = {
102
- entities: entities.map(({ _id, guid, prints, simpleProducts, product }) => ({
103
- _id,
104
- guid,
105
- simpleProducts: simpleProducts.map(({ _id, guid, amount, pricing, unprintedPricing, weight = 0 }) => ({
106
- amount,
107
- pricing: (prints || []).length > 0 ? pricing : unprintedPricing,
108
- weight: product.weight,
109
- guid,
110
- _id
111
- })).filter(({ amount }) => +amount > 0),
112
- prints: (prints || []).map(print => {
113
- const { setupCost, freeSetupOver, printCost } = getPrintTypeSizePricing(print.printType, print.printSize?._id) || {};
114
- return {
115
- costType: print.printType.costType,
116
- setupCost,
117
- printCost,
118
- freeSetupOver,
119
- printType: getSimpleObj(print.printType),
120
- printArea: getSimpleObj(print.printArea),
121
- printSize: getSimpleObj(print.printSize)
122
- };
123
- }),
124
- printSurcharge: product.printSurcharge || 0
125
- })),
126
- postcode: suburb && suburb.postcode
127
- };
128
- const response = await api.calculateProductPrice(payload, shop._id);
129
- commit('setCartPricing', response);
101
+ async removeSupplier({ commit, state }, { supplier, shop }) {
102
+ const brands = supplier.brands.map(({ _id }) => _id);
103
+ const entities = state.entities.filter(entity => !brands.includes(entity.product.brand._id));
104
+ const payload = { _id: state.id, entities };
105
+ await api.saveCart(payload, shop._id);
106
+ commit('setEntities', entities);
107
+ },
108
+ async calculateCartPrice({ state: { suburb, entities }, commit }, { shop }) {
109
+ const payload = generateCalculatePriceData(entities, suburb);
110
+ try {
111
+ const response = await api.calculateProductPrice(payload, shop._id);
112
+ commit('setCartPricing', response);
113
+ commit('setCartPricingError', null);
114
+ } catch (e) {
115
+ const { error = 'Error calculate pricing' } = e.response?.data || {};
116
+ commit('setCartPricingError', error);
117
+ commit('setCartPricing', null);
118
+ }
130
119
  },
131
120
  async setSimpleProductAmount({ state, commit }, { guid, amount, shop }) {
132
121
  const entities = (state.entities || []).map(product => ({
@@ -142,6 +131,28 @@ export const actions = {
142
131
  },
143
132
  clearCart({ commit }) {
144
133
  commit('clearCart');
134
+ },
135
+ async selectRate({ state: { cartPricing, entities, suburb }, commit }, { supplier, rate, shop }) {
136
+ const suppliersWithRates = cartPricing.shipping.suppliersWithRates
137
+ .map(supplierWithRates => ({
138
+ ...(
139
+ supplierWithRates === supplier
140
+ ? ({
141
+ ...supplierWithRates,
142
+ rates: supplierWithRates.rates.map(r => ({ ...r, selected: rate === r }))
143
+ })
144
+ : supplierWithRates)
145
+ }));
146
+ const payload = generateCalculatePriceData(entities, suburb, suppliersWithRates);
147
+ try {
148
+ const response = await api.calculateProductPrice(payload, shop._id);
149
+ commit('setCartPricing', response);
150
+ commit('setCartPricingError', null);
151
+ } catch (e) {
152
+ const { error = 'Error calculate pricing' } = e.response?.data || {};
153
+ commit('setCartPricingError', error);
154
+ commit('setCartPricing', null);
155
+ }
145
156
  }
146
157
  };
147
158
 
@@ -162,10 +173,53 @@ export const mutations = {
162
173
  setCartPricing(state, price) {
163
174
  state.cartPricing = price;
164
175
  },
176
+ setCartPricingError(state, error) {
177
+ state.cartPricingError = error;
178
+ },
179
+ setSelectedRates(state, selectedRates) {
180
+ state.selectedRates = selectedRates;
181
+ },
165
182
  clearCart(state) {
166
183
  state.id = null;
167
184
  state.entities = [];
168
185
  state.cartPricing = null;
169
186
  state.suburb = null;
187
+ state.cartPricingError = null;
170
188
  }
171
189
  };
190
+
191
+ function generateCalculatePriceData(entities, suburb, suppliersWithRates) {
192
+ console.log('suburb: ', suburb);
193
+ const getSimpleObj = i => i && ({ _id: i._id, name: i.name });
194
+ return {
195
+ entities: entities.map(({ _id, guid, prints, simpleProducts, product }) => ({
196
+ _id,
197
+ guid,
198
+ brand: getSimpleObj(product.brand),
199
+ simpleProducts: simpleProducts.map(({ _id, guid, amount, pricing, unprintedPricing, weight = 0 }) => ({
200
+ amount,
201
+ pricing: (prints || []).length > 0 ? pricing : unprintedPricing,
202
+ weight: product.weight,
203
+ volume: product.volume,
204
+ guid,
205
+ _id
206
+ })).filter(({ amount }) => +amount > 0),
207
+ prints: (prints || []).map(print => {
208
+ const { setupCost, freeSetupOver, printCost } = getPrintTypeSizePricing(print.printType, print.printSize?._id) || {};
209
+ return {
210
+ costType: print.printType.costType,
211
+ setupCost,
212
+ printCost,
213
+ freeSetupOver,
214
+ printType: getSimpleObj(print.printType),
215
+ printArea: getSimpleObj(print.printArea),
216
+ printSize: getSimpleObj(print.printSize)
217
+ };
218
+ }),
219
+ printSurcharge: product.printSurcharge || 0
220
+ })),
221
+ postcode: suburb && suburb.postcode,
222
+ address: suburb ? [suburb.locality, suburb.state, suburb.postcode].filter(i => !!i).join(', ') : null,
223
+ suppliersWithRates
224
+ };
225
+ }
package/store/order.js CHANGED
@@ -22,6 +22,7 @@ export const actions = {
22
22
  order.productsTotal = pricing.products?.products?.totalPriceWithoutTax || 0;
23
23
  order.printsTotal = pricing.products?.prints?.totalPriceWithoutTax || 0;
24
24
  order.shippingTotal = pricing.shipping?.totalPriceWithoutTax || 0;
25
+ order.suppliersWithRates = pricing.shipping?.suppliersWithRates || [];
25
26
  }
26
27
  const response = await api.createOrder(order, shop);
27
28
  commit('setOrderData', response);