mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
feat: getProductDetail
This commit is contained in:
2
framework/vendure/schema.d.ts
vendored
2
framework/vendure/schema.d.ts
vendored
@@ -3206,7 +3206,7 @@ export type GetProductQuery = { __typename?: 'Query' } & {
|
|||||||
variants: Array<
|
variants: Array<
|
||||||
{ __typename?: 'ProductVariant' } & Pick<
|
{ __typename?: 'ProductVariant' } & Pick<
|
||||||
ProductVariant,
|
ProductVariant,
|
||||||
'id' | 'priceWithTax' | 'currencyCode'
|
'id' | 'priceWithTax' | 'currencyCode' | 'price'
|
||||||
> & {
|
> & {
|
||||||
options: Array<
|
options: Array<
|
||||||
{ __typename?: 'ProductOption' } & Pick<
|
{ __typename?: 'ProductOption' } & Pick<
|
||||||
|
3
next-env.d.ts
vendored
3
next-env.d.ts
vendored
@@ -1,6 +1,3 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/types/global" />
|
/// <reference types="next/types/global" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
|
||||||
|
1
src/components/hooks/product/index.tsx
Normal file
1
src/components/hooks/product/index.tsx
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default as useProductDetail } from './useProductDetail'
|
31
src/components/hooks/product/useProductDetail.tsx
Normal file
31
src/components/hooks/product/useProductDetail.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { GetProductQuery } from '@framework/schema'
|
||||||
|
import { gql } from 'graphql-request'
|
||||||
|
import gglFetcher from 'src/utils/gglFetcher'
|
||||||
|
import useSWR from 'swr'
|
||||||
|
|
||||||
|
const query = gql`
|
||||||
|
query GetProductDetail($slug: String! = "hand-trowel") {
|
||||||
|
product(slug: $slug) {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
variants {
|
||||||
|
price
|
||||||
|
priceWithTax
|
||||||
|
}
|
||||||
|
assets {
|
||||||
|
preview
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
interface ProductDetail {
|
||||||
|
slug: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const useProductDetail = () => {
|
||||||
|
const { data, ...rest } = useSWR<GetProductQuery>([query],gglFetcher)
|
||||||
|
return { productDetail: data?.product, ...rest }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useProductDetail
|
@@ -3,15 +3,15 @@ import { ImgWithLink } from 'src/components/common'
|
|||||||
import s from './ProductImgItem.module.scss'
|
import s from './ProductImgItem.module.scss'
|
||||||
|
|
||||||
export interface ProductImgItemProps {
|
export interface ProductImgItemProps {
|
||||||
src: string
|
preview: string
|
||||||
alt?: string
|
name?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ProductImgItem = ({ src, alt }: ProductImgItemProps) => {
|
const ProductImgItem = ({ preview, name }: ProductImgItemProps) => {
|
||||||
return (
|
return (
|
||||||
<section className={s.productImgItem}>
|
<section className={s.productImgItem}>
|
||||||
<ImgWithLink src={src} alt={alt} />
|
<ImgWithLink src={preview} alt={name} />
|
||||||
</section >
|
</section >
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|||||||
import { ResponsiveType } from 'react-multi-carousel'
|
import { ResponsiveType } from 'react-multi-carousel'
|
||||||
import { CarouselCommon } from 'src/components/common'
|
import { CarouselCommon } from 'src/components/common'
|
||||||
import ProductImgItem, { ProductImgItemProps } from '../ProductImgItem/ProductImgItem'
|
import ProductImgItem, { ProductImgItemProps } from '../ProductImgItem/ProductImgItem'
|
||||||
|
import { useProductDetail } from 'src/components/hooks/product'
|
||||||
import s from './ProductImgs.module.scss'
|
import s from './ProductImgs.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -32,10 +33,11 @@ const RESPONSIVE: ResponsiveType = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
const ProductImgs = ({ }: Props) => {
|
const ProductImgs = ({ }: Props) => {
|
||||||
|
const { productDetail } = useProductDetail()
|
||||||
return (
|
return (
|
||||||
<section className={s.productImgs}>
|
<section className={s.productImgs}>
|
||||||
<CarouselCommon<ProductImgItemProps>
|
<CarouselCommon<ProductImgItemProps>
|
||||||
data={DATA}
|
data={productDetail?.assets ?? []}
|
||||||
itemKey="product-detail-img"
|
itemKey="product-detail-img"
|
||||||
Component={ProductImgItem}
|
Component={ProductImgItem}
|
||||||
responsive={RESPONSIVE}
|
responsive={RESPONSIVE}
|
||||||
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|||||||
import { ButtonCommon, LabelCommon, QuanittyInput } from 'src/components/common'
|
import { ButtonCommon, LabelCommon, QuanittyInput } from 'src/components/common'
|
||||||
import { IconBuy } from 'src/components/icons'
|
import { IconBuy } from 'src/components/icons'
|
||||||
import { LANGUAGE } from 'src/utils/language.utils'
|
import { LANGUAGE } from 'src/utils/language.utils'
|
||||||
|
import { useProductDetail } from 'src/components/hooks/product'
|
||||||
import s from './ProductInfo.module.scss'
|
import s from './ProductInfo.module.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -10,20 +11,21 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ProductInfo = ({ }: Props) => {
|
const ProductInfo = ({ }: Props) => {
|
||||||
|
const {productDetail} = useProductDetail()
|
||||||
return (
|
return (
|
||||||
<section className={s.productInfo}>
|
<section className={s.productInfo}>
|
||||||
<div className={s.info}>
|
<div className={s.info}>
|
||||||
<LabelCommon shape='half'>SEAFOOD</LabelCommon>
|
<LabelCommon shape='half'>SEAFOOD</LabelCommon>
|
||||||
<h2 className={s.heading}>SeaPAk</h2>
|
<h2 className={s.heading}>{productDetail?.name}</h2>
|
||||||
<div className={s.price}>
|
<div className={s.price}>
|
||||||
<div className={s.old}>
|
<div className={s.old}>
|
||||||
<span className={s.number}>Rp 32.000</span>
|
<span className={s.number}>Rp {productDetail?.variants[0].priceWithTax}</span>
|
||||||
<LabelCommon type='discount'>-15%</LabelCommon>
|
<LabelCommon type='discount'>-15%</LabelCommon>
|
||||||
</div>
|
</div>
|
||||||
<div className={s.current}>Rp 27.500</div>
|
<div className={s.current}>Rp {productDetail?.variants[0].price}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={s.description}>
|
<div className={s.description}>
|
||||||
In a large non-reactive dish, mix together the orange juice, soy sauce, olive oil, lemon juice, parsley
|
{productDetail?.description}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={s.actions}>
|
<div className={s.actions}>
|
||||||
|
Reference in New Issue
Block a user