@lancom/shared 0.0.303 → 0.0.305

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 (28) hide show
  1. package/assets/js/api/index.js +4 -0
  2. package/components/checkout/cart/cart_entity/cart-entity.mixin.js +2 -1
  3. package/components/checkout/order/order-payment-information/order-payment-information.vue +1 -0
  4. package/components/common/payment/payment_card/payment-card.vue +7 -2
  5. package/components/common/payment/payment_card/stripe_payment/stripe-payment.scss +0 -0
  6. package/components/common/payment/payment_card/stripe_payment/stripe-payment.vue +114 -0
  7. package/components/common/postcode_select/postcode-select.vue +1 -1
  8. package/components/editor/editor_product_details/editor-product-details.scss +16 -0
  9. package/components/editor/editor_product_details/editor-product-details.vue +23 -3
  10. package/components/editor/mobile_editor_product_details/mobile-editor-product-details.scss +2 -2
  11. package/components/editor/mobile_editor_product_details/mobile-editor-product-details.vue +14 -2
  12. package/components/modals/payment_modal/payment-modal.vue +1 -0
  13. package/components/order/order_payment/order-payment.vue +1 -0
  14. package/components/products/product_list_product/product-list-product.vue +7 -2
  15. package/components/quotes/quote_request/quote-request.scss +2 -2
  16. package/components/quotes/quote_request/quote-request.vue +38 -13
  17. package/components/quotes/quote_request_modal/quote-request-modal.scss +11 -0
  18. package/components/quotes/quote_request_modal/quote-request-modal.vue +10 -2
  19. package/mixins/payment.js +1 -1
  20. package/mixins/product-preview.js +3 -0
  21. package/package.json +1 -1
  22. package/pages/news/_alias.vue +83 -0
  23. package/pages/news/index.vue +54 -0
  24. package/pages/news/tag/_tag.vue +63 -0
  25. package/routes/index.js +15 -0
  26. package/store/index.js +4 -2
  27. /package/components/common/payment/payment_card/{stripe/stripe.scss → stripe_card/stripe-card.scss} +0 -0
  28. /package/components/common/payment/payment_card/{stripe/stripe.vue → stripe_card/stripe-card.vue} +0 -0
