diff options
Diffstat (limited to 'src-migrate/modules')
7 files changed, 106 insertions, 70 deletions
diff --git a/src-migrate/modules/product-detail/components/AddToWishlist.tsx b/src-migrate/modules/product-detail/components/AddToWishlist.tsx index eab3c7be..fccbdcf5 100644 --- a/src-migrate/modules/product-detail/components/AddToWishlist.tsx +++ b/src-migrate/modules/product-detail/components/AddToWishlist.tsx @@ -6,7 +6,7 @@ const AddToWishlist = () => { return ( <Button variant='link' - className='!text-gray-500 !font-medium' + colorScheme='gray' leftIcon={<HeartIcon size={18} />} > Wishlist diff --git a/src-migrate/modules/product-detail/components/Breadcrumb.tsx b/src-migrate/modules/product-detail/components/Breadcrumb.tsx new file mode 100644 index 00000000..0ee5b115 --- /dev/null +++ b/src-migrate/modules/product-detail/components/Breadcrumb.tsx @@ -0,0 +1,40 @@ +import React, { Fragment } from 'react' +import { useQuery } from 'react-query' +import { getProductCategoryBreadcrumb } from '~/services/product' +import Link from 'next/link' +import { createSlug } from '~/libs/slug' + +type Props = { + id: number, + name: string +} + +const Breadcrumb = ({ id, name }: Props) => { + const query = useQuery({ + queryKey: ['product-category-breadcrumb'], + queryFn: () => getProductCategoryBreadcrumb(id) + }) + + const breadcrumbs = query.data || [] + + return ( + <div className='line-clamp-3 md:line-clamp-1 leading-7'> + <Link href='/' className='text-danger-500'>Home</Link> + <span className='mx-2'>/</span> + {breadcrumbs.map((category, index) => ( + <Fragment key={index}> + <Link + href={createSlug('/shop/category/', category.name, category.id.toString())} + className='text-danger-500' + > + {category.name} + </Link> + <span className='mx-2'>/</span> + </Fragment> + ))} + <span>{name}</span> + </div> + ) +} + +export default Breadcrumb
\ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx index 361580ea..2c5e989b 100644 --- a/src-migrate/modules/product-detail/components/Image.tsx +++ b/src-migrate/modules/product-detail/components/Image.tsx @@ -11,14 +11,16 @@ type Props = { const Image = ({ product }: Props) => { return ( - <div className='h-[340px] border border-gray-200 rounded-lg p-2 relative'> + <div className='h-[250px] md:h-[340px] flex items-center justify-center border border-gray-200 rounded-lg p-4 relative'> <ImageUI src={product.image || '/images/noimage.jpeg'} alt={product.name} - width={512} - height={512} - className='object-contain object-center h-full' - classNames={{ wrapper: 'h-full' }} + width={256} + height={256} + className='object-contain object-center h-full w-full' + classNames={{ wrapper: 'h-full w-full' }} + loading='eager' + priority /> <div className='absolute hidden md:block top-4 right-4'> <Tooltip diff --git a/src-migrate/modules/product-detail/components/Information.tsx b/src-migrate/modules/product-detail/components/Information.tsx index fd0e0b3c..52eb6b88 100644 --- a/src-migrate/modules/product-detail/components/Information.tsx +++ b/src-migrate/modules/product-detail/components/Information.tsx @@ -9,6 +9,7 @@ import { IProductDetail } from '~/types/product' import { IProductVariantSLA } from '~/types/productVariant' import { createSlug } from '~/libs/slug' import { getVariantSLA } from '~/services/productVariant' +import { formatToShortText } from '~/libs/formatNumber' const Skeleton = dynamic(() => import('@chakra-ui/react').then((mod) => mod.Skeleton)) @@ -31,10 +32,6 @@ const Information = ({ product }: Props) => { <div className={style['label']}>SKU Number</div> <div className={style['value']}>SKU-{product.id}</div> </div> - {/* <div className={style['row']}> - <div className={style['label']}>Part Number</div> - <div className={style['value']}>{product.code || '-'}</div> - </div> */} <div className={style['row']}> <div className={style['label']}>Manufacture</div> <div className={style['value']}> @@ -48,35 +45,10 @@ const Information = ({ product }: Props) => { ) : '-'} </div> </div> - {/* <div className={style['row']}> - <div className={style['label']}>Preparation Time</div> - <div className={style['value']}> - {product.variant_total > 1 && 'Lihat Variant'} - {product.variant_total === 1 && ( - <Skeleton isLoaded={querySLA.isSuccess} w={querySLA.isSuccess ? '100%' : '40px'} h='100%'> - {sla?.sla_date} - </Skeleton> - )} - </div> - </div> <div className={style['row']}> - <div className={style['label']}>Stock</div> - <div className={style['value']}> - {product.variant_total > 1 && 'Lihat Variant'} - {product.variant_total === 1 && ( - <Skeleton isLoaded={querySLA.isSuccess} w={querySLA.isSuccess ? '100%' : '10px'} h='100%'> - {sla?.qty && sla.qty > 0 ? sla?.qty : '-'} - </Skeleton> - )} - </div> + <div className={style['label']}>Terjual</div> + <div className={style['value']}>{product.qty_sold > 0 ? formatToShortText(product.qty_sold) : '-'}</div> </div> - <div className={style['row']}> - <div className={style['label']}>Weight</div> - <div className={style['value']}> - {product.variant_total > 1 && 'Lihat Variant'} - {product.variant_total === 1 && (product.weight > 0 ? `${product.weight} kg` : '-')} - </div> - </div> */} </div> ) } diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx index cfb596fa..dd211f6f 100644 --- a/src-migrate/modules/product-detail/components/PriceAction.tsx +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -28,13 +28,6 @@ const PriceAction = ({ product }: Props) => { return ( <div className='block md:sticky top-[150px] bg-white py-0 md:py-6 z-10'> - {product.qty_sold > 0 && ( - <div className={style['secondary-text']}> - {formatToShortText(product.qty_sold)} Terjual - </div> - )} - <div className='h-2' /> - {!!activePrice && activePrice.price > 0 && ( <> <div className={style['main-price']}> @@ -60,7 +53,8 @@ const PriceAction = ({ product }: Props) => { <div className='h-4' /> <div className={style['action-wrapper']}> - <input type='number' value={quantityInput} onChange={(e) => setQuantityInput(e.target.value)} className={style['quantity-input']} /> + <label htmlFor="quantity" className='hidden'>Quantity</label> + <input type='number' id='quantity' value={quantityInput} onChange={(e) => setQuantityInput(e.target.value)} className={style['quantity-input']} /> <AddToCart variantId={activeVariantId} quantity={Number(quantityInput)} /> <AddToCart source='buy' variantId={activeVariantId} quantity={Number(quantityInput)} /> </div> diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx index 08ad7d51..93fa7118 100644 --- a/src-migrate/modules/product-detail/components/ProductDetail.tsx +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -2,28 +2,34 @@ import style from '../styles/product-detail.module.css' import React, { useEffect } from 'react' import Link from 'next/link' -import { MessageCircleIcon } from 'lucide-react' +import { useRouter } from 'next/router' + +import { MessageCircleIcon, Share2Icon } from 'lucide-react' import { Button } from '@chakra-ui/react' import { IProductDetail } from '~/types/product' +import useDevice from '@/core/hooks/useDevice' +import { whatsappUrl } from '~/libs/whatsappUrl' +import { useProductDetail } from '../stores/useProductDetail' + +import { RWebShare } from 'react-web-share' import ProductImage from './Image' import Information from './Information' import AddToWishlist from './AddToWishlist' import VariantList from './VariantList' import SimilarSide from './SimilarSide' import SimilarBottom from './SimilarBottom' -import useDevice from '@/core/hooks/useDevice' import PriceAction from './PriceAction' -import { whatsappUrl } from '~/libs/whatsappUrl' -import { useRouter } from 'next/router' -import { useProductDetail } from '../stores/useProductDetail' import ProductPromoSection from '~/modules/product-promo/components/Section' +import Breadcrumb from './Breadcrumb' type Props = { product: IProductDetail } +const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST + const ProductDetail = ({ product }: Props) => { const { isDesktop, isMobile } = useDevice() const router = useRouter() @@ -46,6 +52,9 @@ const ProductDetail = ({ product }: Props) => { return ( <> <div className='md:flex md:flex-wrap'> + <div className="w-full mb-4 md:mb-6 px-4 md:px-0"> + <Breadcrumb id={product.id} name={product.name} /> + </div> <div className='md:w-9/12 md:flex md:flex-col md:pr-4'> <div className='md:flex md:flex-wrap'> <div className="md:w-4/12"> @@ -63,18 +72,39 @@ const ProductDetail = ({ product }: Props) => { <Information product={product} /> - <div className='h-4' /> + <div className='h-6' /> + + <div className="flex gap-x-5"> + <Button + as={Link} + href={askAdminUrl} + variant='link' + target='_blank' + colorScheme='gray' + leftIcon={<MessageCircleIcon size={18} />} + > + Ask Admin + </Button> + + <AddToWishlist /> + + <RWebShare + data={{ + text: 'Check out this product', + title: `${product.name} - Indoteknik.com`, + url: SELF_HOST + router.asPath + }} + > + <Button + variant='link' + colorScheme='gray' + leftIcon={<Share2Icon size={18} />} + > + Share + </Button> + </RWebShare> + </div> - <Button - as={Link} - href={askAdminUrl} - variant='link' - target='_blank' - colorScheme='red' - leftIcon={<MessageCircleIcon size={18} />} - > - Ask Admin - </Button> </div> </div> @@ -117,9 +147,7 @@ const ProductDetail = ({ product }: Props) => { <div className="md:w-3/12"> <PriceAction product={product} /> - <AddToWishlist /> - - <div className='h-8' /> + <div className='h-6' /> <div className={style['heading']}> Produk Serupa @@ -131,7 +159,7 @@ const ProductDetail = ({ product }: Props) => { </div> )} - <div className='md:w-full py-0 md:py-10 px-4 md:px-0'> + <div className='md:w-full pt-4 md:py-10 px-4 md:px-0'> <div className={style['heading']}> Kamu Mungkin Juga Suka </div> diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx index 96b7486b..e8c18921 100644 --- a/src-migrate/modules/product-detail/components/VariantList.tsx +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -22,10 +22,10 @@ const VariantList = ({ variants }: Props) => { <div className={style['header']}> <div className="w-2/12 sticky left-0 bg-gray-200">Part Number</div> <div className="w-2/12">Variant</div> - <div className="w-2/12">Stock</div> + <div className="w-1/12">Stock</div> <div className="w-2/12">Masa Persiapan</div> <div className="w-1/12">Berat</div> - <div className="w-2/12">Harga</div> + <div className="w-3/12">Harga</div> </div> {variants.map((variant) => ( <LazyLoadComponent key={variant.id}> @@ -49,8 +49,8 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { return ( <div className={style['row']}> <div className='w-2/12 sticky left-0 bg-white md:bg-transparent'>{variant.code}</div> - <div className='w-2/12'>{variant.attributes.join(', ')}</div> - <div className='w-2/12'> + <div className='w-2/12'>{variant.attributes.join(', ') || '-'}</div> + <div className='w-1/12'> <Skeleton isLoaded={querySLA.isSuccess} h='21px' w={16}> {sla?.qty !== undefined && ( <> @@ -68,7 +68,7 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { <div className='w-1/12'> {variant.weight > 0 ? `${variant.weight} Kg` : '-'} </div> - <div className='w-2/12'> + <div className='w-3/12'> {variant.price.price > 0 && `Rp ${formatCurrency(variant.price.price)}`} {variant.price.price === 0 && '-'} </div> |
