mirror of
https://github.com/vercel/commerce.git
synced 2025-07-04 12:11:22 +00:00
🎨 styles: product info detail
:%s
This commit is contained in:
parent
fb48ab77d7
commit
887c3ae2e3
@ -1 +0,0 @@
|
|||||||
Subproject commit 3c7aa8e862bfd8d44719be44c6c0a31ab01524a3
|
|
@ -1,76 +1,11 @@
|
|||||||
import { Layout } from '@components/common'
|
|
||||||
import commerce from '@lib/api/commerce'
|
|
||||||
import type {
|
|
||||||
GetStaticPathsContext,
|
|
||||||
GetStaticPropsContext,
|
|
||||||
InferGetStaticPropsType
|
|
||||||
} from 'next'
|
|
||||||
import { useRouter } from 'next/router'
|
|
||||||
|
|
||||||
export async function getStaticProps({
|
import { Layout } from 'src/components/common'
|
||||||
params,
|
import { ProductInfoDetail } from 'src/components/modules/product-detail'
|
||||||
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({
|
export default function Slug() {
|
||||||
variables: { first: 4 },
|
return <>
|
||||||
config,
|
<ProductInfoDetail/>
|
||||||
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 function Slug({
|
|
||||||
product,
|
|
||||||
relatedProducts,
|
|
||||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
return <div>This is product page</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Slug.Layout = Layout
|
Slug.Layout = Layout
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import React, { memo, useEffect, useState } from 'react'
|
import React, { memo, useEffect, useState } from 'react'
|
||||||
import { useModalCommon } from 'src/components/hooks/useModalCommon'
|
import { useModalCommon } from 'src/components/hooks'
|
||||||
import { isMobile } from 'src/utils/funtion.utils'
|
import { isMobile } from 'src/utils/funtion.utils'
|
||||||
import ModalAuthenticate from '../ModalAuthenticate/ModalAuthenticate'
|
import ModalAuthenticate from '../ModalAuthenticate/ModalAuthenticate'
|
||||||
import ModalCreateUserInfo from '../ModalCreateUserInfo/ModalCreateUserInfo'
|
import ModalCreateUserInfo from '../ModalCreateUserInfo/ModalCreateUserInfo'
|
||||||
|
1
src/components/hooks/index.ts
Normal file
1
src/components/hooks/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default as useModalCommon } from './useModalCommon'
|
@ -4,7 +4,7 @@ interface Props {
|
|||||||
initialValue?: boolean,
|
initialValue?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useModalCommon = ({ initialValue = false }: Props) => {
|
const useModalCommon = ({ initialValue = false }: Props) => {
|
||||||
const [visible, setVisible] = useState<boolean>(initialValue)
|
const [visible, setVisible] = useState<boolean>(initialValue)
|
||||||
|
|
||||||
const openModal = (e?: any) => {
|
const openModal = (e?: any) => {
|
||||||
@ -21,3 +21,5 @@ export const useModalCommon = ({ initialValue = false }: Props) => {
|
|||||||
visible, openModal, closeModal
|
visible, openModal, closeModal
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default useModalCommon
|
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import ProductImgs from './components/ProductImgs/ProductImgs'
|
||||||
|
import ProductInfo from './components/ProductInfo/ProductInfo'
|
||||||
|
import s from './ProductInfoDetail.module.scss'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string
|
||||||
|
children?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProductInfoDetail = ({ }: Props) => {
|
||||||
|
return (
|
||||||
|
<section className={s.productInfoDetail}>
|
||||||
|
<ProductImgs/>
|
||||||
|
<ProductInfo/>
|
||||||
|
</section >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductInfoDetail
|
@ -0,0 +1,6 @@
|
|||||||
|
.productImgs {
|
||||||
|
.img {
|
||||||
|
@apply w-full h-full;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { CarouselCommon } from 'src/components/common'
|
||||||
|
import s from './ProductImgs.module.scss'
|
||||||
|
|
||||||
|
interface ImgProps {
|
||||||
|
src: string, alt?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string
|
||||||
|
children?: any,
|
||||||
|
// data: ImgProps[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProductImgs = ({ }: Props) => {
|
||||||
|
return (
|
||||||
|
<section className={s.productImgs}>
|
||||||
|
{/* <CarouselCommon<ImgProps> /> */}
|
||||||
|
<img className={s.img} src="https://user-images.githubusercontent.com/76729908/130574371-3b75fa72-9552-4605-aba9-a4b31cd9dce7.png" alt="" />
|
||||||
|
</section >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductImgs
|
@ -0,0 +1,40 @@
|
|||||||
|
@import "../../../../../../styles/utilities";
|
||||||
|
|
||||||
|
.productInfo {
|
||||||
|
.info {
|
||||||
|
margin-bottom: 3.2rem;
|
||||||
|
.heading {
|
||||||
|
@apply heading-2 font-heading;
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
.price {
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
.old {
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
.number {
|
||||||
|
margin-right: 0.8rem;
|
||||||
|
color: var(--text-label);
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.current {
|
||||||
|
@apply text-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.description {
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom {
|
||||||
|
@screen md {
|
||||||
|
margin-top: 2.4rem;
|
||||||
|
max-width: 39rem;
|
||||||
|
button {
|
||||||
|
@apply w-full;
|
||||||
|
&:first-child {
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { ButtonCommon, LabelCommon, QuanittyInput } from 'src/components/common'
|
||||||
|
import { LANGUAGE } from 'src/utils/language.utils'
|
||||||
|
import s from './ProductInfo.module.scss'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
className?: string
|
||||||
|
children?: any,
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProductInfo = ({ }: Props) => {
|
||||||
|
return (
|
||||||
|
<section className={s.productInfo}>
|
||||||
|
<div className={s.info}>
|
||||||
|
<LabelCommon shape='half'>SEAFOOD</LabelCommon>
|
||||||
|
<h2 className={s.heading}>SeaPAk</h2>
|
||||||
|
<div className={s.price}>
|
||||||
|
<div className={s.old}>
|
||||||
|
<span className={s.number}>Rp 32.000</span>
|
||||||
|
<LabelCommon type='discount'>-15%</LabelCommon>
|
||||||
|
</div>
|
||||||
|
<div className={s.current}>Rp 27.500</div>
|
||||||
|
</div>
|
||||||
|
<div className={s.description}>
|
||||||
|
In a large non-reactive dish, mix together the orange juice, soy sauce, olive oil, lemon juice, parsley
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<QuanittyInput />
|
||||||
|
<div className={s.bottom}>
|
||||||
|
<ButtonCommon size='large'>{LANGUAGE.BUTTON_LABEL.BUY_NOW}</ButtonCommon>
|
||||||
|
<ButtonCommon size='large' type='light'>{LANGUAGE.BUTTON_LABEL.ADD_TO_CARD}</ButtonCommon>
|
||||||
|
</div>
|
||||||
|
</section >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductInfo
|
1
src/components/modules/product-detail/index.ts
Normal file
1
src/components/modules/product-detail/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default as ProductInfoDetail } from './ProductInfoDetail/ProductInfoDetail'
|
@ -21,7 +21,7 @@
|
|||||||
--warning-light: #fef8eb;
|
--warning-light: #fef8eb;
|
||||||
|
|
||||||
--negative-dark: #741a06;
|
--negative-dark: #741a06;
|
||||||
--negative: #f34f2b;
|
--negative: #D1644D;
|
||||||
--negative-border-line: #fddfd8;
|
--negative-border-line: #fddfd8;
|
||||||
--negative-light: #feefec;
|
--negative-light: #feefec;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ export const LANGUAGE = {
|
|||||||
BUTTON_LABEL: {
|
BUTTON_LABEL: {
|
||||||
BUY_NOW: 'Buy now',
|
BUY_NOW: 'Buy now',
|
||||||
SHOP_NOW: 'Shop now',
|
SHOP_NOW: 'Shop now',
|
||||||
|
ADD_TO_CARD: 'Add to Cart'
|
||||||
},
|
},
|
||||||
PLACE_HOLDER: {
|
PLACE_HOLDER: {
|
||||||
SEARCH: 'Search',
|
SEARCH: 'Search',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user