diff options
Diffstat (limited to 'src-migrate')
| -rw-r--r-- | src-migrate/modules/product-detail/components/AddToQuotation.tsx | 221 | ||||
| -rw-r--r-- | src-migrate/modules/product-detail/components/PriceAction.tsx | 9 |
2 files changed, 230 insertions, 0 deletions
diff --git a/src-migrate/modules/product-detail/components/AddToQuotation.tsx b/src-migrate/modules/product-detail/components/AddToQuotation.tsx new file mode 100644 index 00000000..cc91f729 --- /dev/null +++ b/src-migrate/modules/product-detail/components/AddToQuotation.tsx @@ -0,0 +1,221 @@ +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import style from '../styles/price-action.module.css'; +import { Button, Link, useToast } from '@chakra-ui/react'; +import { ArrowDownTrayIcon } from '@heroicons/react/24/outline'; +import product from 'next-seo/lib/jsonld/product'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import Image from '~/components/ui/image'; +import { getAuth } from '~/libs/auth'; +import { upsertUserCart } from '~/services/cart'; +import LazyLoad from 'react-lazy-load'; +import ProductSimilar from '../../../../src/lib/product/components/ProductSimilar'; +import { IProductDetail } from '~/types/product'; +import ImageNext from 'next/image'; +import { useProductCartContext } from '@/contexts/ProductCartContext'; +import { createSlug } from '~/libs/slug'; +import formatCurrency from '~/libs/formatCurrency'; +import { useProductDetail } from '../stores/useProductDetail'; + +type Props = { + variantId: number | null; + quantity?: number; + source?: 'buy' | 'add_to_cart'; + products: IProductDetail; +}; + +type Status = 'idle' | 'loading' | 'success'; + +const AddToQuotation = ({ + variantId, + quantity = 1, + source = 'add_to_cart', + products, +}: Props) => { + const auth = getAuth(); + const router = useRouter(); + const toast = useToast({ + position: 'top', + isClosable: true, + }); + + const { askAdminUrl } = useProductDetail(); + + const [product, setProducts] = useState(products); + const [status, setStatus] = useState<Status>('idle'); + const { + productCart, + setRefreshCart, + setProductCart, + refreshCart, + isLoading, + setIsloading, + } = useProductCartContext(); + + const productSimilarQuery = [ + product?.name, + `fq=-product_id_i:${product.id}`, + `fq=-manufacture_id_i:${product.manufacture?.id || 0}`, + ].join('&'); + const [addCartAlert, setAddCartAlert] = useState(false); + + const handleButton = async () => { + if (typeof auth !== 'object') { + const currentUrl = encodeURIComponent(router.asPath); + router.push(`/login?next=${currentUrl}`); + return; + } + + if (!variantId || isNaN(quantity) || typeof auth !== 'object') return; + if (status === 'success') return; + setStatus('loading'); + await upsertUserCart({ + userId: auth.id, + type: 'product', + id: variantId, + qty: quantity, + selected: true, + source: source, + qtyAppend: true, + }); + setStatus('idle'); + setRefreshCart(true); + setAddCartAlert(true); + + toast({ + title: 'Tambah ke keranjang', + description: 'Berhasil menambahkan barang ke keranjang belanja', + status: 'success', + duration: 3000, + isClosable: true, + position: 'top', + }); + + if (source === 'buy') { + router.push('/shop/quotation?source=buy'); + } + }; + useEffect(() => { + if (status === 'success') + setTimeout(() => { + setStatus('idle'); + }, 3000); + }, [status]); + + const btnConfig = { + add_to_cart: { + colorScheme: 'yellow', + + text: 'Keranjang', + }, + buy: { + colorScheme: 'red', + text: 'Beli', + }, + }; + + return ( + <div className='w-full'> + <Button + onClick={handleButton} + color={'red'} + colorScheme='white' + className='w-full border-2 flex items-center' + > + <ArrowDownTrayIcon className='w-[18px] mr-2' /> + Penawaran Harga Instan + </Button> + <BottomPopup + className='!container' + title='Berhasil Ditambahkan' + active={addCartAlert} + close={() => { + setAddCartAlert(false); + }} + > + <div className='flex mt-4'> + <div className='w-[10%]'> + <ImageNext + src={product.image} + alt={product.name} + className='h-32 object-contain object-center w-full border border-gray_r-4' + width={80} + height={80} + /> + </div> + <div className='ml-3 flex flex-1 items-start font-medium justify-center flex-col gap-y-1'> + {!!product.manufacture.name ? ( + <Link + href={createSlug( + '/shop/brands/', + product.manufacture.name, + product.manufacture.id.toString() + )} + className=' hover:underline' + color={'red'} + > + {product.manufacture.name} + </Link> + ) : ( + '-' + )} + <p className='text-ellipsis overflow-hidden'>{product.name}</p> + <p>{product.code}</p> + {!!product.lowest_price && product.lowest_price.price > 0 && ( + <> + <div className='flex items-end gap-x-2'> + {product.lowest_price.discount_percentage > 0 && ( + <> + <div className='badge-solid-red'> + {Math.floor(product.lowest_price.discount_percentage)}% + </div> + <div className='text-gray_r-11 line-through text-[11px] sm:text-caption-2'> + Rp {formatCurrency(product.lowest_price.price || 0)} + </div> + </> + )} + <div className='text-danger-500 font-semibold'> + Rp{' '} + {formatCurrency(product.lowest_price.price_discount || 0)} + </div> + </div> + </> + )} + + {!!product.lowest_price && product.lowest_price.price === 0 && ( + <span> + Hubungi kami untuk dapatkan harga terbaik,{' '} + <Link + href={askAdminUrl} + target='_blank' + className='font-medium underline' + color={'red'} + > + klik disini + </Link> + </span> + )} + </div> + <div className='ml-3 flex items-center font-normal'> + <Link + href='/shop/cart' + className='flex-1 py-2 text-gray_r-12 btn-yellow' + > + Lihat Keranjang + </Link> + </div> + </div> + <div className='mt-8 mb-4'> + <div className='text-h-sm font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> + <LazyLoad> + <ProductSimilar query={productSimilarQuery} /> + </LazyLoad> + </div> + </BottomPopup> + </div> + ); +}; + +export default AddToQuotation; diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx index 9021264e..a69e896c 100644 --- a/src-migrate/modules/product-detail/components/PriceAction.tsx +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -5,6 +5,7 @@ import formatCurrency from '~/libs/formatCurrency'; import { IProductDetail } from '~/types/product'; import { useProductDetail } from '../stores/useProductDetail'; import AddToCart from './AddToCart'; +import AddToQuotation from './AddToQuotation'; import Link from 'next/link'; import { getAuth } from '~/libs/auth'; @@ -110,6 +111,14 @@ const PriceAction = ({ product }: Props) => { /> )} </div> + <div className='mt-4'> + <AddToQuotation + source='buy' + products={product} + variantId={activeVariantId} + quantity={Number(quantityInput)} + /> + </div> </div> ); }; |
