mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
✨ feat: fresh products
:%s
This commit is contained in:
@@ -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
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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 (
|
||||
<>
|
||||
<HomeBanner />
|
||||
<HomeFeature />
|
||||
<HomeCategories />
|
||||
<FreshProducts data={freshProducts}/>
|
||||
<HomeCollection />
|
||||
<HomeVideo />
|
||||
<HomeSpice />
|
||||
|
BIN
public/assets/images/default_img.jpg
Normal file
BIN
public/assets/images/default_img.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
@@ -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 (
|
||||
<div className={s.imgWithLink}>
|
||||
<Image src={src} alt={alt}
|
||||
<Image src={src || DEFAULT_IMG.src} alt={alt}
|
||||
layout="fill"
|
||||
className={s.imgWithLink}
|
||||
placeholder="blur"
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { ProductCard } from '@commerce/types/product'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import { IconBuy } from 'src/components/icons'
|
||||
import { ROUTE } from 'src/utils/constanst.utils'
|
||||
import { ProductProps } from 'src/utils/types.utils'
|
||||
import { ImgWithLink } from '..'
|
||||
import ButtonCommon from '../ButtonCommon/ButtonCommon'
|
||||
import ButtonIconBuy from '../ButtonIconBuy/ButtonIconBuy'
|
||||
@@ -11,16 +11,18 @@ import LabelCommon from '../LabelCommon/LabelCommon'
|
||||
import s from './ProductCard.module.scss'
|
||||
import ProductNotSell from './ProductNotSell/ProductNotSell'
|
||||
|
||||
export interface ProductCardProps extends ProductProps {
|
||||
export interface ProductCardProps extends ProductCard {
|
||||
buttonText?: string
|
||||
isSingleButton?: boolean,
|
||||
}
|
||||
|
||||
const ProductCard = ({
|
||||
const ProductCardComponent = ({
|
||||
category,
|
||||
name,
|
||||
slug,
|
||||
weight,
|
||||
price,
|
||||
currencyCode,
|
||||
buttonText = 'Buy Now',
|
||||
imageSrc,
|
||||
isNotSell,
|
||||
@@ -35,24 +37,31 @@ const ProductCard = ({
|
||||
return (
|
||||
<div className={s.productCardWarpper}>
|
||||
<div className={s.cardTop}>
|
||||
<Link href={`${ROUTE.PRODUCT_DETAIL}/test`}>
|
||||
<div className={s.productImage}>
|
||||
<ImgWithLink src={imageSrc} alt={name}/>
|
||||
</div>
|
||||
<Link href={`${ROUTE.PRODUCT_DETAIL}/${slug}`}>
|
||||
<a>
|
||||
<div className={s.productImage}>
|
||||
<ImgWithLink src={imageSrc} alt={name}/>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
{
|
||||
category &&
|
||||
<div className={s.productLabel}>
|
||||
<LabelCommon shape="half">{category}</LabelCommon>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div className={s.cardMid}>
|
||||
<div className={s.cardMidTop}>
|
||||
<Link href={`${ROUTE.PRODUCT_DETAIL}/test`}>
|
||||
<div className={s.productname}>{name} </div>
|
||||
<Link href={`${ROUTE.PRODUCT_DETAIL}/${slug}`}>
|
||||
<a>
|
||||
<div className={s.productname}>{name} </div>
|
||||
</a>
|
||||
</Link>
|
||||
<div className={s.productWeight}>{weight}</div>
|
||||
</div>
|
||||
<div className={s.cardMidBot}>
|
||||
<div className={s.productPrice}>{price}</div>
|
||||
<div className={s.productPrice}>{price} {currencyCode}</div>
|
||||
<div className={s.wishList}>
|
||||
<ItemWishList />
|
||||
</div>
|
||||
@@ -80,4 +89,4 @@ const ProductCard = ({
|
||||
)
|
||||
}
|
||||
|
||||
export default ProductCard
|
||||
export default ProductCardComponent
|
||||
|
@@ -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"}
|
||||
/>
|
||||
<CollectionCarcousel
|
||||
data={dataTest}
|
||||
itemKey="product-2"
|
||||
title="VEGGIE"
|
||||
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||
category={"veggie"}
|
||||
/>
|
||||
<CollectionCarcousel
|
||||
data={dataTest}
|
||||
itemKey="product-3"
|
||||
title="VEGGIE"
|
||||
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||
category={"veggie"}
|
||||
/>
|
||||
<CollectionCarcousel
|
||||
data={dataTest}
|
||||
itemKey="product-4"
|
||||
title="VEGGIE"
|
||||
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||
category={"veggie"}
|
||||
/>
|
||||
<CollectionCarcousel
|
||||
data={dataTest}
|
||||
itemKey="product-5"
|
||||
title="VEGGIE"
|
||||
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||
category={"veggie"}
|
||||
/>
|
||||
<CollectionCarcousel
|
||||
data={dataTest}
|
||||
itemKey="product-6"
|
||||
title="VEGGIE"
|
||||
subtitle="Last call! Shop deep deals on 100+ bulk picks while you can."
|
||||
category={"veggie"}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@@ -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',
|
||||
|
Reference in New Issue
Block a user