@lancom/shared 0.0.90 → 0.0.91

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,4 +1,4 @@
1
- import moment from 'moment';
1
+ import dayjs from 'dayjs';
2
2
  import DateOnly from 'dateonly';
3
3
 
4
4
  import currencies from '../constants/currencies';
@@ -68,11 +68,11 @@ export const highlight = (string = '', query) => {
68
68
  return string.toString().replace(q, matchedTxt => (`<span class="highlight">${matchedTxt}</span>`));
69
69
  };
70
70
 
71
- export const date = d => moment(d).format('lll');
71
+ export const date = d => dayjs(d).format('ddd, MMM D, YYYY h:mm A');
72
72
 
73
- export const shortDate = d => moment(d).format('DD/MM/YYYY');
73
+ export const shortDate = d => dayjs(d).format('DD/MM/YYYY');
74
74
 
75
- export const sydneyTime = d => moment(d).utc().utcOffset(10).format('lll');
75
+ export const sydneyTime = d => dayjs(d).utc().utcOffset(10).format('MMM D, YYYY h:mm A');
76
76
 
77
77
  export const priceInRange = (prices, amount) => (prices.find(({ min, max }) => min <= amount && (!max || max >= amount)) || { price: 0 }).price;
78
78
 
@@ -79,12 +79,16 @@
79
79
 
80
80
  <script>
81
81
  import { createNamespacedHelpers, mapGetters } from 'vuex';
82
+ import FileUploader from '@lancom/shared/components/common/file_uploader';
82
83
  import modals from '@lancom/shared/mixins/modals';
83
84
 
84
85
  const { mapActions, mapMutations } = createNamespacedHelpers('product');
85
86
 
86
87
  export default {
87
88
  name: 'EditorLayersToolbar',
89
+ components: {
90
+ FileUploader
91
+ },
88
92
  mixins: [
89
93
  modals
90
94
  ],
@@ -14,7 +14,22 @@
14
14
  }"
15
15
  @mouseenter="setActiveProduct(index)"
16
16
  @mouseleave="setActiveProduct(null)">
17
- <slot name="product" v-bind="{ product, full: activeProduct === index, toEditor }">
17
+ <slot
18
+ v-if="placeholder"
19
+ name="placeholder"
20
+ v-bind="{ product, full: activeProduct === index, toEditor }">
21
+ <product-list-product-placeholder
22
+ :product="product"
23
+ :to-editor="toEditor"
24
+ class="ProductList__item"
25
+ :class="{
26
+ 'ProductList__item--active': activeProduct === index
27
+ }" />
28
+ </slot>
29
+ <slot
30
+ v-else
31
+ name="product"
32
+ v-bind="{ product, full: activeProduct === index, toEditor }">
18
33
  <product-list-product
19
34
  :product="product"
20
35
  :to-editor="toEditor"
@@ -36,11 +51,13 @@
36
51
 
37
52
  <script>
38
53
  import ProductListProduct from '../product_list_product/product-list-product';
54
+ import ProductListProductPlaceholder from '../product_list_product_placeholder/product-list-product-placeholder';
39
55
 
