mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
✨ feat: (product list) all products, brands, collection, featured
:%s
This commit is contained in:
@@ -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, {
|
||||
|
@@ -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/>
|
||||
<ViewedProducts/>
|
||||
<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
|
||||
|
@@ -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}[]
|
||||
heading: 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>
|
||||
|
@@ -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>
|
||||
)
|
||||
|
@@ -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 { PRODUCT_DATA_TEST_PAGE } from 'src/utils/demo-data'
|
||||
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>
|
||||
|
@@ -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',
|
||||
}
|
||||
|
@@ -34,18 +34,23 @@ export interface BlogProps {
|
||||
|
||||
export interface CheckOutForm {
|
||||
name?: string
|
||||
email?:string
|
||||
email?: string
|
||||
address?: string
|
||||
city?:string
|
||||
state?:string
|
||||
code?:number
|
||||
phone?:number
|
||||
method?:string
|
||||
shipping_fee?:number
|
||||
city?: string
|
||||
state?: string
|
||||
code?: number
|
||||
phone?: number
|
||||
method?: string
|
||||
shipping_fee?: number
|
||||
}
|
||||
|
||||
export type MouseAndTouchEvent = MouseEvent | TouchEvent
|
||||
|
||||
export enum SortOrder {
|
||||
Asc = 'ASC',
|
||||
Desc = 'DESC',
|
||||
}
|
||||
|
||||
export type filterContextType = {
|
||||
visible: boolean;
|
||||
open: () => void;
|
||||
|
Reference in New Issue
Block a user