From 55d476a4666150a013a308deb6cb99513778ac22 Mon Sep 17 00:00:00 2001
From: Rafi Zadanly <zadanlyr@gmail.com>
Date: Fri, 23 Feb 2024 09:16:24 +0700
Subject: Update variant image without watermark

---
 .../components/Product/ProductDesktopVariant.jsx   | 275 +++++++++++++--------
 1 file changed, 166 insertions(+), 109 deletions(-)

(limited to 'src/lib/product/components/Product/ProductDesktopVariant.jsx')

diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx
index ef61bafd..bae00b87 100644
--- a/src/lib/product/components/Product/ProductDesktopVariant.jsx
+++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx
@@ -1,137 +1,154 @@
-import Image from '@/core/components/elements/Image/Image'
-import Link from '@/core/components/elements/Link/Link'
-import DesktopView from '@/core/components/views/DesktopView'
-import currencyFormat from '@/core/utils/currencyFormat'
-import { HeartIcon } from '@heroicons/react/24/outline'
-import { useCallback, useEffect, useRef, useState } from 'react'
-import LazyLoad from 'react-lazy-load'
-import ProductSimilar from '../ProductSimilar'
-import { toast } from 'react-hot-toast'
-import { updateItemCart } from '@/core/utils/cart'
-import { useRouter } from 'next/router'
-import { createSlug } from '@/core/utils/slug'
-import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
-import ProductCard from '../ProductCard'
-import productSimilarApi from '../../api/productSimilarApi'
-import whatsappUrl from '@/core/utils/whatsappUrl'
-import useAuth from '@/core/hooks/useAuth'
-import odooApi from '@/core/api/odooApi'
-import { useProductCartContext } from '@/contexts/ProductCartContext'
-import { Box, Skeleton, Tooltip } from '@chakra-ui/react'
-import { Info } from 'lucide-react'
-
-const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) => {
-  const router = useRouter()
-  const auth = useAuth()
-  const { slug } = router.query
-
-  const [lowestPrice, setLowestPrice] = useState(null)
-
-  const [addCartAlert, setAddCartAlert] = useState(false)
-  const [isLoadingSLA, setIsLoadingSLA] = useState(true)
-
-  const { setRefreshCart } = useProductCartContext()
+import { Box, Skeleton, Tooltip } from '@chakra-ui/react';
+import { HeartIcon } from '@heroicons/react/24/outline';
+import { Info } from 'lucide-react';
+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 { useProductCartContext } from '@/contexts/ProductCartContext';
+import odooApi from '@/core/api/odooApi';
+import Image from '@/core/components/elements/Image/Image';
+import Link from '@/core/components/elements/Link/Link';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import DesktopView from '@/core/components/views/DesktopView';
+import useAuth from '@/core/hooks/useAuth';
+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 productSimilarApi from '../../api/productSimilarApi';
+import ProductCard from '../ProductCard';
+import ProductSimilar from '../ProductSimilar';
+
+const ProductDesktopVariant = ({
+  product,
+  wishlist,
+  toggleWishlist,
+  isVariant,
+}) => {
+  const router = useRouter();
+  const auth = useAuth();
+  const { slug } = router.query;
+
+  const [lowestPrice, setLowestPrice] = useState(null);
+
+  const [addCartAlert, setAddCartAlert] = useState(false);
+  const [isLoadingSLA, setIsLoadingSLA] = useState(true);
+
+  const { setRefreshCart } = useProductCartContext();
 
   const getLowestPrice = useCallback(() => {
-    const lowest = product.price
+    const lowest = product.price;
     /* const lowest = prices.reduce((lowest, price) => {
       return price.priceDiscount < lowest.priceDiscount ? price : lowest
     }, prices[0])*/
-    return lowest
-  }, [product])
+    return lowest;
+  }, [product]);
 
   useEffect(() => {
-    const lowest = getLowestPrice()
-    setLowestPrice(lowest)
-  }, [getLowestPrice])
+    const lowest = getLowestPrice();
+    setLowestPrice(lowest);
+  }, [getLowestPrice]);
 
-  const [informationTab, setInformationTab] = useState(informationTabOptions[0].value)
+  const [informationTab, setInformationTab] = useState(
+    informationTabOptions[0].value
+  );
 
