From c49ba5062a20417c8c8e82a4c8cd1ce21db6705c Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 6 Oct 2021 15:01:23 +0700 Subject: [PATCH] :sparkles: feat: initial active value for option filter products :%s --- .../utils/queries/get-collections-query.ts | 2 +- .../LayoutContent/LayoutContent.module.scss | 2 +- .../Layout/LayoutContent/LayoutContent.tsx | 3 +- .../common/MenuFilter/MenuFilter.module.scss | 17 +---- .../common/MenuFilter/MenuFilter.tsx | 17 ++--- .../MenuFilterItem/MenuFilterItem.module.scss | 1 - .../MenuFilterItem/MenuFilterItem.tsx | 18 +++-- .../MenuNavigation/MenuNavigation.module.scss | 32 ++------ .../common/MenuNavigation/MenuNavigation.tsx | 25 +++---- .../MenuNavigationItem.module.scss | 15 ++++ .../MenuNavigationItem/MenuNavigationItem.tsx | 57 ++++++++++++++ .../MenuNavigationProductList.tsx | 74 ++++++++++++++++--- .../MenuSort/MenuSort.module.scss | 25 ------- .../MenuSort/MenuSort.tsx | 61 ++++----------- .../MenuSortItem/MenuSortItem.module.scss | 26 +++++++ .../MenuSort/MenuSortItem/MenuSortItem.tsx | 24 ++++++ .../MenuSort/MenuSortItem/check.svg | 3 + .../ModalCreateUserInfo.tsx | 2 +- .../ProductList/ProductList.module.scss | 3 +- .../common/SelectCommon/SelectCommon.tsx | 35 ++++++--- .../SelectOption/SelectOption.tsx | 10 +-- .../EditInfoModal/EditInfoModal.tsx | 2 +- .../ShippingInfoForm/ShippingInfoForm.tsx | 2 +- .../ProductListFilter.module.scss | 26 +------ .../ProductListFilter/ProductListFilter.tsx | 42 ++--------- .../ProductSort/ProductSort.tsx | 40 ++++++++++ .../ProductsMenuNavigationTablet.module.scss | 12 +++ .../ProductsMenuNavigationTablet.tsx | 28 +++++++ .../recipes-list/RecipesList/RecipesList.tsx | 4 +- src/styles/_base.scss | 2 +- src/utils/constanst.utils.ts | 31 +++++++- 31 files changed, 400 insertions(+), 241 deletions(-) create mode 100644 src/components/common/MenuNavigation/MenuNavigationItem/MenuNavigationItem.module.scss create mode 100644 src/components/common/MenuNavigation/MenuNavigationItem/MenuNavigationItem.tsx create mode 100644 src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/MenuSortItem.module.scss create mode 100644 src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/MenuSortItem.tsx create mode 100644 src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/check.svg create mode 100644 src/components/modules/product-list/ProductListFilter/ProductSort/ProductSort.tsx create mode 100644 src/components/modules/product-list/ProductListFilter/ProductsMenuNavigationTablet/ProductsMenuNavigationTablet.module.scss create mode 100644 src/components/modules/product-list/ProductListFilter/ProductsMenuNavigationTablet/ProductsMenuNavigationTablet.tsx diff --git a/framework/vendure/utils/queries/get-collections-query.ts b/framework/vendure/utils/queries/get-collections-query.ts index 79e00a292..f07a85249 100644 --- a/framework/vendure/utils/queries/get-collections-query.ts +++ b/framework/vendure/utils/queries/get-collections-query.ts @@ -24,7 +24,7 @@ export const getCollectionsNameQuery = /* GraphQL */ ` collections{ items{ name - link:slug + slug } } } diff --git a/src/components/common/Layout/LayoutContent/LayoutContent.module.scss b/src/components/common/Layout/LayoutContent/LayoutContent.module.scss index 97ed29624..9e687217e 100644 --- a/src/components/common/Layout/LayoutContent/LayoutContent.module.scss +++ b/src/components/common/Layout/LayoutContent/LayoutContent.module.scss @@ -17,7 +17,7 @@ } } .filter { - @screen xl { + @screen md { display: none; } } diff --git a/src/components/common/Layout/LayoutContent/LayoutContent.tsx b/src/components/common/Layout/LayoutContent/LayoutContent.tsx index ce4022dd0..6e82f338a 100644 --- a/src/components/common/Layout/LayoutContent/LayoutContent.tsx +++ b/src/components/common/Layout/LayoutContent/LayoutContent.tsx @@ -15,7 +15,7 @@ interface Props { const LayoutContent: FC = ({ children }) => { const router = useRouter() - const { visible: visibleFilter, openModal: openFilter, closeModal: closeFilter } = useModalCommon({ initialValue: true }) + const { visible: visibleFilter, openModal: openFilter, closeModal: closeFilter } = useModalCommon({ initialValue: false }) const {messages, removeMessage} = useMessage() const toggleFilter = () => { @@ -29,7 +29,6 @@ const LayoutContent: FC = ({ children }) => { return ( <>
- {router.pathname}
{ router.pathname === ROUTE.ACCOUNT ? diff --git a/src/components/common/MenuFilter/MenuFilter.module.scss b/src/components/common/MenuFilter/MenuFilter.module.scss index e887734a9..ef045ef02 100644 --- a/src/components/common/MenuFilter/MenuFilter.module.scss +++ b/src/components/common/MenuFilter/MenuFilter.module.scss @@ -1,4 +1,5 @@ @import "../../../styles/utilities"; + .menuFilterWrapper{ .menuFilterHeading{ @apply sub-headline font-bold; @@ -17,21 +18,5 @@ width: 100%; border-bottom: 1px solid var(--border-line); } - - li{ - 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:white; - background-color: var(--primary); - } - } - } } } diff --git a/src/components/common/MenuFilter/MenuFilter.tsx b/src/components/common/MenuFilter/MenuFilter.tsx index a0021da79..b23816aff 100644 --- a/src/components/common/MenuFilter/MenuFilter.tsx +++ b/src/components/common/MenuFilter/MenuFilter.tsx @@ -1,19 +1,17 @@ -import classNames from 'classnames' -import { useEffect, useState } from 'react'; - -import s from './MenuFilter.module.scss' +import s from './MenuFilter.module.scss'; import MenuFilterItem from './MenuFilterItem/MenuFilterItem'; + interface Props { children?: any, heading?: string, categories: { name: string, slug?: string, code?: string }[], type: string, - onChangeValue?: (value: Object) => void + onChange: (value: string, type: string, isSellect?: boolean) => void } -const MenuFilter = ({ heading, categories, type, onChangeValue }: Props) => { - function handleClick(value: string) { - +const MenuFilter = ({ heading, categories, type, onChange }: Props) => { + function handleChange(value: string, isSellect: boolean) { + onChange(value, type, isSellect) } return ( @@ -24,8 +22,9 @@ const MenuFilter = ({ heading, categories, type, onChangeValue }: Props) => { categories.map(item => ) } diff --git a/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.module.scss b/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.module.scss index f70a224f2..3ecab2495 100644 --- a/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.module.scss +++ b/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.module.scss @@ -1,4 +1,3 @@ - .menuFilterItem { margin: 1rem 0; padding: 0; diff --git a/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.tsx b/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.tsx index d38d57208..e247bfe93 100644 --- a/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.tsx +++ b/src/components/common/MenuFilter/MenuFilterItem/MenuFilterItem.tsx @@ -1,18 +1,26 @@ import classNames from 'classnames'; -import { useState } from 'react'; +import { route } from 'next/dist/server/router'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; import s from './MenuFilterItem.module.scss'; interface Props { name: string, value: string, - onClick: (value: string) => void + type: string, + onChange: (value: string, isSellect: boolean) => void } -const MenuFilterItem = ({ name, value, onClick }: Props) => { - const [isSelected, setIsSelected] = useState(false) +const MenuFilterItem = ({ name, value, type, onChange }: Props) => { + const router = useRouter() + const [isSelected, setIsSelected] = useState() + useEffect(() => { + const rs = (router.query[type] || []).includes(value) + setIsSelected(rs) + }, [type, router.query, value]) function handleClick() { - // todo + onChange(value, !isSelected) setIsSelected(!isSelected) } diff --git a/src/components/common/MenuNavigation/MenuNavigation.module.scss b/src/components/common/MenuNavigation/MenuNavigation.module.scss index 6d0a06c3f..49639ce3c 100644 --- a/src/components/common/MenuNavigation/MenuNavigation.module.scss +++ b/src/components/common/MenuNavigation/MenuNavigation.module.scss @@ -3,31 +3,13 @@ @apply hidden; @screen md { @apply block; - } - .menuNavigationHeading{ - @screen md { - @apply sub-headline font-bold ; - color: var(--text-active); - font-feature-settings: 'salt' on; - margin: 1.6rem 0; - } - } - .menuNavigationList{ - @screen md { - li{ - margin: 0.8rem 0; - a{ - display:block; - width:100%; - color:var(--text-base); - &:hover { - @apply text-primary; - } - &.active { - @apply text-primary; - } - } + .menuNavigationHeading{ + @screen md { + @apply sub-headline font-bold ; + color: var(--text-active); + font-feature-settings: 'salt' on; + margin: 1.6rem 0; } } - } + } } diff --git a/src/components/common/MenuNavigation/MenuNavigation.tsx b/src/components/common/MenuNavigation/MenuNavigation.tsx index a2554451e..669eacf59 100644 --- a/src/components/common/MenuNavigation/MenuNavigation.tsx +++ b/src/components/common/MenuNavigation/MenuNavigation.tsx @@ -1,32 +1,25 @@ -import classNames from 'classnames' -import Link from 'next/link' -import { useRouter } from 'next/router' -import { ROUTE } from 'src/utils/constanst.utils' import s from './MenuNavigation.module.scss' +import MenuNavigationItem from './MenuNavigationItem/MenuNavigationItem' interface Props { children?: any, heading: string, - linkPrefix: string, + queryKey: string, categories: { name: string, slug?: string, code?: string }[] } -const MenuNavigation = ({ heading, linkPrefix, categories }: Props) => { - const router = useRouter() - +const MenuNavigation = ({ heading, queryKey, categories }: Props) => { return (

{heading}({categories.length})

diff --git a/src/components/common/MenuNavigation/MenuNavigationItem/MenuNavigationItem.module.scss b/src/components/common/MenuNavigation/MenuNavigationItem/MenuNavigationItem.module.scss new file mode 100644 index 000000000..97f336443 --- /dev/null +++ b/src/components/common/MenuNavigation/MenuNavigationItem/MenuNavigationItem.module.scss @@ -0,0 +1,15 @@ +.menuNavigationItem { + @screen md { + display: block; + width: 100%; + margin: 0.8rem 0; + color: var(--text-base); + cursor: pointer; + &:hover { + @apply text-active; + } + &.active { + @apply text-primary; + } + } +} diff --git a/src/components/common/MenuNavigation/MenuNavigationItem/MenuNavigationItem.tsx b/src/components/common/MenuNavigation/MenuNavigationItem/MenuNavigationItem.tsx new file mode 100644 index 000000000..c7aeba724 --- /dev/null +++ b/src/components/common/MenuNavigation/MenuNavigationItem/MenuNavigationItem.tsx @@ -0,0 +1,57 @@ +import classNames from 'classnames' +import { useRouter } from 'next/router' +import { useEffect, useState } from 'react' +import { QUERY_SPLIT_SEPERATOR, ROUTE } from 'src/utils/constanst.utils' +import s from './MenuNavigationItem.module.scss' + +interface Props { + name: string + value: string + queryKey: string, +} + +const MenuNavigationItem = ({ name, value, queryKey }: Props) => { + const router = useRouter() + const [isActive, setIsActive] = useState() + + useEffect(() => { + if (!value) { + setIsActive(false) + } + + const queryString = router.query[queryKey] as string || '' + setIsActive(queryString.split(QUERY_SPLIT_SEPERATOR).includes(value)) + }, [router.query, queryKey, value]) + + const handleClick = () => { + const queryString = router.query[queryKey] as string || '' + const prevQuery = queryString.split(QUERY_SPLIT_SEPERATOR) + + let newQuery = [] as string[] + if (isActive) { + newQuery = prevQuery.filter(item => item !== value) + } else { + newQuery = [...prevQuery, value] + } + // setIsActive(!isActive) + + router.push({ + pathname: ROUTE.PRODUCTS, + query: { + ...router.query, + [queryKey]: newQuery.join(QUERY_SPLIT_SEPERATOR) + } + }, + undefined, { shallow: true } + ) + } + + return (
  • + {name} +
  • ) + + +} + +export default MenuNavigationItem diff --git a/src/components/common/MenuNavigationProductList/MenuNavigationProductList.tsx b/src/components/common/MenuNavigationProductList/MenuNavigationProductList.tsx index ff4ab2b5a..af3d4c9f9 100644 --- a/src/components/common/MenuNavigationProductList/MenuNavigationProductList.tsx +++ b/src/components/common/MenuNavigationProductList/MenuNavigationProductList.tsx @@ -1,11 +1,12 @@ import { QueryFacetsArgs } from '@framework/schema'; import classNames from 'classnames'; -import React, { useState } from 'react'; +import { useRouter } from 'next/router'; +import React, { useEffect, useState } from 'react'; 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 { CODE_FACET_BRAND, CODE_FACET_FEATURED, OPTIONS_SORT_PRODUCT, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'; import { LANGUAGE } from 'src/utils/language.utils'; import { SortOrder } from 'src/utils/types.utils'; import MenuFilter from '../MenuFilter/MenuFilter'; @@ -32,16 +33,65 @@ const FACET_QUERY = { } as QueryFacetsArgs const MenuNavigationProductList = ({ visible, onClose }: Props) => { + const router = useRouter() const { facets, loading: facetsLoading } = useFacets(FACET_QUERY) const { collections, loading: collectionLoading } = useGetAllCollection() + const [brandQuery, setBrandQuery] = useState([]) + const [featuredQuery, setFeaturedQuery] = useState([]) + const [categoryQuery, setCategoryQuery] = useState([]) + const [sortValue, setSortValue] = useState(); - const [dataSort, setDataSort] = useState({}); + useEffect(() => { + const rs = router.query[QUERY_KEY.SORTBY] as string + if (rs) { + setSortValue(rs) + } + }, [router.query]) - function handleValue(value: Object) { - setDataSort({ ...dataSort, ...value }); + function onSubmit() { + let newURL = `${ROUTE.PRODUCTS}?` + + if (categoryQuery.length > 0) { + newURL += `&${QUERY_KEY.CATEGORY}=${categoryQuery.join(",")}` + } + + if (brandQuery.length > 0) { + newURL += `&${QUERY_KEY.BRAND}=${brandQuery.join(",")}` + } + + if (featuredQuery.length > 0) { + newURL += `&${QUERY_KEY.FEATURED}=${featuredQuery.join(",")}` + } + + if (sortValue) { + newURL += `&${QUERY_KEY.SORTBY}=${sortValue}` + } + router.push(newURL) + onClose() } - function filter() { - // console.log(dataSort) + + const onSortChange = (value: string) => { + setSortValue(value) + } + + const onFilterOptionChange = (value: string, type: string, isSelect: boolean = true) => { + let rs = [...categoryQuery] + let setDataFunction = setCategoryQuery + + if (type === CODE_FACET_BRAND) { + rs = [...brandQuery] + setDataFunction = setBrandQuery + } else if (type === CODE_FACET_FEATURED) { + rs = [...featuredQuery] + setDataFunction = setFeaturedQuery + } + + if (isSelect) { + rs.push(value) + } else { + rs = rs.filter(item => item !== value) + } + setDataFunction(rs) } @@ -54,7 +104,7 @@ const MenuNavigationProductList = ({ visible, onClose }: Props) => {
    {collectionLoading && } - + {facetsLoading && <> @@ -64,11 +114,13 @@ const MenuNavigationProductList = ({ visible, onClose }: Props) => { key={item.id} type={item.code} categories={item.values} - heading={item.name} />) + heading={item.name} + onChange={onFilterOptionChange} + />) } - +
    - {LANGUAGE.BUTTON_LABEL.CONFIRM} + {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 8a466ff74..ac3b0681a 100644 --- a/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss +++ b/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.module.scss @@ -8,30 +8,5 @@ .menuSortList{ padding-bottom: 1rem; box-sizing: border-box; - - li{ - div{ - height: 4.8rem; - line-height: 4.8rem; - padding: 0 1.6rem; - margin-right: 0.8rem; - border-radius: 0.8rem; - cursor: pointer; - &.active { - @apply font-bold relative; - color:var(--text-active); - background-color: var(--gray); - &::after{ - @apply absolute; - content:""; - background-image: url('/assets/svg/check.svg'); - right: 1.6rem; - top: calc(50% - 24px/2); - width: 2.4rem; - height: 2.4rem; - } - } - } - } } } diff --git a/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.tsx b/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.tsx index 2e66dfc83..cd771fe6e 100644 --- a/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.tsx +++ b/src/components/common/MenuNavigationProductList/MenuSort/MenuSort.tsx @@ -1,63 +1,30 @@ import classNames from 'classnames'; import { useEffect, useState } from 'react'; -import { QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'; +import { PRODUCT_SORT_OPTION_VALUE, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'; import s from './MenuSort.module.scss'; +import MenuSortItem from './MenuSortItem/MenuSortItem'; interface Props { children?: any, - heading:string, - type:string, - onChangeValue?: (value: Object) => void + heading: string, + options: {name: string, value: string}[] + value?: string, + onChange: (value: string) => void } -const SORT = [ - { - name: 'By Name', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.SORTBY}=by-name`, - }, - { - name: 'Price(High to Low)', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.SORTBY}=high-to-low`, - }, - { - name: 'Price (Low to High)', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.SORTBY}=low-to-high`, - }, - { - name: 'On Sale', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.SORTBY}=on-sale`, - }, - ]; - -const MenuSort = ({heading,type,onChangeValue}:Props)=> { - const [active, setActive] = useState(''); - - function handleClick(link:string){ - setActive(link); - - if(active === link){ - setActive(''); - } - } - - useEffect(()=>{ - - let href = active?.split("="); - const linkValue = href[1]; - - onChangeValue && onChangeValue({[type]:linkValue}); - },[active]) - +const MenuSort = ({ heading, value, onChange, options }: Props) => { return (

    {heading}

      { - SORT.map(item =>
    • -
      handleClick(item.link)} className={classNames({ [s.active]: item.link === active? true: false })}> - {item.name} -
      -
    • ) + options.map(item => ) }
    diff --git a/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/MenuSortItem.module.scss b/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/MenuSortItem.module.scss new file mode 100644 index 000000000..894cc191a --- /dev/null +++ b/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/MenuSortItem.module.scss @@ -0,0 +1,26 @@ +.menuSortItem { + div { + height: 4.8rem; + line-height: 4.8rem; + padding: 0 1.6rem; + margin-right: 0.8rem; + border-radius: 0.8rem; + cursor: pointer; + &.active { + @apply font-bold relative; + color: var(--text-active); + background-color: var(--primary-lightest); + &::after { + @apply absolute; + content: ""; + background-image: url("./check.svg"); + background-repeat: no-repeat; + background-position: center; + right: 1.6rem; + top: calc(50% - 24px / 2); + width: 2.4rem; + height: 2.4rem; + } + } + } +} diff --git a/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/MenuSortItem.tsx b/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/MenuSortItem.tsx new file mode 100644 index 000000000..f14e9cf24 --- /dev/null +++ b/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/MenuSortItem.tsx @@ -0,0 +1,24 @@ +import classNames from 'classnames'; +import s from './MenuSortItem.module.scss'; + +interface Props { + name: string, + value: string, + currentValue?: string, + onChange: (value: string) => void +} + +const MenuSortItem = ({ onChange, name, value, currentValue }: Props) => { + const handleChange = () => { + onChange(value) + } + return ( +
  • +
    + {name} +
    +
  • + ) +} + +export default MenuSortItem diff --git a/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/check.svg b/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/check.svg new file mode 100644 index 000000000..0962fae2c --- /dev/null +++ b/src/components/common/MenuNavigationProductList/MenuSort/MenuSortItem/check.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.tsx b/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.tsx index c3794bf81..c5625c691 100644 --- a/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.tsx +++ b/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.tsx @@ -25,7 +25,7 @@ const ModalCreateUserInfo = ({ demoVisible: visible, demoCloseModal: closeModal
    - +
    diff --git a/src/components/common/ProductList/ProductList.module.scss b/src/components/common/ProductList/ProductList.module.scss index c49696ea5..e58b37f86 100644 --- a/src/components/common/ProductList/ProductList.module.scss +++ b/src/components/common/ProductList/ProductList.module.scss @@ -1,11 +1,10 @@ .wrapper{ + margin-top: 4rem; .list{ - // max-width: 109.4rem; @apply flex flex-wrap justify-around; } .pagination{ padding-top: 4.8rem; - // max-width: 109.4rem; @apply flex justify-center items-center ; } } \ No newline at end of file diff --git a/src/components/common/SelectCommon/SelectCommon.tsx b/src/components/common/SelectCommon/SelectCommon.tsx index 9b8c88e24..bf34ed3f9 100644 --- a/src/components/common/SelectCommon/SelectCommon.tsx +++ b/src/components/common/SelectCommon/SelectCommon.tsx @@ -1,24 +1,33 @@ -import s from './SelectCommon.module.scss' import classNames from 'classnames' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { IconVectorDown } from 'src/components/icons' +import s from './SelectCommon.module.scss' import SelectOption from './SelectOption/SelectOption' interface Props { placeholder? : string, + value?: string, size?: 'base' | 'large', type?: 'default' | 'custom', - option: {name: string, value: string}[], + options: {name: string, value: string}[], onChange?: (value: string) => void, } -const SelectCommon = ({ type = 'default', size = 'base', option, placeholder, onChange}: Props) => { - const [selectedName, setSelectedName] = useState(placeholder) - const [selectedValue, setSelectedValue] = useState('') +const SelectCommon = ({ value, type = 'default', size = 'base', options, placeholder, onChange}: Props) => { + const [selectedName, setSelectedName] = useState() + const [selectedValue, setSelectedValue] = useState('') - const changeSelectedName = (item:string, value: string) => { + useEffect(() => { + setSelectedValue(value || '') + + const name = options.find(item => item.value === value)?.name + setSelectedName(name) + }, [value, options]) + + const changeSelectedName = (value: string) => { setSelectedValue(value) - setSelectedName(item) + const name = options.find(item => item.value === value)?.name + setSelectedName(name) onChange && onChange(value) } return( @@ -33,7 +42,7 @@ const SelectCommon = ({ type = 'default', size = 'base', option, placeholder, on [s.selectTrigger] : true, })} - >{selectedName} + >{selectedName || placeholder}
    { - option.map(item => - + options.map(item => + ) }
    diff --git a/src/components/common/SelectCommon/SelectOption/SelectOption.tsx b/src/components/common/SelectCommon/SelectOption/SelectOption.tsx index 7e1968f9e..2968d6b33 100644 --- a/src/components/common/SelectCommon/SelectOption/SelectOption.tsx +++ b/src/components/common/SelectCommon/SelectOption/SelectOption.tsx @@ -2,16 +2,16 @@ import s from './SelectOption.module.scss' import classNames from 'classnames' interface Props{ - onClick: (name: string, value: string) => void, + onChange: (value: string) => void, itemName: string, size: 'base' | 'large', value: string, selected?: boolean, } -const SelectOption = ({onClick, itemName, size, value, selected} : Props) => { - const changeName = () => { - onClick(itemName, value) +const SelectOption = ({onChange, itemName, size, value, selected} : Props) => { + const handleChange = () => { + onChange(value) } return(
    { [s[size]] : !!size, [s.isChoose] : selected , })} - onClick = {changeName} + onClick = {handleChange} >{itemName}
    ) } diff --git a/src/components/modules/account/AccountPage/components/EditInfoModal/EditInfoModal.tsx b/src/components/modules/account/AccountPage/components/EditInfoModal/EditInfoModal.tsx index 06e6b2124..8289a3a93 100644 --- a/src/components/modules/account/AccountPage/components/EditInfoModal/EditInfoModal.tsx +++ b/src/components/modules/account/AccountPage/components/EditInfoModal/EditInfoModal.tsx @@ -43,7 +43,7 @@ const EditInfoModal = ({ accountInfo, visible = false, closeModal }: EditInfoMod
    - +
    diff --git a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx index 233e9d057..04217d706 100644 --- a/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx +++ b/src/components/modules/checkout/CheckoutInfo/components/ShippingInfoForm/ShippingInfoForm.tsx @@ -46,7 +46,7 @@ const ShippingInfoForm = ({onConfirm,id}: ShippingInfoFormProps) => { />
    - State + State
    { +const ProductListFilter = ({ facets, collections, products }: ProductListFilterProps) => { + return (
    -
    - - { - facets.map(item => ) - } -
    - +
    SPECIAL RECIPES
    -
    -
    - -
    -
    +
    diff --git a/src/components/modules/product-list/ProductListFilter/ProductSort/ProductSort.tsx b/src/components/modules/product-list/ProductListFilter/ProductSort/ProductSort.tsx new file mode 100644 index 000000000..a10cec443 --- /dev/null +++ b/src/components/modules/product-list/ProductListFilter/ProductSort/ProductSort.tsx @@ -0,0 +1,40 @@ +import { useRouter } from 'next/router'; +import React, { useEffect, useState } from 'react'; +import { SelectCommon } from 'src/components/common'; +import { OPTIONS_SORT_PRODUCT, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'; + +const ProductSort = () => { + const router = useRouter() + const [sortValue, setSortValue] = useState(); + + useEffect(() => { + const rs = router.query[QUERY_KEY.SORTBY] as string + if (rs) { + setSortValue(rs) + } + }, [router.query]) + + const onSortChange = (value: string) => { + setSortValue(value) + router.push({ + pathname: ROUTE.PRODUCTS, + query: { + ...router.query, + [QUERY_KEY.SORTBY]: value + } + }, + undefined, { shallow: true } + ) + } + + return ( + + ); +}; + +export default ProductSort; \ No newline at end of file diff --git a/src/components/modules/product-list/ProductListFilter/ProductsMenuNavigationTablet/ProductsMenuNavigationTablet.module.scss b/src/components/modules/product-list/ProductListFilter/ProductsMenuNavigationTablet/ProductsMenuNavigationTablet.module.scss new file mode 100644 index 000000000..a27b395c3 --- /dev/null +++ b/src/components/modules/product-list/ProductListFilter/ProductsMenuNavigationTablet/ProductsMenuNavigationTablet.module.scss @@ -0,0 +1,12 @@ + +.productsMenuNavigationTablet { + @apply hidden; + @screen md { + @apply block; + padding-right: 2.4rem; + } + @screen xl { + @apply block; + width: 25%; + } +} diff --git a/src/components/modules/product-list/ProductListFilter/ProductsMenuNavigationTablet/ProductsMenuNavigationTablet.tsx b/src/components/modules/product-list/ProductListFilter/ProductsMenuNavigationTablet/ProductsMenuNavigationTablet.tsx new file mode 100644 index 000000000..47127d53e --- /dev/null +++ b/src/components/modules/product-list/ProductListFilter/ProductsMenuNavigationTablet/ProductsMenuNavigationTablet.tsx @@ -0,0 +1,28 @@ +import { Collection, Facet } from '@framework/schema' +import React from 'react' +import MenuNavigation from 'src/components/common/MenuNavigation/MenuNavigation' +import { QUERY_KEY } from 'src/utils/constanst.utils' +import s from './ProductsMenuNavigationTablet.module.scss' + +interface Props { + facets: Facet[] + collections: Collection[] + +} + +const ProductsMenuNavigationTablet = ({ facets, collections }: Props) => { + return ( +
    + + { + facets.map(item => ) + } +
    + ) +} + +export default ProductsMenuNavigationTablet diff --git a/src/components/modules/recipes-list/RecipesList/RecipesList.tsx b/src/components/modules/recipes-list/RecipesList/RecipesList.tsx index f636157fa..e91599a2c 100644 --- a/src/components/modules/recipes-list/RecipesList/RecipesList.tsx +++ b/src/components/modules/recipes-list/RecipesList/RecipesList.tsx @@ -189,13 +189,13 @@ const RecipesList = ({ data =recipe}:Props) => {
    - +
    - +
    diff --git a/src/styles/_base.scss b/src/styles/_base.scss index 1eab49e38..e41b6763f 100644 --- a/src/styles/_base.scss +++ b/src/styles/_base.scss @@ -4,7 +4,7 @@ :root { --primary: #5b9a74; --primary-light: #e3f2e9; - --primary-lightest: #effaf4; + --primary-lightest: #F1F8F4; --info-dark: #00317a; --info: #3468B7; diff --git a/src/utils/constanst.utils.ts b/src/utils/constanst.utils.ts index 432e9cc78..630054959 100644 --- a/src/utils/constanst.utils.ts +++ b/src/utils/constanst.utils.ts @@ -45,15 +45,24 @@ export const LOCAL_STORAGE_KEY = { TOKEN: 'token' } +export const QUERY_SPLIT_SEPERATOR = ',' export const QUERY_KEY = { TAB: 'tab', CATEGORY: 'category', BRAND: 'brand', - FEATURED: 'feature', + FEATURED: 'featured', SORTBY: 'sortby', RECIPES: 'recipes' } +export const PRODUCT_SORT_OPTION_VALUE = { + NAME_ASC: 'name_asc', + NAME_DESC: 'name_desc', + PRICE_ASC: 'price_asc', + PRICE_DESC: 'price_desc', + +} + export enum ProductFeature { BestSellers = 'Best Sellers', Sales = 'Sales', @@ -118,6 +127,26 @@ export const CODE_FACET_FEATURED_VARIANT = { FRESH: 'fresh', } +export const OPTIONS_SORT_PRODUCT = [ + { + name: 'By Name (A-Z)', + value: PRODUCT_SORT_OPTION_VALUE.NAME_ASC, + }, + { + name: 'By Name (Z-A)', + value: PRODUCT_SORT_OPTION_VALUE.NAME_DESC, + }, + { + name: 'Price (Low to High)', + value: PRODUCT_SORT_OPTION_VALUE.PRICE_ASC, + }, + { + name: 'Price (High to Low)', + value: PRODUCT_SORT_OPTION_VALUE.PRICE_DESC, + }, +]; + + export const FEATURED = [ { name: 'Best Sellers',