40
56
  export default {
41
57
  name: 'LancomProductList',
42
58
  components: {
43
- ProductListProduct
59
+ ProductListProduct,
60
+ ProductListProductPlaceholder
44
61
  },
45
62
  props: {
46
63
  products: {
@@ -50,6 +67,10 @@ export default {
50
67
  toEditor: {
51
68
  type: Boolean,
52
69
  default: true
70
+ },
71
+ placeholder: {
72
+ type: Boolean,
73
+ default: true
53
74
  }
54
75
  },
55
76
  data() {
@@ -0,0 +1,52 @@
1
+ @import "@/assets/scss/variables";
2
+
3
+ .ProductListProductPlaceholder {
4
+ &__wrapper {
5
+ padding: 30px;
6
+ }
7
+ &__link {
8
+ position: absolute;
9
+ top: 0;
10
+ left: 0;
11
+ right: 0;
12
+ bottom: 0;
13
+ padding: 30px;
14
+ text-indent: -99999px;
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: center;
18
+ flex-direction: column;
19
+ }
20
+ &__image {
21
+ width: 100%;
22
+ height: 250px;
23
+ animation-name: backgroundColorPalette;
24
+ animation-duration: 1s;
25
+ animation-iteration-count: infinite;
26
+ animation-direction: alternate;
27
+ }
28
+ &__info {
29
+ margin-top: 20px;
30
+ width: 100%;
31
+ height: 30px;
32
+ animation-name: backgroundColorPalette;
33
+ animation-duration: 1.5s;
34
+ animation-iteration-count: infinite;
35
+ animation-direction: alternate;
36
+ &--medium {
37
+ width: 80%;
38
+ }
39
+ &--small {
40
+ width: 60%;
41
+ }
42
+ }
43
+ }
44
+
45
+ @keyframes backgroundColorPalette {
46
+ 0% {
47
+ background: #efefef;
48
+ }
49
+ 100% {
50
+ background: #d9d9d9;
51
+ }
52
+ }
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <div class="ProductListProductPlaceholder__wrapper">
3
+ <nuxt-link
4
+ :to="productLink"
5
+ class="ProductListProductPlaceholder__link">
6
+ <span class="ProductListProductPlaceholder__image"></span>
7
+ <span class="ProductListProductPlaceholder__info ProductListProductPlaceholder__info--large"></span>
8
+ <span class="ProductListProductPlaceholder__info ProductListProductPlaceholder__info--medium"></span>
9
+ <span class="ProductListProductPlaceholder__info ProductListProductPlaceholder__info--small"></span>
10
+ {{ product.name }}
11
+ </nuxt-link>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+ import productPreview from '@lancom/shared/mixins/product-preview';
17
+
18
+ export default {
19
+ name: 'ProductListProductPlaceholder',
20
+ mixins: [productPreview]
21
+ };
22
+ </script>
23
+
24
+ <style lang="scss" scoped>
25
+ @import 'product-list-product-placeholder';
26
+ </style>
@@ -11,4 +11,36 @@
11
11
  display: none;
12
12
  }
13
13
  }
14
+ &__placeholder {
15
+ display: flex;
16
+ flex-direction: column;
17
+ margin-right: 20px;
18
+ }
19
+ &__info {
20
+ margin-top: 20px;
21
+ width: 100%;
22
+ height: 20px;
23
+ animation-name: backgroundColorPalette;
24
+ animation-duration: 1.5s;
25
+ animation-iteration-count: infinite;
26
+ animation-direction: alternate;
27
+ &--medium {
28
+ width: 85%;
29
+ }
30
+ &--small {
31
+ width: 70%;
32
+ }
33
+ &--small2 {
34
+ width: 55%;
35
+ }
36
+ }
37
+ }
38
+
39
+ @keyframes backgroundColorPalette {
40
+ 0% {
41
+ background: #efefef;
42
+ }
43
+ 100% {
44
+ background: #d9d9d9;
45
+ }
14
46
  }
@@ -2,38 +2,35 @@
2
2
  <div
3
3
  :data-aos="aosFadeRight"
4
4
  class="ProductsAside__wrapper">
5
- <!-- <div class="ProductsAside__item hidden-md-and-up">
6
- <input
7
- v-model="search"
8
- name="search"
9
- placeholder="Search"
10
- type="text"
11
- class="form-field no-label tiny-placeholder labelless"
12
- @change="goToTextSearch" />
13
- </div> -->
14
- <!-- <div class="ProductsAside__item">
15
- <products-types
16
- :has-selected-icon="hasSelectedIcon"
17
- :has-thumbs="hasThumbs" />
18
- </div> -->
19
- <div class="ProductsAside__item">
20
- <products-brands
21
- :has-selected-icon="hasSelectedIcon" />
5
+ <div
6
+ v-if="placeholder"
7
+ class="ProductsAside__placeholder">
8
+ <span class="ProductsAside__info ProductsAside__info--large"></span>
9
+ <span class="ProductsAside__info ProductsAside__info--medium"></span>
10
+ <span class="ProductsAside__info ProductsAside__info--small"></span>
11
+ <span class="ProductsAside__info ProductsAside__info--small2"></span>
22
12
  </div>
23
- <div class="ProductsAside__item">
24
- <products-colors />
25
- </div>
26
- <div class="ProductsAside__item">
27
- <products-attributes
28
- :has-selected-icon="hasSelectedIcon" />
29
- <products-tags
30
- :has-selected-icon="hasSelectedIcon" />
13
+ <div v-else>
14
+ <div class="ProductsAside__item">
15
+ <products-brands
16
+ :has-selected-icon="hasSelectedIcon" />
17
+ </div>
18
+ <div class="ProductsAside__item">
19
+ <products-colors />
20
+ </div>
21
+ <div class="ProductsAside__item">
22
+ <products-attributes
23
+ :has-selected-icon="hasSelectedIcon" />
24
+ <products-tags
25
+ :has-selected-icon="hasSelectedIcon" />
26
+ </div>
31
27
  </div>
32
28
  </div>
33
29
  </template>
34
30
 
35
31
  <script>
36
- import ProductsTypes from '@lancom/shared/components/products/products_types/products-types';
32
+ // import ProductsTypes from '@lancom/shared/components/products/products_types/products-types';
33
+ import { mapGetters } from 'vuex';
37
34
  import ProductsBrands from '@lancom/shared/components/products/products_brands/products-brands';
38
35
  import ProductsTags from '@lancom/shared/components/products/products_tags/products-tags';
39
36
  import ProductsAttributes from '@lancom/shared/components/products/products_attributes/products-attributes';
@@ -43,7 +40,7 @@ import { generateProductsLink } from '@lancom/shared/assets/js/utils/product';
43
40
  export default {
44
41
  name: 'ProductsAside',
45
42
  components: {
46
- ProductsTypes,
43
+ // ProductsTypes,
47
44
  ProductsBrands,
48
45
  ProductsTags,
49
46
  ProductsAttributes,
@@ -64,6 +61,9 @@ export default {
64
61
  search: this.$route.query.text || ''
65
62
  };
66
63
  },
64
+ computed: {
65
+ ...mapGetters('products', ['placeholder'])
66
+ },
67
67
  methods: {
68
68
  goToTextSearch() {
69
69
  this.goToPageWithFilters({ text: this.search });
@@ -3,8 +3,11 @@
3
3
  <div v-if="products">
4
4
  <slot
5
5
  name="list"
6
- v-bind="{ products, toEditor }">
7
- <product-list :products="products" :to-editor="toEditor" />
6
+ v-bind="{ products, toEditor, placeholder }">
7
+ <product-list
8
+ :products="products"
9
+ :to-editor="toEditor"
10
+ :placeholder="placeholder" />
8
11
  </slot>
9
12
  <pagination
10
13
  v-model="currentPage"
@@ -38,7 +41,8 @@ export default {
38
41
  'products',
39
42
  'page',
40
43
  'count',
41
- 'perPage'
44
+ 'perPage',
45
+ 'placeholder'
42
46
  ]),
43
47
  currentPage: {
44
48
  get() {
@@ -47,6 +51,7 @@ export default {
47
51
  set(page) {
48
52
  const link = generateProductsLink(this.$route, { page });
49
53
  this.$router.push(link);
54
+ window.scrollTo(0, 0);
50
55
  }
51
56
  }
52
57
  }
@@ -69,7 +69,7 @@ export default {
69
69
  mounted() {
70
70
  setTimeout(() => {
71
71
  this.canLoadImages = true;
72
- }, 5000);
72
+ }, 1000);
73
73
  },
74
74
  methods: {
75
75
  isSelectedColor(color) {
@@ -297,11 +297,13 @@
297
297
  import api from '@lancom/shared/assets/js/api';
298
298
  import { mapGetters } from 'vuex';
299
299
  import CheckedIcon from '@lancom/shared/components/common/checked-icon';
300
+ import FileUploader from '@lancom/shared/components/common/file_uploader';
300
301
 
301
302
  export default {
302
303
  name: 'QuoteRequest',
303
304
  components: {
304
- CheckedIcon
305
+ CheckedIcon,
306
+ FileUploader
305
307
  },
306
308
  data() {
307
309
  return {
@@ -54,9 +54,6 @@ const productPreview = {
54
54
  productLink() {
55
55
  return generateProductLink(this.product, this.currentColor, this.toEditor);
56
56
  },
57
- productСoverBig() {
58
- return getProductLargeCover(this.product, 'front', this.currentColor);
59
- },
60
57
  productСover() {
61
58
  return getProductMediumCover(this.product, 'front', this.currentColor);
62
59
  },
@@ -84,11 +81,11 @@ const productPreview = {
84
81
  if (process.client) {
85
82
  setTimeout(() => {
86
83
  this.loadHolder.canLoadImages = true;
87
- }, 2500);
84
+ }, 0);
88
85
  setTimeout(() => {
89
86
  this.loadHolder.canLoadBackImages = true;
90
87
  this.loadHolder.canLoadColorImages = true;
91
- }, 5000);
88
+ }, 3000);
92
89
  }
93
90
  }
94
91
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lancom/shared",
3
- "version": "0.0.90",
3
+ "version": "0.0.91",
4
4
  "description": "lancom common scripts",
5
5
  "author": "e.tokovenko <e.tokovenko@gmail.com>",
6
6
  "repository": {
@@ -1,12 +1,10 @@
1
1
  import Vue from 'vue';
2
2
  import Btn from '@lancom/shared/components/common/btn';
3
3
  import Spinner from '@lancom/shared/components/common/spinner';
4
- import FileUploader from '@lancom/shared/components/common/file_uploader';
5
4
  import Checkbox from '@lancom/shared/components/common/checkbox';
6
5
  import Breakpoint from '@lancom/shared/components/common/breakpoint';
7
6
 
8
7
  Vue.component('btn', Btn);
9
8
  Vue.component('spinner', Spinner);
10
- Vue.component('file-uploader', FileUploader);
11
9
  Vue.component('Checkbox', Checkbox);
12
10
  Vue.component('breakpoint', Breakpoint);
@@ -1,17 +1,22 @@
1
1
  import Vue from 'vue';
2
- import { VueReCaptcha } from 'vue-recaptcha-v3';
3
2
 
4
3
  export default () => {
5
- Vue.use(VueReCaptcha, {
6
- siteKey: process.env.RECAPTCHA_KEY,
7
- loaderOptions: {
8
- useRecaptchaNet: true
9
- }
10
- });
11
4
  Vue.mixin({
12
5
  methods: {
13
6
  async getRecaptcha(name) {
7
+ if (!this.$recaptcha) {
8
+ await this.loadReCaptcha();
9
+ }
14
10
  return process.env.IS_LOCAL === 'true' || await this.$recaptcha(name);
11
+ },
12
+ async loadReCaptcha() {
13
+ const { VueReCaptcha } = await import('vue-recaptcha-v3');
14
+ Vue.use(VueReCaptcha, {
15
+ siteKey: process.env.RECAPTCHA_KEY,
16
+ loaderOptions: {
17
+ useRecaptchaNet: true
18
+ }
19
+ });
15
20
  }
16
21
  }
17
22
  });
package/store/products.js CHANGED
@@ -10,7 +10,8 @@ export const state = () => ({
10
10
  brands: [],
11
11
  tags: [],
12
12
  attributes: [],
13
- loadError: null
13
+ loadError: null,
14
+ placeholder: false
14
15
  });
15
16
 
16
17
  export const getters = {
@@ -23,7 +24,8 @@ export const getters = {
23
24
  page: ({ page }) => page,
24
25
  count: ({ count }) => count,
25
26
  perPage: ({ perPage }) => perPage,
26
- loadError: ({ loadError }) => loadError
27
+ loadError: ({ loadError }) => loadError,
28
+ placeholder: ({ placeholder }) => placeholder
27
29
  };
28
30
 
29
31
  export const actions = {
@@ -55,6 +57,9 @@ export const actions = {
55
57
  };
56
58
 
57
59
  export const mutations = {
60
+ setPlaceholder(state, placeholder) {
61
+ state.placeholder = placeholder;
62
+ },
58
63
  setProducts(state, products) {
59
64
  state.products = products;
60
65
  },