-  const variantQuantityRefs = useRef([])
+  const variantQuantityRefs = useRef([]);
 
   const setVariantQuantityRef = (variantId) => (element) => {
-    variantQuantityRefs.current[variantId] = element
-  }
+    variantQuantityRefs.current[variantId] = element;
+  };
 
   const validQuantity = (quantity) => {
-    let isValid = true
+    let isValid = true;
     if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) {
-      toast.error('Jumlah barang minimal 1')
-      isValid = false
+      toast.error('Jumlah barang minimal 1');
+      isValid = false;
     }
-    return isValid
-  }
+    return isValid;
+  };
 
   const handleAddToCart = (variant) => {
     if (!auth) {
-      router.push(`/login?next=/shop/product/${slug}`)
-      return
+      router.push(`/login?next=/shop/product/${slug}`);
+      return;
     }
-    const quantity = variantQuantityRefs.current[product.id].value
-    if (!validQuantity(quantity)) return
+    const quantity = variantQuantityRefs.current[product.id].value;
+    if (!validQuantity(quantity)) return;
     updateItemCart({
       productId: product.id,
       quantity,
       programLineId: null,
       selected: true,
-      source: null
+      source: null,
     }).then(() => {
-      setRefreshCart(true)
-    })
-    setAddCartAlert(true)
-  }
+      setRefreshCart(true);
+    });
+    setAddCartAlert(true);
+  };
 
   const handleBuy = (variant) => {
-    const quantity = variantQuantityRefs.current[product.id].value
-    if (!validQuantity(quantity)) return
+    const quantity = variantQuantityRefs.current[product.id].value;
+    if (!validQuantity(quantity)) return;
 
     updateItemCart({
       productId: variant,
       quantity,
       programLineId: null,
       selected: true,
-      source: 'buy'
-    })
-    router.push(`/shop/checkout?source=buy`)
-  }
+      source: 'buy',
+    });
+    router.push(`/shop/checkout?source=buy`);
+  };
 
-  const variantSectionRef = useRef(null)
+  const variantSectionRef = useRef(null);
   const goToVariantSection = () => {
     if (variantSectionRef.current) {
-      const position = variantSectionRef.current.getBoundingClientRect()
+      const position = variantSectionRef.current.getBoundingClientRect();
       window.scrollTo({
         top: position.top - 120 + window.pageYOffset,
-        behavior: 'smooth'
-      })
+        behavior: 'smooth',
+      });
     }
-  }
+  };
 
   const productSimilarQuery = [
     product?.name,
     `fq=-product_id_i:${product.id}`,
-    `fq=-manufacture_id_i:${product.manufacture?.id || 0}`
-  ].join('&')
+    `fq=-manufacture_id_i:${product.manufacture?.id || 0}`,
+  ].join('&');
 
