mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36: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 { OperationContext } from '@commerce/api/operations'
|
||||||
import { Facet } from '@commerce/types/facet'
|
import { Facet } from '@commerce/types/facet'
|
||||||
import { Provider, VendureConfig } from '../'
|
import { Provider, VendureConfig } from '../'
|
||||||
import { GetAllFacetsQuery } from '../../schema'
|
import { FacetFilterParameter, FacetSortParameter, GetAllFacetsQuery } from '../../schema'
|
||||||
import { getAllFacetsQuery } from '../../utils/queries/get-all-facets-query'
|
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({
|
export default function getAllFacetsOperation({
|
||||||
commerce,
|
commerce,
|
||||||
@@ -27,9 +27,10 @@ export default function getAllFacetsOperation({
|
|||||||
} = {}): Promise<{ facets: Facet[] | any[] }> {
|
} = {}): Promise<{ facets: Facet[] | any[] }> {
|
||||||
const config = commerce.getConfig(cfg)
|
const config = commerce.getConfig(cfg)
|
||||||
const variables = {
|
const variables = {
|
||||||
input: {
|
options: {
|
||||||
take: vars.first,
|
take: vars.first,
|
||||||
groupByFacet: true,
|
filter: vars.filter,
|
||||||
|
sort: vars.sort,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const { data } = await config.fetch<GetAllFacetsQuery>(query, {
|
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 { Layout } from 'src/components/common';
|
||||||
import { ViewedProducts } from 'src/components/modules/product-detail';
|
import { ViewedProducts } from 'src/components/modules/product-detail';
|
||||||
import ProductListFilter from 'src/components/modules/product-list/ProductListFilter/ProductListFilter';
|
import ProductListFilter from 'src/components/modules/product-list/ProductListFilter/ProductListFilter';
|
||||||
import RecipeListBanner from 'src/components/modules/recipes-list/RecipeListBanner/RecipeListBanner';
|
import { CODE_FACET_BRAND, CODE_FACET_FEATURED, DEFAULT_PAGE_SIZE } from 'src/utils/constanst.utils';
|
||||||
import RecipesList from 'src/components/modules/recipes-list/RecipesList/RecipesList';
|
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';
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<ProductListBanner />
|
<ProductListBanner />
|
||||||
<ProductListFilter/>
|
<ProductListFilter collections={collections} facets={facets} products={products} />
|
||||||
<ViewedProducts/>
|
<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
|
Products.Layout = Layout
|
||||||
|
@@ -1,15 +1,17 @@
|
|||||||
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 { ROUTE } from 'src/utils/constanst.utils'
|
||||||
import s from './MenuNavigation.module.scss'
|
import s from './MenuNavigation.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children?: any,
|
children?: any,
|
||||||
heading:string,
|
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()
|
const router = useRouter()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -19,8 +21,8 @@ const MenuNavigation = ({heading,categories}:Props)=> {
|
|||||||
{
|
{
|
||||||
categories.map(item => <li key={item.name}
|
categories.map(item => <li key={item.name}
|
||||||
>
|
>
|
||||||
<Link href={item.link}>
|
<Link href={`${linkPrefix}${item.slug || item.code}`}>
|
||||||
<a className={classNames({ [s.active]: router.asPath === item.link})}>
|
<a className={classNames({ [s.active]: router.asPath === `${linkPrefix}${item.slug || item.code}`})}>
|
||||||
{item.name}
|
{item.name}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
|
import { DEFAULT_PAGE_SIZE } from 'src/utils/constanst.utils'
|
||||||
import PaginationCommon from '../PaginationCommon/PaginationCommon'
|
import PaginationCommon from '../PaginationCommon/PaginationCommon'
|
||||||
import ProductCard, { ProductCardProps } from '../ProductCard/ProductCard'
|
import ProductCard, { ProductCardProps } from '../ProductCard/ProductCard'
|
||||||
import s from "./ProductList.module.scss"
|
import s from "./ProductList.module.scss"
|
||||||
@@ -15,13 +16,13 @@ const ProductList = ({data}: ProductListProps) => {
|
|||||||
<div className={s.wrapper}>
|
<div className={s.wrapper}>
|
||||||
<div className={s.list}>
|
<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}/>
|
return <ProductCard {...product} key={index}/>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className={s.pagination}>
|
<div className={s.pagination}>
|
||||||
<PaginationCommon total={data.length} pageSize={20} onChange={onPageChange}/>
|
<PaginationCommon total={data.length} pageSize={DEFAULT_PAGE_SIZE} onChange={onPageChange}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@@ -1,12 +1,19 @@
|
|||||||
|
import { ProductCard } from '@commerce/types/product'
|
||||||
|
import { Collection, Facet } from '@framework/schema'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { HeadingCommon, ProductList, SelectCommon } from 'src/components/common'
|
import { HeadingCommon, ProductList, SelectCommon } from 'src/components/common'
|
||||||
import BreadcrumbCommon from 'src/components/common/BreadcrumbCommon/BreadcrumbCommon'
|
import BreadcrumbCommon from 'src/components/common/BreadcrumbCommon/BreadcrumbCommon'
|
||||||
import MenuNavigation from 'src/components/common/MenuNavigation/MenuNavigation'
|
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 { PRODUCT_DATA_TEST_PAGE } from 'src/utils/demo-data'
|
||||||
import s from './ProductListFilter.module.scss'
|
import s from './ProductListFilter.module.scss'
|
||||||
|
|
||||||
interface ProductListFilterProps {}
|
interface ProductListFilterProps {
|
||||||
|
facets: Facet[]
|
||||||
|
collections: Collection[]
|
||||||
|
products: ProductCard[]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const BREADCRUMB = [
|
const BREADCRUMB = [
|
||||||
{
|
{
|
||||||
@@ -29,11 +36,7 @@ const OPTIONSLECT = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const onModalClose = () => {
|
const ProductListFilter = ({facets, collections, products}: ProductListFilterProps) => {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const ProductListFilter = (props: ProductListFilterProps) => {
|
|
||||||
return (
|
return (
|
||||||
<div className={s.warpper}>
|
<div className={s.warpper}>
|
||||||
<div className={s.breadcrumb}>
|
<div className={s.breadcrumb}>
|
||||||
@@ -41,9 +44,14 @@ const ProductListFilter = (props: ProductListFilterProps) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className={s.main}>
|
<div className={s.main}>
|
||||||
<div className={s.categories}>
|
<div className={s.categories}>
|
||||||
<MenuNavigation categories={CATEGORY} heading="Categories" />
|
<MenuNavigation categories={collections} heading="Categories" linkPrefix={`${ROUTE.PRODUCTS}?${QUERY_KEY.CATEGORY}=`}/>
|
||||||
<MenuNavigation categories={BRAND} heading="Brands" />
|
{
|
||||||
<MenuNavigation categories={FEATURED} heading="featured" />
|
facets.map(item => <MenuNavigation
|
||||||
|
key={item.id}
|
||||||
|
linkPrefix={`${ROUTE.PRODUCTS}/${item.code}=`}
|
||||||
|
categories={item.values}
|
||||||
|
heading={item.name} />)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={s.list}>
|
<div className={s.list}>
|
||||||
@@ -56,7 +64,7 @@ const ProductListFilter = (props: ProductListFilterProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ProductList data={PRODUCT_DATA_TEST_PAGE} />
|
<ProductList data={products} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -113,6 +113,7 @@ export const BRAND = [
|
|||||||
|
|
||||||
export const CODE_FACET_FEATURED = 'featured'
|
export const CODE_FACET_FEATURED = 'featured'
|
||||||
export const CODE_FACET_DISCOUNT = 'discount'
|
export const CODE_FACET_DISCOUNT = 'discount'
|
||||||
|
export const CODE_FACET_BRAND = 'brand'
|
||||||
export const CODE_FACET_FEATURED_VARIANT = {
|
export const CODE_FACET_FEATURED_VARIANT = {
|
||||||
FRESH: 'fresh',
|
FRESH: 'fresh',
|
||||||
}
|
}
|
||||||
|
@@ -34,18 +34,23 @@ export interface BlogProps {
|
|||||||
|
|
||||||
export interface CheckOutForm {
|
export interface CheckOutForm {
|
||||||
name?: string
|
name?: string
|
||||||
email?:string
|
email?: string
|
||||||
address?: string
|
address?: string
|
||||||
city?:string
|
city?: string
|
||||||
state?:string
|
state?: string
|
||||||
code?:number
|
code?: number
|
||||||
phone?:number
|
phone?: number
|
||||||
method?:string
|
method?: string
|
||||||
shipping_fee?:number
|
shipping_fee?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MouseAndTouchEvent = MouseEvent | TouchEvent
|
export type MouseAndTouchEvent = MouseEvent | TouchEvent
|
||||||
|
|
||||||
|
export enum SortOrder {
|
||||||
|
Asc = 'ASC',
|
||||||
|
Desc = 'DESC',
|
||||||
|
}
|
||||||
|
|
||||||
export type filterContextType = {
|
export type filterContextType = {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
open: () => void;
|
open: () => void;
|
||||||
|
Reference in New Issue
Block a user