@lancom/shared 0.0.128 → 0.0.131

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,7 +1,51 @@
1
1
  const gtm = {
2
- push(data) {
2
+ push(data, skipReset) {
3
3
  window.dataLayer = window.dataLayer || [];
4
+ if (!skipReset) {
5
+ window.dataLayer.push(function() {
6
+ this.reset();
7
+ });
8
+ }
4
9
  window.dataLayer.push(data);
10
+ },
11
+ addToCart(entities, pricing) {
12
+ this.push({
13
+ event: 'add_to_cart',
14
+ value: pricing.totalPriceWithoutTax,
15
+ currency: 'AUD',
16
+ items: entities.reduce((products, { product, simpleProducts }) => {
17
+ return [
18
+ ...products,
19
+ ...simpleProducts
20
+ .filter(({ amount }) => amount > 0)
21
+ .map(({ SKU, amount, _id }) => ({
22
+ item_id: SKU,
23
+ item_name: product.name,
24
+ item_brand: product.brand.name,
25
+ currency: 'AUD',
26
+ price: pricing.products[product._id]?.products[_id]?.totalPriceWithoutTax,
27
+ quantity: amount
28
+ }))
29
+ ];
30
+ }, [])
31
+ });
32
+ },
33
+ removeFromCart(simpleProducts, pricing) {
34
+ const removeSimpleProducts = simpleProducts.filter(({ amount }) => amount > 0);
35
+ const spPricing = Object.keys(pricing.products)
36
+ .filter(k => !!pricing.products[k].products)
37
+ .reduce((res, k) => ({ ...res, ...pricing.products[k].products }), {});
38
+ gtm.push({
39
+ event: 'remove_from_cart',
40
+ value: removeSimpleProducts.reduce((sum, { guid }) => sum + (spPricing[guid]?.totalPriceWithoutTax || 0), 0),
41
+ currency: 'AUD',
42
+ items: removeSimpleProducts.map(({ SKU, amount, guid }) => ({
43
+ item_id: SKU,
44
+ currency: 'AUD',
45
+ price: spPricing[guid]?.totalPriceWithoutTax,
46
+ quantity: amount
47
+ }))
48
+ });
5
49
  }
6
50
  };
7
51
 
@@ -53,15 +53,16 @@ export default {
53
53
  this.calculatePriceWithDebounce();
54
54
  }
55
55
  },
56
- mounted() {
57
- this.calculatePriceWithDebounce();
56
+ async mounted() {
57
+ await this.calculatePrice();
58
+ this.$emit('loaded', this.cartPricing);
58
59
  },
59
60
  methods: {
60
61
  ...mapActions([
61
62
  'calculateCartPrice'
62
63
  ]),
63
- calculatePrice() {
64
- this.calculateCartPrice({ shop: this.shop });
64
+ async calculatePrice() {
65
+ await this.calculateCartPrice({ shop: this.shop });
65
66
  }
66
67
  }
67
68
  };
@@ -160,23 +160,23 @@
160
160
  name="Address line 2"
161
161
  class="form-row">
162
162
  <label
163
- for="address_line2"
163
+ for="addressLine2"
164
164
  class="form-label">
165
165
  Address line 2
166
166
  </label>
167
167
  <input
168
- id="address_line2"
169
- ref="address_line2"
170
- v-model="address.address_line2"
171
- name="address_line2"
168
+ id="addressLine2"
169
+ ref="addressLine2"
170
+ v-model="address.addressLine2"
171
+ name="addressLine2"
172
172
  type="text"
173
173
  class="form-field labelless"
174
174
  placeholder="Address line 2"
175
175
  :class="{
176
176
  'is-danger': errors.length,
177
- filled: address.address_line2
177
+ filled: address.addressLine2
178
178
  }"
179
- @keyup.enter="$refs.address_line2.focus()" />
179
+ @keyup.enter="$refs.addressLine2.focus()" />
180
180
  <span
181
181
  v-if="errors.length"
182
182
  class="form-help is-danger">
@@ -177,7 +177,7 @@ export default {
177
177
  },