-  const [productSimilarInBrand, setProductSimilarInBrand] = useState(null)
+  const [productSimilarInBrand, setProductSimilarInBrand] = useState(null);
 
   useEffect(() => {
     const loadProductSimilarInBrand = async () => {
-      const productSimilarQuery = [product?.name, `fq=-product_id_i:${product.id}`].join('&')
-      const dataProductSimilar = await productSimilarApi({ query: productSimilarQuery })
-      setProductSimilarInBrand(dataProductSimilar.products)
-    }
-    if (!productSimilarInBrand) loadProductSimilarInBrand()
-  }, [product, productSimilarInBrand])
+      const productSimilarQuery = [
+        product?.name,
+        `fq=-product_id_i:${product.id}`,
+      ].join('&');
+      const dataProductSimilar = await productSimilarApi({
+        query: productSimilarQuery,
+      });
+      setProductSimilarInBrand(dataProductSimilar.products);
+    };
+    if (!productSimilarInBrand) loadProductSimilarInBrand();
+  }, [product, productSimilarInBrand]);
 
   useEffect(() => {
     const fetchData = async () => {
-      const dataSLA = await odooApi('GET', `/api/v1/product_variant/${product.id}/stock`)
-      product.sla = dataSLA
+      const dataSLA = await odooApi(
+        'GET',
+        `/api/v1/product_variant/${product.id}/stock`
+      );
+      product.sla = dataSLA;
 
-      setIsLoadingSLA(false)
-    }
-    fetchData()
-  }, [product])
+      setIsLoadingSLA(false);
+    };
+    fetchData();
+  }, [product]);
 
   return (
     <DesktopView>
@@ -140,14 +157,16 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
           <div className='w-full flex flex-wrap'>
             <div className='w-5/12'>
               <Image
-                src={product.image}
+                src={product.image + '?variant=True'}
                 alt={product.name}
                 className='h-[430px] object-contain object-center w-full border border-gray_r-4'
               />
             </div>
 
             <div className='w-7/12 px-4'>
-              <h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1>
+              <h1 className='text-title-md leading-10 font-medium'>
+                {product?.name}
+              </h1>
               <div className='mt-10'>
                 <div className='flex p-3'>
                   <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div>
@@ -177,7 +196,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
                 </div>
 
                 <div className='flex p-3 items-center bg-gray_r-4'>
-                  <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div>
+                  <div className='w-4/12 text-gray_r-12/70'>
+                    Persiapan Barang
+                  </div>
                   <div className='w-8/12'>
                     {!product?.sla && <Skeleton width='20%' height='16px' />}
                     {product?.sla && (
@@ -203,8 +224,13 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
                       <a
                         href={whatsappUrl('product', {
                           name: product.name,
-                            manufacture: product?.manufacture?.name,
-                            url: createSlug('/shop/product/', product.name, product.id, true)
+                          manufacture: product?.manufacture?.name,
+                          url: createSlug(
+                            '/shop/product/',
+                            product.name,
+                            product.id,
+                            true
+                          ),
                         })}
                         className='text-danger-500 font-medium'
                       >
@@ -221,7 +247,12 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
                       <a
                         href={whatsappUrl('productWeight', {
                           name: product.name,
-                          url: createSlug('/shop/product/', product.name, product.id, true)
+                          url: createSlug(
+                            '/shop/product/',
+                            product.name,
+                            product.id,
+                            true
+                          ),
                         })}
                         className='text-danger-500 font-medium'
                       >
@@ -270,7 +301,8 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
             </div> */}
           </div>
           <div className='w-[25%]'>
-            {product?.isFlashsale > 0 && product?.price?.discountPercentage > 0? (
+            {product?.isFlashsale > 0 &&
+            product?.price?.discountPercentage > 0 ? (
               <>
                 <div className='flex gap-x-1 items-center mt-2'>
                   <div className='badge-solid-red text-caption-1'>
@@ -285,7 +317,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
                 </div>
                 <div className='text-gray_r-9 text-base font-normal mt-1'>
                   Termasuk PPN:{' '}
-                  {currencyFormat(product?.price?.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
+                  {currencyFormat(
+                    product?.price?.priceDiscount * process.env.NEXT_PUBLIC_PPN
+                  )}
                 </div>
               </>
             ) : (
@@ -295,7 +329,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
                     {currencyFormat(product?.price?.price)}
                     <div className='text-gray_r-9 text-base font-normal mt-1'>
                       Termasuk PPN:{' '}
-                      {currencyFormat(product?.price?.price * process.env.NEXT_PUBLIC_PPN)}
+                      {currencyFormat(
+                        product?.price?.price * process.env.NEXT_PUBLIC_PPN
+                      )}
                     </div>
                   </>
                 ) : (
@@ -305,7 +341,12 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
                       href={whatsappUrl('product', {
                         name: product.name,
                         manufacture: product.manufacture?.name,
-                        url: createSlug('/shop/product/', product.name, product.id, true)
+                        url: createSlug(
+                          '/shop/product/',
+                          product.name,
+                          product.id,
+                          true
+                        ),
                       })}
                       className='text-danger-500 underline'
                       rel='noopener noreferrer'
@@ -340,7 +381,10 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
               </button>
             </div>
             <div className='flex mt-4'>
-              <button className='flex items-center gap-x-1' onClick={toggleWishlist}>
+              <button
+                className='flex items-center gap-x-1'
+                onClick={toggleWishlist}
+              >
                 {wishlist.data?.productTotal > 0 ? (
                   <HeartIcon className='w-6 fill-danger-500 text-danger-500' />
                 ) : (
@@ -366,7 +410,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
         </div>
 
         <div className='my-12'>
-          <div className='text-h-lg font-semibold mb-6'>Kamu Mungkin Juga Suka</div>
+          <div className='text-h-lg font-semibold mb-6'>
+            Kamu Mungkin Juga Suka
+          </div>
           <LazyLoad>
             <ProductSimilar query={productSimilarQuery} />
           </LazyLoad>
@@ -381,21 +427,28 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
           <div className='flex mt-4'>
             <div className='w-[10%]'>
               <Image
-                src={product.image}
+                src={product.image + '?variant=True'}
                 alt={product.name}
                 className='h-32 object-contain object-center w-full border border-gray_r-4'
               />
             </div>
-            <div className='ml-3 flex flex-1 items-center font-normal'>{product.name}</div>
+            <div className='ml-3 flex flex-1 items-center font-normal'>
+              {product.name}
+            </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'>
+              <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>
+            <div className='text-h-sm font-semibold mb-6'>
+              Kamu Mungkin Juga Suka
+            </div>
             <LazyLoad>
               <ProductSimilar query={productSimilarQuery} />
             </LazyLoad>
@@ -403,29 +456,33 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
         </BottomPopup>
       </div>
     </DesktopView>
-  )
-}
+  );
+};
 
 const informationTabOptions = [
   { value: 'description', label: 'Deskripsi' },
-  { value: 'information', label: 'Info Penting' }
-]
+  { value: 'information', label: 'Info Penting' },
+];
 
 const TabButton = ({ children, active, ...props }) => {
   const activeClassName = active
     ? 'text-danger-500 underline underline-offset-4'
-    : 'text-gray_r-12/80'
+    : 'text-gray_r-12/80';
   return (
-    <button {...props} type='button' className={`font-medium ${activeClassName}`}>
+    <button
+      {...props}
+      type='button'
+      className={`font-medium ${activeClassName}`}
+    >
       {children}
     </button>
-  )
-}
+  );
+};
 
 const TabContent = ({ children, active, className = '', ...props }) => (
   <div {...props} className={`${active ? 'block' : 'hidden'} ${className}`}>
     {children}
   </div>
-)
+);
 
-export default ProductDesktopVariant
+export default ProductDesktopVariant;
-- 
cgit v1.2.3


From 7892008931b6c2e4c0f220212aa51b489d79dc86 Mon Sep 17 00:00:00 2001
From: "HATEC\\SPVDEV001" <tri.susilo@altama.co.id>
Date: Thu, 7 Mar 2024 14:51:12 +0700
Subject: add information product in page variant detail

---
 .../components/Product/ProductDesktopVariant.jsx   | 49 +++++++---------------
 1 file changed, 14 insertions(+), 35 deletions(-)

(limited to 'src/lib/product/components/Product/ProductDesktopVariant.jsx')

diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx
index bae00b87..09b30a44 100644
--- a/src/lib/product/components/Product/ProductDesktopVariant.jsx
+++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx
@@ -1,3 +1,4 @@
+
 import { Box, Skeleton, Tooltip } from '@chakra-ui/react';
 import { HeartIcon } from '@heroicons/react/24/outline';
 import { Info } from 'lucide-react';
@@ -264,41 +265,19 @@ const ProductDesktopVariant = ({
               </div>
             </div>
 
-            {/* <div className='w-full'>
-              <div className='mt-12'>
-                <div className='text-h-lg font-semibold'>Informasi Produk</div>
-                <div className='flex gap-x-4 mt-6 mb-4'>
-                  {informationTabOptions.map((option) => (
-                    <TabButton
-                      value={option.value}
-                      key={option.value}
-                      active={informationTab == option.value}
-                      onClick={() => setInformationTab(option.value)}
-                    >
-                      {option.label}
-                    </TabButton>
-                  ))}
-                </div>
-                <div className='flex'>
-                  <div className='w-3/4 leading-7 product__description'>
-                    <TabContent active={informationTab == 'description'}>
-                      <span
-                        dangerouslySetInnerHTML={{
-                          __html:
-                            product.description != ''
-                              ? product.description
-                              : 'Belum ada deskripsi produk.'
-                        }}
-                      />
-                    </TabContent>
-
-                    <TabContent active={informationTab == 'information'}>
-                      Belum ada informasi.
-                    </TabContent>
-                  </div>
-                </div>
-              </div>
-            </div> */}
+            <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
+                className='leading-relaxed text-gray-700'
+                dangerouslySetInnerHTML={{
+                  __html:
+                    !product.parent.description || product.parent.description == '<p><br></p>'
+                      ? 'Belum ada deskripsi'
+                      : product.parent.description,
+                }}
+              />
+            </div>
           </div>
           <div className='w-[25%]'>
             {product?.isFlashsale > 0 &&
-- 
cgit v1.2.3

