From 5c70c8be25d775e63a81778bb18f936dcfb8758b Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Thu, 30 Sep 2021 17:50:35 +0700 Subject: [PATCH 01/11] :sparkles: feat: get all facets :%s --- framework/vendure/schema.d.ts | 45 +++++++++++++++++++ .../utils/queries/get-all-facets-query.ts | 17 +++++++ pages/product/[slug].tsx | 1 + pages/test.tsx | 34 +++++++++++--- src/components/hooks/facets/index.ts | 3 ++ src/components/hooks/facets/useFacets.tsx | 12 +++++ 6 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 framework/vendure/utils/queries/get-all-facets-query.ts create mode 100644 src/components/hooks/facets/index.ts create mode 100644 src/components/hooks/facets/useFacets.tsx diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index b0b0170d7..3922f679b 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -93,6 +93,10 @@ export type QueryProductsArgs = { options?: Maybe } +export type QueryFacetsArgs = { + options?: Maybe +} + export type QuerySearchArgs = { input: SearchInput } @@ -2727,6 +2731,13 @@ export type ProductListOptions = { filter?: Maybe } +export type FacetListOptions = { + skip?: Maybe + take?: Maybe + sort?: Maybe + filter?: Maybe +} + export type UpdateOrderItemsResult = | Order | OrderModificationError @@ -2884,6 +2895,23 @@ export type ProductVariantSortParameter = { discountPrice?: Maybe } + +export type FacetFilterParameter = { + createdAt?: Maybe + updatedAt?: Maybe + languageCode?: Maybe + name?: Maybe + code?: Maybe +} + +export type FacetSortParameter = { + id?: Maybe + createdAt?: Maybe + updatedAt?: Maybe + name?: Maybe + code?: Maybe +} + export type CustomerFilterParameter = { createdAt?: Maybe updatedAt?: Maybe @@ -3192,6 +3220,23 @@ export type GetAllProductsQuery = { __typename?: 'Query' } & { } } +export type GetAllFacetsQuery = { __typename?: 'Query' } & { + facets: { __typename?: 'FacetList' } & { + items: Array< + { __typename?: 'Facet' } & Pick< + Facet, + 'id' | 'name' | 'code' + > & { + parent?: Maybe<{ __typename?: 'Facet' } & Pick> + children?: Maybe< + Array<{ __typename?: 'Facet' } & Pick> + > + } + >, + 'totalItems' + } +} + export type ActiveOrderQueryVariables = Exact<{ [key: string]: never }> export type ActiveOrderQuery = { __typename?: 'Query' } & { diff --git a/framework/vendure/utils/queries/get-all-facets-query.ts b/framework/vendure/utils/queries/get-all-facets-query.ts new file mode 100644 index 000000000..906507c69 --- /dev/null +++ b/framework/vendure/utils/queries/get-all-facets-query.ts @@ -0,0 +1,17 @@ +export const getAllFacetsQuery = /* GraphQL */ ` +query facets ($options: FacetListOptions) { + facets (options: $options){ + totalItems, + items { + id + name + code + values { + id + name + code + } + } + } +} +` diff --git a/pages/product/[slug].tsx b/pages/product/[slug].tsx index ab9a1c17c..a8e925df9 100644 --- a/pages/product/[slug].tsx +++ b/pages/product/[slug].tsx @@ -4,6 +4,7 @@ import { ProductInfoDetail, ReleventProducts, ViewedProducts } from 'src/compone import { BLOGS_DATA_TEST, INGREDIENT_DATA_TEST, RECIPE_DATA_TEST } from 'src/utils/demo-data' export default function Slug() { + return <> diff --git a/pages/test.tsx b/pages/test.tsx index b60fe63c7..452b42173 100644 --- a/pages/test.tsx +++ b/pages/test.tsx @@ -1,16 +1,40 @@ +import { QueryFacetsArgs } from '@framework/schema' +import { useMemo, useState } from 'react' import { Layout } from 'src/components/common' -import { useMessage } from 'src/components/contexts' +import { useFacets } from 'src/components/hooks/facets' export default function Test() { - const { showMessageError } = useMessage() + const [keyword, setKeyword] = useState('c') - const handleClick = () => { - showMessageError("Create account successfully") + const optionsFilter = useMemo(() => { + console.log("change options") + return { + options: { + filter: { + name: { + contains: keyword + } + } + } + } as QueryFacetsArgs + }, [keyword]) + + const { items, totalItems } = useFacets(optionsFilter) + + const changeQuery = () => { + setKeyword('ca') } return ( <> - +
Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, praesentium.
+
+ total: {totalItems} +
+
+ ITEMS: {JSON.stringify(items)} +
+ ) } diff --git a/src/components/hooks/facets/index.ts b/src/components/hooks/facets/index.ts new file mode 100644 index 000000000..f039373e3 --- /dev/null +++ b/src/components/hooks/facets/index.ts @@ -0,0 +1,3 @@ +export { default as useFacets } from './useFacets' + + diff --git a/src/components/hooks/facets/useFacets.tsx b/src/components/hooks/facets/useFacets.tsx new file mode 100644 index 000000000..59d5485ec --- /dev/null +++ b/src/components/hooks/facets/useFacets.tsx @@ -0,0 +1,12 @@ +import { GetAllFacetsQuery, QueryFacetsArgs } from '@framework/schema' +import { getAllFacetsQuery } from '@framework/utils/queries/get-all-facets-query' +import gglFetcher from 'src/utils/gglFetcher' +import useSWR from 'swr' + +const useFacets = (options: QueryFacetsArgs) => { + const { data, isValidating, ...rest } = useSWR([getAllFacetsQuery, options], gglFetcher) + console.log("here", data) + return { items: data?.facets.items, totalItems: data?.facets.totalItems, loading: isValidating, ...rest } +} + +export default useFacets From 8f290f94f66036951fae40ce5c5abb9a1314a31e Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Fri, 1 Oct 2021 09:19:34 +0700 Subject: [PATCH 02/11] :fire: remove: log :%s --- src/components/hooks/facets/useFacets.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/hooks/facets/useFacets.tsx b/src/components/hooks/facets/useFacets.tsx index 59d5485ec..94630b868 100644 --- a/src/components/hooks/facets/useFacets.tsx +++ b/src/components/hooks/facets/useFacets.tsx @@ -5,7 +5,6 @@ import useSWR from 'swr' const useFacets = (options: QueryFacetsArgs) => { const { data, isValidating, ...rest } = useSWR([getAllFacetsQuery, options], gglFetcher) - console.log("here", data) return { items: data?.facets.items, totalItems: data?.facets.totalItems, loading: isValidating, ...rest } } From 21b0200205e816332de845ae7d7fe2ac33966b6c Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 4 Oct 2021 11:14:38 +0700 Subject: [PATCH 03/11] :raising_hand: test getStaticProps with revalidate --- pages/index.tsx | 51 ++++++++++++++++++++++++++++--- pages/test.tsx | 79 +++++++++++++++++++++++++++---------------------- 2 files changed, 91 insertions(+), 39 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 3fa86079d..aabbb1f94 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,19 +1,29 @@ +import commerce from '@lib/api/commerce'; +import { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; import { FeaturedProductsCarousel, HomeBanner, HomeCategories, HomeCollection, HomeCTA, HomeFeature, HomeRecipe, HomeSubscribe, HomeVideo } from 'src/components/modules/home'; import HomeSpice from 'src/components/modules/home/HomeSpice/HomeSpice'; -export default function Home() { +interface Props { + products: any +} +export default function Home({ products }: Props) { return ( <> +

+ TOTAL: {products?.length} +

+ + {JSON.stringify(products[0])} - - + + - + {/* // todo: uncomment @@ -22,4 +32,37 @@ export default function Home() { ) } + +export async function getStaticProps({ + preview, + locale, + locales, +}: GetStaticPropsContext) { + const config = { locale, locales } + const productsPromise = commerce.getAllProducts({ + // const productsPromise = commerce.getAllFacets({ + variables: { + first: 70, + // filter: { + // name: { + // contains: 'ca' + // } + // } + }, + config, + preview, + // Saleor provider only + ...({ featured: true } as any), + }) + + const { products } = await productsPromise + + + return { + props: { products }, + revalidate: 20, + } +} + + Home.Layout = Layout diff --git a/pages/test.tsx b/pages/test.tsx index 452b42173..6244c3dd6 100644 --- a/pages/test.tsx +++ b/pages/test.tsx @@ -1,42 +1,51 @@ -import { QueryFacetsArgs } from '@framework/schema' -import { useMemo, useState } from 'react' -import { Layout } from 'src/components/common' -import { useFacets } from 'src/components/hooks/facets' - -export default function Test() { - const [keyword, setKeyword] = useState('c') - - const optionsFilter = useMemo(() => { - console.log("change options") - return { - options: { - filter: { - name: { - contains: keyword - } - } - } - } as QueryFacetsArgs - }, [keyword]) - - const { items, totalItems } = useFacets(optionsFilter) - - const changeQuery = () => { - setKeyword('ca') - } +import commerce from '@lib/api/commerce'; +import { GetStaticPropsContext } from 'next'; +import { Layout } from 'src/components/common'; +interface Props { + products: any +} +export default function Home({ products }: Props) { return ( <> -
Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore, praesentium.
-
- total: {totalItems} -
-
- ITEMS: {JSON.stringify(items)} -
- +

+ TOTAL: {products?.length} +

+ {JSON.stringify(products[0])} ) } -Test.Layout = Layout + +export async function getServerSideProps({ + preview, + locale, + locales, +}: GetStaticPropsContext) { + const config = { locale, locales } + const productsPromise = commerce.getAllProducts({ + // const productsPromise = commerce.getAllFacets({ + variables: { + first: 70, + // filter: { + // name: { + // contains: 'ca' + // } + // } + }, + config, + preview, + // Saleor provider only + ...({ featured: true } as any), + }) + + const { products } = await productsPromise + + + return { + props: { products }, + } +} + + +Home.Layout = Layout From 6b7b8e4ad154f22c715ae7af541a6b289f16efe0 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 4 Oct 2021 11:17:30 +0700 Subject: [PATCH 04/11] :raising_hand: test getStaticProps with revalidate --- framework/commerce/api/operations.ts | 18 ++++ framework/commerce/types/facet.ts | 85 +++++++++++++++++++ framework/vendure/api/index.ts | 16 ++-- .../vendure/api/operations/get-all-facets.ts | 46 ++++++++++ pages/index.tsx | 2 +- src/components/hooks/facets/useFacets.tsx | 2 +- 6 files changed, 160 insertions(+), 9 deletions(-) create mode 100644 framework/commerce/types/facet.ts create mode 100644 framework/vendure/api/operations/get-all-facets.ts diff --git a/framework/commerce/api/operations.ts b/framework/commerce/api/operations.ts index 2910a2d82..8e5137c40 100644 --- a/framework/commerce/api/operations.ts +++ b/framework/commerce/api/operations.ts @@ -23,6 +23,8 @@ export const OPERATIONS = [ 'getAllProductPaths', 'getAllProducts', 'getProduct', + 'getAllFacets', + ] as const export const defaultOperations = OPERATIONS.reduce((ops, k) => { @@ -156,6 +158,22 @@ export type Operations

= { } } +// getAllFacets: { +// (opts: { +// variables?: T['variables'] +// config?: P['config'] +// preview?: boolean +// }): Promise + +// ( +// opts: { +// variables?: T['variables'] +// config?: P['config'] +// preview?: boolean +// } & OperationOptions +// ): Promise +// } + export type APIOperations

= { [K in keyof Operations

]?: (ctx: OperationContext

) => Operations

[K] } diff --git a/framework/commerce/types/facet.ts b/framework/commerce/types/facet.ts new file mode 100644 index 000000000..d1ae5b382 --- /dev/null +++ b/framework/commerce/types/facet.ts @@ -0,0 +1,85 @@ + +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 = { + id: string + name: string + description: string + descriptionHtml?: string + sku?: string + slug?: string + path?: string + images: FacetImage[] + variants: FacetVariant[] + price: FacetPrice + options: FacetOption[] +} + +export type SearchFacetsBody = { + search?: string + categoryId?: string | number + brandId?: string | number + sort?: string + locale?: string +} + +export type FacetTypes = { + facet: Facet + searchBody: SearchFacetsBody +} + +export type SearchFacetsHook = { + data: { + facets: T['facet'][] + found: boolean + } + body: T['searchBody'] + input: T['searchBody'] + fetcherInput: T['searchBody'] +} + +export type FacetsSchema = { + endpoint: { + options: {} + handlers: { + getFacets: SearchFacetsHook + } + } +} + +export type GetAllFacetPathsOperation< + T extends FacetTypes = FacetTypes +> = { + data: { facets: Pick[] } + variables: { first?: number } +} + +export type GetAllFacetsOperation = { + data: { facets: T['facet'][] } + variables: { + relevance?: 'featured' | 'best_selling' | 'newest' + ids?: string[] + first?: number + } +} + +export type GetFacetOperation = { + data: { facet?: T['facet'] } + variables: { path: string; slug?: never } | { path?: never; slug: string } +} diff --git a/framework/vendure/api/index.ts b/framework/vendure/api/index.ts index 6762ee6aa..7e49d6c1f 100644 --- a/framework/vendure/api/index.ts +++ b/framework/vendure/api/index.ts @@ -1,15 +1,16 @@ -import type { APIProvider, CommerceAPIConfig } from '@commerce/api' +import type { CommerceAPIConfig } from '@commerce/api' import { CommerceAPI, getCommerceApi as commerceApi } from '@commerce/api' -import fetchGraphqlApi from './utils/fetch-graphql-api' - -import login from './operations/login' +import getAllFacets from './operations/get-all-facets' import getAllPages from './operations/get-all-pages' -import getPage from './operations/get-page' -import getSiteInfo from './operations/get-site-info' -import getCustomerWishlist from './operations/get-customer-wishlist' import getAllProductPaths from './operations/get-all-product-paths' import getAllProducts from './operations/get-all-products' +import getCustomerWishlist from './operations/get-customer-wishlist' +import getPage from './operations/get-page' import getProduct from './operations/get-product' +import getSiteInfo from './operations/get-site-info' +import login from './operations/login' +import fetchGraphqlApi from './utils/fetch-graphql-api' + export interface VendureConfig extends CommerceAPIConfig {} @@ -40,6 +41,7 @@ const operations = { getAllProductPaths, getAllProducts, getProduct, + getAllFacets, } export const provider = { config, operations } diff --git a/framework/vendure/api/operations/get-all-facets.ts b/framework/vendure/api/operations/get-all-facets.ts new file mode 100644 index 000000000..9187525d3 --- /dev/null +++ b/framework/vendure/api/operations/get-all-facets.ts @@ -0,0 +1,46 @@ +import { Facet } from '@commerce/types/facet' +import { Provider, VendureConfig } from '../' +import { GetAllFacetsQuery } from '../../schema' +import { normalizeSearchResult } from '../../utils/normalize' +import { getAllFacetsQuery } from '../../utils/queries/get-all-facets-query' +import { OperationContext } from '@commerce/api/operations' + +export type FacetVariables = { first?: number } + +export default function getAllFacetsOperation({ + commerce, +}: OperationContext) { + async function getAllFacets(opts?: { + variables?: FacetVariables + config?: Partial + preview?: boolean + }): Promise<{ facets: Facet[] }> + + async function getAllFacets({ + query = getAllFacetsQuery, + variables: { ...vars } = {}, + config: cfg, + }: { + query?: string + variables?: FacetVariables + config?: Partial + preview?: boolean + } = {}): Promise<{ facets: Facet[] | any[] }> { + const config = commerce.getConfig(cfg) + const variables = { + input: { + take: vars.first, + groupByFacet: true, + }, + } + const { data } = await config.fetch(query, { + variables, + }) + + return { + facets: data.search.items.map((item) => normalizeSearchResult(item)), + } + } + + return getAllFacets +} diff --git a/pages/index.tsx b/pages/index.tsx index aabbb1f94..371922e59 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -60,7 +60,7 @@ export async function getStaticProps({ return { props: { products }, - revalidate: 20, + revalidate: 60, } } diff --git a/src/components/hooks/facets/useFacets.tsx b/src/components/hooks/facets/useFacets.tsx index 94630b868..c9a4e85ab 100644 --- a/src/components/hooks/facets/useFacets.tsx +++ b/src/components/hooks/facets/useFacets.tsx @@ -3,7 +3,7 @@ import { getAllFacetsQuery } from '@framework/utils/queries/get-all-facets-query import gglFetcher from 'src/utils/gglFetcher' import useSWR from 'swr' -const useFacets = (options: QueryFacetsArgs) => { +const useFacets = (options?: QueryFacetsArgs) => { const { data, isValidating, ...rest } = useSWR([getAllFacetsQuery, options], gglFetcher) return { items: data?.facets.items, totalItems: data?.facets.totalItems, loading: isValidating, ...rest } } From 77a0432d0745e53f891335f5f377550099370c47 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 4 Oct 2021 14:16:32 +0700 Subject: [PATCH 05/11] :sparkles: feat: feat fresh and featured products :%s --- framework/commerce/api/operations.ts | 34 ++-- framework/commerce/new-provider.md | 1 + framework/commerce/types/facet.ts | 41 +---- framework/commerce/types/product.ts | 24 ++- .../vendure/api/operations/get-all-facets.ts | 5 +- .../api/operations/get-all-products.ts | 3 +- framework/vendure/schema.d.ts | 4 +- framework/vendure/utils/normalize.ts | 6 +- pages/index.tsx | 66 +++++--- .../home/FreshProducts/FreshProducts.tsx | 148 ++++++++++++++++++ src/components/modules/home/index.ts | 1 + src/utils/constanst.utils.ts | 11 +- src/utils/funtion.utils.ts | 32 +++- 13 files changed, 280 insertions(+), 96 deletions(-) create mode 100644 src/components/modules/home/FreshProducts/FreshProducts.tsx diff --git a/framework/commerce/api/operations.ts b/framework/commerce/api/operations.ts index 8e5137c40..342d6bbc9 100644 --- a/framework/commerce/api/operations.ts +++ b/framework/commerce/api/operations.ts @@ -1,3 +1,4 @@ +import { GetAllFacetsOperation } from './../types/facet'; import type { ServerResponse } from 'http' import type { LoginOperation } from '../types/login' import type { GetAllPagesOperation, GetPageOperation } from '../types/page' @@ -156,23 +157,26 @@ export type Operations

= { } & OperationOptions ): Promise } + + getAllFacets: { + (opts: { + variables?: T['variables'] + config?: P['config'] + preview?: boolean + }): Promise + + ( + opts: { + variables?: T['variables'] + config?: P['config'] + preview?: boolean + } & OperationOptions + ): Promise + } + + } -// getAllFacets: { -// (opts: { -// variables?: T['variables'] -// config?: P['config'] -// preview?: boolean -// }): Promise - -// ( -// opts: { -// variables?: T['variables'] -// config?: P['config'] -// preview?: boolean -// } & OperationOptions -// ): Promise -// } export type APIOperations

= { [K in keyof Operations

]?: (ctx: OperationContext

) => Operations

[K] diff --git a/framework/commerce/new-provider.md b/framework/commerce/new-provider.md index 8c2feeab2..a48e6961b 100644 --- a/framework/commerce/new-provider.md +++ b/framework/commerce/new-provider.md @@ -15,6 +15,7 @@ Adding a commerce provider means adding a new folder in `framework` with a folde - useSearch - getProduct - getAllProducts + - getAllFacets - `wishlist` - useWishlist - useAddItem diff --git a/framework/commerce/types/facet.ts b/framework/commerce/types/facet.ts index d1ae5b382..adfe1e061 100644 --- a/framework/commerce/types/facet.ts +++ b/framework/commerce/types/facet.ts @@ -1,40 +1,14 @@ - -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 -} +import { FacetValue } from './../../vendure/schema.d'; export type Facet = { id: string name: string - description: string - descriptionHtml?: string - sku?: string - slug?: string - path?: string - images: FacetImage[] - variants: FacetVariant[] - price: FacetPrice - options: FacetOption[] + code: string + values: FacetValue[] } export type SearchFacetsBody = { search?: string - categoryId?: string | number - brandId?: string | number sort?: string locale?: string } @@ -63,17 +37,10 @@ export type FacetsSchema = { } } -export type GetAllFacetPathsOperation< - T extends FacetTypes = FacetTypes -> = { - data: { facets: Pick[] } - variables: { first?: number } -} export type GetAllFacetsOperation = { data: { facets: T['facet'][] } variables: { - relevance?: 'featured' | 'best_selling' | 'newest' ids?: string[] first?: number } @@ -81,5 +48,5 @@ export type GetAllFacetsOperation = { export type GetFacetOperation = { data: { facet?: T['facet'] } - variables: { path: string; slug?: never } | { path?: never; slug: string } + variables: { code: string; } | { code?: never; } } diff --git a/framework/commerce/types/product.ts b/framework/commerce/types/product.ts index 6a68d8ad1..fec48a63d 100644 --- a/framework/commerce/types/product.ts +++ b/framework/commerce/types/product.ts @@ -1,3 +1,5 @@ +import { FacetValueFilterInput, LogicalOperator, SearchResultSortParameter } from "@framework/schema" + export type ProductImage = { url: string alt?: string @@ -40,7 +42,6 @@ export type Product = { slug?: string path?: string images: ProductImage[] - variants: ProductVariant[] price: ProductPrice options: ProductOption[] } @@ -79,17 +80,24 @@ export type ProductsSchema = { export type GetAllProductPathsOperation< T extends ProductTypes = ProductTypes -> = { - data: { products: Pick[] } - variables: { first?: number } -} + > = { + data: { products: Pick[] } + variables: { first?: number } + } export type GetAllProductsOperation = { data: { products: T['product'][] } variables: { - relevance?: 'featured' | 'best_selling' | 'newest' - ids?: string[] - first?: number + term?: String + facetValueIds?: string[] + facetValueOperator?: LogicalOperator + facetValueFilters?: FacetValueFilterInput[] + collectionId?: string + collectionSlug?: string + groupByProduct?: Boolean + take?: number + skip?: number + sort?: SearchResultSortParameter } } diff --git a/framework/vendure/api/operations/get-all-facets.ts b/framework/vendure/api/operations/get-all-facets.ts index 9187525d3..c4b002744 100644 --- a/framework/vendure/api/operations/get-all-facets.ts +++ b/framework/vendure/api/operations/get-all-facets.ts @@ -1,9 +1,8 @@ +import { OperationContext } from '@commerce/api/operations' import { Facet } from '@commerce/types/facet' import { Provider, VendureConfig } from '../' import { GetAllFacetsQuery } from '../../schema' -import { normalizeSearchResult } from '../../utils/normalize' import { getAllFacetsQuery } from '../../utils/queries/get-all-facets-query' -import { OperationContext } from '@commerce/api/operations' export type FacetVariables = { first?: number } @@ -38,7 +37,7 @@ export default function getAllFacetsOperation({ }) return { - facets: data.search.items.map((item) => normalizeSearchResult(item)), + facets: data.facets.items, } } diff --git a/framework/vendure/api/operations/get-all-products.ts b/framework/vendure/api/operations/get-all-products.ts index 68d4ce9b7..1f558a7cb 100644 --- a/framework/vendure/api/operations/get-all-products.ts +++ b/framework/vendure/api/operations/get-all-products.ts @@ -5,7 +5,7 @@ import { normalizeSearchResult } from '../../utils/normalize' import { getAllProductsQuery } from '../../utils/queries/get-all-products-query' import { OperationContext } from '@commerce/api/operations' -export type ProductVariables = { first?: number } +export type ProductVariables = { first?: number, facetValueIds?: string[] } export default function getAllProductsOperation({ commerce, @@ -30,6 +30,7 @@ export default function getAllProductsOperation({ const variables = { input: { take: vars.first, + facetValueIds: vars.facetValueIds, groupByProduct: true, }, } diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index 3922f679b..a817d6799 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -3036,7 +3036,9 @@ export type CartFragment = { __typename?: 'Order' } & Pick< export type SearchResultFragment = { __typename?: 'SearchResult' } & Pick< SearchResult, - 'productId' | 'productName' | 'description' | 'slug' | 'sku' | 'currencyCode' + 'productId' | 'sku' | 'productName' | 'description' | 'slug' | 'sku' | 'currencyCode' + | 'productAsset' | 'price' | 'priceWithTax' | 'currencyCode' + | 'collectionIds' > & { productAsset?: Maybe< { __typename?: 'SearchResultAsset' } & Pick< diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index 09c1c6e42..b99aa5096 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -3,18 +3,20 @@ import { Cart } from '@commerce/types/cart' import { CartFragment, SearchResultFragment } from '../schema' export function normalizeSearchResult(item: SearchResultFragment): Product { + const imageUrl = item.productAsset?.preview ? item.productAsset?.preview + '?w=800&mode=crop' : '' return { id: item.productId, name: item.productName, description: item.description, slug: item.slug, path: item.slug, - images: [{ url: item.productAsset?.preview + '?w=800&mode=crop' || '' }], - variants: [], + images: imageUrl ? [{ url: imageUrl }] : [], price: { + // TODO: check price value: (item.priceWithTax as any).min / 100, currencyCode: item.currencyCode, }, + // TODO: check product option options: [], sku: item.sku, } diff --git a/pages/index.tsx b/pages/index.tsx index 371922e59..3082d1790 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -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 { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; 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 { getAllFeaturedFacetId, getFreshProductFacetId } from 'src/utils/funtion.utils'; 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 ( <> -

- TOTAL: {products?.length} -

- - {JSON.stringify(products[0])} @@ -39,29 +41,51 @@ export async function getStaticProps({ locales, }: GetStaticPropsContext) { const config = { locale, locales } - const productsPromise = commerce.getAllProducts({ - // const productsPromise = commerce.getAllFacets({ + const { facets } = await 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: { - first: 70, - // filter: { - // name: { - // contains: 'ca' - // } - // } + facetValueIds: allFeaturedFacetId }, config, 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, } + + + } diff --git a/src/components/modules/home/FreshProducts/FreshProducts.tsx b/src/components/modules/home/FreshProducts/FreshProducts.tsx new file mode 100644 index 000000000..b06138079 --- /dev/null +++ b/src/components/modules/home/FreshProducts/FreshProducts.tsx @@ -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 ( +
+ + + + + + +
+ ) +} + +export default FreshProducts diff --git a/src/components/modules/home/index.ts b/src/components/modules/home/index.ts index 82a0e3d8a..0618812c5 100644 --- a/src/components/modules/home/index.ts +++ b/src/components/modules/home/index.ts @@ -4,6 +4,7 @@ export { default as HomeCategories } from './HomeCategories/HomeCategories' export { default as HomeCTA } from './HomeCTA/HomeCTA' export { default as HomeSubscribe } from './HomeSubscribe/HomeSubscribe' export { default as HomeVideo } from './HomeVideo/HomeVideo' +export { default as FreshProducts } from './FreshProducts/FreshProducts' export { default as HomeCollection } from './HomeCollection/HomeCollection' export { default as HomeRecipe } from './HomeRecipe/HomeRecipe' export { default as FeaturedProductsCarousel } from './FeaturedProductsCarousel/FeaturedProductsCarousel' diff --git a/src/utils/constanst.utils.ts b/src/utils/constanst.utils.ts index f77991604..f66d6a7ea 100644 --- a/src/utils/constanst.utils.ts +++ b/src/utils/constanst.utils.ts @@ -107,7 +107,15 @@ export const CATEGORY = [ link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chinsu`, }, ] - + +export const FACET = { + FEATURE: { + PARENT_NAME: 'Featured', + FRESH: 'Fresh', + BEST_SELLERS: 'Best seller' + } +} + export const FEATURED = [ { name: 'Best Sellers', @@ -141,3 +149,4 @@ export const STATE_OPTIONS = [ value: 'Hà Nội', }, ] + diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts index 43d517589..d2ad83be1 100644 --- a/src/utils/funtion.utils.ts +++ b/src/utils/funtion.utils.ts @@ -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() { - return window.innerWidth < 768 + return window.innerWidth < 768 } -export function removeItem(arr: Array, value: T): Array { - const index = arr.indexOf(value); - if (index > -1) { - arr.splice(index, 1); - } - return [...arr]; +export function removeItem(arr: Array, value: T): Array { + const index = arr.indexOf(value); + if (index > -1) { + arr.splice(index, 1); + } + 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 } \ No newline at end of file From 68f4e5beb526e5392416658f81d80ce1e6ae6aba Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 4 Oct 2021 15:07:09 +0700 Subject: [PATCH 06/11] :sparkles: feat: fresh products :%s --- framework/commerce/types/product.ts | 16 +++ framework/vendure/utils/normalize.ts | 27 ++-- pages/index.tsx | 5 +- public/assets/images/default_img.jpg | Bin 0 -> 4357 bytes .../common/ImgWithLink/ImgWithLink.tsx | 4 +- .../common/ProductCard/ProductCard.tsx | 31 +++-- .../home/FreshProducts/FreshProducts.tsx | 125 ------------------ src/utils/constanst.utils.ts | 3 + 8 files changed, 56 insertions(+), 155 deletions(-) create mode 100644 public/assets/images/default_img.jpg diff --git a/framework/commerce/types/product.ts b/framework/commerce/types/product.ts index fec48a63d..39f594a7a 100644 --- a/framework/commerce/types/product.ts +++ b/framework/commerce/types/product.ts @@ -1,3 +1,4 @@ +import { CurrencyCode } from './../../vendure/schema.d'; import { FacetValueFilterInput, LogicalOperator, SearchResultSortParameter } from "@framework/schema" export type ProductImage = { @@ -46,6 +47,21 @@ export type Product = { options: ProductOption[] } +export type ProductCard = { + id: string + name: string + slug?: string + imageSrc: string + price: number + currencyCode: CurrencyCode + oldPrice?: number, + discount?: number + weight?: number + // TODO: collection + category?: string, + isNotSell?: boolean +} + export type SearchProductsBody = { search?: string categoryId?: string | number diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index b99aa5096..a5cb96c8a 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -1,24 +1,23 @@ -import { Product } from '@commerce/types/product' +import { Product, ProductCard } from '@commerce/types/product' import { Cart } from '@commerce/types/cart' import { CartFragment, SearchResultFragment } from '../schema' -export function normalizeSearchResult(item: SearchResultFragment): Product { - const imageUrl = item.productAsset?.preview ? item.productAsset?.preview + '?w=800&mode=crop' : '' +export function normalizeSearchResult(item: SearchResultFragment): ProductCard { return { + id: item.productId, name: item.productName, - description: item.description, slug: item.slug, - path: item.slug, - images: imageUrl ? [{ url: imageUrl }] : [], - price: { - // TODO: check price - value: (item.priceWithTax as any).min / 100, - currencyCode: item.currencyCode, - }, - // TODO: check product option - options: [], - sku: item.sku, + imageSrc: item.productAsset?.preview ? item.productAsset?.preview + '?w=800&mode=crop' : '', + price: (item.priceWithTax as any).min / 100, + currencyCode: item.currencyCode, + + // TODO: + // oldPrice: item.price + // discount + // isNotSell + // weight + // category } } diff --git a/pages/index.tsx b/pages/index.tsx index 3082d1790..55988ada1 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -3,7 +3,7 @@ import { Product } from '@framework/schema'; import commerce from '@lib/api/commerce'; import { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; -import { FeaturedProductsCarousel, 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 { getAllFeaturedFacetId, getFreshProductFacetId } from 'src/utils/funtion.utils'; @@ -13,13 +13,12 @@ interface Props { } export default function Home({ freshProducts, featuredProducts }: Props) { - console.log("total: ", freshProducts.length, featuredProducts.length) - console.log("rs: ", freshProducts, featuredProducts) return ( <> + diff --git a/public/assets/images/default_img.jpg b/public/assets/images/default_img.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f72d03596acd9adc6738829610afb1b1001cb2bf GIT binary patch literal 4357 zcmex=ggl;wax*+5%QU0q#I+tk#+z|_>i!5-O|{|6WZIT$}Ow=gp* zF)#@-G7B>PKf)jhbUFwC-3kLN%uI}IKq+kjppTeXSlF21@{CN(g2IM@EJlfiLL!Qe zL5)hr6P*@r1S%FmF#>E9NK_EnV2J1~1|DWcpaYl%8SEK;FM!!PN{@!XXb2DpflAY0 zsWT3?GQO`1-*?Y^r1`CLLYDeGrS%yd#pZeb`#*?sJWDH`6ME#apmp;F0%j2_&3NXz zOLmCm>@RMgc-f4P}`+#0+m#|oGOs^7qq+Z zEI(#`jpSbT&9T92PEQZa+j(hbxtR9cf`%0HKKZKseT$9?UJOK znpL=+Go;}2k2ARnSBP~RK6Pxtb;_3%kKA8uDGS5JQX*W9?K;A{06=M@iMexErZL95&B@ol+xi)JNzbg*pn4PN52tJ_@tHs33U zL>Zgkr&nxr-*aXwiJNiTyH9#0#r`JctqHT0o;xc&cl$Y| zW?tIupALp6c3wEK^WwJL{Zk~j{R`kJ(kn62E6JUm|C9|V#4OW2m#2HKG*G1@P>A6; zMDtCcN|H1?ugY4sR$ah1bk)k9ba$@&fBUx_xZi%MdRy}0m$tVl4F(2|X9hESr>X9i zh?$`4C$9WsrHr4j@TLPoG0#`;+5(DCR-23WM3*d|WqoLayVag*t38a@+twD$u{PhD zr`a*{+58_D1iA8VcP+~5%lOZ*vH{|t+{3Sf#qQW`W#0XtVf|a9*&x!u{Na~*Z)be? zJrfXJ48OaSA!;62{rY`) zci11pp3n7<9o!8KE&Mio^u1kYam;d|g$=E}#oT?dcjwDjZ=VMC8cQEg&OdzKq;^AQ zQo(xO2O>*$o)0h0)GNMvhpTe&9&Jx>itH<`_*Pm04o!`%+5D&0)-F6dJO0)B6?qH{ zMtk$+PtC1;xPoJL!LKWE+uNV|&HDgk@x2Eop;OdOM+{6}i@BCrO?%Gua^AZ2ZsO{z z8zMki=&B2_4p<6wdx7S&z7K0vL8+<9^6KN8S06BY>4wIyo4C6w_p(o-;2j~})f?Zt zf1GmU_>$&h+tya>*V^)}_g>WYM|0Ar*}s|q@+9L?u|J|d$0ogDEC0_Be=F4-L?+~e zGJ+u}aW#NLf)awUT~KbLPDp(JA@xi@uC;z<4{gs??cTQ0zUA1ZV?gg50A++NQ$Pue zKkDa~Y#oK=_BT%|Z4A3xz0wqS=ATKM>#-E$;Y;YRW^ zRZa(GVC8At3+%CIG6LDQN%z literal 0 HcmV?d00001 diff --git a/src/components/common/ImgWithLink/ImgWithLink.tsx b/src/components/common/ImgWithLink/ImgWithLink.tsx index 4f61946e0..a31a14832 100644 --- a/src/components/common/ImgWithLink/ImgWithLink.tsx +++ b/src/components/common/ImgWithLink/ImgWithLink.tsx @@ -1,7 +1,7 @@ import React from 'react' import s from './ImgWithLink.module.scss' import Image from 'next/image' -import { BLUR_DATA_IMG } from 'src/utils/constanst.utils' +import { BLUR_DATA_IMG, DEFAULT_IMG } from 'src/utils/constanst.utils' export interface ImgWithLinkProps { src: string, @@ -12,7 +12,7 @@ export interface ImgWithLinkProps { const ImgWithLink = ({ src, alt, blurDataURL = BLUR_DATA_IMG }: ImgWithLinkProps) => { return (
- {alt}
- -
- -
+ + +
+ +
+
+ { + category &&
{category}
+ }
- -
{name}
+ + +
{name}
+
{weight}
-
{price}
+
{price} {currencyCode}
@@ -80,4 +89,4 @@ const ProductCard = ({ ) } -export default ProductCard +export default ProductCardComponent diff --git a/src/components/modules/home/FreshProducts/FreshProducts.tsx b/src/components/modules/home/FreshProducts/FreshProducts.tsx index b06138079..586a572dd 100644 --- a/src/components/modules/home/FreshProducts/FreshProducts.tsx +++ b/src/components/modules/home/FreshProducts/FreshProducts.tsx @@ -1,99 +1,9 @@ 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 ( @@ -106,41 +16,6 @@ const FreshProducts = ({data}: FreshProductsProps) => { subtitle="Last call! Shop deep deals on 100+ bulk picks while you can." category={"veggie"} /> - - - - -
) } diff --git a/src/utils/constanst.utils.ts b/src/utils/constanst.utils.ts index f66d6a7ea..e6ae9fabc 100644 --- a/src/utils/constanst.utils.ts +++ b/src/utils/constanst.utils.ts @@ -1,4 +1,7 @@ +import DefaultImg from '../../public/assets/images/default_img.jpg' + export const BLUR_DATA_IMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mN8fBIAApUBruKYvzsAAAAASUVORK5CYII=' +export const DEFAULT_IMG = DefaultImg export const SOCIAL_LINKS = { FB: 'FB', From 6ad8f75c67b34cc900a11436cb2225e8fcc7f620 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 4 Oct 2021 16:41:23 +0700 Subject: [PATCH 07/11] :recycle: enhan: not show fresh product item when empty :%s --- pages/index.tsx | 8 ++++---- .../modules/home/FreshProducts/FreshProducts.tsx | 8 ++++++-- .../modules/home/HomeCollection/HomeCollection.tsx | 8 -------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 55988ada1..d06f29013 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,5 +1,5 @@ +import { ProductCard } from '@commerce/types/product'; import { ProductVariables } from '@framework/api/operations/get-all-products'; -import { Product } from '@framework/schema'; import commerce from '@lib/api/commerce'; import { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; @@ -8,8 +8,8 @@ import HomeSpice from 'src/components/modules/home/HomeSpice/HomeSpice'; import { getAllFeaturedFacetId, getFreshProductFacetId } from 'src/utils/funtion.utils'; interface Props { - freshProducts: Product[], - featuredProducts: Product[], + freshProducts: ProductCard[], + featuredProducts: ProductCard[], } export default function Home({ freshProducts, featuredProducts }: Props) { @@ -74,7 +74,7 @@ export async function getStaticProps({ return { props: { - freshProducts: rs[0].products, + freshProducts: freshFacetId ? rs[0].products : [], featuredProducts: rs[1].products }, revalidate: 60, diff --git a/src/components/modules/home/FreshProducts/FreshProducts.tsx b/src/components/modules/home/FreshProducts/FreshProducts.tsx index 586a572dd..33b872032 100644 --- a/src/components/modules/home/FreshProducts/FreshProducts.tsx +++ b/src/components/modules/home/FreshProducts/FreshProducts.tsx @@ -1,11 +1,15 @@ +import { ProductCard } from '@commerce/types/product' import { Product } from '@framework/schema' import React from 'react' import { CollectionCarcousel } from '..' interface FreshProductsProps { - data: Product[] + data: ProductCard[] } -const FreshProducts = ({data}: FreshProductsProps) => { +const FreshProducts = ({ data }: FreshProductsProps) => { + if (data.length === 0) { + return null + } return (
{ return (
- Date: Mon, 4 Oct 2021 19:36:47 +0700 Subject: [PATCH 08/11] :sparkles: feat: featured products :%s --- framework/commerce/types/product.ts | 6 +- framework/vendure/schema.d.ts | 3 +- .../utils/fragments/search-result-fragment.ts | 4 +- framework/vendure/utils/normalize.ts | 5 +- pages/index.tsx | 16 +- .../FeaturedProductCard.tsx | 44 ++-- .../FeaturedProductsCarousel.tsx | 28 +-- src/utils/constanst.utils.ts | 206 +++++++++--------- src/utils/funtion.utils.ts | 21 +- 9 files changed, 174 insertions(+), 159 deletions(-) diff --git a/framework/commerce/types/product.ts b/framework/commerce/types/product.ts index 39f594a7a..ac7025158 100644 --- a/framework/commerce/types/product.ts +++ b/framework/commerce/types/product.ts @@ -1,4 +1,4 @@ -import { CurrencyCode } from './../../vendure/schema.d'; +import { CurrencyCode, FacetValue } from './../../vendure/schema.d'; import { FacetValueFilterInput, LogicalOperator, SearchResultSortParameter } from "@framework/schema" export type ProductImage = { @@ -54,9 +54,11 @@ export type ProductCard = { imageSrc: string price: number currencyCode: CurrencyCode - oldPrice?: number, + oldPrice?: number discount?: number weight?: number + facetValueIds?: string[], + collectionIds?: string[], // TODO: collection category?: string, isNotSell?: boolean diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index a817d6799..c5c3e8e89 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -1,3 +1,4 @@ +import { FacetValue } from './schema.d'; export type Maybe = T | null export type Exact = { [K in keyof T]: T[K] @@ -3038,7 +3039,7 @@ export type SearchResultFragment = { __typename?: 'SearchResult' } & Pick< SearchResult, 'productId' | 'sku' | 'productName' | 'description' | 'slug' | 'sku' | 'currencyCode' | 'productAsset' | 'price' | 'priceWithTax' | 'currencyCode' - | 'collectionIds' + | 'collectionIds' | 'facetValueIds' | 'collectionIds' > & { productAsset?: Maybe< { __typename?: 'SearchResultAsset' } & Pick< diff --git a/framework/vendure/utils/fragments/search-result-fragment.ts b/framework/vendure/utils/fragments/search-result-fragment.ts index 6155b5b47..d2d82f42e 100644 --- a/framework/vendure/utils/fragments/search-result-fragment.ts +++ b/framework/vendure/utils/fragments/search-result-fragment.ts @@ -19,6 +19,8 @@ export const searchResultFragment = /* GraphQL */ ` min max } - } + }, + facetValueIds, + collectionIds, } ` diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index a5cb96c8a..a790aa8cd 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -1,16 +1,17 @@ -import { Product, ProductCard } from '@commerce/types/product' import { Cart } from '@commerce/types/cart' +import { ProductCard } from '@commerce/types/product' import { CartFragment, SearchResultFragment } from '../schema' export function normalizeSearchResult(item: SearchResultFragment): ProductCard { return { - id: item.productId, name: item.productName, slug: item.slug, imageSrc: item.productAsset?.preview ? item.productAsset?.preview + '?w=800&mode=crop' : '', price: (item.priceWithTax as any).min / 100, currencyCode: item.currencyCode, + facetValueIds: item.facetValueIds, + collectionIds: item.collectionIds, // TODO: // oldPrice: item.price diff --git a/pages/index.tsx b/pages/index.tsx index d06f29013..97052fd1a 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -5,7 +5,7 @@ import { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; 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 { getAllFeaturedFacetId, getFreshProductFacetId } from 'src/utils/funtion.utils'; +import { getAllFeaturedFacetId, getFreshFacetId } from 'src/utils/funtion.utils'; interface Props { freshProducts: ProductCard[], @@ -18,11 +18,11 @@ export default function Home({ freshProducts, featuredProducts }: Props) { - + - + @@ -48,7 +48,7 @@ export async function getStaticProps({ const freshProductvariables: ProductVariables = {} - const freshFacetId = getFreshProductFacetId(facets) + const freshFacetId = getFreshFacetId(facets) if (freshFacetId) { freshProductvariables.facetValueIds = [freshFacetId] @@ -60,6 +60,7 @@ export async function getStaticProps({ }) const allFeaturedFacetId = getAllFeaturedFacetId(facets) + console.log("featured** ", allFeaturedFacetId) const featuredProductsPromise = commerce.getAllProducts({ variables: { facetValueIds: allFeaturedFacetId @@ -68,12 +69,15 @@ export async function getStaticProps({ preview, }) - try { - const rs = await Promise.all([freshProductsPromise, featuredProductsPromise]) + const rs = await Promise.all([ + freshProductsPromise, + featuredProductsPromise, + ]) return { props: { + facets, freshProducts: freshFacetId ? rs[0].products : [], featuredProducts: rs[1].products }, diff --git a/src/components/common/FeaturedProductCard/FeaturedProductCard.tsx b/src/components/common/FeaturedProductCard/FeaturedProductCard.tsx index a82b6857b..4a492b6c1 100644 --- a/src/components/common/FeaturedProductCard/FeaturedProductCard.tsx +++ b/src/components/common/FeaturedProductCard/FeaturedProductCard.tsx @@ -1,39 +1,53 @@ +import { ProductCard } from '@commerce/types/product' +import Link from 'next/link' import React from 'react' -import { FeaturedProductProps } from 'src/utils/types.utils' -import s from './FeaturedProductCard.module.scss' -import { LANGUAGE } from '../../../utils/language.utils' -import ButtonIconBuy from '../ButtonIconBuy/ButtonIconBuy' -import ButtonCommon from '../ButtonCommon/ButtonCommon' +import { ROUTE } from 'src/utils/constanst.utils' import { ImgWithLink } from '..' -export interface FeaturedProductCardProps extends FeaturedProductProps { +import { LANGUAGE } from '../../../utils/language.utils' +import ButtonCommon from '../ButtonCommon/ButtonCommon' +import ButtonIconBuy from '../ButtonIconBuy/ButtonIconBuy' +import s from './FeaturedProductCard.module.scss' +export interface FeaturedProductCardProps extends ProductCard { buttonText?: string + featuredFacetId?: string, } const FeaturedProductCard = ({ imageSrc, - title, - subTitle, + name, + slug, price, - originPrice, + currencyCode, buttonText = LANGUAGE.BUTTON_LABEL.BUY_NOW, }: FeaturedProductCardProps) => { return (
- + + + + +
-
{title}
-
{subTitle}
+ + +
{name}
+
+ + + {/* TODO: */} + {/*
{subTitle}
*/}
-
{price}
-
{originPrice}
+
{price} {currencyCode}
+ {/* TODO: */} + {/*
{originPrice}
*/}
- +
{buttonText} diff --git a/src/components/modules/home/FeaturedProductsCarousel/FeaturedProductsCarousel.tsx b/src/components/modules/home/FeaturedProductsCarousel/FeaturedProductsCarousel.tsx index 452427616..b06c0214f 100644 --- a/src/components/modules/home/FeaturedProductsCarousel/FeaturedProductsCarousel.tsx +++ b/src/components/modules/home/FeaturedProductsCarousel/FeaturedProductsCarousel.tsx @@ -1,31 +1,15 @@ +import { ProductCard } from '@commerce/types/product' import React from 'react' import { ResponsiveType } from 'react-multi-carousel' import { CarouselCommon, FeaturedProductCard,HeadingCommon} from 'src/components/common' import { FeaturedProductCardProps } from 'src/components/common/FeaturedProductCard/FeaturedProductCard' import s from "./FeaturedProductsCarousel.module.scss" interface FeaturedProductsCarouselProps { - title?: string + title?: string, + data: ProductCard[] } -const dataDemo:FeaturedProductCardProps[] = [{ - title: "Sale 25% Coffee Bean", - subTitle: "50 first Orders within a day", - originPrice: "$20.00", - price: "$14.00", - imageSrc: "https://user-images.githubusercontent.com/76099413/133043628-db7813f9-1bb7-4ee1-b028-dc4295563494.png" -},{ - title: "Sale 20% Fruits", - subTitle: "50 first Orders within a day", - originPrice: "$20.00", - price: "$14.00", - imageSrc: "https://user-images.githubusercontent.com/76099413/133043630-07a353b9-573d-4c1d-b1de-2c932e3f14f7.png" -},{ - title: "Sale 25% Coffee Bean", - subTitle: "50 first Orders within a day", - originPrice: "$20.00", - price: "$14.00", - imageSrc: "https://user-images.githubusercontent.com/76099413/133043633-954c105b-c703-4e5c-8f5f-7943ad633ff0.png" -}] + const RESPONSIVE: ResponsiveType = { hugeScreen: { breakpoint: { max: 9999, min: 1500 }, @@ -78,13 +62,13 @@ const dataDemo:FeaturedProductCardProps[] = [{ }, } -const FeaturedProductsCarousel = ({title="Featured Products"}: FeaturedProductsCarouselProps) => { +const FeaturedProductsCarousel = ({title="Featured Products", data}: FeaturedProductsCarouselProps) => { return (
{title}
- data={dataDemo} Component={FeaturedProductCard} itemKey="featured-products" responsive={RESPONSIVE}/> + data={data} Component={FeaturedProductCard} itemKey="featured-products" responsive={RESPONSIVE}/>
) } diff --git a/src/utils/constanst.utils.ts b/src/utils/constanst.utils.ts index e6ae9fabc..bc4c00287 100644 --- a/src/utils/constanst.utils.ts +++ b/src/utils/constanst.utils.ts @@ -4,41 +4,41 @@ export const BLUR_DATA_IMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEA export const DEFAULT_IMG = DefaultImg export const SOCIAL_LINKS = { - FB: 'FB', - TWITTER: 'TWITTER', - YOUTUBE: 'YOUTUBE', - IG: 'IG', + FB: 'FB', + TWITTER: 'TWITTER', + YOUTUBE: 'YOUTUBE', + IG: 'IG', } export const ROUTE = { - HOME: '/', - ABOUT: '/about', - ACCOUNT: '/account', + HOME: '/', + ABOUT: '/about', + ACCOUNT: '/account', - PRODUCTS: '/products', - PRODUCT_DETAIL: '/product', - - BLOGS: '/blogs', - BLOG_DETAIL: '/blog', + PRODUCTS: '/products', + PRODUCT_DETAIL: '/product', - RECIPES: '/recipes', - RECIPE_DETAIL: '/recipe', + BLOGS: '/blogs', + BLOG_DETAIL: '/blog', - NOTIFICATION: '/notifications', - BUSSINESS: '/bussiness', - CONTACT: '/contact', - CHECKOUT: '/checkout', - FAQ: '/faq', - CUSTOMER_SERVICE: '/customer-service', - TERM_CONDITION: '/term-condition', - PRIVACY_POLICY: '/privacy-policy', - FORGOT_PASSWORD: '/forgot-password' + RECIPES: '/recipes', + RECIPE_DETAIL: '/recipe', + + NOTIFICATION: '/notifications', + BUSSINESS: '/bussiness', + CONTACT: '/contact', + CHECKOUT: '/checkout', + FAQ: '/faq', + CUSTOMER_SERVICE: '/customer-service', + TERM_CONDITION: '/term-condition', + PRIVACY_POLICY: '/privacy-policy', + FORGOT_PASSWORD: '/forgot-password' } export const ACCOUNT_TAB = { - CUSTOMER_INFO: '', - ORDER: 'orders', - FAVOURITE: 'wishlist', + CUSTOMER_INFO: '', + ORDER: 'orders', + FAVOURITE: 'wishlist', } export const LOCAL_STORAGE_KEY = { @@ -46,101 +46,99 @@ export const LOCAL_STORAGE_KEY = { } export const QUERY_KEY = { - TAB: 'tab', - CATEGORY: 'category', - BRAND: 'brand', - FEATURED: 'feature', - SORTBY:'sortby', - RECIPES:'recipes' + TAB: 'tab', + CATEGORY: 'category', + BRAND: 'brand', + FEATURED: 'feature', + SORTBY: 'sortby', + RECIPES: 'recipes' } export enum ProductFeature { - BestSellers = 'Best Sellers', - Sales = 'Sales', - NewItem = 'New Item', - Viewed = 'Viewed', + BestSellers = 'Best Sellers', + Sales = 'Sales', + NewItem = 'New Item', + Viewed = 'Viewed', } export const KEY = { - ENTER: 'Enter', + ENTER: 'Enter', } export const OPTION_ALL = 'all'; -export const DEFAULT_PAGE_SIZE=20; +export const DEFAULT_PAGE_SIZE = 20; export const CATEGORY = [ - { - name: 'All', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=${OPTION_ALL}`, - }, - { - name: 'Veggie', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=veggie`, - }, - { - name: 'Seafood', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=seafood`, - }, - { - name: 'Frozen', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=frozen`, - }, - { - name: 'Coffee Bean', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=coffee_bean`, - }, - { - name: 'Sauce', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=sauce`, - }, - ] - - export const BRAND = [ - { - name: 'Maggi', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=maggi`, - }, - { - name: 'Chomilex', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chomilex`, - }, - { - name: 'Chinsu', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chinsu`, - }, - ] + { + name: 'All', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=${OPTION_ALL}`, + }, + { + name: 'Veggie', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=veggie`, + }, + { + name: 'Seafood', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=seafood`, + }, + { + name: 'Frozen', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=frozen`, + }, + { + name: 'Coffee Bean', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=coffee_bean`, + }, + { + name: 'Sauce', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.CATEGORY}=sauce`, + }, +] -export const FACET = { - FEATURE: { - PARENT_NAME: 'Featured', - FRESH: 'Fresh', - BEST_SELLERS: 'Best seller' - } +export const BRAND = [ + { + name: 'Maggi', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=maggi`, + }, + { + name: 'Chomilex', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chomilex`, + }, + { + name: 'Chinsu', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=chinsu`, + }, +] + +export const CODE_FACET_FEATURED = 'featured' +export const CODE_FACET_FEATURED_VARIANT = { + FRESH: 'fresh', + BEST_SELLERS: 'best-sellers' } export const FEATURED = [ - { - name: 'Best Sellers', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=best_sellers`, - }, - { - name: 'Sales', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=sales`, - }, - { - name: 'New Item', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=new_item`, - }, - { - name: 'Viewed', - link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=viewed`, - }, - ] - -export const DEFAULT_BLOG_PAGE_SIZE=6; + { + name: 'Best Sellers', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=best_sellers`, + }, + { + name: 'Sales', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=sales`, + }, + { + name: 'New Item', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=new_item`, + }, + { + name: 'Viewed', + link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.FEATURED}=viewed`, + }, +] -export const FILTER_PAGE = [ROUTE.HOME,ROUTE.PRODUCTS] +export const DEFAULT_BLOG_PAGE_SIZE = 6; + +export const FILTER_PAGE = [ROUTE.HOME, ROUTE.PRODUCTS] export const STATE_OPTIONS = [ { diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts index d2ad83be1..e8dc6f2d5 100644 --- a/src/utils/funtion.utils.ts +++ b/src/utils/funtion.utils.ts @@ -1,6 +1,6 @@ -import { FacetValue } from './../../framework/vendure/schema.d'; import { Facet } from "@commerce/types/facet"; -import { FACET } from "./constanst.utils"; +import { FacetValue } from './../../framework/vendure/schema.d'; +import { CODE_FACET_FEATURED, CODE_FACET_FEATURED_VARIANT } from "./constanst.utils"; export function isMobile() { return window.innerWidth < 768 @@ -14,15 +14,24 @@ export function removeItem(arr: Array, value: T): Array { 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) +function findFacetByCode(code: string, facets?: Facet) { + return facets?.values.find((item: FacetValue) => item.code === code) +} + +export function getFeaturedFacetId(facets: Facet[]) { + const featuredFacet = facets.find((item: Facet) => item.code === CODE_FACET_FEATURED) + return featuredFacet?.id +} + +export function getFreshFacetId(facets: Facet[]) { + const featuredFacet = facets.find((item: Facet) => item.code === CODE_FACET_FEATURED) + const freshFacetValue = findFacetByCode(CODE_FACET_FEATURED_VARIANT.FRESH, featuredFacet) return freshFacetValue?.id } export function getAllFeaturedFacetId(facets: Facet[]) { - const featuredFacet = facets.find((item: Facet) => item.name === FACET.FEATURE.PARENT_NAME) + const featuredFacet = facets.find((item: Facet) => item.code === CODE_FACET_FEATURED) const rs = featuredFacet?.values.map((item: FacetValue) => item.id) return rs From 8898882a72952a435f443c9b4af9d4ae41919152 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 4 Oct 2021 20:41:38 +0700 Subject: [PATCH 09/11] :sparkles: feat: featured product sub text :%s --- pages/index.tsx | 13 +- .../FeaturedProductCard.module.scss | 3 + .../FeaturedProductCard.tsx | 12 +- .../FeaturedProductsCarousel.tsx | 145 ++++++++++-------- src/utils/funtion.utils.ts | 15 ++ 5 files changed, 112 insertions(+), 76 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 97052fd1a..0c1aae948 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,18 +1,21 @@ import { ProductCard } from '@commerce/types/product'; import { ProductVariables } from '@framework/api/operations/get-all-products'; +import { FacetValue } from '@framework/schema'; import commerce from '@lib/api/commerce'; import { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; 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 { getAllFeaturedFacetId, getFreshFacetId } from 'src/utils/funtion.utils'; +import { getAllFeaturedFacetId, getAllFeaturedFacetValue, getFreshFacetId } from 'src/utils/funtion.utils'; interface Props { + featuredFacetsValue: FacetValue[], freshProducts: ProductCard[], featuredProducts: ProductCard[], } -export default function Home({ freshProducts, featuredProducts }: Props) { +export default function Home({ featuredFacetsValue, + freshProducts, featuredProducts }: Props) { return ( <> @@ -22,7 +25,7 @@ export default function Home({ freshProducts, featuredProducts }: Props) { - + @@ -45,7 +48,7 @@ export async function getStaticProps({ config, preview, }) - + const featuredFacetsValue = getAllFeaturedFacetValue(facets) const freshProductvariables: ProductVariables = {} const freshFacetId = getFreshFacetId(facets) @@ -60,7 +63,6 @@ export async function getStaticProps({ }) const allFeaturedFacetId = getAllFeaturedFacetId(facets) - console.log("featured** ", allFeaturedFacetId) const featuredProductsPromise = commerce.getAllProducts({ variables: { facetValueIds: allFeaturedFacetId @@ -78,6 +80,7 @@ export async function getStaticProps({ return { props: { facets, + featuredFacetsValue, freshProducts: freshFacetId ? rs[0].products : [], featuredProducts: rs[1].products }, diff --git a/src/components/common/FeaturedProductCard/FeaturedProductCard.module.scss b/src/components/common/FeaturedProductCard/FeaturedProductCard.module.scss index 036e84629..3f95f92da 100644 --- a/src/components/common/FeaturedProductCard/FeaturedProductCard.module.scss +++ b/src/components/common/FeaturedProductCard/FeaturedProductCard.module.scss @@ -21,6 +21,9 @@ width: 24rem; height: 24rem; } + img { + object-fit: contain; + } } .right{ margin-left: 1.2rem; diff --git a/src/components/common/FeaturedProductCard/FeaturedProductCard.tsx b/src/components/common/FeaturedProductCard/FeaturedProductCard.tsx index 4a492b6c1..23b9ac987 100644 --- a/src/components/common/FeaturedProductCard/FeaturedProductCard.tsx +++ b/src/components/common/FeaturedProductCard/FeaturedProductCard.tsx @@ -1,4 +1,5 @@ import { ProductCard } from '@commerce/types/product' +import { Facet, FacetValue } from '@framework/schema' import Link from 'next/link' import React from 'react' import { ROUTE } from 'src/utils/constanst.utils' @@ -8,8 +9,8 @@ import ButtonCommon from '../ButtonCommon/ButtonCommon' import ButtonIconBuy from '../ButtonIconBuy/ButtonIconBuy' import s from './FeaturedProductCard.module.scss' export interface FeaturedProductCardProps extends ProductCard { - buttonText?: string - featuredFacetId?: string, + buttonText?: string, + subText?: string, } const FeaturedProductCard = ({ @@ -17,9 +18,12 @@ const FeaturedProductCard = ({ name, slug, price, + subText, currencyCode, buttonText = LANGUAGE.BUTTON_LABEL.BUY_NOW, }: FeaturedProductCardProps) => { + + return (
@@ -36,9 +40,7 @@ const FeaturedProductCard = ({
{name}
- - {/* TODO: */} - {/*
{subTitle}
*/} +
{subText}
{price} {currencyCode}
{/* TODO: */} diff --git a/src/components/modules/home/FeaturedProductsCarousel/FeaturedProductsCarousel.tsx b/src/components/modules/home/FeaturedProductsCarousel/FeaturedProductsCarousel.tsx index b06c0214f..66865194b 100644 --- a/src/components/modules/home/FeaturedProductsCarousel/FeaturedProductsCarousel.tsx +++ b/src/components/modules/home/FeaturedProductsCarousel/FeaturedProductsCarousel.tsx @@ -1,76 +1,89 @@ -import { ProductCard } from '@commerce/types/product' -import React from 'react' +import { FacetValue } from '@framework/schema' +import React, { useMemo } from 'react' import { ResponsiveType } from 'react-multi-carousel' -import { CarouselCommon, FeaturedProductCard,HeadingCommon} from 'src/components/common' +import { CarouselCommon, FeaturedProductCard, HeadingCommon } from 'src/components/common' import { FeaturedProductCardProps } from 'src/components/common/FeaturedProductCard/FeaturedProductCard' +import { getFacetNamesFromIds } from 'src/utils/funtion.utils' import s from "./FeaturedProductsCarousel.module.scss" interface FeaturedProductsCarouselProps { - title?: string, - data: ProductCard[] + data: FeaturedProductCardProps[] + featuredFacetsValue: FacetValue[], } +const RESPONSIVE: ResponsiveType = { + hugeScreen: { + breakpoint: { max: 9999, min: 1500 }, + items: 2.25, + slidesToSlide: 1, // optional, default to 1. + }, + largeScreen: { + breakpoint: { max: 1500, min: 1440 }, + items: 2.075, + slidesToSlide: 1, // optional, default to 1. + }, + largeDesktop: { + breakpoint: { max: 1440, min: 1280 }, + items: 1.75, + slidesToSlide: 1, // optional, default to 1. + }, + desktop: { + breakpoint: { max: 1280, min: 1148 }, + items: 1.5, + slidesToSlide: 1, // optional, default to 1. + }, + smallDesktop: { + breakpoint: { max: 1148, min: 1024 }, + items: 1.375, + slidesToSlide: 1, // optional, default to 1. + }, + lap: { + breakpoint: { max: 1024, min: 968 }, + items: 1.7, + }, + tablet: { + breakpoint: { max: 968, min: 768 }, + items: 1.075, + }, + smallTablet: { + breakpoint: { max: 768, min: 640 }, + items: 1.25, + }, + largeMobile: { + breakpoint: { max: 640, min: 400 }, + items: 1.275, + }, + mobile: { + breakpoint: { max: 400, min: 300 }, + items: 1.1, + }, + smallMobile: { + breakpoint: { max: 300, min: 0 }, + items: 1, + }, +} - const RESPONSIVE: ResponsiveType = { - hugeScreen: { - breakpoint: { max: 9999, min: 1500 }, - items: 2.25, - slidesToSlide: 1, // optional, default to 1. - }, - largeScreen: { - breakpoint: { max: 1500, min: 1440 }, - items: 2.075, - slidesToSlide: 1, // optional, default to 1. - }, - largeDesktop: { - breakpoint: { max: 1440, min: 1280 }, - items: 1.75, - slidesToSlide: 1, // optional, default to 1. - }, - desktop: { - breakpoint: { max: 1280, min: 1148 }, - items: 1.5, - slidesToSlide: 1, // optional, default to 1. - }, - smallDesktop: { - breakpoint: { max: 1148, min: 1024 }, - items: 1.375, - slidesToSlide: 1, // optional, default to 1. - }, - lap: { - breakpoint: { max: 1024, min: 968 }, - items: 1.7, - }, - tablet: { - breakpoint: { max: 968, min: 768 }, - items: 1.075, - }, - smallTablet: { - breakpoint: { max: 768, min: 640 }, - items: 1.25, - }, - largeMobile: { - breakpoint: { max: 640, min: 400 }, - items: 1.275, - }, - mobile: { - breakpoint: { max: 400, min: 300 }, - items: 1.1, - }, - smallMobile: { - breakpoint: { max: 300, min: 0 }, - items: 1, - }, - } - -const FeaturedProductsCarousel = ({title="Featured Products", data}: FeaturedProductsCarouselProps) => { - return ( -
-
- {title} -
- data={data} Component={FeaturedProductCard} itemKey="featured-products" responsive={RESPONSIVE}/> -
- ) +const FeaturedProductsCarousel = ({ data, featuredFacetsValue }: FeaturedProductsCarouselProps) => { + const featuredProducts = useMemo(() => { + return data.map(item => { + return { + ...item, + subText: getFacetNamesFromIds(featuredFacetsValue, item.facetValueIds) + } + }) + }, [data, featuredFacetsValue]) + return ( +
+
+ Featured Products +
+ + data={featuredProducts} + defaultComponentProps={featuredFacetsValue} + Component={FeaturedProductCard} + itemKey="featured-products" + responsive={RESPONSIVE} /> +
+ ) } export default FeaturedProductsCarousel diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts index e8dc6f2d5..e16a250b7 100644 --- a/src/utils/funtion.utils.ts +++ b/src/utils/funtion.utils.ts @@ -35,4 +35,19 @@ export function getAllFeaturedFacetId(facets: Facet[]) { const rs = featuredFacet?.values.map((item: FacetValue) => item.id) return rs +} + +export function getAllFeaturedFacetValue(facets: Facet[]) { + const featuredFacet = facets.find((item: Facet) => item.code === CODE_FACET_FEATURED) + return featuredFacet?.values +} + +export function getFacetNamesFromIds(facets: FacetValue[], ids?: string[]): string { + if (!ids || ids?.length === 0) { + return '' + } + + const facetItems = facets.filter((item: FacetValue) => ids.includes(item.id)) + const names = facetItems.map((item: FacetValue) => item.name) + return names.join(", ") } \ No newline at end of file From c6dc27ab59c43d646e0ee2502082e41838d4de07 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Mon, 4 Oct 2021 21:12:47 +0700 Subject: [PATCH 10/11] :sparkles: feat: get featured product base on facet Featured and Discount :%s --- pages/index.tsx | 27 ++++++++++++++++----------- src/utils/constanst.utils.ts | 2 +- src/utils/funtion.utils.ts | 19 ++++++++++++------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 0c1aae948..589c7ae30 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -6,15 +6,16 @@ import { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; 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 { getAllFeaturedFacetId, getAllFeaturedFacetValue, getFreshFacetId } from 'src/utils/funtion.utils'; +import { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED } from 'src/utils/constanst.utils'; +import { getAllFacetValueIdsByParentCode, getAllFacetValuesForFeatuedProducts, getFreshFacetId } from 'src/utils/funtion.utils'; interface Props { - featuredFacetsValue: FacetValue[], + featuredAndDiscountFacetsValue: FacetValue[], freshProducts: ProductCard[], featuredProducts: ProductCard[], } -export default function Home({ featuredFacetsValue, +export default function Home({ featuredAndDiscountFacetsValue, freshProducts, featuredProducts }: Props) { return ( <> @@ -25,7 +26,7 @@ export default function Home({ featuredFacetsValue, - + @@ -48,11 +49,12 @@ export async function getStaticProps({ config, preview, }) - const featuredFacetsValue = getAllFeaturedFacetValue(facets) + const featuredAndDiscountFacetsValue = getAllFacetValuesForFeatuedProducts(facets) + + // fresh products const freshProductvariables: ProductVariables = {} const freshFacetId = getFreshFacetId(facets) - if (freshFacetId) { freshProductvariables.facetValueIds = [freshFacetId] } @@ -62,15 +64,19 @@ export async function getStaticProps({ preview, }) - const allFeaturedFacetId = getAllFeaturedFacetId(facets) + // featured products + const allFeaturedFacetIds = getAllFacetValueIdsByParentCode(facets, CODE_FACET_FEATURED) + const allDiscountFacetIds = getAllFacetValueIdsByParentCode(facets, CODE_FACET_DISCOUNT) + const facetValueIdsForFeaturedProducts = [...allFeaturedFacetIds, ...allDiscountFacetIds] const featuredProductsPromise = commerce.getAllProducts({ variables: { - facetValueIds: allFeaturedFacetId + facetValueIds: facetValueIdsForFeaturedProducts }, config, preview, }) + try { const rs = await Promise.all([ freshProductsPromise, @@ -79,10 +85,9 @@ export async function getStaticProps({ return { props: { - facets, - featuredFacetsValue, + featuredAndDiscountFacetsValue, freshProducts: freshFacetId ? rs[0].products : [], - featuredProducts: rs[1].products + featuredProducts: facetValueIdsForFeaturedProducts.length > 0 ? rs[1].products : [] }, revalidate: 60, } diff --git a/src/utils/constanst.utils.ts b/src/utils/constanst.utils.ts index bc4c00287..1db198178 100644 --- a/src/utils/constanst.utils.ts +++ b/src/utils/constanst.utils.ts @@ -112,9 +112,9 @@ export const BRAND = [ ] export const CODE_FACET_FEATURED = 'featured' +export const CODE_FACET_DISCOUNT = 'discount' export const CODE_FACET_FEATURED_VARIANT = { FRESH: 'fresh', - BEST_SELLERS: 'best-sellers' } export const FEATURED = [ diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts index e16a250b7..d486ca4d0 100644 --- a/src/utils/funtion.utils.ts +++ b/src/utils/funtion.utils.ts @@ -1,6 +1,6 @@ import { Facet } from "@commerce/types/facet"; import { FacetValue } from './../../framework/vendure/schema.d'; -import { CODE_FACET_FEATURED, CODE_FACET_FEATURED_VARIANT } from "./constanst.utils"; +import { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED, CODE_FACET_FEATURED_VARIANT } from "./constanst.utils"; export function isMobile() { return window.innerWidth < 768 @@ -30,16 +30,21 @@ export function getFreshFacetId(facets: Facet[]) { return freshFacetValue?.id } -export function getAllFeaturedFacetId(facets: Facet[]) { - const featuredFacet = facets.find((item: Facet) => item.code === CODE_FACET_FEATURED) +export function getAllFacetValueIdsByParentCode(facets: Facet[], code: string) { + const featuredFacet = facets.find((item: Facet) => item.code === code) const rs = featuredFacet?.values.map((item: FacetValue) => item.id) - return rs + return rs || [] } -export function getAllFeaturedFacetValue(facets: Facet[]) { - const featuredFacet = facets.find((item: Facet) => item.code === CODE_FACET_FEATURED) - return featuredFacet?.values +export function getAllFacetValuesForFeatuedProducts(facets: Facet[]) { + const facetsRs = facets.filter((item: Facet) => item.code === CODE_FACET_FEATURED || item.code === CODE_FACET_DISCOUNT) + let rs = [] as FacetValue[] + facetsRs.map((item: Facet) => { + rs = rs.concat(item.values) + return null + }) + return rs } export function getFacetNamesFromIds(facets: FacetValue[], ids?: string[]): string { From 1546d5df4b129ce67756052b127e8a32882fe4d1 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Tue, 5 Oct 2021 10:30:39 +0700 Subject: [PATCH 11/11] :sparkles: feat: get all collection :%s --- commerce.config.json | 6 +-- framework/commerce/api/operations.ts | 18 +++++++ framework/commerce/new-provider.md | 1 + framework/commerce/types/collection.ts | 54 +++++++++++++++++++ framework/commerce/types/product.ts | 5 +- framework/vendure/api/index.ts | 2 + .../api/operations/get-all-collection.ts | 45 ++++++++++++++++ framework/vendure/schema.d.ts | 17 ++++++ framework/vendure/utils/normalize.ts | 1 - .../queries/get-all-collections-query.ts | 12 +++++ pages/index.tsx | 48 ++++++++++------- .../common/LabelCommon/LabelCommon.tsx | 1 + .../common/ProductCard/ProductCard.tsx | 6 +-- .../CollectionCarcousel.tsx | 7 +-- .../home/FreshProducts/FreshProducts.tsx | 30 +++++++++-- src/utils/funtion.utils.ts | 7 ++- src/utils/types.utils.ts | 8 ++- 17 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 framework/commerce/types/collection.ts create mode 100644 framework/vendure/api/operations/get-all-collection.ts create mode 100644 framework/vendure/utils/queries/get-all-collections-query.ts diff --git a/commerce.config.json b/commerce.config.json index ad72b58de..6fb526aaf 100644 --- a/commerce.config.json +++ b/commerce.config.json @@ -2,8 +2,8 @@ "features": { "cart": true, "search": true, - "wishlist": false, - "customerAuth": false, - "customCheckout": false + "wishlist": true, + "customerAuth": true, + "customCheckout": true } } diff --git a/framework/commerce/api/operations.ts b/framework/commerce/api/operations.ts index 342d6bbc9..ca9b325c2 100644 --- a/framework/commerce/api/operations.ts +++ b/framework/commerce/api/operations.ts @@ -10,6 +10,7 @@ import type { GetProductOperation, } from '../types/product' import type { APIProvider, CommerceAPI } from '.' +import { GetAllCollectionsOperation } from '@commerce/types/collection'; const noop = () => { throw new Error('Not implemented') @@ -25,6 +26,7 @@ export const OPERATIONS = [ 'getAllProducts', 'getProduct', 'getAllFacets', + 'getAllCollections', ] as const @@ -174,6 +176,22 @@ export type Operations

= { ): Promise } + getAllCollections: { + (opts: { + variables?: T['variables'] + config?: P['config'] + preview?: boolean + }): Promise + + ( + opts: { + variables?: T['variables'] + config?: P['config'] + preview?: boolean + } & OperationOptions + ): Promise + } + } diff --git a/framework/commerce/new-provider.md b/framework/commerce/new-provider.md index a48e6961b..3c7f05b7a 100644 --- a/framework/commerce/new-provider.md +++ b/framework/commerce/new-provider.md @@ -16,6 +16,7 @@ Adding a commerce provider means adding a new folder in `framework` with a folde - getProduct - getAllProducts - getAllFacets + - getAllCollections - `wishlist` - useWishlist - useAddItem diff --git a/framework/commerce/types/collection.ts b/framework/commerce/types/collection.ts new file mode 100644 index 000000000..3ccb72ea3 --- /dev/null +++ b/framework/commerce/types/collection.ts @@ -0,0 +1,54 @@ +import { Asset } from '../../vendure/schema.d'; + +export type Collection = { + id: string + name: string + slug: string + description: string + featuredAsse: Asset + asset: Asset[] +} + +export type SearchCollectionsBody = { + search?: string + sort?: string + locale?: string +} + +export type CollectionTypes = { + collection: Collection + searchBody: SearchCollectionsBody +} + +export type SearchCollectionsHook = { + data: { + collections: T['collection'][] + found: boolean + } + body: T['searchBody'] + input: T['searchBody'] + fetcherInput: T['searchBody'] +} + +export type CollectionsSchema = { + endpoint: { + options: {} + handlers: { + getCollections: SearchCollectionsHook + } + } +} + + +export type GetAllCollectionsOperation = { + data: { collections: T['collection'][] } + variables: { + ids?: string[] + first?: number + } +} + +export type GetCollectionOperation = { + data: { collection?: T['collection'] } + variables: { code: string; } | { code?: never; } +} diff --git a/framework/commerce/types/product.ts b/framework/commerce/types/product.ts index ac7025158..e1a8da200 100644 --- a/framework/commerce/types/product.ts +++ b/framework/commerce/types/product.ts @@ -1,4 +1,4 @@ -import { CurrencyCode, FacetValue } from './../../vendure/schema.d'; +import { CurrencyCode } from './../../vendure/schema.d'; import { FacetValueFilterInput, LogicalOperator, SearchResultSortParameter } from "@framework/schema" export type ProductImage = { @@ -59,8 +59,7 @@ export type ProductCard = { weight?: number facetValueIds?: string[], collectionIds?: string[], - // TODO: collection - category?: string, + collection?: string, isNotSell?: boolean } diff --git a/framework/vendure/api/index.ts b/framework/vendure/api/index.ts index 7e49d6c1f..95ec47d66 100644 --- a/framework/vendure/api/index.ts +++ b/framework/vendure/api/index.ts @@ -1,6 +1,7 @@ import type { CommerceAPIConfig } from '@commerce/api' import { CommerceAPI, getCommerceApi as commerceApi } from '@commerce/api' import getAllFacets from './operations/get-all-facets' +import getAllCollections from './operations/get-all-collection' import getAllPages from './operations/get-all-pages' import getAllProductPaths from './operations/get-all-product-paths' import getAllProducts from './operations/get-all-products' @@ -42,6 +43,7 @@ const operations = { getAllProducts, getProduct, getAllFacets, + getAllCollections, } export const provider = { config, operations } diff --git a/framework/vendure/api/operations/get-all-collection.ts b/framework/vendure/api/operations/get-all-collection.ts new file mode 100644 index 000000000..b7cc3a725 --- /dev/null +++ b/framework/vendure/api/operations/get-all-collection.ts @@ -0,0 +1,45 @@ +import { OperationContext } from '@commerce/api/operations' +import { Collection } from '@commerce/types/collection' +import { Provider, VendureConfig } from '..' +import { GetAllCollectionsQuery } from '../../schema' +import { getAllCollectionsQuery } from '../../utils/queries/get-all-collections-query' + +export type CollectionVariables = { first?: number } + +export default function getAllCollectionsOperation({ + commerce, +}: OperationContext) { + async function getAllCollections(opts?: { + variables?: CollectionVariables + config?: Partial + preview?: boolean + }): Promise<{ collections: Collection[] }> + + async function getAllCollections({ + query = getAllCollectionsQuery, + variables: { ...vars } = {}, + config: cfg, + }: { + query?: string + variables?: CollectionVariables + config?: Partial + preview?: boolean + } = {}): Promise<{ collections: Collection[] | any[] }> { + const config = commerce.getConfig(cfg) + const variables = { + input: { + take: vars.first, + groupByCollection: true, + }, + } + const { data } = await config.fetch(query, { + variables, + }) + + return { + collections: data.collections.items, + } + } + + return getAllCollections +} diff --git a/framework/vendure/schema.d.ts b/framework/vendure/schema.d.ts index c5c3e8e89..ef667d9f3 100644 --- a/framework/vendure/schema.d.ts +++ b/framework/vendure/schema.d.ts @@ -3240,6 +3240,23 @@ export type GetAllFacetsQuery = { __typename?: 'Query' } & { } } +export type GetAllCollectionsQuery = { __typename?: 'Query' } & { + collections: { __typename?: 'CollectionList' } & { + items: Array< + { __typename?: 'Collection' } & Pick< + Collection, + 'id' | 'name' | 'slug' + > & { + parent?: Maybe<{ __typename?: 'Collection' } & Pick> + children?: Maybe< + Array<{ __typename?: 'Collection' } & Pick> + > + } + >, + 'totalItems' + } +} + export type ActiveOrderQueryVariables = Exact<{ [key: string]: never }> export type ActiveOrderQuery = { __typename?: 'Query' } & { diff --git a/framework/vendure/utils/normalize.ts b/framework/vendure/utils/normalize.ts index a790aa8cd..cc76e5f97 100644 --- a/framework/vendure/utils/normalize.ts +++ b/framework/vendure/utils/normalize.ts @@ -18,7 +18,6 @@ export function normalizeSearchResult(item: SearchResultFragment): ProductCard { // discount // isNotSell // weight - // category } } diff --git a/framework/vendure/utils/queries/get-all-collections-query.ts b/framework/vendure/utils/queries/get-all-collections-query.ts new file mode 100644 index 000000000..359c81ea9 --- /dev/null +++ b/framework/vendure/utils/queries/get-all-collections-query.ts @@ -0,0 +1,12 @@ +export const getAllCollectionsQuery = /* GraphQL */ ` +query collections ($options: CollectionListOptions) { + collections (options: $options){ + totalItems, + items { + id + name + slug + } + } +} +` diff --git a/pages/index.tsx b/pages/index.tsx index 589c7ae30..cac464a43 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,28 +1,31 @@ import { ProductCard } from '@commerce/types/product'; import { ProductVariables } from '@framework/api/operations/get-all-products'; -import { FacetValue } from '@framework/schema'; +import { Collection, FacetValue } from '@framework/schema'; import commerce from '@lib/api/commerce'; import { GetStaticPropsContext } from 'next'; import { Layout } from 'src/components/common'; 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 { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED } from 'src/utils/constanst.utils'; -import { getAllFacetValueIdsByParentCode, getAllFacetValuesForFeatuedProducts, getFreshFacetId } from 'src/utils/funtion.utils'; +import { getAllFacetValueIdsByParentCode, getAllFacetValuesForFeatuedProducts, getAllPromies, getFreshFacetId } from 'src/utils/funtion.utils'; +import { PromiseWithKey } from 'src/utils/types.utils'; interface Props { featuredAndDiscountFacetsValue: FacetValue[], freshProducts: ProductCard[], featuredProducts: ProductCard[], + collections: Collection[] } export default function Home({ featuredAndDiscountFacetsValue, - freshProducts, featuredProducts }: Props) { + freshProducts, featuredProducts, + collections }: Props) { return ( <> - + @@ -44,13 +47,15 @@ export async function getStaticProps({ locales, }: GetStaticPropsContext) { const config = { locale, locales } + let promisesWithKey = [] as PromiseWithKey[] + let props = {} as any + const { facets } = await commerce.getAllFacets({ variables: {}, config, preview, }) - const featuredAndDiscountFacetsValue = getAllFacetValuesForFeatuedProducts(facets) - + props.featuredAndDiscountFacetsValue = getAllFacetValuesForFeatuedProducts(facets) // fresh products const freshProductvariables: ProductVariables = {} @@ -63,6 +68,8 @@ export async function getStaticProps({ config, preview, }) + promisesWithKey.push({ key: 'freshProducts', promise: freshProductsPromise, keyResult: 'products' }) + // featured products const allFeaturedFacetIds = getAllFacetValueIdsByParentCode(facets, CODE_FACET_FEATURED) @@ -75,28 +82,33 @@ export async function getStaticProps({ config, preview, }) + promisesWithKey.push({ key: 'featuredProducts', promise: featuredProductsPromise, keyResult: 'products' }) + + // collection + const collectionsPromise = commerce.getAllCollections({ + variables: {}, + config, + preview, + }) + promisesWithKey.push({ key: 'collections', promise: collectionsPromise, keyResult: 'collections' }) try { - const rs = await Promise.all([ - freshProductsPromise, - featuredProductsPromise, - ]) + 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: { - featuredAndDiscountFacetsValue, - freshProducts: freshFacetId ? rs[0].products : [], - featuredProducts: facetValueIdsForFeaturedProducts.length > 0 ? rs[1].products : [] - }, + props, revalidate: 60, } } catch (err) { } - - - } diff --git a/src/components/common/LabelCommon/LabelCommon.tsx b/src/components/common/LabelCommon/LabelCommon.tsx index fcb9b7eae..23f2d7d6a 100644 --- a/src/components/common/LabelCommon/LabelCommon.tsx +++ b/src/components/common/LabelCommon/LabelCommon.tsx @@ -2,6 +2,7 @@ import classNames from 'classnames' import React from 'react' import s from './LabelCommon.module.scss' interface LabelCommonProps extends React.HTMLAttributes { + children?: React.ReactNode size?: 'default' | 'large' shape?: 'half' | 'round' | 'default' type?: 'default' | 'discount' | 'waiting' | 'delivering' | 'delivered' diff --git a/src/components/common/ProductCard/ProductCard.tsx b/src/components/common/ProductCard/ProductCard.tsx index b9c351aab..4761aac92 100644 --- a/src/components/common/ProductCard/ProductCard.tsx +++ b/src/components/common/ProductCard/ProductCard.tsx @@ -17,7 +17,7 @@ export interface ProductCardProps extends ProductCard { } const ProductCardComponent = ({ - category, + collection, name, slug, weight, @@ -45,9 +45,9 @@ const ProductCardComponent = ({ { - category && + collection &&

- {category} + {collection}
}
diff --git a/src/components/modules/home/CollectionCarcousel/CollectionCarcousel.tsx b/src/components/modules/home/CollectionCarcousel/CollectionCarcousel.tsx index 3007624db..5dccb1052 100644 --- a/src/components/modules/home/CollectionCarcousel/CollectionCarcousel.tsx +++ b/src/components/modules/home/CollectionCarcousel/CollectionCarcousel.tsx @@ -12,7 +12,7 @@ interface ColectionCarcouselProps extends CollectionHeadingProps { data: ProductCardProps[] itemKey: string viewAllLink?: string, - category:string + category?: string } const ColectionCarcousel = ({ @@ -21,7 +21,8 @@ const ColectionCarcousel = ({ title, subtitle, type, - category + category, + viewAllLink = ROUTE.PRODUCTS, }: ColectionCarcouselProps) => { return (
@@ -34,7 +35,7 @@ const ColectionCarcousel = ({ >
- +
diff --git a/src/components/modules/home/FreshProducts/FreshProducts.tsx b/src/components/modules/home/FreshProducts/FreshProducts.tsx index 33b872032..cf773d495 100644 --- a/src/components/modules/home/FreshProducts/FreshProducts.tsx +++ b/src/components/modules/home/FreshProducts/FreshProducts.tsx @@ -1,12 +1,32 @@ import { ProductCard } from '@commerce/types/product' -import { Product } from '@framework/schema' -import React from 'react' +import { Collection } from '@framework/schema' +import React, { useMemo } from 'react' +import { OPTION_ALL, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils' import { CollectionCarcousel } from '..' interface FreshProductsProps { data: ProductCard[] + collections: Collection[] } -const FreshProducts = ({ data }: FreshProductsProps) => { +const getCategoryNameFromCollectionId = (colelctions: Collection[], collectionId?: string ) => { + if (!collectionId) { + return '' + } + + const collection = colelctions.find(item => item.id === collectionId) + return collection?.name || '' +} + +const FreshProducts = ({ data, collections }: FreshProductsProps) => { + const dataWithCategory = useMemo(() => { + return data.map(item => { + return { + ...item, + collection: getCategoryNameFromCollectionId(collections, item.collectionIds ? item.collectionIds[0] : undefined) + } + }) + }, [data, collections]) + if (data.length === 0) { return null } @@ -14,11 +34,11 @@ const FreshProducts = ({ data }: FreshProductsProps) => {
) diff --git a/src/utils/funtion.utils.ts b/src/utils/funtion.utils.ts index d486ca4d0..853b77108 100644 --- a/src/utils/funtion.utils.ts +++ b/src/utils/funtion.utils.ts @@ -1,6 +1,7 @@ import { Facet } from "@commerce/types/facet"; import { FacetValue } from './../../framework/vendure/schema.d'; import { CODE_FACET_DISCOUNT, CODE_FACET_FEATURED, CODE_FACET_FEATURED_VARIANT } from "./constanst.utils"; +import { PromiseWithKey } from "./types.utils"; export function isMobile() { return window.innerWidth < 768 @@ -55,4 +56,8 @@ export function getFacetNamesFromIds(facets: FacetValue[], ids?: string[]): stri const facetItems = facets.filter((item: FacetValue) => ids.includes(item.id)) const names = facetItems.map((item: FacetValue) => item.name) return names.join(", ") -} \ No newline at end of file +} + +export function getAllPromies (promies: PromiseWithKey[]) { + return promies.map(item => item.promise) +} diff --git a/src/utils/types.utils.ts b/src/utils/types.utils.ts index e2ce516d4..ca21b605f 100644 --- a/src/utils/types.utils.ts +++ b/src/utils/types.utils.ts @@ -50,4 +50,10 @@ export type filterContextType = { visible: boolean; open: () => void; close: () => void; -}; \ No newline at end of file +}; + +export type PromiseWithKey = { + key: string + promise: PromiseLike + keyResult?: string, +}