@@ -95,6 +95,10 @@ const api = {
95
95
  fetchOrderByToken(token, params) {
96
96
  return _get(`order/token/${token}`, params);
97
97
  },
98
+ getPaymentIntent(shop, { amount, currency, payment, description }) {
99
+ const url = `shop/${shop}/payment-intent`;
100
+ return _post(url, { amount, currency, payment, description });
101
+ },
98
102
  createOrderPayment(id, { card, shop, country, currency, invoice, payment, recaptchaToken }) {
99
103
  const url = invoice ? `shop/${shop}/order/${id}/invoice/${invoice}/payment` : `shop/${shop}/order/${id}/payment`;
100
104
  return _post(url, { card, country, payment, currency, recaptchaToken });
@@ -10,6 +10,7 @@ export default {
10
10
  }
11
11
  },
12
12
  computed: {
13
+ ...mapGetters(['SETTINGS']),
13
14
  ...mapGetters('cart', [
14
15
  'cartPricing',
15
16
  'cartProductsPricing'
@@ -18,7 +19,7 @@ export default {
18
19
  return this.entity.product;
19
20
  },
20
21
  productLink() {
21
- return generateProductLink(this.product);
22
+ return generateProductLink(this.product, null, !!this.SETTINGS.CART_PRODUCT_LINK_TO_EDITOR);
22
23
  },
23
24
  sumPrints() {
24
25
  return (this.entity.prints || []).length;
@@ -152,6 +152,7 @@ export default {
152
152
  try {
153
153
  card = await this.$refs.paymentCart.tokenize();
154
154
  } catch (e) {
155
+ console.log('handleErrors: ', e);
155
156
  await this.handleErrors(e);
156
157
  }
157
158
  if (card) {
@@ -5,6 +5,7 @@
5
5
  :is="cardComponent"
6
6
  ref="card"
7
7
  :paymentData="paymentData"
8
+ :amount="amount"
8
9
  @inited="$emit('inited')" />
9
10
  </client-only>
10
11
  </div>
@@ -17,18 +18,22 @@ export default {
17
18
  name: 'PaymentCard',
18
19
  components: {
19
20
  Pinpayment: () => import('./pinpayment/pinpayment'),
20
- Stripe: () => import('./stripe/stripe')
21
+ Stripe: () => import('./stripe_card/stripe-card'),
22
+ StripePayment: () => import('./stripe_payment/stripe-payment')
21
23
  },
22
24
  props: {
23
25
  paymentData: {
24
26
  type: Object,
25
27
  required: true
28
+ },
29
+ amount: {
30
+ type: Number
26
31
  }
27
32
  },
28
33
  computed: {
29
34
  ...mapGetters(['payment']),
30
35
  cardComponent() {
31
- return this.payment?.type || 'stripe';
36
+ return this.payment?.type || 'stripe-payment';
32
37
  }
33
38
  },
34
39
  methods: {
@@ -0,0 +1,114 @@
1
+ <template>
2
+ <div>
3
+ <div id="payment-element"></div>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import api from '@lancom/shared/assets/js/api';
9
+ import { mapGetters } from 'vuex';
10
+
11
+ let stripeStartLoaded = false;
12
+
13
+ export default {
14
+ name: 'PaymentStripePayment',
15
+ data() {
16
+ return {
17
+ paymentIntent: null,
18
+ stripe: null,
19
+ elements: null,
20
+ loadedStripe: false
21
+ }
22
+ },
23
+ props: {
24
+ paymentData: {
25
+ type: Object,
26
+ required: true
27
+ },
28
+ amount: {
29
+ type: Number
30
+ },
31
+ },
32
+ computed: {
33
+ ...mapGetters(['shop', 'payment', 'currency']),
34
+ stripeClientKey() {
35
+ return this.payment.clientKey;
36
+ }
37
+ },
38
+ created() {
39
+ this.loadStripe();
40
+ },
41
+ methods: {
42
+ async tokenize() {
43
+ if (this.paymentIntent) {
44
+ return this.paymentIntent;
45
+ }
46
+
47
+ const result = await this.stripe.confirmPayment({
48
+ elements: this.elements,
49
+ confirmParams: {
50
+ return_url: `https://${process.env.HOST_NAME}/checkout/order`
51
+ },
52
+ redirect: "if_required"
53
+ });
54
+ // console.log(result);
55
+ if (result.error) {
56
+ throw new Error(result.error.message);
57
+ }
58
+
59
+ this.paymentIntent = result
60
+ return this.paymentIntent;
61
+ },
62
+ loadStripe() {
63
+ if (process.browser) {
64
+ if (!stripeStartLoaded) {
65
+ stripeStartLoaded = true;
66
+ let domElement = document.createElement('script');
67
+ domElement.setAttribute('src', 'https://js.stripe.com/v3/');
68
+ domElement.onload = () => {
69
+ this.onLoaded();
70
+ };
71
+ domElement.onerror = () => {
72
+ setTimeout(() => this.loadStripe(), 1000);
73
+ };
74
+ document.body.appendChild(domElement);
75
+ } else {
76
+ let repeated = 0;
77
+ let timer = setInterval(() => {
78
+ if (typeof window.Stripe !== 'undefined' || repeated++ > 20) {
79
+ this.onLoaded();
80
+ clearInterval(timer);
81
+ }
82
+ }, 500);
83
+ }
84
+ }
85
+ },
86
+ async onLoaded() {
87
+ const params = {
88
+ currency: this.currency?.isoCode,
89
+ amount: this.amount,
90
+ payment: this.payment
91
+ };
92
+ const { clientSecret } = await api.getPaymentIntent(this.shop._id, params);
93
+ this.stripe = window.Stripe(this.stripeClientKey);
94
+ const appearance = this.payment.appearance || {};
95
+ const options = this.payment.options || {};
96
+ this.elements = this.stripe.elements({ clientSecret, appearance });
97
+ const paymentElement = this.elements.create('payment', options);
98
+ paymentElement.mount('#payment-element');
99
+ this.$emit('inited');
100
+ this.loadedStripe = true;
101
+ }
102
+ }
103
+ };
104
+ </script>
105
+
106
+ <style>
107
+ .StripeElement {
108
+ border: 1px solid #cccccc;
109
+ border-radius: 4px;
110
+ padding: 10px;
111
+ width: 100%;
112
+ margin-top: -10px
113
+ }
114
+ </style>
@@ -157,7 +157,7 @@ export default {
157
157
  if (query.trim().length > 1) {
158
158
  this.isLoading = true;
159
159
  const country = this.codeCountry || this.country;
160
- const countryName = country ? (country.isoCode === 'GB' ? 'England' : (country.name || country)) : 'Australia';
160
+ const countryName = country ? (['GB','UK'].includes(country.isoCode) ? 'England' : (country.name || country)) : 'Australia';
161
161
  const params = {
162
162
  query: query.trim(),
163
163
  country: countryName
@@ -103,4 +103,20 @@
103
103
  padding: 10px;
104
104
  cursor: pointer;
105
105
  }
106
+ &__quote-botton {
107
+ font-weight: 800;
108
+ font-size: 14px;
109
+ line-height: 19px;
110
+ text-align: center;
111
+ color: $black;
112
+ background-color: $green;
113
+ text-transform: uppercase;
114
+ padding: 4px 15px;
115
+ margin-top: 7px;
116
+ cursor: pointer;
117
+ &:hover {
118
+ background-color: $black;
119
+ color: $white;
120
+ }
121
+ }
106
122
  }
@@ -73,12 +73,19 @@
73
73
  </span>
74
74
  </div>
75
75
  </div>
76
+ <div>
77
+ <div
78
+ class="EditorProductDetails__quote-botton"
79
+ @click="showQuoteRequestModal()">
80
+ REQUEST QUOTE
81
+ </div>
82
+ </div>
76
83
  </div>
77
- <div
84
+ <!-- <div
78
85
  v-if="!productAvailableInCurrentCountry"
79
86
  class="EditorProductDetails__available-warning">
80
87
  Product Not Available in {{ country.name }}
81
- </div>
88
+ </div> -->
82
89
  <div
83
90
  v-if="product.description"
84
91
  class="EditorProductDetails__description">
@@ -100,7 +107,7 @@
100
107
  </div>
101
108
  </div>
102
109
  <div
103
- v-if="productDetailsLoaded && productAvailableInCurrentCountry">
110
+ v-if="productDetailsLoaded">
104
111
  <div class="EditorProductDetails__section">
105
112
  <product-colors-selector
106
113
  :has-another-print-btn="false"
@@ -125,6 +132,7 @@ import { generateProductLink } from '@lancom/shared/assets/js/utils/product';
125
132
  import Price from '@lancom/shared/components/common/price';
126
133
  import ProductSideWithPrint from '@lancom/shared/components/common/product_side_with_print/product-side-with-print';
127
134
  import RichText from '@lancom/shared/components/common/rich-text';
135
+ import QuoteRequestModal from '@lancom/shared/components/quotes/quote_request_modal/quote-request-modal';
128
136
 
129
137
  export default {
130
138
  name: 'EditorProductDetails',
@@ -208,6 +216,18 @@ export default {
208
216
  },
209
217
  methods: {
210
218
  ...mapMutations('product', ['setPriceIncludeGST']),
219
+ showQuoteRequestModal() {
220
+ const params = {
221
+ name: 'quote-request',
222
+ root: this.$root,
223
+ height: 'auto',
224
+ width: 1012,
225
+ adaptive: true,
226
+ clickToClose: true,
227
+ transition: 'from-right-to-left'
228
+ };
229
+ this.$modal.show(QuoteRequestModal, { visibleProductTypes: false }, params);
230
+ },
211
231
  toggleSide() {
212
232
  this.side = this.side === 'front' ? 'back' : 'front';
213
233
  }
@@ -4,8 +4,8 @@
4
4
  .MobileEditorProductDetails {
5
5
  &__menu {
6
6
  position: fixed;
7
- right: 0;
8
- top: calc(100vh - 78px);
7
+ // right: 0;
8
+ // top: calc(100vh - 78px);
9
9
  left: 0;
10
10
  height: 78px;
11
11
  z-index: 999999;
@@ -1,6 +1,9 @@
1
1
  <template>
2
2
  <div class="MobileEditorProductDetails__wrapper">
3
- <div class="MobileEditorProductDetails__menu">
3
+ <div
4
+ v-if="width"
5
+ class="MobileEditorProductDetails__menu"
6
+ :style="{ width, top }">
4
7
  <div
5
8
  class="MobileEditorProductDetails__menu-action"
6
9
  :class="{ active: currentTab === 'details' }"
@@ -92,7 +95,9 @@ export default {
92
95
  data() {
93
96
  return {
94
97
  isOpen: false,
95
- currentTab: null
98
+ currentTab: null,
99
+ top: null,
100
+ width: null
96
101
  };
97
102
  },
98
103
  computed: {
@@ -100,12 +105,19 @@ export default {
100
105
  },
101
106
  mounted() {
102
107
  EventBus.$on('focus-on-default-product', this.focusOnDefaultProduct);
108
+ this.updateMobileMenuPosition();
109
+ window.addEventListener('resize', this.updateMobileMenuPosition);
103
110
  },
104
111
  beforeDestroy() {
105
112
  EventBus.$off('focus-on-default-product', this.focusOnDefaultProduct);
113
+ window.removeEventListener('resize', this.updateMobileMenuPosition);
106
114
  },
107
115
  methods: {
108
116
  ...mapMutations(['setEditModeSelectedLayer', 'removeTemplateLayer', 'setSelectedLayer']),
117
+ updateMobileMenuPosition() {
118
+ this.top = `${window.outerHeight - 78}px`;
119
+ this.width = `${window.outerWidth}px`;
120
+ },
109
121
  focusOnDefaultProduct() {
110
122
  this.show('details');
111
123
  },
@@ -202,6 +202,7 @@ export default {
202
202
  const response = await this.$refs.card.tokenize();
203
203
  this.proceedPayment(response);
204
204
  } catch (e) {
205
+ console.log('handleErrors: ', e);
205
206
  this.handleErrors(e);
206
207
  } finally {
207
208
  this.processing = false;
@@ -101,6 +101,7 @@ export default {
101
101
  this.model.paid = paid;
102
102
  }
103
103
  } catch (e) {
104
+ console.log('handleErrors: ', e);
104
105
  if (e.response) {
105
106
  const { message } = (e.response && e.response.data) || e;
106
107
  this.handleErrors({ messages: [{ message }] });
@@ -55,12 +55,17 @@
55
55
  </span>
56
56
  </div>
57
57
  <div
58
- v-if="product.minimumPrintOrderQuantity > 0"
58
+ v-if="noMinimum"
59
+ class="ProductListProduct__tag-item ProductListProduct__tag-item--qty">
60
+ <span>No Mimimums</span>
61
+ </div>
62
+ <div
63
+ v-if="!noMinimum && product.minimumPrintOrderQuantity > 0"
59
64
  class="ProductListProduct__tag-item ProductListProduct__tag-item--qty">
60
65
  <span>Print Minimum: {{ product.minimumPrintOrderQuantity }}</span>
61
66
  </div>
62
67
  <div
63
- v-if="product.minimumPrintOrderQuantity > 0"
68
+ v-if="!noMinimum && product.minimumOrderQuantity > 0"
64
69
  class="ProductListProduct__tag-item ProductListProduct__tag-item--qty">
65
70
  <span>{{ product.printOnly ? 'No Blanks' : `Blank Minimum: ${product.minimumOrderQuantity}` }}</span>
66
71
  </div>
@@ -2,9 +2,9 @@
2
2
 
3
3
  .QuoteRequest {
4
4
  &__wrapper {
5
- margin: -20px 40px 0 40px;
5
+ margin: -30px 20px 0 20px;
6
6
  @media (max-width: $bp-extra-small-max) {
7
- margin: -20px 0px 0 0px;
7
+ margin: -30px 0px 0 0px;
8
8
  }
9
9
  }
10
10
  &__title {
@@ -257,7 +257,9 @@
257
257
  </div>
258
258
  </div>
259
259
  </div>
260
- <div class="form-row">
260
+ <div
261
+ v-if="visibleProductTypes"
262
+ class="form-row">
261
263
  <div class="QuoteRequest__label">
262
264
  what would you like us to quote on?
263
265
  </div>
@@ -275,20 +277,37 @@
275
277
  </div>
276
278
  </div>
277
279
  </div>
280
+ <div v-else>
281
+ <div v-if="submittedErrors.length > 0">
282
+ Please fill in all required fields
283
+ </div>
284
+ <div class="QuoteRequest__btn form-actions full">
285
+ <btn
286
+ btn-class="green"
287
+ :btn-disabled="processing"
288
+ :btn-processing="processing"
289
+ :btn-block="true"
290
+ btn-label="GET A QUOTE NOW"
291
+ @onclick="handleSubmit(submit)">
292
+ </btn>
293
+ </div>
294
+ </div>
278
295
  </div>
279
296
  </div>
280
- <div v-if="submittedErrors.length > 0">
281
- Please fill in all required fields
282
- </div>
283
- <div class="QuoteRequest__btn form-actions full">
284
- <btn
285
- btn-class="green"
286
- :btn-disabled="processing"
287
- :btn-processing="processing"
288
- :btn-block="true"
289
- btn-label="GET A QUOTE NOW"
290
- @onclick="handleSubmit(submit)">
291
- </btn>
297
+ <div v-if="visibleProductTypes">
298
+ <div v-if="submittedErrors.length > 0">
299
+ Please fill in all required fields
300
+ </div>
301
+ <div class="QuoteRequest__btn form-actions full">
302
+ <btn
303
+ btn-class="green"
304
+ :btn-disabled="processing"
305
+ :btn-processing="processing"
306
+ :btn-block="true"
307
+ btn-label="GET A QUOTE NOW"
308
+ @onclick="handleSubmit(submit)">
309
+ </btn>
310
+ </div>
292
311
  </div>
293
312
  </validation-observer>
294
313
  </div>
@@ -365,6 +384,12 @@ export default {
365
384
  }
366
385
  };
367
386
  },
387
+ props: {
388
+ visibleProductTypes: {
389
+ type: Boolean,
390
+ default: true
391
+ }
392
+ },
368
393
  computed: {
369
394
  ...mapGetters(['shop', 'currency']),
370
395
  ...mapGetters('cart', ['entities']),
@@ -1,5 +1,16 @@
1
+ @import "@/assets/scss/variables";
2
+
1
3
  .QuoteRequestModal {
2
4
  &__wrapper {
3
5
  border-radius: 0px;
6
+ margin-bottom: 50px;
7
+ .lc_modal__content {
8
+ @media (min-width: $bp-extra-small-max) {
9
+ padding: 0 0 20px 0 !important;
10
+ }
11
+ }
12
+ .icon-cancel {
13
+ z-index: 2;
14
+ }
4
15
  }
5
16
  }
@@ -6,7 +6,9 @@
6
6
  @click="$emit('close')"></i>
7
7
  </div>
8
8
  <div class="lc_modal__content">
9
- <quote-request @added="$emit('close', $event)" />
9
+ <quote-request
10
+ :visible-product-types="visibleProductTypes"
11
+ @added="$emit('close', $event)" />
10
12
  </div>
11
13
  </div>
12
14
  </template>
@@ -18,7 +20,13 @@ export default {
18
20
  name: 'QuoteRequestModal',
19
21
  components: {
20
22
  QuoteRequest
21
- }
23
+ },
24
+ props: {
25
+ visibleProductTypes: {
26
+ type: Boolean,
27
+ default: true
28
+ }
29
+ },
22
30
  };
23
31
  </script>
24
32
 
package/mixins/payment.js CHANGED
@@ -39,7 +39,7 @@ export default {
39
39
  handleErrors(err) {
40
40
  // err.messages.forEach(({ message }) => this.$toastr.e(message));
41
41
  const defaultMessage = 'Payment error';
42
- this.errorMessage = (err.messages ? err.messages.map(({ message }) => message).join(', ') : (err.error_description)) || defaultMessage;
42
+ this.errorMessage = (err.messages ? err.messages.map(({ message }) => message).join(', ') : (err.error_description)) || err.message || defaultMessage;
43
43
  },
44
44
  async proceedPayment(card) {
45
45
  try {
@@ -34,6 +34,9 @@ const productPreview = {
34
34
  };
35
35
  },
36
36
  computed: {
37
+ noMinimum() {
38
+ return !(this.product.minimumPrintOrderQuantity > 1) && !(this.product.minimumOrderQuantity > 1);
39
+ },
37
40
  canLoadImages() {
38
41
  return this.loadHolder.canLoadImages;
39
42
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.303",
3
+ "version": "0.0.305",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
@@ -0,0 +1,83 @@
1
+ <template>
2
+ <div class="SingleNewsPage__wrapper">
3
+ <breadcrumbs :items="breadcrumbs" />
4
+ <transition name="from-right-to-left" appear>
5
+ <news :item="item" />
6
+ </transition>
7
+ <transition name="from-left-to-right" appear>
8
+ <div class="content-inner">
9
+ <h2 class="lc_h2 lc_black SingleNewsPage__list-title">
10
+ You might also like
11
+ </h2>
12
+ <news-list
13
+ class="SingleNewsPage__list"
14
+ :news="newsList" />
15
+ </div>
16
+ </transition>
17
+ </div>
18
+ </template>
19
+ <script>
20
+ import metaInfo from '@lancom/shared/mixins/meta-info';
21
+ import api from '@lancom/shared/assets/js/api';
22
+
23
+ export default {
24
+ name: 'SingleNewsPage',
25
+ components: {
26
+ Breadcrumbs: () => import('@lancom/shared/components/common/breadcrumbs/breadcrumbs'),
27
+ News: () => import('@lancom/shared/components/news/news'),
28
+ NewsList: () => import('@lancom/shared/components/news/news_list/news-list')
29
+ },
30
+ mixins: [metaInfo],
31
+ async asyncData({ params, store, error }) {
32
+ const { _id } = store.getters.shop;
33
+ try {
34
+ const item = await api.fetchSingleNews(_id, params.alias, true);
35
+ const { news } = await api.fetchNews(_id);
36
+ return { item, news, pageItem: item };
37
+ } catch (e) {
38
+ const { status, data } = e?.response || {};
39
+ const statusCode = status || 500;
40
+ error({
41
+ statusCode,
42
+ error: data?.error || 'News not found'
43
+ });
44
+ }
45
+ },
46
+ data() {
47
+ return {
48
+ item: null,
49
+ news: []
50
+ };
51
+ },
52
+ computed: {
53
+ newsList() {
54
+ return this.news.filter(i => i.alias !== this.item.alias).slice(0, 3);
55
+ },
56
+ breadcrumbs() {
57
+ const item = this.item ? { text: this.item.title } : null;
58
+ return [{
59
+ to: '/news',
60
+ text: 'Blog'
61
+ }, item].filter(i => !!i);
62
+ }
63
+ },
64
+ getRoute() {
65
+ return '/shop/:shop/news/:alias';
66
+ }
67
+ };
68
+ </script>
69
+
70
+ <style lang="scss" scoped>
71
+ .SingleNewsPage{
72
+ &__wrapper {
73
+ margin-top: 30px;
74
+ }
75
+ &__list-title {
76
+ margin-top: 20px;
77
+ text-align: center;
78
+ }
79
+ &__list {
80
+ padding: 20px 0;
81
+ }
82
+ }
83
+ </style>
@@ -0,0 +1,54 @@
1
+ <template>
2
+ <div class="NewsPage__wrapper view-transition">
3
+ <div class="content-inner">
4
+ <breadcrumbs :items="breadcrumbs" />
5
+ <news-list
6
+ class="NewsPage__list"
7
+ :news="news"
8
+ :count="count"
9
+ :page="page"
10
+ :per-page="perPage" />
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+ import metaInfo from '@lancom/shared/mixins/meta-info';
17
+ import api from '@lancom/shared/assets/js/api';
18
+
19
+ const NEWS_PER_PAGE = 18;
20
+
21
+ export default {
22
+ name: 'ProductPage',
23
+ components: {
24
+ Breadcrumbs: () => import('@lancom/shared/components/common/breadcrumbs/breadcrumbs'),
25
+ NewsList: () => import('@lancom/shared/components/news/news_list/news-list')
26
+ },
27
+ mixins: [metaInfo],
28
+ async asyncData({ store, params, query }) {
29
+ const { _id } = store.getters.shop;
30
+ const newsQuery = { ...params, ...query, limit: NEWS_PER_PAGE };
31
+ const { news, count, page, perPage } = await api.fetchNews(_id, newsQuery);
32
+ return { news, count, page, perPage };
33
+ },
34
+ data() {
35
+ return {
36
+ news: [],
37
+ count: null,
38
+ page: null,
39
+ perPage: null,
40
+ breadcrumbs: [{
41
+ text: 'Blog'
42
+ }]
43
+ };
44
+ }
45
+ };
46
+ </script>
47
+
48
+ <style lang="scss" scoped>
49
+ .NewsPage {
50
+ &__wrapper {
51
+ padding: 30px 0;
52
+ }
53
+ }
54
+ </style>
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <div class="NewsPage__wrapper view-transition">
3
+ <div class="content-inner">
4
+ <breadcrumbs :items="breadcrumbs" />
5
+ <news-list
6
+ class="NewsPage__list"
7
+ :news="news"
8
+ :count="count"
9
+ :page="page"
10
+ :per-page="perPage" />
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+ import metaInfo from '@lancom/shared/mixins/meta-info';
17
+ import api from '@lancom/shared/assets/js/api';
18
+
19
+ const NEWS_PER_PAGE = 18;
20
+
21
+ export default {
22
+ name: 'ProductPage',
23
+ components: {
24
+ Breadcrumbs: () => import('@lancom/shared/components/common/breadcrumbs/breadcrumbs'),
25
+ NewsList: () => import('@lancom/shared/components/news/news_list/news-list')
26
+ },
27
+ mixins: [metaInfo],
28
+ async asyncData({ store, params, query }) {
29
+ const { _id } = store.getters.shop;
30
+ const newsQuery = { ...params, ...query, limit: NEWS_PER_PAGE };
31
+ console.log(newsQuery);
32
+ const { news, count, page, perPage, tag } = await api.fetchNews(_id, newsQuery);
33
+ return { news, count, page, perPage, pageItem: tag };
34
+ },
35
+ data() {
36
+ return {
37
+ news: [],
38
+ tag: null,
39
+ count: null,
40
+ page: null,
41
+ perPage: null
42
+ };
43
+ },
44
+ computed: {
45
+ breadcrumbs() {
46
+ return [{
47
+ text: 'Blog',
48
+ to: '/news'
49
+ }, {
50
+ text: this.pageItem.title
51
+ }];
52
+ }
53
+ }
54
+ };
55
+ </script>
56
+
57
+ <style lang="scss" scoped>
58
+ .NewsPage {
59
+ &__wrapper {
60
+ padding: 30px 0;
61
+ }
62
+ }
63
+ </style>
package/routes/index.js CHANGED
@@ -69,5 +69,20 @@ module.exports = function(routes, resolve) {
69
69
  path: '/faq/:group',
70
70
  component: resolve('@lancom/shared/pages/faq/_group/index.vue'),
71
71
  chunkName: 'pages/faq/group'
72
+ }, {
73
+ name: 'news',
74
+ path: '/news',
75
+ component: resolve('@lancom/shared/pages/news/index.vue'),
76
+ chunkName: 'pages/news'
77
+ }, {
78
+ name: 'news-view',
79
+ path: '/news/:alias',
80
+ component: resolve('@lancom/shared/pages/news/_alias.vue'),
81
+ chunkName: 'pages/news/view'
82
+ }, {
83
+ name: 'news-tag',
84
+ path: '/news/tag/:tag',
85
+ component: resolve('@lancom/shared/pages/news/tag/_tag.vue'),
86
+ chunkName: 'pages/news/tag'
72
87
  }];
73
88
  }
package/store/index.js CHANGED
@@ -73,8 +73,10 @@ export const actions = {
73
73
  const countrySetting = (countrySettings?.settings || []).find(s => !!s.settings.app.STRIPE_PUBLIC_KEY);
74
74
  if (countrySetting) {
75
75
  commit('setPayment', {
76
- type: 'stripe',
77
- clientKey: countrySetting.settings.app.STRIPE_PUBLIC_KEY
76
+ type: 'stripe-payment',
77
+ clientKey: countrySetting.settings.app.STRIPE_PUBLIC_KEY,
78
+ appearance: countrySetting.settings.app.STRIPE_APPEARANCE,
79
+ options: countrySetting.settings.app.STRIPE_OPTIONS
78
80
  });
79
81
  }
80
82
  }