178
178
  proceedToCard() {
179
179
  const entities = generateCartProducts(this.product, this.template.simpleProducts, this.template.layers, this.isPrintPricing, this.layerThumbnails);
180
- this.addToCart({ entities, shop: this.shop });
180
+ this.addToCart({ entities, shop: this.shop, pricing: this.productPricing });
181
181
  this.showCartModal(async () => {
182
182
  const message = 'Do you wish to continue with editing the current design or reset the editor?';
183
183
  const reset = await this.showConfirmationModal(message, {
@@ -192,19 +192,19 @@
192
192
  name="Address line 2"
193
193
  class="form-row">
194
194
  <input
195
- id="address_line2"
196
- ref="address_line2"
197
- v-model="form.address_line2"
198
- name="address_line2"
195
+ id="addressLine2"
196
+ ref="addressLine2"
197
+ v-model="form.addressLine2"
198
+ name="addressLine2"
199
199
  type="text"
200
200
  class="form-field"
201
201
  :class="{
202
202
  'is-danger': errors.length,
203
- filled: form.address_line2
203
+ filled: form.addressLine2
204
204
  }"
205
- @keyup.enter="$refs.address_line2.focus()" />
205
+ @keyup.enter="$refs.addressLine2.focus()" />
206
206
  <label
207
- for="address_line2"
207
+ for="addressLine2"
208
208
  class="form-label label-inner">
209
209
  Address line 2
210
210
  </label>
@@ -306,7 +306,7 @@ export default {
306
306
  city: this.orderData.city,
307
307
  phone: this.orderData.phone,
308
308
  addressLine1: this.orderData.addressLine1,
309
- address_line2: this.orderData.addressLine2,
309
+ addressLine2: this.orderData.addressLine2,
310
310
  email: this.orderData.email,
311
311
  fullName: this.orderData.fullName,
312
312
  company: this.orderData.company,
@@ -49,6 +49,7 @@
49
49
  <script>
50
50
  import debounce from 'lodash.debounce';
51
51
  import { mapGetters } from 'vuex';
52
+ import gtm from '@lancom/shared/assets/js/utils/gtm';
52
53
  import api from '@lancom/shared/assets/js/api';
53
54
  import ProductsAutocompleteItem from './products_autocomplete-item/products-autocomplete-item';
54
55
 
@@ -97,6 +98,12 @@ export default {
97
98
  },
98
99
  async search() {
99
100
  this.searching = true;
101
+ if (this.text) {
102
+ gtm.push({
103
+ event: 'search',
104
+ search_term: this.text
105
+ });
106
+ }
100
107
  try {
101
108
  this.products = this.text ? await api.searchProducts(this.shop._id, this.text) : [];
102
109
  } catch (e) {
@@ -9,7 +9,7 @@ export default async function ({ store, route, redirect }) {
9
9
  };
10
10
  const routeInfo = await store.dispatch('page/fetchRouteInfo', data);
11
11
  if (routeInfo?.type === 'redirect' && routeInfo.redirectTo) {
12
- redirect(routeInfo.redirectTo);
12
+ redirect(301, routeInfo.redirectTo);
13
13
  }
14
14
  }
15
15
  }
package/mixins/payment.js CHANGED
@@ -63,13 +63,30 @@ export default {
63
63
  }
64
64
  },
65
65
  sendConversionData() {
66
- if (!process.env.IS_LOCAL) {
67
- gtm.push({
68
- event: 'OrderCheckout',
69
- code: this.orderData.code,
70
- value: this.orderData.total
71
- });
72
- }
66
+ gtm.push({
67
+ event: 'purchase',
68
+ transaction_id: this.orderData.code,
69
+ value: this.orderData.total,
70
+ currency: 'AUD',
71
+ coupon: this.orderData.couponCode,
72
+ shipping: this.orderData.shippingTotal,
73
+ tax: this.orderData.totalGST - this.orderData.total,
74
+ items: this.orderData.products.reduce((products, { product, simpleProducts }) => {
75
+ return [
76
+ ...products,
77
+ ...simpleProducts
78
+ .filter(({ amount }) => amount > 0)
79
+ .map(({ SKU, productCost, amount }) => ({
80
+ item_id: SKU,
81
+ item_name: product.name,
82
+ item_brand: product.brand.name,
83
+ price: productCost,
84
+ currency: 'AUD',
85
+ quantity: amount
86
+ }))
87
+ ];
88
+ }, [])
89
+ });
73
90
  },
74
91
  clearFailedCharge() {
75
92
  this.errorMessage = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.128",
3
+ "version": "0.0.131",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
package/store/cart.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import groupBy from 'lodash/groupBy';
2
2
  import api from '@lancom/shared/assets/js/api';
3
+ import gtm from '@lancom/shared/assets/js/utils/gtm';
3
4
  import { getPrintTypeSizePricing } from '@lancom/shared/assets/js/utils/prints';
4
5
 
5
6
  export const state = () => ({
@@ -63,7 +64,8 @@ export const getters = {
63
64
  };
64
65
 
65
66
  export const actions = {
66
- async addToCart({ state, commit }, { entities, shop }) {
67
+ async addToCart({ state, commit }, { entities, shop, pricing }) {
68
+ const addingEntities = [...entities];
67
69
  const withoutPrints = e => (e.prints || []).length === 0;
68
70
  entities = entities.map(e => {
69
71
  const entitiy = withoutPrints(e) && state.entities.find(e2 => withoutPrints(e2) && e2?.product?._id === e?.product?._id);
@@ -89,6 +91,9 @@ export const actions = {
89
91
  commit('setId', cart._id);
90
92
  commit('setEntities', cart.entities);
91
93
  }
94
+ if (pricing) {
95
+ gtm.addToCart(addingEntities, pricing);
96
+ }
92
97
  },
93
98
  async removeSimpleProductsFromCart({ commit, state }, { simpleProducts, shop }) {
94
99
  const removeGuids = (simpleProducts || []).map(e => e.guid);
@@ -99,10 +104,17 @@ export const actions = {
99
104
  const payload = { _id: state.id, entities };
100
105
  await api.saveCart(payload, shop._id);
101
106
  commit('setEntities', entities);
107
+ if (state.cartPricing) {
108
+ gtm.removeFromCart(simpleProducts, state.cartPricing);
109
+ }
102
110
  },
103
111
  async removeSupplier({ commit, state }, { supplier, shop }) {
104
112
  const brands = supplier.brands.map(({ _id }) => _id);
105
113
  const entities = state.entities.filter(entity => !brands.includes(entity.product.brand._id));
114
+ if (state.cartPricing) {
115
+ const simpleProducts = entities.reduce((items, entity) => [...items, ...entity.simpleProducts], []);
116
+ gtm.removeFromCart(simpleProducts, state.cartPricing);
117
+ }
106
118
  const payload = { _id: state.id, entities };
107
119
  await api.saveCart(payload, shop._id);
108
120
  commit('setEntities', entities);