diff options
Diffstat (limited to 'src/lib/product')
| -rw-r--r-- | src/lib/product/components/CategorySection.jsx | 104 | ||||
| -rw-r--r-- | src/lib/product/components/LobSectionCategory.jsx | 81 | ||||
| -rw-r--r-- | src/lib/product/components/Product/ProductDesktopVariant.jsx | 86 | ||||
| -rw-r--r-- | src/lib/product/components/Product/ProductMobileVariant.jsx | 71 | ||||
| -rw-r--r-- | src/lib/product/components/ProductCard.jsx | 32 | ||||
| -rw-r--r-- | src/lib/product/components/ProductFilter.jsx | 1 | ||||
| -rw-r--r-- | src/lib/product/components/ProductFilterDesktop.jsx | 7 | ||||
| -rw-r--r-- | src/lib/product/components/ProductSearch.jsx | 19 |
8 files changed, 58 insertions, 343 deletions
diff --git a/src/lib/product/components/CategorySection.jsx b/src/lib/product/components/CategorySection.jsx deleted file mode 100644 index 2af3db10..00000000 --- a/src/lib/product/components/CategorySection.jsx +++ /dev/null @@ -1,104 +0,0 @@ -import Image from "next/image"; -import Link from 'next/link'; -import { createSlug } from '@/core/utils/slug'; -import useDevice from '@/core/hooks/useDevice'; -import { Swiper, SwiperSlide } from 'swiper/react'; -import 'swiper/css'; -import { useQuery } from 'react-query'; -import { useRouter } from 'next/router'; -import { - ChevronDownIcon, - ChevronUpIcon, // Import ChevronUpIcon for toggling - DocumentCheckIcon, - HeartIcon, -} from '@heroicons/react/24/outline'; -import { useState } from 'react'; // Import useState -import { getIdFromSlug } from '@/core/utils/slug' - -const CategorySection = ({ categories }) => { - const { isDesktop, isMobile } = useDevice(); - const [isOpenCategory, setIsOpenCategory] = useState(false); // State to manage category visibility - - const handleToggleCategories = () => { - setIsOpenCategory(!isOpenCategory); - }; - - - const displayedCategories = isOpenCategory ? categories : categories.slice(0, 10); - - return ( - <section> - {isDesktop && ( - <div className="group/item grid grid-cols-5 gap-y-2 gap-x-2 w-full h-full col-span-2 "> - {displayedCategories.map((category) => ( - <Link href={createSlug('/shop/category/', category?.name, category?.id)} key={category?.id} passHref> - <div className="group transition-colors duration-300 "> - <div className="KartuInti h-12 w-26 max-w-sm lg:max-w-full flex flex-col border-[2px] border-gray-200 group-hover:border-red-400 rounded relative "> - <div className="flex items-center justify-start h-full px-1 flex-row "> - <Image className="h-full" src={category?.image1920 ? category?.image1920 : '/images/noimage.jpeg'} width={56} height={48} alt={category?.name} /> - <h2 className="text-gray-700 group-hover:text-[#E20613] line-clamp-2 content-center h-fit w-60 px-1 font-semibold text-sm text-start">{category?.name}</h2> - </div> - </div> - </div> - </Link> - ))} - </div> - )} - {isDesktop && categories.length > 10 && ( - <div className="w-full flex justify-center mt-4"> - <button - onClick={handleToggleCategories} - className="flex justify-end mt-4 text-red-500 font-bold px-4 py-2 rounded" - > - {isOpenCategory ? 'Sembunyikan' : 'Lihat semua'} - {isOpenCategory ? ( - <ChevronUpIcon className="ml-auto w-5 font-bold" /> - ) : ( - <ChevronDownIcon className="ml-auto w-5 font-bold" /> - )} - </button> - </div> - )} - - {isMobile && ( - <div className="py-4"> - <Swiper slidesPerView={2.3} spaceBetween={10}> - {displayedCategories.map((category) => ( - <SwiperSlide key={category?.id}> - <Link href={createSlug('/shop/category/', category?.name, category?.id)} passHref> - <div className="group transition-colors duration-300"> - <div className="KartuInti min-h-16 max-h-16 w-26 max-w-sm lg:max-w-full flex flex-col border-[2px] border-gray-200 group-hover:bg-red-200 group-hover:border-red-400 rounded relative"> - <div className="flex items-center justify-center h-full px-1 flex-row"> - <Image - src={category?.image1920 ? category?.image1920 : '/images/noimage.jpeg'} - width={56} - height={48} - alt={category?.name} - /> - <h2 className="text-gray-700 group-hover:text-[#E20613] line-clamp-2 content-center h-fit w-60 px-1 font-semibold text-sm text-start"> - {category?.name} - </h2> - </div> - </div> - </div> - </Link> - </SwiperSlide> - ))} - </Swiper> - {categories.length > 10 && ( - <div className="w-full flex justify-end mt-4"> - <button - onClick={handleToggleCategories} - className="flex justify-end mt-4 bg-red-500 text-white text-sm px-4 py-2 rounded" - > - {isOpenCategory ? 'Sembunyikan Semua' : 'Lihat Semua'} - </button> - </div> - )} - </div> - )} - </section> - ) -} - -export default CategorySection diff --git a/src/lib/product/components/LobSectionCategory.jsx b/src/lib/product/components/LobSectionCategory.jsx deleted file mode 100644 index 03d6e8c0..00000000 --- a/src/lib/product/components/LobSectionCategory.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import Image from "next/image"; -import Link from 'next/link'; -import { createSlug } from '@/core/utils/slug'; -import useDevice from '@/core/hooks/useDevice'; -import { Swiper, SwiperSlide } from 'swiper/react'; -import 'swiper/css'; -import { useQuery } from 'react-query'; -import { useRouter } from 'next/router'; -import { - ChevronDownIcon, - ChevronUpIcon, // Import ChevronUpIcon for toggling - DocumentCheckIcon, - HeartIcon, -} from '@heroicons/react/24/outline'; -import { useState } from 'react'; // Import useState -import { getIdFromSlug } from '@/core/utils/slug' - -const LobSectionCategory = ({ categories }) => { - const { isDesktop, isMobile } = useDevice(); - const [isOpenCategory, setIsOpenCategory] = useState(false); // State to manage category visibility - - const handleToggleCategories = () => { - setIsOpenCategory(!isOpenCategory); - }; - - const displayedCategories = categories[0]?.categoryIds; - - return ( - <section> - {isDesktop && ( - <div className="group/item grid grid-flow-col gap-y-2 gap-x-4 w-full h-full"> - {displayedCategories?.map((category) => ( - <Link - href={createSlug('/shop/category/', category?.name, category?.id)} - key={category?.id} - passHref - className="block hover:scale-105 transition-transform duration-300 bg-cover bg-center h-[144px]" - style={{ - backgroundImage: `url('${category?.image ? category?.image : 'https://erp.indoteknik.com/web/image?model=x_banner.banner&id=5&field=x_banner_image&unique=09202023100557'}')`, - }} - > - </Link> - ))} - </div> - )} - - {isMobile && ( - <div className="py-4"> - <Swiper slidesPerView={1.2} spaceBetween={10}> - {displayedCategories?.map((category) => ( - <SwiperSlide key={category?.id}> - <Link - href={createSlug('/shop/category/', category?.name, category?.id)} - key={category?.id} - passHref - className="block bg-cover bg-center h-[144px]" - style={{ - backgroundImage: `url('${category?.image ? category?.image : 'https://erp.indoteknik.com/web/image?model=x_banner.banner&id=5&field=x_banner_image&unique=09202023100557'}')`, - }} - > - </Link> - </SwiperSlide> - ))} - </Swiper> - {categories.length > 10 && ( - <div className="w-full flex justify-end mt-4"> - <button - onClick={handleToggleCategories} - className="flex justify-end mt-4 bg-red-500 text-white text-sm px-4 py-2 rounded" - > - {isOpenCategory ? 'Sembunyikan Semua' : 'Lihat Semua'} - </button> - </div> - )} - </div> - )} - </section> - ) -} - -export default LobSectionCategory diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index c8a5a205..09b30a44 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -6,11 +6,6 @@ import { useRouter } from 'next/router'; import { useCallback, useEffect, useRef, useState } from 'react'; import { toast } from 'react-hot-toast'; import LazyLoad from 'react-lazy-load'; -import { Button } from '@chakra-ui/react' -import { MessageCircleIcon, Share2Icon } from 'lucide-react' -import AddToWishlist from '../../../../../src-migrate/modules/product-detail/components/AddToWishlist' -import { RWebShare } from 'react-web-share' -// import Link from 'next/link' import { useProductCartContext } from '@/contexts/ProductCartContext'; import odooApi from '@/core/api/odooApi'; @@ -23,14 +18,11 @@ import { updateItemCart } from '@/core/utils/cart'; import currencyFormat from '@/core/utils/currencyFormat'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; -import Breadcrumb from '../../../../../src-migrate/modules/product-detail/components/Breadcrumb'; import productSimilarApi from '../../api/productSimilarApi'; import ProductCard from '../ProductCard'; import ProductSimilar from '../ProductSimilar'; -const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST - const ProductDesktopVariant = ({ product, wishlist, @@ -40,7 +32,7 @@ const ProductDesktopVariant = ({ const router = useRouter(); const auth = useAuth(); const { slug } = router.query; - const [ askAdminUrl, setAskAdminUrl ] = useState() + const [lowestPrice, setLowestPrice] = useState(null); const [addCartAlert, setAddCartAlert] = useState(false); @@ -61,20 +53,6 @@ const ProductDesktopVariant = ({ setLowestPrice(lowest); }, [getLowestPrice]); - useEffect(() => { - const createdAskUrl = whatsappUrl({ - template: 'product', - payload: { - manufacture: product.manufacture.name, - productName: product.name, - url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath - }, - fallbackUrl: router.asPath - }) - - setAskAdminUrl(createdAskUrl) - }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]) - const [informationTab, setInformationTab] = useState( informationTabOptions[0].value ); @@ -137,25 +115,20 @@ const ProductDesktopVariant = ({ }); } }; - const regex = /\b(?![A-Z\s]+\b)[A-Za-z\s]+\b/g; - const matches = product?.parent?.name?.match(regex); - const extractedName = matches ? matches.join(' ').trim() : ''; - console.log("extractedName",extractedName) const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, `fq=-manufacture_id_i:${product.manufacture?.id || 0}`, ].join('&'); - + const [productSimilarInBrand, setProductSimilarInBrand] = useState(null); - + useEffect(() => { const loadProductSimilarInBrand = async () => { const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, - `fq=display_name_s:${extractedName}`, ].join('&'); const dataProductSimilar = await productSimilarApi({ query: productSimilarQuery, @@ -181,7 +154,6 @@ const ProductDesktopVariant = ({ return ( <DesktopView> <div className='container mx-auto pt-10'> - <Breadcrumb id={product.id} name={product.parent.name} /> <div className='flex'> <div className='w-full flex flex-wrap'> <div className='w-5/12'> @@ -291,42 +263,9 @@ const ProductDesktopVariant = ({ </div> </div> </div> - <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 productId={product.id} /> - - <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> </div> - - - <div className='p-4 md:p-6 md:bg-gray-50 rounded-xl w-[99%]'> + <div className='p-4 md:p-6 md:bg-gray-50 rounded-xl'> <h2 className='text-h-md md:text-h-lg font-medium'>Informasi Produk</h2> <div className='h-4' /> <div @@ -340,7 +279,7 @@ const ProductDesktopVariant = ({ /> </div> </div> - <div className='w-[35%]'> + <div className='w-[25%]'> {product?.isFlashsale > 0 && product?.price?.discountPercentage > 0 ? ( <> @@ -420,11 +359,24 @@ const ProductDesktopVariant = ({ Beli </button> </div> + <div className='flex mt-4'> + <button + className='flex items-center gap-x-1' + onClick={toggleWishlist} + > + {wishlist.data?.productTotal > 0 ? ( + <HeartIcon className='w-6 fill-danger-500 text-danger-500' /> + ) : ( + <HeartIcon className='w-6' /> + )} + Wishlist + </button> + </div> <div className='border border-gray_r-6 overflow-auto mt-4'> <div className='font-medium text-center p-4 bg-gray_r-1 border-b border-gray_r-6 sticky top-0 z-10'> Produk Serupa </div> - <div className='h-full divide-y divide-gray_r-6 max-h-[500px]'> + <div className='h-full divide-y divide-gray_r-6 max-h-96'> {productSimilarInBrand && productSimilarInBrand?.map((product) => ( <div className='py-2' key={product.id}> diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx index ce836d5b..af9e52bb 100644 --- a/src/lib/product/components/Product/ProductMobileVariant.jsx +++ b/src/lib/product/components/Product/ProductMobileVariant.jsx @@ -16,14 +16,8 @@ import currencyFormat from '@/core/utils/currencyFormat'; import { gtagAddToCart } from '@/core/utils/googleTag'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; -import Breadcrumb from '../../../../../src-migrate/modules/product-detail/components/Breadcrumb'; -import { Button } from '@chakra-ui/react' -import { MessageCircleIcon, Share2Icon } from 'lucide-react' -import AddToWishlist from '../../../../../src-migrate/modules/product-detail/components/AddToWishlist' -import { RWebShare } from 'react-web-share' -import ProductSimilar from '../ProductSimilar'; -const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST +import ProductSimilar from '../ProductSimilar'; const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { const router = useRouter(); @@ -34,7 +28,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { informationTabOptions[0].value ); const [addCartAlert, setAddCartAlert] = useState(false); - const [ askAdminUrl, setAskAdminUrl ] = useState() + const [isLoadingSLA, setIsLoadingSLA] = useState(true); const getLowestPrice = () => { @@ -66,20 +60,6 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { } }, [selectedVariant, product]); - useEffect(() => { - const createdAskUrl = whatsappUrl({ - template: 'product', - payload: { - manufacture: product.manufacture.name, - productName: product.name, - url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath - }, - fallbackUrl: router.asPath - }) - - setAskAdminUrl(createdAskUrl) - }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]) - const validAction = () => { let isValid = true; if (!selectedVariant) { @@ -140,17 +120,14 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { return ( <MobileView> - <div className='p-4'> - <Breadcrumb id={product.id} name={product.name} /> - </div> <Image src={product.image + '?variant=True'} alt={product.name} - className='h-72 object-contain mt-4 object-center w-full border-b border-gray_r-4' + className='h-72 object-contain object-center w-full border-b border-gray_r-4' /> <div className='p-4'> - <div className='flex items-center mb-2'> + <div className='flex items-end mb-2'> {product.manufacture?.name ? ( <Link href={createSlug( @@ -164,45 +141,15 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { ) : ( <div>-</div> )} - <div className="ml-2 flex gap-x-5"> - <Button - as={Link} - href={askAdminUrl} - variant='link' - target='_blank' - colorScheme='gray' - leftIcon={<MessageCircleIcon size={18} />} - > - Ask Admin - </Button> - - <AddToWishlist productId={product.id} /> - - <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 type='button' className='ml-auto' onClick={toggleWishlist}> + <button type='button' className='ml-auto' onClick={toggleWishlist}> {wishlist.data?.productTotal > 0 ? ( <HeartIcon className='w-6 fill-danger-500 text-danger-500' /> ) : ( <HeartIcon className='w-6' /> )} - </button> */} + </button> </div> - <h1 className='font-medium text-h-lg leading-8 md:text-title-md md:leading-10 mb-3'>{activeVariant?.name}</h1> + <h1 className='leading-6 font-medium mb-3'>{activeVariant?.name}</h1> {activeVariant.isFlashSale && activeVariant?.price?.discountPercentage > 0 ? ( @@ -226,11 +173,11 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { </div> </> ) : ( - <h3 className='font-medium text-danger-500 text-title-md mt-1'> + <h3 className='text-danger-500 font-semibold mt-1'> {activeVariant?.price?.price > 0 ? ( <> {currencyFormat(activeVariant?.price?.price)} - <div className='text-gray_r-9 text-base font-medium mt-1'> + <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} {currencyFormat( activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index a1491c7f..35e2a665 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -146,20 +146,13 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { )} </Link> <div className='p-2 sm:p-3 pb-3 text-caption-2 sm:text-body-2 leading-5'> - <div className='flex justify-between '> - {product?.manufacture?.name ? ( - <Link href={URL.manufacture} className='mb-1 mt-1'> - {product.manufacture.name} - </Link> - ) : ( - <div>-</div> - )} - {product?.is_in_bu && ( - <div className=''> - <Image src='/images/PICKUP-NOW.png' alt='pickup now' width={90} height={12} /> - </div> - )} - </div> + {product?.manufacture?.name ? ( + <Link href={URL.manufacture} className='mb-1'> + {product.manufacture.name} + </Link> + ) : ( + <div>-</div> + )} <Link href={URL.product} className={`mb-2 !text-gray_r-12 leading-6 block line-clamp-3 h-[64px]`} @@ -299,18 +292,9 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </div> )} {product?.manufacture?.name ? ( - <div className='flex justify-between'> - <Link href={URL.manufacture} className='mb-1'> + <Link href={URL.manufacture} className='mb-1'> {product.manufacture.name} </Link> - {/* {product?.is_in_bu && ( - <div className='bg-red-500 rounded'> - <span className='p-[6px] text-xs text-white'> - Click & Pickup - </span> - </div> - )} */} - </div> ) : ( <div>-</div> )} diff --git a/src/lib/product/components/ProductFilter.jsx b/src/lib/product/components/ProductFilter.jsx index d52fcb90..dd9ec8f4 100644 --- a/src/lib/product/components/ProductFilter.jsx +++ b/src/lib/product/components/ProductFilter.jsx @@ -62,6 +62,7 @@ const ProductFilter = ({ active, close, brands, categories, prefixUrl, defaultBr const handleSubmit = () => { let params = { + penawaran: router.query.penawaran, q: router.query.q, orderBy: order, brand, diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx index 1933c5f0..2bdf962a 100644 --- a/src/lib/product/components/ProductFilterDesktop.jsx +++ b/src/lib/product/components/ProductFilterDesktop.jsx @@ -93,6 +93,7 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu const handleSubmit = () => { let params = { + penawaran: router.query.penawaran, q: router.query.q, orderBy: order, brand: brandValues.join(','), @@ -107,11 +108,7 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu const slug = Array.isArray(router.query.slug) ? router.query.slug[0] : router.query.slug; if (slug) { - if(prefixUrl.includes('category') || prefixUrl.includes('lob')){ - router.push(`${prefixUrl}?${params}`) - }else{ - router.push(`${prefixUrl}/${slug}?${params}`) - } + router.push(`${prefixUrl}/${slug}?${params}`) } else { router.push(`${prefixUrl}?${params}`) } diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index a83e5e1e..a427e134 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -142,6 +142,23 @@ const ProductSearch = ({ } }, [prefixUrl,dataCategoriesProduct, query, finalQuery]); + useEffect(() => { + const checkIfPenawaran = async () => { + if (router.asPath.includes('penawaran')) { + query = { + ...query, + fq: [ + `-flashsale_id_i:${router.query.penawaran}`, + `flashsale_price_f:[1 TO *]` + ], + orderBy: 'flashsale-discount-desc' + }; + setOrderBy('flashsale-discount-desc') + } + }; + checkIfPenawaran(); + }, [router]); + const { productSearch } = useProductSearch({ query: queryFinal, operation: 'AND', @@ -340,6 +357,7 @@ const ProductSearch = ({ const handleDeleteFilter = async (source, value) => { let params = { + penawaran: router.query.penawaran, q: router.query.q, orderBy: orderBy, brand: brandValues.join(','), @@ -367,6 +385,7 @@ const ProductSearch = ({ break; case 'delete': params = { + penawaran: router.query.penawaran, q: router.query.q, orderBy: orderBy, }; |
