mirror of
https://github.com/vercel/commerce.git
synced 2025-07-23 04:36:49 +00:00
✨ feat: feat fresh and featured products
:%s
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { GetAllFacetsOperation } from './../types/facet';
|
||||||
import type { ServerResponse } from 'http'
|
import type { ServerResponse } from 'http'
|
||||||
import type { LoginOperation } from '../types/login'
|
import type { LoginOperation } from '../types/login'
|
||||||
import type { GetAllPagesOperation, GetPageOperation } from '../types/page'
|
import type { GetAllPagesOperation, GetPageOperation } from '../types/page'
|
||||||
@@ -156,23 +157,26 @@ export type Operations<P extends APIProvider> = {
|
|||||||
} & OperationOptions
|
} & OperationOptions
|
||||||
): Promise<T['data']>
|
): Promise<T['data']>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAllFacets: {
|
||||||
|
<T extends GetAllFacetsOperation>(opts: {
|
||||||
|
variables?: T['variables']
|
||||||
|
config?: P['config']
|
||||||
|
preview?: boolean
|
||||||
|
}): Promise<T['data']>
|
||||||
|
|
||||||
|
<T extends GetAllFacetsOperation>(
|
||||||
|
opts: {
|
||||||
|
variables?: T['variables']
|
||||||
|
config?: P['config']
|
||||||
|
preview?: boolean
|
||||||
|
} & OperationOptions
|
||||||
|
): Promise<T['data']>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAllFacets: {
|
|
||||||
// <T extends GetAllFacetsOperation>(opts: {
|
|
||||||
// variables?: T['variables']
|
|
||||||
// config?: P['config']
|
|
||||||
// preview?: boolean
|
|
||||||
// }): Promise<T['data']>
|
|
||||||
|
|
||||||
// <T extends GetAllFacetsOperation>(
|
|
||||||
// opts: {
|
|
||||||
// variables?: T['variables']
|
|
||||||
// config?: P['config']
|
|
||||||
// preview?: boolean
|
|
||||||
// } & OperationOptions
|
|
||||||
// ): Promise<T['data']>
|
|
||||||
// }
|
|
||||||
|
|
||||||
export type APIOperations<P extends APIProvider> = {
|
export type APIOperations<P extends APIProvider> = {
|
||||||
[K in keyof Operations<P>]?: (ctx: OperationContext<P>) => Operations<P>[K]
|
[K in keyof Operations<P>]?: (ctx: OperationContext<P>) => Operations<P>[K]
|
||||||
|
@@ -15,6 +15,7 @@ Adding a commerce provider means adding a new folder in `framework` with a folde
|
|||||||
- useSearch
|
- useSearch
|
||||||
- getProduct
|
- getProduct
|
||||||
- getAllProducts
|
- getAllProducts
|
||||||
|
- getAllFacets
|
||||||
- `wishlist`
|
- `wishlist`
|
||||||
- useWishlist
|
- useWishlist
|
||||||
- useAddItem
|
- useAddItem
|
||||||
|
@@ -1,40 +1,14 @@
|
|||||||
|
import { FacetValue } from './../../vendure/schema.d';
|
||||||
export type FacetOption = {
|
|
||||||
__typename?: 'MultipleChoiceOption'
|
|
||||||
id: string
|
|
||||||
displayName: string
|
|
||||||
values: FacetOptionValues[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type FacetOptionValues = {
|
|
||||||
label: string
|
|
||||||
hexColors?: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type FacetVariant = {
|
|
||||||
id: string | number
|
|
||||||
options: FacetOption[]
|
|
||||||
availableForSale?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Facet = {
|
export type Facet = {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
description: string
|
code: string
|
||||||
descriptionHtml?: string
|
values: FacetValue[]
|
||||||
sku?: string
|
|
||||||
slug?: string
|
|
||||||
path?: string
|
|
||||||
images: FacetImage[]
|
|
||||||
variants: FacetVariant[]
|
|
||||||
price: FacetPrice
|
|
||||||
options: FacetOption[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SearchFacetsBody = {
|
export type SearchFacetsBody = {
|
||||||
search?: string
|
search?: string
|
||||||
categoryId?: string | number
|
|
||||||
brandId?: string | number
|
|
||||||
sort?: string
|
sort?: string
|
||||||
locale?: string
|
locale?: string
|
||||||
}
|
}
|
||||||
@@ -63,17 +37,10 @@ export type FacetsSchema<T extends FacetTypes = FacetTypes> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetAllFacetPathsOperation<
|
|
||||||
T extends FacetTypes = FacetTypes
|
|
||||||
> = {
|
|
||||||
data: { facets: Pick<T['facet'], 'path'>[] }
|
|
||||||
variables: { first?: number }
|
|
||||||
}
|
|
||||||
|
|
||||||
export type GetAllFacetsOperation<T extends FacetTypes = FacetTypes> = {
|
export type GetAllFacetsOperation<T extends FacetTypes = FacetTypes> = {
|
||||||
data: { facets: T['facet'][] }
|
data: { facets: T['facet'][] }
|
||||||
variables: {
|
variables: {
|
||||||
relevance?: 'featured' | 'best_selling' | 'newest'
|
|
||||||
ids?: string[]
|
ids?: string[]
|
||||||
first?: number
|
first?: number
|
||||||
}
|
}
|
||||||
@@ -81,5 +48,5 @@ export type GetAllFacetsOperation<T extends FacetTypes = FacetTypes> = {
|
|||||||
|
|
||||||
export type GetFacetOperation<T extends FacetTypes = FacetTypes> = {
|
export type GetFacetOperation<T extends FacetTypes = FacetTypes> = {
|
||||||
data: { facet?: T['facet'] }
|
data: { facet?: T['facet'] }
|
||||||
variables: { path: string; slug?: never } | { path?: never; slug: string }
|
variables: { code: string; } | { code?: never; }
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
import { FacetValueFilterInput, LogicalOperator, SearchResultSortParameter } from "@framework/schema"
|
||||||
|
|
||||||
export type ProductImage = {
|
export type ProductImage = {
|
||||||
url: string
|
url: string
|
||||||
alt?: string
|
alt?: string
|
||||||
@@ -40,7 +42,6 @@ export type Product = {
|
|||||||
slug?: string
|
slug?: string
|
||||||
path?: string
|
path?: string
|
||||||
images: ProductImage[]
|
images: ProductImage[]
|
||||||
variants: ProductVariant[]
|
|
||||||
price: ProductPrice
|
price: ProductPrice
|
||||||
options: ProductOption[]
|
options: ProductOption[]
|
||||||
}
|
}
|
||||||
@@ -79,17 +80,24 @@ export type ProductsSchema<T extends ProductTypes = ProductTypes> = {
|
|||||||
|
|
||||||
export type GetAllProductPathsOperation<
|
export type GetAllProductPathsOperation<
|
||||||
T extends ProductTypes = ProductTypes
|
T extends ProductTypes = ProductTypes
|
||||||
> = {
|
> = {
|
||||||
data: { products: Pick<T['product'], 'path'>[] }
|
data: { products: Pick<T['product'], 'path'>[] }
|
||||||
variables: { first?: number }
|
variables: { first?: number }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetAllProductsOperation<T extends ProductTypes = ProductTypes> = {
|
export type GetAllProductsOperation<T extends ProductTypes = ProductTypes> = {
|
||||||
data: { products: T['product'][] }
|
data: { products: T['product'][] }
|
||||||
variables: {
|
variables: {
|
||||||
relevance?: 'featured' | 'best_selling' | 'newest'
|
term?: String
|
||||||
ids?: string[]
|
facetValueIds?: string[]
|
||||||
first?: number
|
facetValueOperator?: LogicalOperator
|
||||||
|
facetValueFilters?: FacetValueFilterInput[]
|
||||||
|
collectionId?: string
|
||||||
|
collectionSlug?: string
|
||||||
|
groupByProduct?: Boolean
|
||||||
|
take?: number
|
||||||
|
skip?: number
|
||||||
|
sort?: SearchResultSortParameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
|
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 { GetAllFacetsQuery } from '../../schema'
|
||||||
import { normalizeSearchResult } from '../../utils/normalize'
|
|
||||||
import { getAllFacetsQuery } from '../../utils/queries/get-all-facets-query'
|
import { getAllFacetsQuery } from '../../utils/queries/get-all-facets-query'
|
||||||
import { OperationContext } from '@commerce/api/operations'
|
|
||||||
|
|
||||||
export type FacetVariables = { first?: number }
|
export type FacetVariables = { first?: number }
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ export default function getAllFacetsOperation({
|
|||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
facets: data.search.items.map((item) => normalizeSearchResult(item)),
|
facets: data.facets.items,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ import { normalizeSearchResult } from '../../utils/normalize'
|
|||||||
import { getAllProductsQuery } from '../../utils/queries/get-all-products-query'
|
import { getAllProductsQuery } from '../../utils/queries/get-all-products-query'
|
||||||
import { OperationContext } from '@commerce/api/operations'
|
import { OperationContext } from '@commerce/api/operations'
|
||||||
|
|
||||||
export type ProductVariables = { first?: number }
|
export type ProductVariables = { first?: number, facetValueIds?: string[] }
|
||||||
|
|
||||||
export default function getAllProductsOperation({
|
export default function getAllProductsOperation({
|
||||||
commerce,
|
commerce,
|
||||||
@@ -30,6 +30,7 @@ export default function getAllProductsOperation({
|
|||||||
const variables = {
|
const variables = {
|
||||||
input: {
|
input: {
|
||||||
take: vars.first,
|
take: vars.first,
|
||||||
|
facetValueIds: vars.facetValueIds,
|
||||||
groupByProduct: true,
|
groupByProduct: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
4
framework/vendure/schema.d.ts
vendored
4
framework/vendure/schema.d.ts
vendored
@@ -3036,7 +3036,9 @@ export type CartFragment = { __typename?: 'Order' } & Pick<
|
|||||||
|
|
||||||
export type SearchResultFragment = { __typename?: 'SearchResult' } & Pick<
|
export type SearchResultFragment = { __typename?: 'SearchResult' } & Pick<
|
||||||
SearchResult,
|
SearchResult,
|
||||||
'productId' | 'productName' | 'description' | 'slug' | 'sku' | 'currencyCode'
|
'productId' | 'sku' | 'productName' | 'description' | 'slug' | 'sku' | 'currencyCode'
|
||||||
|
| 'productAsset' | 'price' | 'priceWithTax' | 'currencyCode'
|
||||||
|
| 'collectionIds'
|
||||||
> & {
|
> & {
|
||||||
productAsset?: Maybe<
|
productAsset?: Maybe<
|
||||||
{ __typename?: 'SearchResultAsset' } & Pick<
|
{ __typename?: 'SearchResultAsset' } & Pick<
|
||||||
|
@@ -3,18 +3,20 @@ import { Cart } from '@commerce/types/cart'
|
|||||||
import { CartFragment, SearchResultFragment } from '../schema'
|
import { CartFragment, SearchResultFragment } from '../schema'
|
||||||
|
|
||||||
export function normalizeSearchResult(item: SearchResultFragment): Product {
|
export function normalizeSearchResult(item: SearchResultFragment): Product {
|
||||||
|
const imageUrl = item.productAsset?.preview ? item.productAsset?.preview + '?w=800&mode=crop' : ''
|
||||||
return {
|
return {
|
||||||
id: item.productId,
|
id: item.productId,
|
||||||
name: item.productName,
|
name: item.productName,
|
||||||
description: item.description,
|
description: item.description,
|
||||||
slug: item.slug,
|
slug: item.slug,
|
||||||
path: item.slug,
|
path: item.slug,
|
||||||
images: [{ url: item.productAsset?.preview + '?w=800&mode=crop' || '' }],
|
images: imageUrl ? [{ url: imageUrl }] : [],
|
||||||
variants: [],
|
|
||||||
price: {
|
price: {
|
||||||
|
// TODO: check price
|
||||||
value: (item.priceWithTax as any).min / 100,
|
value: (item.priceWithTax as any).min / 100,
|
||||||
currencyCode: item.currencyCode,
|
currencyCode: item.currencyCode,
|
||||||
},
|
},
|
||||||
|
// TODO: check product option
|
||||||
options: [],
|
options: [],
|
||||||
sku: item.sku,
|
sku: item.sku,
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +1,22 @@
|
|||||||
|
import { ProductVariables } from '@framework/api/operations/get-all-products';
|
||||||
|
import { Product } from '@framework/schema';
|
||||||
import commerce from '@lib/api/commerce';
|
import commerce from '@lib/api/commerce';
|
||||||
import { GetStaticPropsContext } from 'next';
|
import { GetStaticPropsContext } from 'next';
|
||||||
import { Layout } from 'src/components/common';
|
import { Layout } from 'src/components/common';
|
||||||
import { FeaturedProductsCarousel, HomeBanner, HomeCategories, HomeCollection, HomeCTA, HomeFeature, HomeRecipe, HomeSubscribe, HomeVideo } from 'src/components/modules/home';
|
import { FeaturedProductsCarousel, 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 { getAllFeaturedFacetId, getFreshProductFacetId } from 'src/utils/funtion.utils';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
products: any
|
freshProducts: Product[],
|
||||||
|
featuredProducts: Product[],
|
||||||
|
|
||||||
}
|
}
|
||||||
export default function Home({ products }: Props) {
|
export default function Home({ freshProducts, featuredProducts }: Props) {
|
||||||
|
console.log("total: ", freshProducts.length, featuredProducts.length)
|
||||||
|
console.log("rs: ", freshProducts, featuredProducts)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p>
|
|
||||||
TOTAL: {products?.length}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{JSON.stringify(products[0])}
|
|
||||||
<HomeBanner />
|
<HomeBanner />
|
||||||
<HomeFeature />
|
<HomeFeature />
|
||||||
<HomeCategories />
|
<HomeCategories />
|
||||||
@@ -39,29 +41,51 @@ export async function getStaticProps({
|
|||||||
locales,
|
locales,
|
||||||
}: GetStaticPropsContext) {
|
}: GetStaticPropsContext) {
|
||||||
const config = { locale, locales }
|
const config = { locale, locales }
|
||||||
const productsPromise = commerce.getAllProducts({
|
const { facets } = await commerce.getAllFacets({
|
||||||
// const productsPromise = commerce.getAllFacets({
|
variables: {},
|
||||||
|
config,
|
||||||
|
preview,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const freshProductvariables: ProductVariables = {}
|
||||||
|
const freshFacetId = getFreshProductFacetId(facets)
|
||||||
|
|
||||||
|
if (freshFacetId) {
|
||||||
|
freshProductvariables.facetValueIds = [freshFacetId]
|
||||||
|
}
|
||||||
|
const freshProductsPromise = commerce.getAllProducts({
|
||||||
|
variables: freshProductvariables,
|
||||||
|
config,
|
||||||
|
preview,
|
||||||
|
})
|
||||||
|
|
||||||
|
const allFeaturedFacetId = getAllFeaturedFacetId(facets)
|
||||||
|
const featuredProductsPromise = commerce.getAllProducts({
|
||||||
variables: {
|
variables: {
|
||||||
first: 70,
|
facetValueIds: allFeaturedFacetId
|
||||||
// filter: {
|
|
||||||
// name: {
|
|
||||||
// contains: 'ca'
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
config,
|
config,
|
||||||
preview,
|
preview,
|
||||||
// Saleor provider only
|
|
||||||
...({ featured: true } as any),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const { products } = await productsPromise
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rs = await Promise.all([freshProductsPromise, featuredProductsPromise])
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
freshProducts: rs[0].products,
|
||||||
|
featuredProducts: rs[1].products
|
||||||
|
},
|
||||||
|
revalidate: 60,
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
|
||||||
return {
|
|
||||||
props: { products },
|
|
||||||
revalidate: 60,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
148
src/components/modules/home/FreshProducts/FreshProducts.tsx
Normal file
148
src/components/modules/home/FreshProducts/FreshProducts.tsx
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
import { Product } from '@framework/schema'
|
||||||
|
import React from 'react'
|
||||||
|
import { CollectionCarcousel } from '..'
|
||||||
|
import image5 from '../../../../../public/assets/images/image5.png'
|
||||||
|
import image6 from '../../../../../public/assets/images/image6.png'
|
||||||
|
import image7 from '../../../../../public/assets/images/image7.png'
|
||||||
|
import image8 from '../../../../../public/assets/images/image8.png'
|
||||||
|
interface FreshProductsProps {
|
||||||
|
data: Product[]
|
||||||
|
}
|
||||||
|
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 FreshProducts = ({data}: FreshProductsProps) => {
|
||||||
|
return (
|
||||||
|
<div className="w-full">
|
||||||
|
<CollectionCarcousel
|
||||||
|
type="highlight"
|
||||||
|
data={data}
|
||||||
|
itemKey="product-1"
|
||||||
|
title="Fresh Products Today"
|
||||||
|
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||||
|
category={"veggie"}
|
||||||
|
/>
|
||||||
|
<CollectionCarcousel
|
||||||
|
data={dataTest}
|
||||||
|
itemKey="product-2"
|
||||||
|
title="VEGGIE"
|
||||||
|
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||||
|
category={"veggie"}
|
||||||
|
/>
|
||||||
|
<CollectionCarcousel
|
||||||
|
data={dataTest}
|
||||||
|
itemKey="product-3"
|
||||||
|
title="VEGGIE"
|
||||||
|
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||||
|
category={"veggie"}
|
||||||
|
/>
|
||||||
|
<CollectionCarcousel
|
||||||
|
data={dataTest}
|
||||||
|
itemKey="product-4"
|
||||||
|
title="VEGGIE"
|
||||||
|
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||||
|
category={"veggie"}
|
||||||
|
/>
|
||||||
|
<CollectionCarcousel
|
||||||
|
data={dataTest}
|
||||||
|
itemKey="product-5"
|
||||||
|
title="VEGGIE"
|
||||||
|
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||||
|
category={"veggie"}
|
||||||
|
/>
|
||||||
|
<CollectionCarcousel
|
||||||
|
data={dataTest}
|
||||||
|
itemKey="product-6"
|
||||||
|
title="VEGGIE"
|
||||||
|
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||||
|
category={"veggie"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FreshProducts
|
@@ -4,6 +4,7 @@ export { default as HomeCategories } from './HomeCategories/HomeCategories'
|
|||||||
export { default as HomeCTA } from './HomeCTA/HomeCTA'
|
export { default as HomeCTA } from './HomeCTA/HomeCTA'
|
||||||
export { default as HomeSubscribe } from './HomeSubscribe/HomeSubscribe'
|
export { default as HomeSubscribe } from './HomeSubscribe/HomeSubscribe'
|
||||||
export { default as HomeVideo } from './HomeVideo/HomeVideo'
|
export { default as HomeVideo } from './HomeVideo/HomeVideo'
|
||||||
|
export { default as FreshProducts } from './FreshProducts/FreshProducts'
|
||||||
export { default as HomeCollection } from './HomeCollection/HomeCollection'
|
export { default as HomeCollection } from './HomeCollection/HomeCollection'
|
||||||
export { default as HomeRecipe } from './HomeRecipe/HomeRecipe'
|
export { default as HomeRecipe } from './HomeRecipe/HomeRecipe'
|
||||||
export { default as FeaturedProductsCarousel } from './FeaturedProductsCarousel/FeaturedProductsCarousel'
|
export { default as FeaturedProductsCarousel } from './FeaturedProductsCarousel/FeaturedProductsCarousel'
|
||||||
|
@@ -107,7 +107,15 @@ export const CATEGORY = [
|
|||||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chinsu`,
|
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chinsu`,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const FACET = {
|
||||||
|
FEATURE: {
|
||||||
|
PARENT_NAME: 'Featured',
|
||||||
|
FRESH: 'Fresh',
|
||||||
|
BEST_SELLERS: 'Best seller'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const FEATURED = [
|
export const FEATURED = [
|
||||||
{
|
{
|
||||||
name: 'Best Sellers',
|
name: 'Best Sellers',
|
||||||
@@ -141,3 +149,4 @@ export const STATE_OPTIONS = [
|
|||||||
value: 'Hà Nội',
|
value: 'Hà Nội',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@@ -1,11 +1,29 @@
|
|||||||
|
import { FacetValue } from './../../framework/vendure/schema.d';
|
||||||
|
import { Facet } from "@commerce/types/facet";
|
||||||
|
import { FACET } from "./constanst.utils";
|
||||||
|
|
||||||
export function isMobile() {
|
export function isMobile() {
|
||||||
return window.innerWidth < 768
|
return window.innerWidth < 768
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeItem<T>(arr: Array<T>, value: T): Array<T> {
|
export function removeItem<T>(arr: Array<T>, value: T): Array<T> {
|
||||||
const index = arr.indexOf(value);
|
const index = arr.indexOf(value);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
arr.splice(index, 1);
|
arr.splice(index, 1);
|
||||||
}
|
}
|
||||||
return [...arr];
|
return [...arr];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getFreshProductFacetId(facets: Facet[]) {
|
||||||
|
const featuredFacet = facets.find((item: Facet) => item.name === FACET.FEATURE.PARENT_NAME)
|
||||||
|
const freshFacetValue = featuredFacet?.values.find((item: FacetValue) => item.name === FACET.FEATURE.FRESH)
|
||||||
|
|
||||||
|
return freshFacetValue?.id
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAllFeaturedFacetId(facets: Facet[]) {
|
||||||
|
const featuredFacet = facets.find((item: Facet) => item.name === FACET.FEATURE.PARENT_NAME)
|
||||||
|
const rs = featuredFacet?.values.map((item: FacetValue) => item.id)
|
||||||
|
|
||||||
|
return rs
|
||||||
}
|
}
|
Reference in New Issue
Block a user