feat: initial active value for option filter products

:%s
This commit is contained in:
lytrankieio123
2021-10-06 15:01:23 +07:00
parent ef7b490416
commit c49ba5062a
31 changed files with 400 additions and 241 deletions

View File

@@ -24,7 +24,7 @@ export const getCollectionsNameQuery = /* GraphQL */ `
collections{
items{
name
link:slug
slug
}
}
}

View File

@@ -17,7 +17,7 @@
}
}
.filter {
@screen xl {
@screen md {
display: none;
}
}

View File

@@ -15,7 +15,7 @@ interface Props {
const LayoutContent: FC<Props> = ({ 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<Props> = ({ children }) => {
return (
<>
<div className={s.mainLayout}>
{router.pathname}
<Header toggleFilter={toggleFilter} visibleFilter={visibleFilter} />
{
router.pathname === ROUTE.ACCOUNT ?

View File

@@ -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);
}
}
}
}
}

View File

@@ -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 => <MenuFilterItem
key={item.slug || item.code}
name={item.name}
type={type}
value={item.slug || item.code || ''}
onClick={handleClick}
onChange={handleChange}
/>)
}
</ul>

View File

@@ -1,4 +1,3 @@
.menuFilterItem {
margin: 1rem 0;
padding: 0;

View File

@@ -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<boolean>()
useEffect(() => {
const rs = (router.query[type] || []).includes(value)
setIsSelected(rs)
}, [type, router.query, value])
function handleClick() {
// todo
onChange(value, !isSelected)
setIsSelected(!isSelected)
}

View File

@@ -3,7 +3,6 @@
@apply hidden;
@screen md {
@apply block;
}
.menuNavigationHeading{
@screen md {
@apply sub-headline font-bold ;
@@ -12,22 +11,5 @@
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;
}
}
}
}
}
}

View File

@@ -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 (
<section className={s.menuNavigationWrapper}>
<h2 className={s.menuNavigationHeading}>{heading}({categories.length})</h2>
<ul className={s.menuNavigationList}>
{
categories.map(item => <li key={item.name}
>
<Link href={`${linkPrefix}${item.slug || item.code}`}>
<a className={classNames({ [s.active]: router.asPath === `${linkPrefix}${item.slug || item.code}`})}>
{item.name}
</a>
</Link>
</li>)
categories.map(item => <MenuNavigationItem
key={item.name}
name={item.name}
value={item.slug || item.code || ''}
queryKey={queryKey}
/>)
}
</ul>
</section>

View File

@@ -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;
}
}
}

View File

@@ -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<boolean>()
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 (<li className={classNames(s.menuNavigationItem, { [s.active]: isActive })}
onClick={handleClick}>
{name}
</li>)
}
export default MenuNavigationItem

View File

@@ -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<string[]>([])
const [featuredQuery, setFeaturedQuery] = useState<string[]>([])
const [categoryQuery, setCategoryQuery] = useState<string[]>([])
const [sortValue, setSortValue] = useState<string>();
const [dataSort, setDataSort] = useState({});
function handleValue(value: Object) {
setDataSort({ ...dataSort, ...value });
useEffect(() => {
const rs = router.query[QUERY_KEY.SORTBY] as string
if (rs) {
setSortValue(rs)
}
function filter() {
// console.log(dataSort)
}, [router.query])
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()
}
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) => {
<div onClick={onClose}><IconHide /></div>
</div>
{collectionLoading && <SkeletonParagraph rows={5} />}
<MenuFilter categories={collections} heading="Categories" type={QUERY_KEY.CATEGORY} onChangeValue={handleValue} />
<MenuFilter categories={collections} heading="Categories" type={QUERY_KEY.CATEGORY} onChange={onFilterOptionChange} />
{facetsLoading && <>
<SkeletonParagraph rows={5} />
<SkeletonParagraph rows={5} />
@@ -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}
/>)
}
<MenuSort heading="SORT BY" type="sort" onChangeValue={handleValue} />
<MenuSort heading="SORT BY" onChange={onSortChange} value={sortValue} options={OPTIONS_SORT_PRODUCT}/>
<div className={s.foot}>
<ButtonCommon size="large" onClick={filter}>{LANGUAGE.BUTTON_LABEL.CONFIRM}</ButtonCommon>
<ButtonCommon size="large" onClick={onSubmit}>{LANGUAGE.BUTTON_LABEL.CONFIRM}</ButtonCommon>
</div>
</div>
</div>

View File

@@ -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;
}
}
}
}
}
}

View File

@@ -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<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])
const MenuSort = ({ heading, value, onChange, options }: Props) => {
return (
<section className={classNames(s.menuSortWrapper)}>
<h2 className={classNames(s.menuSortHeading)}>{heading}</h2>
<ul className={s.menuSortList}>
{
SORT.map(item => <li key={item.name}>
<div onClick={()=> handleClick(item.link)} className={classNames({ [s.active]: item.link === active? true: false })}>
{item.name}
</div>
</li>)
options.map(item => <MenuSortItem
key={item.value}
name={item.name}
value={item.value}
currentValue={value}
onChange={onChange}
/>)
}
</ul>
</section>

View File

@@ -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;
}
}
}
}

View File

@@ -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 (
<li className={s.menuSortItem}>
<div onClick={handleChange} className={classNames({ [s.active]: value === currentValue })}>
{name}
</div>
</li>
)
}
export default MenuSortItem

View File

@@ -0,0 +1,3 @@
<svg width="16" height="12" viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.7104 1.20986C14.6175 1.11613 14.5069 1.04174 14.385 0.990969C14.2632 0.940201 14.1324 0.914062 14.0004 0.914062C13.8684 0.914062 13.7377 0.940201 13.6159 0.990969C13.494 1.04174 13.3834 1.11613 13.2904 1.20986L5.84044 8.66986L2.71044 5.52986C2.61392 5.43662 2.49998 5.36331 2.37512 5.3141C2.25026 5.2649 2.11694 5.24077 1.98276 5.24309C1.84858 5.24541 1.71617 5.27414 1.59309 5.32763C1.47001 5.38113 1.35868 5.45834 1.26544 5.55486C1.1722 5.65138 1.09889 5.76532 1.04968 5.89018C1.00048 6.01503 0.976347 6.14836 0.978669 6.28254C0.98099 6.41672 1.00972 6.54913 1.06321 6.67221C1.1167 6.79529 1.19392 6.90662 1.29044 6.99986L5.13044 10.8399C5.2234 10.9336 5.334 11.008 5.45586 11.0588C5.57772 11.1095 5.70843 11.1357 5.84044 11.1357C5.97245 11.1357 6.10316 11.1095 6.22502 11.0588C6.34687 11.008 6.45748 10.9336 6.55044 10.8399L14.7104 2.67986C14.8119 2.58622 14.893 2.47257 14.9484 2.34607C15.0038 2.21957 15.0324 2.08296 15.0324 1.94486C15.0324 1.80676 15.0038 1.67015 14.9484 1.54365C14.893 1.41715 14.8119 1.3035 14.7104 1.20986Z" fill="#5b9a74" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -25,7 +25,7 @@ const ModalCreateUserInfo = ({ demoVisible: visible, demoCloseModal: closeModal
<Inputcommon placeholder='Street Address' ref={firstInputRef} />
<Inputcommon placeholder='City' />
<div className={s.line}>
<SelectCommon option={STATE_OPTIONS} type="custom" size="large" placeholder='State'/>
<SelectCommon options={STATE_OPTIONS} type="custom" size="large" placeholder='State'/>
<Inputcommon placeholder='Zip code' />
</div>
<Inputcommon placeholder='Phone (delivery contact)' />

View File

@@ -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 ;
}
}

View File

@@ -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<string>()
const [selectedValue, setSelectedValue] = useState<string>('')
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}<IconVectorDown /></div>
>{selectedName || placeholder}<IconVectorDown /></div>
<div className={s.hoverWrapper}>
<div className={classNames({
@@ -43,8 +52,12 @@ const SelectCommon = ({ type = 'default', size = 'base', option, placeholder, on
})}
>
{
option.map(item =>
<SelectOption key={item.value} itemName={item.name} value={item.value} onClick={changeSelectedName} size={size} selected={(selectedValue === item.value)} />
options.map(item =>
<SelectOption key={item.value}
itemName={item.name}
value={item.value}
onChange={changeSelectedName}
size={size} selected={(selectedValue === item.value)} />
)
}
</div>

View File

@@ -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(
<div className={classNames({
@@ -19,7 +19,7 @@ const SelectOption = ({onClick, itemName, size, value, selected} : Props) => {
[s[size]] : !!size,
[s.isChoose] : selected ,
})}
onClick = {changeName}
onClick = {handleChange}
>{itemName}</div>
)
}

View File

@@ -43,7 +43,7 @@ const EditInfoModal = ({ accountInfo, visible = false, closeModal }: EditInfoMod
<div className="flex">
<div className={s.inputState}>
<SelectCommon type="custom" placeholder="State" option={states} />
<SelectCommon type="custom" placeholder="State" options={states} />
</div>
<div className={s.inputPostalCode}>

View File

@@ -46,7 +46,7 @@ const ShippingInfoForm = ({onConfirm,id}: ShippingInfoFormProps) => {
/>
<Inputcommon type="text" placeholder="City" ref={cityRef} />
<div className={s.line}>
<SelectCommon option={option} type="custom" size="large">State</SelectCommon>
<SelectCommon options={option} type="custom" size="large">State</SelectCommon>
<Inputcommon type="text" placeholder="Zip Code" ref={codeRef} />
</div>
<Inputcommon

View File

@@ -13,17 +13,6 @@
@screen md {
@apply flex;
}
.categories{
padding-right: 2.4rem;
@apply hidden;
@screen md {
@apply block;
}
@screen xl{
@apply block;
width:25%;
}
}
.list{
@screen md {
@apply flex justify-between flex-wrap w-full;
@@ -56,29 +45,22 @@
.boxSelect{
@apply w-auto;
// padding: 2.5rem 0;
display: none;
@screen xl {
@screen md {
@apply block;
width: auto;
padding:0;
margin-top: 1rem;
}
.categorySelectCate{
@screen xl {
@apply hidden;
}
}
label{
label {
@apply font-bold topline ;
color:var(--text-active);
@screen xl {
@apply hidden;
}
}
.select{
margin-top: 1rem;
}
}
}

View File

@@ -1,12 +1,11 @@
import { ProductCard } from '@commerce/types/product'
import { Collection, Facet } from '@framework/schema'
import React from 'react'
import { HeadingCommon, ProductList, SelectCommon } from 'src/components/common'
import { HeadingCommon, ProductList } from 'src/components/common'
import BreadcrumbCommon from 'src/components/common/BreadcrumbCommon/BreadcrumbCommon'
import MenuNavigation from 'src/components/common/MenuNavigation/MenuNavigation'
import { QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
import { PRODUCT_DATA_TEST_PAGE } from 'src/utils/demo-data'
import s from './ProductListFilter.module.scss'
import ProductsMenuNavigationTablet from './ProductsMenuNavigationTablet/ProductsMenuNavigationTablet'
import ProductSort from './ProductSort/ProductSort'
interface ProductListFilterProps {
facets: Facet[]
@@ -21,48 +20,21 @@ const BREADCRUMB = [
link: `#`,
},
]
const OPTIONSLECT = [
{
name: 'Most Viewed',
value: 'most-viewed',
},
{
name: 'Lastest Products',
value: 'lastest-products',
},
{
name: 'Recent Products',
value: 'recent-products',
},
]
const ProductListFilter = ({facets, collections, products}: ProductListFilterProps) => {
const ProductListFilter = ({ facets, collections, products }: ProductListFilterProps) => {
return (
<div className={s.warpper}>
<div className={s.breadcrumb}>
<BreadcrumbCommon crumbs={BREADCRUMB} />
</div>
<div className={s.main}>
<div className={s.categories}>
<MenuNavigation categories={collections} heading="Categories" linkPrefix={`${ROUTE.PRODUCTS}?${QUERY_KEY.CATEGORY}=`}/>
{
facets.map(item => <MenuNavigation
key={item.id}
linkPrefix={`${ROUTE.PRODUCTS}/${item.code}=`}
categories={item.values}
heading={item.name} />)
}
</div>
<ProductsMenuNavigationTablet facets={facets} collections={collections} />
<div className={s.list}>
<HeadingCommon align="left">SPECIAL RECIPES</HeadingCommon>
<div className={s.boxSelect}>
<div className={s.categorySelectSort}>
<div className={s.select}>
<SelectCommon option={OPTIONSLECT} placeholder="Sort By" />
</div>
</div>
<ProductSort/>
</div>
<ProductList data={products} />
</div>

View File

@@ -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<string>();
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 (
<SelectCommon
options={OPTIONS_SORT_PRODUCT}
placeholder="Sort By"
value={sortValue}
onChange={onSortChange}
/>
);
};
export default ProductSort;

View File

@@ -0,0 +1,12 @@
.productsMenuNavigationTablet {
@apply hidden;
@screen md {
@apply block;
padding-right: 2.4rem;
}
@screen xl {
@apply block;
width: 25%;
}
}

View File

@@ -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 (
<div className={s.productsMenuNavigationTablet}>
<MenuNavigation categories={collections} heading="Categories" queryKey={QUERY_KEY.CATEGORY} />
{
facets.map(item => <MenuNavigation
key={item.id}
queryKey={item.code}
categories={item.values}
heading={item.name} />)
}
</div>
)
}
export default ProductsMenuNavigationTablet

View File

@@ -189,13 +189,13 @@ const RecipesList = ({ data =recipe}:Props) => {
<div className={s.categorySelectCate}>
<label htmlFor="">Categories</label>
<div className={s.select}>
<SelectCommon option={CATEGORYSELECT} placeholder="Categories"/>
<SelectCommon options={CATEGORYSELECT} placeholder="Categories"/>
</div>
</div>
<div className={s.categorySelectSort}>
<label htmlFor="" >Sort By</label>
<div className={s.select}>
<SelectCommon option={OPTIONSLECT} placeholder="Sort By" />
<SelectCommon options={OPTIONSLECT} placeholder="Sort By" />
</div>
</div>
</div>

View File

@@ -4,7 +4,7 @@
:root {
--primary: #5b9a74;
--primary-light: #e3f2e9;
--primary-lightest: #effaf4;
--primary-lightest: #F1F8F4;
--info-dark: #00317a;
--info: #3468B7;

View File

@@ -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',