feat: get-product-detail

This commit is contained in:
Tan Le
2021-10-07 16:16:24 +07:00
parent 51d1624fab
commit 148326c7ef
9 changed files with 40 additions and 107 deletions

View File

@@ -47,6 +47,8 @@ export type Product = {
currencyCode: CurrencyCode
options: ProductOption[]
facetValueIds?: string[]
collectionIds?: string[]
collection?: string,
}
export type ProductCard = {

View File

@@ -53,7 +53,8 @@ export default function getProductOperation({
displayName: og.name,
values: og.options.map((o) => ({ label: o.name })),
})),
facetValueIds: product.facetValues.map(item=> item.id)
facetValueIds: product.facetValues.map(item=> item.id),
collectionIds: product.collections.map(item => item.id)
} as Product
}

View File

@@ -39,6 +39,9 @@ export const getProductQuery = /* GraphQL */ `
facetValues {
id
}
collections {
id
}
}
}
`

View File

@@ -12,7 +12,7 @@ import { PromiseWithKey } from 'src/utils/types.utils'
export default function Slug({ product, relevantProducts, collections }: InferGetStaticPropsType<typeof getStaticProps>) {
return <>
<ProductInfoDetail />
<ProductInfoDetail productDetail={product} collections={collections}/>
<RecipeDetail ingredients={INGREDIENT_DATA_TEST} />
<RecommendedRecipes data={RECIPE_DATA_TEST} />
<ReleventProducts data={relevantProducts} collections={collections}/>

View File

@@ -1,83 +1,28 @@
import React from 'react'
import React, { useMemo } from 'react';
import ProductImgs from './components/ProductImgs/ProductImgs'
import ProductInfo from './components/ProductInfo/ProductInfo'
import s from './ProductInfoDetail.module.scss'
import { GetStaticPropsContext, GetStaticPathsContext, InferGetStaticPropsType } from 'next'
import commerce from '@lib/api/commerce'
import { PromiseWithKey } from 'src/utils/types.utils'
import { getAllPromies } from 'src/utils/funtion.utils'
import { ProductCard } from '@commerce/types/product';
import { useRouter } from 'next/router'
import { Product } from '@commerce/types/product'
import { Collection } from '@framework/schema'
import { getCategoryNameFromCollectionId } from 'src/utils/funtion.utils';
interface Props {
productDetail: ProductCard[],
productDetail: Product,
collections: Collection[]
}
const ProductInfoDetail = ({ product }: InferGetStaticPropsType<typeof getStaticProps>) => {
console.log(product)
const ProductInfoDetail = ({ productDetail, collections }: Props) => {
const dataWithCategoryName = useMemo(() => {
return {
...productDetail,
collection: getCategoryNameFromCollectionId(collections, productDetail.collectionIds ? productDetail.collectionIds[0] : undefined)
}
}, [productDetail, collections])
return (
<section className={s.productInfoDetail}>
<ProductImgs/>
<ProductInfo/>
<ProductImgs productImage={productDetail.images}/>
<ProductInfo productInfoDetail={dataWithCategoryName}/>
</section >
)
}
export async function getStaticProps({
params,
locale,
locales,
preview,
}: GetStaticPropsContext<{ slug: string }>) {
const config = { locale, locales }
const pagesPromise = commerce.getAllPages({ config, preview })
const siteInfoPromise = commerce.getSiteInfo({ config, preview })
const productPromise = commerce.getProduct({
variables: { slug: params!.slug },
config,
preview,
})
// const allProductsPromise = commerce.getAllProducts({
// variables: { first: 4 },
// config,
// preview,
// })
const { pages } = await pagesPromise
const { categories } = await siteInfoPromise
const { product } = await productPromise
// const { products: relatedProducts } = await allProductsPromise
if (!product) {
throw new Error(`Product with slug '${params!.slug}' not found`)
}
return {
props: {
pages,
product,
// relatedProducts,
categories,
},
revalidate: 200,
}
}
// export async function getStaticPaths({ locales }: GetStaticPathsContext) {
// const { products } = await commerce.getAllProductPaths()
// return {
// paths: locales
// ? locales.reduce<string[]>((arr, locale) => {
// // Add a product path for every locale
// products.forEach((product: any) => {
// arr.push(`/${locale}/product${product.path}`)
// })
// return arr
// }, [])
// : products.map((product: any) => `/product${product.path}`),
// fallback: 'blocking',
// }
// }
export default ProductInfoDetail

View File

@@ -3,15 +3,15 @@ import { ImgWithLink } from 'src/components/common'
import s from './ProductImgItem.module.scss'
export interface ProductImgItemProps {
preview: string
name?: string
url: string
alt?: string
}
const ProductImgItem = ({ preview, name }: ProductImgItemProps) => {
const ProductImgItem = ({ url, alt }: ProductImgItemProps) => {
return (
<section className={s.productImgItem}>
<ImgWithLink src={preview} alt={name} />
<ImgWithLink src={url} alt={alt} />
</section >
)
}

View File

@@ -2,28 +2,13 @@ import React from 'react'
import { ResponsiveType } from 'react-multi-carousel'
import { CarouselCommon } from 'src/components/common'
import ProductImgItem, { ProductImgItemProps } from '../ProductImgItem/ProductImgItem'
import { useProductDetail } from 'src/components/hooks/product'
import s from './ProductImgs.module.scss'
import { ProductImage } from '@commerce/types/product';
interface Props {
className?: string
children?: any,
productImage: ProductImage[]
}
const DATA = [
{
src: 'https://user-images.githubusercontent.com/76729908/133026929-199799fc-bd75-4445-a24d-15c0e41796eb.png',
alt: 'Meat',
},
{
src: 'https://user-images.githubusercontent.com/76729908/130574371-3b75fa72-9552-4605-aba9-a4b31cd9dce7.png',
alt: 'Broccoli',
},
{
src: 'https://user-images.githubusercontent.com/76729908/130574371-3b75fa72-9552-4605-aba9-a4b31cd9dce7.png',
alt: 'Broccoli',
}
]
const RESPONSIVE: ResponsiveType = {
desktop: {
@@ -32,12 +17,11 @@ const RESPONSIVE: ResponsiveType = {
slidesToSlide: 1, // optional, default to 1.
},
}
const ProductImgs = ({ }: Props) => {
const { productDetail } = useProductDetail()
const ProductImgs = ({ productImage }: Props) => {
return (
<section className={s.productImgs}>
<CarouselCommon<ProductImgItemProps>
data={productDetail?.assets ?? []}
data={productImage}
itemKey="product-detail-img"
Component={ProductImgItem}
responsive={RESPONSIVE}

View File

@@ -1,31 +1,30 @@
import { Product } from '@commerce/types/product'
import React from 'react'
import { ButtonCommon, LabelCommon, QuanittyInput } from 'src/components/common'
import { IconBuy } from 'src/components/icons'
import { LANGUAGE } from 'src/utils/language.utils'
import { useProductDetail } from 'src/components/hooks/product'
import s from './ProductInfo.module.scss'
interface Props {
className?: string
children?: any,
productInfoDetail: Product
}
const ProductInfo = ({ }: Props) => {
const {productDetail} = useProductDetail()
const ProductInfo = ({ productInfoDetail }: Props) => {
console.log(productInfoDetail)
return (
<section className={s.productInfo}>
<div className={s.info}>
<LabelCommon shape='half'>SEAFOOD</LabelCommon>
<h2 className={s.heading}>{productDetail?.name}</h2>
<LabelCommon shape='half'>{productInfoDetail.collection}</LabelCommon>
<h2 className={s.heading}>{productInfoDetail.name}</h2>
<div className={s.price}>
<div className={s.old}>
<span className={s.number}>Rp {productDetail?.variants[0].priceWithTax}</span>
<span className={s.number}>Rp {productInfoDetail.price}</span>
<LabelCommon type='discount'>-15%</LabelCommon>
</div>
<div className={s.current}>Rp {productDetail?.variants[0].price}</div>
<div className={s.current}>Rp {productInfoDetail.price}</div>
</div>
<div className={s.description}>
{productDetail?.description}
{productInfoDetail.description}
</div>
</div>
<div className={s.actions}>

View File

@@ -23,7 +23,6 @@ const ReleventProducts = ({ data, collections }: Props) => {
if (data.length === 0) {
return null
}
return (
<ListProductWithInfo
title="Relevant Products"