@lancom/shared 0.0.394 → 0.0.395
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.
- package/assets/js/api/index.js +3 -0
- package/components/products/children_categories/children-categories.scss +65 -0
- package/components/products/children_categories/children-categories.vue +43 -0
- package/layouts/products.vue +28 -10
- package/nuxt.config.js +1 -0
- package/package.json +1 -1
- package/store/products.js +14 -0
package/assets/js/api/index.js
CHANGED
|
@@ -41,6 +41,9 @@ const api = {
|
|
|
41
41
|
fetchCustomerCoupons(customer, shop) {
|
|
42
42
|
return _get(`shop/${shop}/customer/${customer._id}/coupons`);
|
|
43
43
|
},
|
|
44
|
+
fetchChildrenCategories(category, params) {
|
|
45
|
+
return _get(`category/${category}/children`, params);
|
|
46
|
+
},
|
|
44
47
|
searchProducts(shop, text, save) {
|
|
45
48
|
return _get(`shop/${shop}/products/search`, { text, save });
|
|
46
49
|
},
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
@import "@/assets/scss/variables";
|
|
2
|
+
|
|
3
|
+
.ChildrenCategories {
|
|
4
|
+
&__wrapper {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-wrap: wrap;
|
|
7
|
+
margin-top: 20px;
|
|
8
|
+
@media (max-width: $bp-small-max) {
|
|
9
|
+
justify-content: center;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.CategoryCard {
|
|
15
|
+
width: 270px;
|
|
16
|
+
margin: 0 0 15px 15px;
|
|
17
|
+
position: relative;
|
|
18
|
+
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
19
|
+
border-radius: 5px;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
background-color: white;
|
|
22
|
+
box-shadow: 0px 0px 0px rgba(75, 75, 75, 0.2);
|
|
23
|
+
|
|
24
|
+
&:hover {
|
|
25
|
+
transform: translateY(-5px);
|
|
26
|
+
box-shadow: 0px 5px 15px rgba(75, 75, 75, 0.2);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&__link {
|
|
30
|
+
display: block;
|
|
31
|
+
text-decoration: none;
|
|
32
|
+
color: inherit;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&__image-wrapper {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 300px;
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
position: relative;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&__image {
|
|
43
|
+
width: 100%;
|
|
44
|
+
height: 100%;
|
|
45
|
+
object-fit: cover;
|
|
46
|
+
transition: transform 0.3s ease;
|
|
47
|
+
|
|
48
|
+
&:hover {
|
|
49
|
+
transform: scale(1.05);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&__name {
|
|
54
|
+
padding: 15px;
|
|
55
|
+
font-size: 16px;
|
|
56
|
+
font-weight: 600;
|
|
57
|
+
color: $grey_1;
|
|
58
|
+
text-align: center;
|
|
59
|
+
background-color: white;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@media (max-width: $bp-extra-small-max) {
|
|
63
|
+
margin: 0 auto 25px auto;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ChildrenCategories__wrapper">
|
|
3
|
+
<div
|
|
4
|
+
v-for="category in childrenCategories"
|
|
5
|
+
:key="category._id"
|
|
6
|
+
class="CategoryCard">
|
|
7
|
+
<a
|
|
8
|
+
:href="generateProductsLink($route, { category }, true)"
|
|
9
|
+
class="CategoryCard__link">
|
|
10
|
+
<div class="CategoryCard__image-wrapper">
|
|
11
|
+
<img
|
|
12
|
+
v-if="category.image"
|
|
13
|
+
:src="category.image.medium"
|
|
14
|
+
:alt="category.name"
|
|
15
|
+
class="CategoryCard__image" />
|
|
16
|
+
</div>
|
|
17
|
+
<div class="CategoryCard__name">
|
|
18
|
+
{{ category.name }}
|
|
19
|
+
</div>
|
|
20
|
+
</a>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script>
|
|
26
|
+
import { mapGetters } from 'vuex';
|
|
27
|
+
import { generateProductsLink } from '@lancom/shared/assets/js/utils/product';
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
name: 'ChildrenCategories',
|
|
31
|
+
computed: {
|
|
32
|
+
...mapGetters('products', ['childrenCategories'])
|
|
33
|
+
},
|
|
34
|
+
methods: {
|
|
35
|
+
generateProductsLink
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<style lang="scss" scoped>
|
|
41
|
+
@import 'children-categories';
|
|
42
|
+
</style>
|
|
43
|
+
|
package/layouts/products.vue
CHANGED
|
@@ -20,12 +20,16 @@
|
|
|
20
20
|
<h1 class="Products__name">
|
|
21
21
|
{{ routeName }}
|
|
22
22
|
</h1>
|
|
23
|
-
<div
|
|
23
|
+
<div
|
|
24
|
+
v-if="!visiblChildrenCategories"
|
|
25
|
+
class="Products__filters">
|
|
24
26
|
<products-filters @open="openAside" />
|
|
25
27
|
</div>
|
|
26
28
|
</div>
|
|
27
29
|
<div class="Products__content">
|
|
28
|
-
<div
|
|
30
|
+
<div
|
|
31
|
+
v-if="!visiblChildrenCategories"
|
|
32
|
+
class="Products__aside">
|
|
29
33
|
<breakpoint
|
|
30
34
|
name="md"
|
|
31
35
|
mode="up">
|
|
@@ -33,7 +37,10 @@
|
|
|
33
37
|
</breakpoint>
|
|
34
38
|
</div>
|
|
35
39
|
<div class="Products__list">
|
|
36
|
-
<
|
|
40
|
+
<children-categories v-if="visiblChildrenCategories" />
|
|
41
|
+
<products-catalog
|
|
42
|
+
v-else
|
|
43
|
+
class="Products__catalog" />
|
|
37
44
|
</div>
|
|
38
45
|
</div>
|
|
39
46
|
<div
|
|
@@ -57,21 +64,22 @@
|
|
|
57
64
|
|
|
58
65
|
<script>
|
|
59
66
|
import debounce from 'lodash.debounce';
|
|
67
|
+
import LazyHydrate from 'vue-lazy-hydration';
|
|
60
68
|
import { mapActions, mapGetters, mapMutations } from 'vuex';
|
|
61
69
|
import gtm from '@lancom/shared/assets/js/utils/gtm';
|
|
62
70
|
import metaInfo from '@lancom/shared/mixins/meta-info';
|
|
63
71
|
import { generateProductsLink, generateProductLink } from '@lancom/shared/assets/js/utils/product';
|
|
64
72
|
import { getProductLargeCover, getProductMediumCover } from '@lancom/shared/assets/js/utils/colors';
|
|
65
|
-
import LazyHydrate from 'vue-lazy-hydration';
|
|
66
|
-
import TheNavbar from '@/components/the_navbar/the-navbar';
|
|
67
73
|
import TheChangesSavedIndicator from '@lancom/shared/components/the_changes_saved_indicator/the-changes-saved-indicator';
|
|
68
74
|
import Breadcrumbs from '@lancom/shared/components/common/breadcrumbs/breadcrumbs';
|
|
69
|
-
import
|
|
75
|
+
import StaticPage from '@lancom/shared/components/static_page/static-page';
|
|
70
76
|
import TheAside from '@lancom/shared/components/the_aside/the-aside';
|
|
71
|
-
import ProductsAside from '@/components/products/products_aside/products-aside';
|
|
72
77
|
import ProductsFilters from '@lancom/shared/components/products/products_filters/products-filters';
|
|
78
|
+
import ChildrenCategories from '@lancom/shared/components/products/children_categories/children-categories';
|
|
79
|
+
import ProductsAside from '@/components/products/products_aside/products-aside';
|
|
80
|
+
import TheNavbar from '@/components/the_navbar/the-navbar';
|
|
81
|
+
import TheFooter from '@/components/the_footer/the-footer';
|
|
73
82
|
import ProductsCatalog from '@/components/products/products_catalog/products-catalog';
|
|
74
|
-
import StaticPage from '@lancom/shared/components/static_page/static-page';
|
|
75
83
|
import Error from './error';
|
|
76
84
|
|
|
77
85
|
export default {
|
|
@@ -85,6 +93,7 @@
|
|
|
85
93
|
ProductsAside,
|
|
86
94
|
ProductsFilters,
|
|
87
95
|
ProductsCatalog,
|
|
96
|
+
ChildrenCategories,
|
|
88
97
|
Error,
|
|
89
98
|
StaticPage,
|
|
90
99
|
TheChangesSavedIndicator
|
|
@@ -93,6 +102,11 @@
|
|
|
93
102
|
middleware: ['page-info'],
|
|
94
103
|
async fetch() {
|
|
95
104
|
await this.loadProducts();
|
|
105
|
+
|
|
106
|
+
if (this.page === 1 && this.products.length === 0) {
|
|
107
|
+
await this.fetchChildrenCategories(this.currentCategory);
|
|
108
|
+
}
|
|
109
|
+
|
|
96
110
|
if (process.server) {
|
|
97
111
|
this.$root.context?.res?.setHeader('Cache-Control', `max-age=${86400}`);;
|
|
98
112
|
}
|
|
@@ -100,7 +114,10 @@
|
|
|
100
114
|
computed: {
|
|
101
115
|
...mapGetters('page', ['routeInfo']),
|
|
102
116
|
...mapGetters(['notificationBar', 'shop', 'country', 'currency']),
|
|
103
|
-
...mapGetters('products', ['category', 'categories', 'brands', 'types', 'tags', 'loadError', 'count', 'products', 'minPrice', 'maxPrice']),
|
|
117
|
+
...mapGetters('products', ['category', 'childrenCategories', 'categories', 'brands', 'types', 'tags', 'loadError', 'count', 'products', 'minPrice', 'maxPrice', 'page']),
|
|
118
|
+
visiblChildrenCategories() {
|
|
119
|
+
return this.page === 1 && this.products.length === 0 && this.childrenCategories.length > 0;
|
|
120
|
+
},
|
|
104
121
|
pageItemCanonical() {
|
|
105
122
|
const page = +this.$route.query.page;
|
|
106
123
|
return `${this.breadcrumbs[this.breadcrumbs.length - 1]?.to}${page > 1 ? `?page=${page}` : ''}`;
|
|
@@ -302,7 +319,8 @@
|
|
|
302
319
|
'loadState'
|
|
303
320
|
]),
|
|
304
321
|
...mapActions('products', [
|
|
305
|
-
'fetchProducts'
|
|
322
|
+
'fetchProducts',
|
|
323
|
+
'fetchChildrenCategories'
|
|
306
324
|
]),
|
|
307
325
|
...mapMutations('products', [
|
|
308
326
|
'setPlaceholder'
|
package/nuxt.config.js
CHANGED
|
@@ -38,6 +38,7 @@ module.exports = (config, axios, { raygunClient, publicPath, productUrlToEditor
|
|
|
38
38
|
'/checkout/**',
|
|
39
39
|
'/customer/**'
|
|
40
40
|
],
|
|
41
|
+
cacheTime: 10,
|
|
41
42
|
routes: async () => {
|
|
42
43
|
const { data } = await axios.get(`${config.LOCAL_API_URL}/feed/sitemap?host=${config.HOST_NAME}&toEditor=${!!productUrlToEditor}`);
|
|
43
44
|
return [
|
package/package.json
CHANGED
package/store/products.js
CHANGED
|
@@ -12,6 +12,7 @@ export const state = () => ({
|
|
|
12
12
|
brands: [],
|
|
13
13
|
category: null,
|
|
14
14
|
categories: [],
|
|
15
|
+
childrenCategories: [],
|
|
15
16
|
tags: [],
|
|
16
17
|
attributes: [],
|
|
17
18
|
loadError: null,
|
|
@@ -25,6 +26,7 @@ export const getters = {
|
|
|
25
26
|
brands: ({ brands }) => brands || [],
|
|
26
27
|
categories: ({ categories }) => categories || [],
|
|
27
28
|
category: ({ category }) => category,
|
|
29
|
+
childrenCategories: ({ childrenCategories }) => childrenCategories,
|
|
28
30
|
tags: ({ tags }) => tags || [],
|
|
29
31
|
attributes: ({ attributes }) => attributes || [],
|
|
30
32
|
page: ({ page }) => page,
|
|
@@ -79,10 +81,22 @@ export const actions = {
|
|
|
79
81
|
});
|
|
80
82
|
throw e;
|
|
81
83
|
}
|
|
84
|
+
},
|
|
85
|
+
async fetchChildrenCategories({ commit }, category) {
|
|
86
|
+
try {
|
|
87
|
+
const categories = await api.fetchChildrenCategories(category?._id);
|
|
88
|
+
commit('setChildrenCategories', categories);
|
|
89
|
+
return categories;
|
|
90
|
+
} catch (e) {
|
|
91
|
+
console.log(e);
|
|
92
|
+
}
|
|
82
93
|
}
|
|
83
94
|
};
|
|
84
95
|
|
|
85
96
|
export const mutations = {
|
|
97
|
+
setChildrenCategories(state, categories) {
|
|
98
|
+
state.childrenCategories = categories;
|
|
99
|
+
},
|
|
86
100
|
setPlaceholder(state, placeholder) {
|
|
87
101
|
state.placeholder = placeholder;
|
|
88
102
|
},
|