feat: get collections, facets in menu filter

:%s
This commit is contained in:
lytrankieio123
2021-10-06 11:14:10 +07:00
parent c154541948
commit ef7b490416
12 changed files with 136 additions and 95 deletions

View File

@@ -3228,8 +3228,9 @@ export type GetAllFacetsQuery = { __typename?: 'Query' } & {
items: Array<
{ __typename?: 'Facet' } & Pick<
Facet,
'id' | 'name' | 'code'
> & {
'id' | 'name' | 'code' | 'values'
>
& {
parent?: Maybe<{ __typename?: 'Facet' } & Pick<Facet, 'id'>>
children?: Maybe<
Array<{ __typename?: 'Facet' } & Pick<Facet, 'id'>>

View File

@@ -42,7 +42,7 @@ const HeaderSubMenu = memo(() => {
<ul className={s.menu}>
{/* todo: handle active item */}
<li>
<MenuDropdown options={collections?.items ?? []} align="left">Categories</MenuDropdown>
<MenuDropdown options={collections || []} align="left">Categories</MenuDropdown>
</li>
{
MENU.map(item => <li key={item.name}

View File

@@ -2,7 +2,7 @@ import { useRouter } from 'next/router'
import { FC } from 'react'
import { useMessage } from 'src/components/contexts'
import { useModalCommon } from 'src/components/hooks'
import { BRAND, CATEGORY, FEATURED, FILTER_PAGE, ROUTE } from 'src/utils/constanst.utils'
import { FILTER_PAGE, ROUTE } from 'src/utils/constanst.utils'
import { CartDrawer, Footer, MessageCommon, ScrollToTop } from '../..'
import Header from '../../Header/Header'
import MenuNavigationProductList from '../../MenuNavigationProductList/MenuNavigationProductList'
@@ -14,9 +14,8 @@ interface Props {
}
const LayoutContent: FC<Props> = ({ children }) => {
const { pathname } = useRouter()
const { visible: visibleFilter, openModal: openFilter, closeModal: closeFilter } = useModalCommon({ initialValue: false })
const router = useRouter()
const { visible: visibleFilter, openModal: openFilter, closeModal: closeFilter } = useModalCommon({ initialValue: true })
const {messages, removeMessage} = useMessage()
const toggleFilter = () => {
@@ -30,6 +29,7 @@ const LayoutContent: FC<Props> = ({ children }) => {
return (
<>
<div className={s.mainLayout}>
{router.pathname}
<Header toggleFilter={toggleFilter} visibleFilter={visibleFilter} />
{
router.pathname === ROUTE.ACCOUNT ?
@@ -38,10 +38,9 @@ const LayoutContent: FC<Props> = ({ children }) => {
</section> :
<main>{children}</main>
}
<div className={s.filter}><MenuNavigationProductList categories={CATEGORY} brands={BRAND} featured={FEATURED} visible={visibleFilter} onClose={closeFilter} /> </div>
<ScrollToTop visibilityHeight={1500} />
{
FILTER_PAGE.includes(pathname) && (<div className={s.filter}><MenuNavigationProductList categories={CATEGORY} brands={BRAND} featured={FEATURED} visible={visibleFilter} onClose={closeFilter} /> </div>)
FILTER_PAGE.includes(router.pathname) && (<div className={s.filter}><MenuNavigationProductList visible={visibleFilter} onClose={closeFilter} /> </div>)
}
<Footer />
</div>

View File

@@ -1,9 +1,7 @@
@import "../../../styles/utilities";
.menuFilterWrapper{
@apply spacing-horizontal;
.menuFilterHeading{
@apply sub-headline font-bold ;
@apply sub-headline font-bold;
color: var(--text-active);
font-feature-settings: 'salt' on;
margin: 0.8rem 0;

View File

@@ -2,43 +2,31 @@ import classNames from 'classnames'
import { useEffect, useState } from 'react';
import s from './MenuFilter.module.scss'
import MenuFilterItem from './MenuFilterItem/MenuFilterItem';
interface Props {
children?: any,
heading?:string,
categories:{name:string,link:string}[],
type:string,
heading?: string,
categories: { name: string, slug?: string, code?: string }[],
type: string,
onChangeValue?: (value: Object) => void
}
const MenuFilter = ({heading,categories,type,onChangeValue}:Props)=> {
const [active, setActive] = useState<string>('');
const MenuFilter = ({ heading, categories, type, onChangeValue }: Props) => {
function handleClick(value: string) {
function handleClick(link:string){
setActive(link);
if(active === link){
setActive('');
}
}
useEffect(()=>{
let href = active?.split("=");
const linkValue = href[1];
onChangeValue && onChangeValue({[type]:linkValue});
},[active])
return (
<section className={s.menuFilterWrapper}>
<h2 className={s.menuFilterHeading}>{heading}</h2>
<ul className={s.menuFilterList}>
{
categories.map(item => <li key={item.name}>
<div onClick={()=> handleClick(item.link)} className={classNames({ [s.active]: item.link === active? true: false })}>
{item.name}
</div>
</li>)
categories.map(item => <MenuFilterItem
key={item.slug || item.code}
name={item.name}
value={item.slug || item.code || ''}
onClick={handleClick}
/>)
}
</ul>
</section>

View File

@@ -0,0 +1,16 @@
.menuFilterItem {
margin: 1rem 0;
padding: 0;
div {
padding: 0.8rem 1.6rem;
margin-right: 0.8rem;
background-color: var(--gray);
border-radius: 0.8rem;
cursor: pointer;
&.active {
color: var(--white);
background-color: var(--primary);
}
}
}

View File

@@ -0,0 +1,28 @@
import classNames from 'classnames';
import { useState } from 'react';
import s from './MenuFilterItem.module.scss';
interface Props {
name: string,
value: string,
onClick: (value: string) => void
}
const MenuFilterItem = ({ name, value, onClick }: Props) => {
const [isSelected, setIsSelected] = useState(false)
function handleClick() {
// todo
setIsSelected(!isSelected)
}
return (
<li className={s.menuFilterItem}>
<div onClick={handleClick} className={classNames({ [s.active]: isSelected })}>
{name}
</div>
</li>
)
}
export default MenuFilterItem

View File

@@ -1,13 +1,5 @@
@import "../../../styles/utilities";
.menuNavigationProductListDesktop{
@screen sm {
@apply hidden;
}
@screen xl {
@apply block;
}
}
.menuNavigationProductListMobile{
@apply relative transition-all duration-100;
&.isShow{
@@ -37,7 +29,7 @@
transform: translateY(0%)
}
.content{
@apply absolute w-full h-full;
@apply absolute w-full h-full spacing-horizontal custom-scroll;
margin-top: 3rem;
padding-top: 10rem ;
padding-bottom: 10rem;
@@ -46,6 +38,7 @@
height: 96%;
bottom: 0;
border-radius: 2.4rem 2.4rem 0 0;
.head{
@apply flex justify-between fixed;
top:0;
@@ -57,12 +50,11 @@
background-color: white;
z-index: 10000;
h3{
@apply heading-3 font-bold;
color:var(--text-base);
@apply heading-3 font-heading;
}
}
.foot{
@apply fixed;
@apply fixed text-center;
bottom: 0;
left:0;
width: 100%;
@@ -70,7 +62,7 @@
padding: 0 1rem 3rem 1rem;
}
button{
button {
margin-top: 2rem;
width: 100%;
}

View File

@@ -1,56 +1,78 @@
import { QueryFacetsArgs } from '@framework/schema';
import classNames from 'classnames';
import React, { useState } from 'react';
import {ButtonCommon} from 'src/components/common';
import { ButtonCommon } from 'src/components/common';
import { useGetAllCollection } from 'src/components/hooks/collection';
import { useFacets } from 'src/components/hooks/facets';
import IconHide from 'src/components/icons/IconHide';
import { CODE_FACET_BRAND, CODE_FACET_FEATURED, QUERY_KEY } from 'src/utils/constanst.utils';
import { LANGUAGE } from 'src/utils/language.utils';
import { SortOrder } from 'src/utils/types.utils';
import MenuFilter from '../MenuFilter/MenuFilter';
import SkeletonParagraph from '../SkeletonCommon/SkeletonParagraph/SkeletonParagraph';
import s from './MenuNavigationProductList.module.scss';
import MenuSort from './MenuSort/MenuSort';
import {LANGUAGE} from 'src/utils/language.utils';
import classNames from 'classnames'
import MenuFilter from '../MenuFilter/MenuFilter';
import MenuNavigation from '../MenuNavigation/MenuNavigation';
import IconHide from 'src/components/icons/IconHide';
interface Props{
categories:{name:string,link:string}[],
brands:{name:string,link:string}[],
featured:{name:string,link:string}[],
interface Props {
visible: boolean,
onClose: () => void
}
const MenuNavigationProductList = ({categories,brands,featured,visible,onClose}:Props)=>{
const [dataSort,setDataSort] = useState({});
function handleValue(value:Object){
setDataSort({...dataSort,...value});
const FACET_QUERY = {
options: {
sort: {
code: SortOrder.Asc
},
filter: {
code: {
in: [CODE_FACET_FEATURED, CODE_FACET_BRAND]
}
function filter(){
}
}
} as QueryFacetsArgs
const MenuNavigationProductList = ({ visible, onClose }: Props) => {
const { facets, loading: facetsLoading } = useFacets(FACET_QUERY)
const { collections, loading: collectionLoading } = useGetAllCollection()
const [dataSort, setDataSort] = useState({});
function handleValue(value: Object) {
setDataSort({ ...dataSort, ...value });
}
function filter() {
// console.log(dataSort)
}
return(
<>
<div className={s.menuNavigationProductListDesktop}>
<MenuNavigation categories={categories} heading="Categories"/>
<MenuNavigation categories={brands} heading="Brands"/>
<MenuNavigation categories={featured} heading="Featured"/>
</div>
<div className={classNames({ [s.menuNavigationProductListMobile] :true,[s.isShow]: visible})}>
<div className={classNames({ [s.menuNavigationProductModal] :true,[s.animation]: visible})}>
return (
<div className={classNames({ [s.menuNavigationProductListMobile]: true, [s.isShow]: visible })}>
<div className={classNames({ [s.menuNavigationProductModal]: true, [s.animation]: visible })}>
<div className={s.content}>
<div className={s.head}>
<h3>FILTER</h3>
<div onClick={onClose}><IconHide/></div>
<div onClick={onClose}><IconHide /></div>
</div>
<MenuFilter categories={categories} heading="Categories" type="category" onChangeValue={handleValue}/>
<MenuFilter categories={brands} heading="Brand" type="brand" onChangeValue={handleValue}/>
<MenuFilter categories={featured} heading="Featured" type="featured" onChangeValue={handleValue}/>
<MenuSort heading="SORT BY" type="sort" onChangeValue={handleValue}/>
{collectionLoading && <SkeletonParagraph rows={5} />}
<MenuFilter categories={collections} heading="Categories" type={QUERY_KEY.CATEGORY} onChangeValue={handleValue} />
{facetsLoading && <>
<SkeletonParagraph rows={5} />
<SkeletonParagraph rows={5} />
</>}
{
facets?.map(item => <MenuFilter
key={item.id}
type={item.code}
categories={item.values}
heading={item.name} />)
}
<MenuSort heading="SORT BY" type="sort" onChangeValue={handleValue} />
<div className={s.foot}>
<ButtonCommon size="large" onClick={filter}>{LANGUAGE.BUTTON_LABEL.CONFIRM}</ButtonCommon>
</div>
</div>
</div>
</div>
</>
)
}

View File

@@ -1,11 +1,8 @@
@import "../../../../styles/utilities";
.menuSortWrapper{
@apply spacing-horizontal;
.menuSortWrapper{
.menuSortHeading{
@apply sub-headline font-bold ;
color: var(--text-active);
font-feature-settings: 'salt' on;
@apply heading-3 font-heading;
margin: 0.8rem 0;
}
.menuSortList{

View File

@@ -5,8 +5,8 @@ import useSWR from 'swr';
const useGetAllCollection = () => {
const { data, ...rest } = useSWR<GetCollectionsQuery>([getCollectionsNameQuery], gglFetcher)
return { collections: data?.collections, ...rest }
const { data, isValidating, ...rest } = useSWR<GetCollectionsQuery>([getCollectionsNameQuery], gglFetcher)
return { collections: data?.collections.items || [], loading: isValidating, ...rest }
}
export default useGetAllCollection;

View File

@@ -5,7 +5,7 @@ import useSWR from 'swr'
const useFacets = (options?: QueryFacetsArgs) => {
const { data, isValidating, ...rest } = useSWR<GetAllFacetsQuery>([getAllFacetsQuery, options], gglFetcher)
return { items: data?.facets.items, totalItems: data?.facets.totalItems, loading: isValidating, ...rest }
return { facets: data?.facets.items, totalItems: data?.facets.totalItems, loading: isValidating, ...rest }
}
export default useFacets