From ef7b490416b19aeace5baa00da68326f116da456 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 6 Oct 2021 11:14:10 +0700 Subject: [PATCH] :sparkles: feat: get collections, facets in menu filter :%s --- framework/vendure/schema.d.ts | 5 +- .../HeaderSubMenu/HeaderSubMenu.tsx | 2 +- .../Layout/LayoutContent/LayoutContent.tsx | 9 +- .../common/MenuFilter/MenuFilter.module.scss | 4 +- .../common/MenuFilter/MenuFilter.tsx | 36 +++---- .../MenuFilterItem/MenuFilterItem.module.scss | 16 +++ .../MenuFilterItem/MenuFilterItem.tsx | 28 +++++ .../MenuNavigationProductList.module.scss | 18 +--- .../MenuNavigationProductList.tsx | 100 +++++++++++------- .../MenuSort/MenuSort.module.scss | 7 +- .../hooks/collection/useGetAllCollection.tsx | 4 +- src/components/hooks/facets/useFacets.tsx | 2 +- 12 files changed, 136 insertions(+), 95 deletions(-) create mode 100644 src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.module.scss create mode 100644 src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.tsx diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index ef667d9f3..5faa87b43 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -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> children?: Maybe< Array<{ __typename?: 'Facet' } & Pick> diff --git a/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.tsx b/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.tsx index 2cd72e5f2..b119a1c8a 100644 --- a/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.tsx +++ b/src/components/common/Header/components/HeaderSubMenu/HeaderSubMenu.tsx @@ -42,7 +42,7 @@ const HeaderSubMenu = memo(() => {
    {/* todo: handle active item */}
  • - Categories + Categories
  • { MENU.map(item =>
  • = ({ 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 = ({ children }) => { return ( <>
    + {router.pathname}
    { router.pathname === ROUTE.ACCOUNT ? @@ -38,10 +38,9 @@ const LayoutContent: FC = ({ children }) => { :
    {children}
    } -
    { - FILTER_PAGE.includes(pathname) && (
    ) + FILTER_PAGE.includes(router.pathname) && (
    ) }
    diff --git a/src/components/common/MenuFilter/MenuFilter.module.scss b/src/components/common/MenuFilter/MenuFilter.module.scss index b8b6596ce..e887734a9 100644 --- a/src/components/common/MenuFilter/MenuFilter.module.scss +++ b/src/components/common/MenuFilter/MenuFilter.module.scss @@ -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; diff --git a/src/components/common/MenuFilter/MenuFilter.tsx b/src/components/common/MenuFilter/MenuFilter.tsx index 454942734..a0021da79 100644 --- a/src/components/common/MenuFilter/MenuFilter.tsx +++ b/src/components/common/MenuFilter/MenuFilter.tsx @@ -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(''); +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 (

    {heading}

      { - categories.map(item =>
    • -
      handleClick(item.link)} className={classNames({ [s.active]: item.link === active? true: false })}> - {item.name} -
      -
    • ) + categories.map(item => ) }
    diff --git a/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.module.scss b/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.module.scss new file mode 100644 index 000000000..f70a224f2 --- /dev/null +++ b/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.module.scss @@ -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); + } + } +} diff --git a/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.tsx b/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.tsx new file mode 100644 index 000000000..d38d57208 --- /dev/null +++ b/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.tsx @@ -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 ( +
  • +
    + {name} +
    +
  • + ) +} + +export default MenuFilterItem diff --git a/src/components/common/MenuNavigationProductList/MenuNavigationProductList.module.scss b/src/components/common/MenuNavigationProductList/MenuNavigationProductList.module.scss index 6c7ee9c17..9fa431ca5 100644 --- a/src/components/common/MenuNavigationProductList/MenuNavigationProductList.module.scss +++ b/src/components/common/MenuNavigationProductList/MenuNavigationProductList.module.scss @@ -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%; } diff --git a/src/components/common/MenuNavigationProductList/MenuNavigationProductList.tsx b/src/components/common/MenuNavigationProductList/MenuNavigationProductList.tsx index 026710bbf..ff4ab2b5a 100644 --- a/src/components/common/MenuNavigationProductList/MenuNavigationProductList.tsx +++ b/src/components/common/MenuNavigationProductList/MenuNavigationProductList.tsx @@ -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( - <> -
    - - - -
    -
    -
    -
    -
    -

    FILTER

    -
    -
    - - - - -
    - {LANGUAGE.BUTTON_LABEL.CONFIRM} -
    + + + return ( +
    +
    +
    +
    +

    FILTER

    +
    +
    + {collectionLoading && } + + {facetsLoading && <> + + + } + { + facets?.map(item => ) + } + +
    + {LANGUAGE.BUTTON_LABEL.CONFIRM}
    - +
    ) } diff --git a/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss b/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss index 732f0e6eb..8a466ff74 100644 --- a/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss +++ b/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss @@ -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{ diff --git a/src/components/hooks/collection/useGetAllCollection.tsx b/src/components/hooks/collection/useGetAllCollection.tsx index 8e7232b2d..7e23cdf40 100644 --- a/src/components/hooks/collection/useGetAllCollection.tsx +++ b/src/components/hooks/collection/useGetAllCollection.tsx @@ -5,8 +5,8 @@ import useSWR from 'swr'; const useGetAllCollection = () => { - const { data, ...rest } = useSWR([getCollectionsNameQuery], gglFetcher) - return { collections: data?.collections, ...rest } + const { data, isValidating, ...rest } = useSWR([getCollectionsNameQuery], gglFetcher) + return { collections: data?.collections.items || [], loading: isValidating, ...rest } } export default useGetAllCollection; \ No newline at end of file diff --git a/src/components/hooks/facets/useFacets.tsx b/src/components/hooks/facets/useFacets.tsx index c9a4e85ab..8966bcedc 100644 --- a/src/components/hooks/facets/useFacets.tsx +++ b/src/components/hooks/facets/useFacets.tsx @@ -5,7 +5,7 @@ import useSWR from 'swr' const useFacets = (options?: QueryFacetsArgs) => { const { data, isValidating, ...rest } = useSWR([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