feat: search bar

:%s
This commit is contained in:
DatNguyen
2021-10-21 14:33:44 +07:00
parent 300755a579
commit bd780099a9
10 changed files with 104 additions and 150 deletions

View File

@@ -7,10 +7,10 @@ import { Layout } from 'src/components/common';
import { FeaturedProductsCarousel, FreshProducts, HomeBanner, HomeCategories, HomeCollection, HomeCTA, HomeFeature, HomeRecipe, HomeSubscribe, HomeVideo } from 'src/components/modules/home'; import { FeaturedProductsCarousel, FreshProducts, HomeBanner, HomeCategories, HomeCollection, HomeCTA, HomeFeature, HomeRecipe, HomeSubscribe, HomeVideo } from 'src/components/modules/home';
import HomeSpice from 'src/components/modules/home/HomeSpice/HomeSpice'; import HomeSpice from 'src/components/modules/home/HomeSpice/HomeSpice';
import { FACET } from 'src/utils/constanst.utils'; import { FACET } from 'src/utils/constanst.utils';
import { FilterOneVatiant, getFacetIdByName } from 'src/utils/funtion.utils'; import { FilterOneVatiant, getFacetIdByCode, getFacetIdByName } from 'src/utils/funtion.utils';
import { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED,COLLECTION_SLUG_SPICE } from 'src/utils/constanst.utils'; import { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED,COLLECTION_SLUG_SPICE } from 'src/utils/constanst.utils';
import { getAllFacetValueIdsByParentCode, getAllFacetValuesForFeatuedProducts, getAllPromies, getFreshFacetId } from 'src/utils/funtion.utils'; import { getAllFacetValueIdsByParentCode, getAllFacetValuesForFeatuedProducts, getAllPromies, getFreshFacetId } from 'src/utils/funtion.utils';
import { PromiseWithKey } from 'src/utils/types.utils'; import { CollectionsWithData, PromiseWithKey } from 'src/utils/types.utils';
interface Props { interface Props {
featuredAndDiscountFacetsValue: FacetValue[], featuredAndDiscountFacetsValue: FacetValue[],
@@ -19,18 +19,17 @@ interface Props {
collections: Collection[] collections: Collection[]
spiceProducts:ProductCard[] spiceProducts:ProductCard[]
veggie: ProductCard[], veggie: ProductCard[],
collectionProps:CollectionsWithData[]
} }
export default function Home({ featuredAndDiscountFacetsValue, veggie, export default function Home({ featuredAndDiscountFacetsValue, veggie,collectionProps,
freshProducts, featuredProducts, freshProducts, featuredProducts,
collections,spiceProducts }: Props) { collections,spiceProducts }: Props) {
return ( return (
<> <>
<HomeBanner /> <HomeBanner />
<HomeFeature /> <HomeFeature />
<HomeCategories /> <HomeCategories />
<HomeCollection data = {veggie}/> <HomeCollection data = {collectionProps}/>
<FreshProducts data={freshProducts} collections={collections} /> <FreshProducts data={freshProducts} collections={collections} />
<HomeVideo /> <HomeVideo />
{spiceProducts.length>0 && <HomeSpice data={spiceProducts}/>} {spiceProducts.length>0 && <HomeSpice data={spiceProducts}/>}
@@ -60,10 +59,26 @@ export async function getStaticProps({
config, config,
preview, preview,
}) })
props.featuredAndDiscountFacetsValue = getAllFacetValuesForFeatuedProducts(facets) props.featuredAndDiscountFacetsValue = getAllFacetValuesForFeatuedProducts(facets)
// collection
const { collections } = await commerce.getAllCollections({
variables: {},
config,
preview,
})
props.collections= collections
let collectionsPromisesWithKey = [] as PromiseWithKey[]
collections.map((collection)=>{
const promise = commerce.getAllProducts({
variables: {collectionSlug:collection.slug},
config,
preview,
})
collectionsPromisesWithKey.push({ key: `${collection.slug}`, promise: promise, keyResult: 'products' })
})
// fresh products // fresh products
const freshProductvariables: ProductVariables = {} const freshProductvariables: ProductVariables = {}
const freshFacetId = getFreshFacetId(facets) const freshFacetId = getFreshFacetId(facets)
@@ -83,7 +98,7 @@ export async function getStaticProps({
const veggieProductvariables: ProductVariables = { const veggieProductvariables: ProductVariables = {
groupByProduct:false groupByProduct:false
} }
const veggieId = getFacetIdByName(facets,FACET.CATEGORY.PARENT_NAME,FACET.CATEGORY.VEGGIE) const veggieId = getFacetIdByCode(facets,FACET.CATEGORY.PARENT_CODE,FACET.CATEGORY.VEGGIE)
if (veggieId) { if (veggieId) {
veggieProductvariables.facetValueIds = [veggieId] veggieProductvariables.facetValueIds = [veggieId]
} }
@@ -111,13 +126,7 @@ export async function getStaticProps({
props.featuredProducts = [] props.featuredProducts = []
} }
// collection
const collectionsPromise = commerce.getAllCollections({
variables: {},
config,
preview,
})
promisesWithKey.push({ key: 'collections', promise: collectionsPromise, keyResult: 'collections' })
// spiceProducts // spiceProducts
const spiceProducts = commerce.getAllProducts({ const spiceProducts = commerce.getAllProducts({
@@ -130,6 +139,17 @@ export async function getStaticProps({
promisesWithKey.push({ key: 'spiceProducts', promise: spiceProducts, keyResult: 'products' }) promisesWithKey.push({ key: 'spiceProducts', promise: spiceProducts, keyResult: 'products' })
try { try {
const collectionPromises = getAllPromies(collectionsPromisesWithKey)
const collectionResult = await Promise.all(collectionPromises)
let collectionProps:CollectionsWithData[] = []
collectionsPromisesWithKey.map((item, index) => {
collectionProps.push({
...collections[index],
items:item.keyResult ? FilterOneVatiant(collectionResult[index][item.keyResult]) : collectionResult[index]
})
return null
})
props.collectionProps=collectionProps
const promises = getAllPromies(promisesWithKey) const promises = getAllPromies(promisesWithKey)
const rs = await Promise.all(promises) const rs = await Promise.all(promises)

View File

@@ -26,7 +26,7 @@ export default function Products({ facets, collections, productsResult }: Props)
facets={facets} facets={facets}
products={productsResult.products} products={productsResult.products}
total={productsResult.totalItems} /> total={productsResult.totalItems} />
<ViewedProducts /> <ViewedProducts data={[]}/>
</> </>
) )
} }

View File

@@ -20,6 +20,7 @@ const Header = memo(({ }: props) => {
const [isModeAuthenRegister, setIsModeAuthenRegister] = useState<boolean>(false) const [isModeAuthenRegister, setIsModeAuthenRegister] = useState<boolean>(false)
const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: false }) const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: false })
const { visible: visibleModalInfo, closeModal: closeModalInfo, openModal: openModalInfo } = useModalCommon({ initialValue: false }) const { visible: visibleModalInfo, closeModal: closeModalInfo, openModal: openModalInfo } = useModalCommon({ initialValue: false })
const [searchValue, setSearchValue] = useState<string|number>("")
useEffect(() => { useEffect(() => {
const handleScroll = () => { const handleScroll = () => {
@@ -56,7 +57,9 @@ const Header = memo(({ }: props) => {
toggleFilter={toggleFilter} toggleFilter={toggleFilter}
openModalLogin={openModalLogin} openModalLogin={openModalLogin}
openModalRegister={openModalRegister} openModalRegister={openModalRegister}
openModalInfo={openModalInfo} /> openModalInfo={openModalInfo}
setSearchValue={setSearchValue}
searchValue={searchValue}/>
</div> </div>
<header ref={headeFullRef} className={classNames({ [s.header]: true, [s.full]: isFullHeader })}> <header ref={headeFullRef} className={classNames({ [s.header]: true, [s.full]: isFullHeader })}>
@@ -68,6 +71,8 @@ const Header = memo(({ }: props) => {
openModalLogin={openModalLogin} openModalLogin={openModalLogin}
openModalRegister = {openModalRegister} openModalRegister = {openModalRegister}
openModalInfo={openModalInfo} openModalInfo={openModalInfo}
setSearchValue={setSearchValue}
searchValue={searchValue}
/> />
<HeaderSubMenu /> <HeaderSubMenu />
</div> </div>

View File

@@ -1,7 +1,7 @@
import classNames from 'classnames' import classNames from 'classnames'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { memo, useMemo } from 'react' import { memo, useMemo, useState } from 'react'
import { ButtonCommon } from 'src/components/common' import { ButtonCommon } from 'src/components/common'
import InputSearch from 'src/components/common/InputSearch/InputSearch' import InputSearch from 'src/components/common/InputSearch/InputSearch'
import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown' import MenuDropdown from 'src/components/common/MenuDropdown/MenuDropdown'
@@ -31,6 +31,8 @@ interface Props {
openModalRegister: () => void openModalRegister: () => void
openModalInfo: () => void openModalInfo: () => void
toggleFilter: () => void toggleFilter: () => void
searchValue:string|number
setSearchValue: (value: string | number) => void
} }
const HeaderMenu = memo( const HeaderMenu = memo(
@@ -41,11 +43,13 @@ const HeaderMenu = memo(
openModalRegister, openModalRegister,
openModalInfo, openModalInfo,
toggleFilter, toggleFilter,
searchValue,
setSearchValue
}: Props) => { }: Props) => {
const router = useRouter() const router = useRouter()
const { toggleCartDrawer } = useCartDrawer() const { toggleCartDrawer } = useCartDrawer()
const { customer } = useActiveCustomer() const { customer } = useActiveCustomer()
const { logout } = useLogout() const { logout } = useLogout()
const optionMenuNotAuthen = useMemo( const optionMenuNotAuthen = useMemo(
@@ -92,6 +96,15 @@ const HeaderMenu = memo(
], ],
[logout] [logout]
) )
const onEnter = () => {
console.log("enter")
router.push(`${ROUTE.PRODUCTS}?${QUERY_KEY.SEARCH}=${searchValue}`)
}
const onChange = (value:string|number) => {
setSearchValue(value)
}
return ( return (
<section <section
@@ -121,10 +134,10 @@ const HeaderMenu = memo(
</div> </div>
<div className={s.searchWrap}> <div className={s.searchWrap}>
<div className={s.inputSearch}> <div className={s.inputSearch}>
<InputSearch /> <InputSearch onChange={onChange} onEnter={onEnter} value={searchValue}/>
</div> </div>
<div className={s.buttonSearch}> <div className={s.buttonSearch}>
<ButtonCommon>Search</ButtonCommon> <ButtonCommon onClick={onEnter}>Search</ButtonCommon>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -6,11 +6,15 @@ import { Inputcommon } from '..';
interface Props { interface Props {
onChange?: (value: string | number) => void, onChange?: (value: string | number) => void,
onEnter?: (value: string | number) => void, onEnter?: (value: string | number) => void,
value: string | number
} }
const InputSearch = ({ onChange, onEnter }: Props) => { const InputSearch = ({ onChange, onEnter, value }: Props) => {
return ( return (
<Inputcommon placeholder={LANGUAGE.PLACE_HOLDER.SEARCH} <Inputcommon placeholder={LANGUAGE.PLACE_HOLDER.SEARCH}
value={value}
styleType='custom' styleType='custom'
icon={<IconSearch />} icon={<IconSearch />}
onChange={onChange} onChange={onChange}

View File

@@ -5,134 +5,26 @@ import image5 from '../../../../../public/assets/images/image5.png'
import image6 from '../../../../../public/assets/images/image6.png' import image6 from '../../../../../public/assets/images/image6.png'
import image7 from '../../../../../public/assets/images/image7.png' import image7 from '../../../../../public/assets/images/image7.png'
import image8 from '../../../../../public/assets/images/image8.png' import image8 from '../../../../../public/assets/images/image8.png'
import { CollectionsWithData } from 'src/utils/types.utils'
interface HomeCollectionProps { interface HomeCollectionProps {
data: ProductCard[] data: CollectionsWithData[]
} }
const dataTest = [
{
name: 'Tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image5.src,
},
{
name: 'Cucumber',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image6.src,
},
{
name: 'Carrot',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image7.src,
},
{
name: 'Salad',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image8.src,
},
{
name: 'Tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image5.src,
},
{
name: 'Cucumber',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image6.src,
},
{
name: 'Tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image5.src,
},
{
name: 'Cucumber',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image6.src,
},
{
name: 'Carrot',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image7.src,
},
{
name: 'Salad',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image8.src,
},
{
name: 'Tomato',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image5.src,
},
{
name: 'Cucumber',
weight: '250g',
category: 'VEGGIE',
price: 'Rp 27.500',
imageSrc: image6.src,
},
]
const HomeCollection = ({data}: HomeCollectionProps) => { const HomeCollection = ({ data }: HomeCollectionProps) => {
return ( return (
<div className="w-full"> <div className="w-full">
<CollectionCarcousel {data.map((collection) => {
data={data} return collection.items.length > 0 ? (
itemKey="product-2" <CollectionCarcousel
title="VEGGIE" key={collection.slug}
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can." data={collection.items}
category={"veggie"} itemKey={collection.id}
/> title={collection.name}
<CollectionCarcousel subtitle={collection.description}
data={data} category={collection.slug}
itemKey="product-3" />
title="VEGGIE" ) : null
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can." })}
category={"veggie"}
/>
<CollectionCarcousel
data={data}
itemKey="product-4"
title="VEGGIE"
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
category={"veggie"}
/>
<CollectionCarcousel
data={data}
itemKey="product-5"
title="VEGGIE"
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
category={"veggie"}
/>
<CollectionCarcousel
data={data}
itemKey="product-6"
title="VEGGIE"
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
category={"veggie"}
/>
</div> </div>
) )
} }

View File

@@ -66,7 +66,11 @@ const ProductListFilter = ({ facets, collections, products, total }: ProductList
const page = getPageFromQuery(router.query[QUERY_KEY.PAGE] as string) const page = getPageFromQuery(router.query[QUERY_KEY.PAGE] as string)
query.input.skip = page * DEFAULT_PAGE_SIZE query.input.skip = page * DEFAULT_PAGE_SIZE
const searchQuery = router.query[QUERY_KEY.SEARCH] as string
if (searchQuery) {
query.input.term = searchQuery
}
const sortQuery = router.query[QUERY_KEY.SORTBY] as string const sortQuery = router.query[QUERY_KEY.SORTBY] as string
if (sortQuery) { if (sortQuery) {
query.input.sort = getProductSortParamFromQuery(sortQuery) query.input.sort = getProductSortParamFromQuery(sortQuery)

View File

@@ -57,6 +57,7 @@ export const QUERY_KEY = {
SORTBY: 'sortby', SORTBY: 'sortby',
RECIPES: 'recipes', RECIPES: 'recipes',
PAGE: 'page', PAGE: 'page',
SEARCH:"search"
} }
export const PRODUCT_SORT_OPTION_VALUE = { export const PRODUCT_SORT_OPTION_VALUE = {
@@ -131,8 +132,11 @@ export const FACET = {
BEST_SELLERS: 'Best seller' BEST_SELLERS: 'Best seller'
}, },
CATEGORY: { CATEGORY: {
PARENT_NAME:"category", PARENT_CODE:"category",
VEGGIE:"veggie" VEGGIE:"veggie",
FROZEN:"frozen",
SEAFOOD:"seafood",
COFFEE_BEAN:"coffee-bean"
} }
} }

View File

@@ -88,6 +88,13 @@ export function getFacetIdByName(facets: Facet[], facetName: string, valueName:s
} }
export function getFacetIdByCode(facets: Facet[], parentCode: string, valueCode:string) {
const featuredFacet = facets.find((item: Facet) => item.code === parentCode)
const freshFacetValue = featuredFacet?.values.find((item: FacetValue) => item.code === valueCode)
return freshFacetValue?.id
}
export function getAllFeaturedFacetId(facets: Facet[]) { export function getAllFeaturedFacetId(facets: Facet[]) {
const featuredFacet = facets.find((item: Facet) => item.name === FACET.FEATURE.PARENT_NAME) const featuredFacet = facets.find((item: Facet) => item.name === FACET.FEATURE.PARENT_NAME)
const rs = featuredFacet?.values.map((item: FacetValue) => item.id) const rs = featuredFacet?.values.map((item: FacetValue) => item.id)

View File

@@ -1,3 +1,5 @@
import { ProductCard } from './../../framework/commerce/types/product';
import { Collection } from './../../framework/commerce/types/collection';
export interface ProductProps { export interface ProductProps {
category?: string category?: string
@@ -72,4 +74,7 @@ export type PromiseWithKey = {
keyResult?: string, keyResult?: string,
} }
export type SelectedOptions = Record<string, string | null> export type SelectedOptions = Record<string, string | null>
export interface CollectionsWithData extends Collection {
items: ProductCard[]
}