feat: (product list) all products, brands, collection, featured

:%s
This commit is contained in:
lytrankieio123
2021-10-05 18:10:22 +07:00
parent 03b1fe5aa5
commit c154541948
7 changed files with 128 additions and 35 deletions

View File

@@ -1,10 +1,10 @@
import { OperationContext } from '@commerce/api/operations'
import { Facet } from '@commerce/types/facet'
import { Provider, VendureConfig } from '../'
import { GetAllFacetsQuery } from '../../schema'
import { FacetFilterParameter, FacetSortParameter, GetAllFacetsQuery } from '../../schema'
import { getAllFacetsQuery } from '../../utils/queries/get-all-facets-query'
export type FacetVariables = { first?: number }
export type FacetVariables = { first?: number, filter?: FacetFilterParameter, sort?: FacetSortParameter }
export default function getAllFacetsOperation({
commerce,
@@ -27,9 +27,10 @@ export default function getAllFacetsOperation({
} = {}): Promise<{ facets: Facet[] | any[] }> {
const config = commerce.getConfig(cfg)
const variables = {
input: {
options: {
take: vars.first,
groupByFacet: true,
filter: vars.filter,
sort: vars.sort,
},
}
const { data } = await config.fetch<GetAllFacetsQuery>(query, {

View File

@@ -1,19 +1,94 @@
import { ProductCard } from '@commerce/types/product';
import { Collection, Facet } from '@framework/schema';
import commerce from '@lib/api/commerce';
import { GetStaticPropsContext } from 'next';
import { Layout } from 'src/components/common';
import { ViewedProducts } from 'src/components/modules/product-detail';
import ProductListFilter from 'src/components/modules/product-list/ProductListFilter/ProductListFilter';
import RecipeListBanner from 'src/components/modules/recipes-list/RecipeListBanner/RecipeListBanner';
import RecipesList from 'src/components/modules/recipes-list/RecipesList/RecipesList';
import { CODE_FACET_BRAND, CODE_FACET_FEATURED, DEFAULT_PAGE_SIZE } from 'src/utils/constanst.utils';
import { getAllPromies } from 'src/utils/funtion.utils';
import { PromiseWithKey, SortOrder } from 'src/utils/types.utils';
import ProductListBanner from '../src/components/modules/product-list/ProductListBanner/ProductListBanner';
interface Props {
facets: Facet[],
collections: Collection[],
products: ProductCard[],
export default function Products() {
}
export default function Products({ facets, collections, products }: Props) {
// console.log("facets: ", products)
return (
<>
<ProductListBanner />
<ProductListFilter/>
<ProductListFilter collections={collections} facets={facets} products={products} />
<ViewedProducts />
</>
)
}
export async function getStaticProps({
preview,
locale,
locales,
}: GetStaticPropsContext) {
const config = { locale, locales }
let promisesWithKey = [] as PromiseWithKey[]
let props = {} as any
const facetsPromise = commerce.getAllFacets({
variables: {
sort: {
code: SortOrder.Asc
},
filter: {
code: {
in: [CODE_FACET_FEATURED, CODE_FACET_BRAND]
}
}
},
config,
preview,
})
promisesWithKey.push({ key: 'facets', promise: facetsPromise, keyResult: 'facets' })
// collection
const collectionsPromise = commerce.getAllCollections({
variables: {},
config,
preview,
})
promisesWithKey.push({ key: 'collections', promise: collectionsPromise, keyResult: 'collections' })
// products
const productsPromise = commerce.getAllProducts({
variables: {
first: DEFAULT_PAGE_SIZE,
},
config,
preview,
})
promisesWithKey.push({ key: 'products', promise: productsPromise, keyResult: 'products' })
try {
const promises = getAllPromies(promisesWithKey)
const rs = await Promise.all(promises)
promisesWithKey.map((item, index) => {
props[item.key] = item.keyResult ? rs[index][item.keyResult] : rs[index]
return null
})
return {
props,
revalidate: 60,
}
} catch (err) {
}
}
Products.Layout = Layout

View File

@@ -1,15 +1,17 @@
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'
interface Props {
children?: any,
heading: string,
categories:{name:string,link:string}[]
linkPrefix: string,
categories: { name: string, slug?: string, code?: string }[]
}
const MenuNavigation = ({heading,categories}:Props)=> {
const MenuNavigation = ({ heading, linkPrefix, categories }: Props) => {
const router = useRouter()
return (
@@ -19,8 +21,8 @@ const MenuNavigation = ({heading,categories}:Props)=> {
{
categories.map(item => <li key={item.name}
>
<Link href={item.link}>
<a className={classNames({ [s.active]: router.asPath === item.link})}>
<Link href={`${linkPrefix}${item.slug || item.code}`}>
<a className={classNames({ [s.active]: router.asPath === `${linkPrefix}${item.slug || item.code}`})}>
{item.name}
</a>
</Link>

View File

@@ -1,4 +1,5 @@
import React, { useState } from 'react'
import { DEFAULT_PAGE_SIZE } from 'src/utils/constanst.utils'
import PaginationCommon from '../PaginationCommon/PaginationCommon'
import ProductCard, { ProductCardProps } from '../ProductCard/ProductCard'
import s from "./ProductList.module.scss"
@@ -15,13 +16,13 @@ const ProductList = ({data}: ProductListProps) => {
<div className={s.wrapper}>
<div className={s.list}>
{
data.slice(currentPage*20,(currentPage+1)*20).map((product,index)=>{
data.slice(currentPage*DEFAULT_PAGE_SIZE,(currentPage+1)* DEFAULT_PAGE_SIZE).map((product,index)=>{
return <ProductCard {...product} key={index}/>
})
}
</div>
<div className={s.pagination}>
<PaginationCommon total={data.length} pageSize={20} onChange={onPageChange}/>
<PaginationCommon total={data.length} pageSize={DEFAULT_PAGE_SIZE} onChange={onPageChange}/>
</div>
</div>
)

View File

@@ -1,12 +1,19 @@
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 BreadcrumbCommon from 'src/components/common/BreadcrumbCommon/BreadcrumbCommon'
import MenuNavigation from 'src/components/common/MenuNavigation/MenuNavigation'
import { BRAND, CATEGORY, FEATURED} from 'src/utils/constanst.utils'
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'
interface ProductListFilterProps {}
interface ProductListFilterProps {
facets: Facet[]
collections: Collection[]
products: ProductCard[]
}
const BREADCRUMB = [
{
@@ -29,11 +36,7 @@ const OPTIONSLECT = [
},
]
const onModalClose = () => {
}
const ProductListFilter = (props: ProductListFilterProps) => {
const ProductListFilter = ({facets, collections, products}: ProductListFilterProps) => {
return (
<div className={s.warpper}>
<div className={s.breadcrumb}>
@@ -41,9 +44,14 @@ const ProductListFilter = (props: ProductListFilterProps) => {
</div>
<div className={s.main}>
<div className={s.categories}>
<MenuNavigation categories={CATEGORY} heading="Categories" />
<MenuNavigation categories={BRAND} heading="Brands" />
<MenuNavigation categories={FEATURED} heading="featured" />
<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>
<div className={s.list}>
@@ -56,7 +64,7 @@ const ProductListFilter = (props: ProductListFilterProps) => {
</div>
</div>
</div>
<ProductList data={PRODUCT_DATA_TEST_PAGE} />
<ProductList data={products} />
</div>
</div>
</div>

View File

@@ -113,6 +113,7 @@ export const BRAND = [
export const CODE_FACET_FEATURED = 'featured'
export const CODE_FACET_DISCOUNT = 'discount'
export const CODE_FACET_BRAND = 'brand'
export const CODE_FACET_FEATURED_VARIANT = {
FRESH: 'fresh',
}

View File

@@ -46,6 +46,11 @@ export interface CheckOutForm {
export type MouseAndTouchEvent = MouseEvent | TouchEvent
export enum SortOrder {
Asc = 'ASC',
Desc = 'DESC',
}
export type filterContextType = {
visible: boolean;
open: () => void;