Skip to content

Commit

Permalink
Merge cf9f8b7 into 3eaf767
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszjedrasik committed Dec 27, 2020
2 parents 3eaf767 + cf9f8b7 commit cf9afaf
Show file tree
Hide file tree
Showing 13 changed files with 472 additions and 65 deletions.
71 changes: 58 additions & 13 deletions packages/boilerplate/api-client/src/api/getCategory/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,70 +5,115 @@ export default async function getCategory(context, params, customQuery?: CustomQ
return Promise.resolve([
{
id: 1,
name: 'New',
slug: 'new',
children: [
{
id: 15,
name: 'Women',
slug: 'new-women',
children: [
{
id: 16,
name: 'Clothing',
slug: 'new-women-clothing',
children: []
},
{
id: 17,
name: 'Shoes',
slug: 'new-women-shoes',
children: []
}
]
},
{
id: 11,
name: 'Men',
slug: 'new-men',
children: [
{
id: 18,
name: 'Clothing',
slug: 'new-men-clothing',
children: []
},
{
id: 19,
name: 'Shoes',
slug: 'new-men-shoes',
children: []
}
]
}
]
},
{
id: 2,
name: 'Women',
slug: 'women',
items: [
children: [
{
id: 4,
name: 'Women jackets',
slug: 'women-jackets',
items: [
children: [
{
id: 9,
name: 'Winter jackets',
slug: 'winter-jackets',
items: []
children: []
},
{
id: 10,
name: 'Autumn jackets',
slug: 'autmun-jackets',
items: []
children: []
}
]
},
{
id: 5,
name: 'Skirts',
slug: 'skirts',
items: []
children: []
}
]
},
{
id: 2,
id: 3,
name: 'Men',
slug: 'men',
items: [
children: [
{
id: 6,
name: 'Men T-shirts',
slug: 'men-tshirts',
items: []
children: []
}
]
},
{
id: 3,
id: 4,
name: 'Kids',
slug: 'kids',
items: [
children: [
{
id: 7,
name: 'Toys',
slug: 'toys',
items: [
children: [
{
id: 8,
name: 'Toy Cars',
slug: 'toy-cars',
items: []
children: []
},
{
id: 8,
name: 'Dolls',
slug: 'dolls',
items: []
children: []
}
]
}
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
import gql from 'graphql-tag';
import { CategoryFragment } from './../../fragments';

export default gql`
export default gql`
${CategoryFragment}
fragment Children on Category {
id
slug(acceptLanguage: $acceptLanguage)
name(acceptLanguage: $acceptLanguage)
childCount
}
fragment DefaultCategory on Category {
id
slug(acceptLanguage: $acceptLanguage)
name(acceptLanguage: $acceptLanguage)
childCount
children {
...Children
children {
...Children
children {
...Children
}
}
}
}
query categories($where: String, $sort: [String!], $limit: Int, $offset: Int, $acceptLanguage: [Locale!]) {
categories(where: $where, sort: $sort, limit: $limit, offset: $offset) {
offset
Expand Down
17 changes: 17 additions & 0 deletions packages/commercetools/api-client/src/fragments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,20 @@ export const OrderFragment = `
}
`;

export const CategoryFragment = `
fragment DefaultCategory on Category {
id
slug(acceptLanguage: $acceptLanguage)
name(acceptLanguage: $acceptLanguage)
childCount
children {
...Children
children {
...Children
children {
...Children
}
}
}
}
`;
161 changes: 161 additions & 0 deletions packages/commercetools/theme/components/TopMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<template>
<SfHeaderNavigation>
<SfHeaderNavigationItem
v-for="(category, index) in categories"
:key="index"
:label="category.name"
@mouseenter="() => handleMouseEnter(category.slug)"
@mouseleave="() => handleMouseLeave()"
@click="handleMouseLeave()"
:link="localePath(`/c/${category.slug}`)"
>
<SfMegaMenu
:is-absolute="true"
:visible="categorySlug === category.slug"
:title="category.name"
@close="categorySlug = ''"
v-if="category && category.children.length"
>
<SfMegaMenuColumn
v-for="(subCategory, subIndex) in category.children"
:key="subIndex"
:title="subCategory.name"
>
<SfLoader :loading="subCategoriesLoading">
<SfList>
<SfListItem
v-for="(subCategoryChild, childIndex) in subCategory.children"
:key="childIndex"
>
<SfMenuItem :label="subCategoryChild.name" :link="localePath(`/c/${subCategoryChild.slug}`)">
<SfLink>
{{ subCategoryChild.name }}
</SfLink>
</SfMenuItem>
</SfListItem>
</SfList>
</SfLoader>
</SfMegaMenuColumn>
<SfMegaMenuColumn
v-if="isCategoryWithBanners"
title="Featured"
class="sf-mega-menu-column--pined-content-on-mobile sf-mega-menu-column--hide-header-on-mobile sb-mega-menu__featured"
>
<div class="sb-mega-menu__banners">
<SfBanner
v-for="(banner, key) in banners"
:key="key"
:title="banner.title"
:subtitle="banner.subtitle"
:image="banner.pictures"
class="sb-mega-menu__banner"
/>
</div>
</SfMegaMenuColumn>
</SfMegaMenu>
</SfHeaderNavigationItem>
</SfHeaderNavigation>
</template>

<script>
import { SfMegaMenu, SfMenuItem, SfList, SfBanner, SfLoader } from '@storefront-ui/vue';
import { useCategory } from '@vue-storefront/commercetools';
import { onSSR } from '@vue-storefront/core';
import { computed, ref } from '@vue/composition-api';
import { menuCatQuery } from '../queries/topCategories';
import debounce from 'lodash.debounce';
export default {
name: 'TopMenu',
components: {
SfMegaMenu,
SfMenuItem,
SfList,
SfBanner,
SfLoader
},
setup (_, { emit }) {
const { categories, search } = useCategory('menu-categories');
const { categories: subCategories, search: subCategoriesSearch, loading: subCategoriesLoading } = useCategory('menu-subCategories');
const categorySlug = ref('');
const categoriesWithBanners = ref(['new']);
const isCategoryWithBanners = computed(() => categoriesWithBanners.value.includes(categorySlug.value));
const handleMouseEnter = debounce((slug) => {
if (categorySlug.value) return;
emit('setOverlay', true);
categorySlug.value = slug;
subCategoriesSearch({ slug });
}, 200);
const handleMouseLeave = debounce(() => {
emit('setOverlay', false);
categorySlug.value = '';
}, 200);
onSSR(async () => {
await search({ customQuery: menuCatQuery });
});
return {
categories,
subCategories,
categorySlug,
subCategoriesLoading,
categoriesWithBanners,
isCategoryWithBanners,
handleMouseEnter,
handleMouseLeave
};
},
data() {
return {
banners: [
{
title: 'THE OFFICE LIFE',
subtitle: 'T-shirts',
pictures: {
mobile: '/megamenu/bannerA.webp',
desktop: '/megamenu/bannerA.webp'
}
},
{
title: 'ECO SANDALS',
subtitle: 'T-shirts',
pictures: {
mobile: '/megamenu/bannerB.webp',
desktop: '/megamenu/bannerB.webp'
}
}
]
};
}
};
</script>

<style scoped lang='scss'>
.sb-mega-menu {
&__featured {
flex: 0 0 43.125rem;
}
&__banners {
display: flex;
flex-direction: column;
padding: var(--spacer-base);
@include for-desktop {
flex-direction: row;
padding: 0;
}
}
&__banner{
&:first-child{
margin: 0 0 var(--spacer-sm) 0;
@include for-desktop {
margin: 0 var(--spacer-sm) 0 0;
}
}
}
}
</style>
36 changes: 36 additions & 0 deletions packages/commercetools/theme/queries/topCategories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import gql from 'graphql-tag';
import { CategoryFragment } from '@vue-storefront/commercetools-api';

const customQuery = gql`
${CategoryFragment}
fragment Children on Category {
id
slug(acceptLanguage: $acceptLanguage)
name(acceptLanguage: $acceptLanguage)
childCount
}
query categories($where: String, $sort: [String!], $limit: Int, $offset: Int, $acceptLanguage: [Locale!]) {
categories(where: $where, sort: $sort, limit: $limit, offset: $offset) {
offset
count
total
results {
...DefaultCategory
}
}
}
`;

export const menuCatQuery = (query, variables) => {
const customVariables = {
...variables,
where: 'parent is not defined'
};

return {
query: customQuery,
variables: customVariables
};
};
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions packages/core/nuxt-theme-module/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"access": "public"
},
"dependencies": {
"lodash.debounce": "^4.0.8",
"lodash.merge": "^4.6.2"
}
}
Loading

0 comments on commit cf9afaf

Please sign in to comment.