summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/components/elements/Navbar/TopBanner.jsx2
-rw-r--r--src/lib/category/components/Category.jsx2
-rw-r--r--src/lib/product/components/Product/ColumnsSLA.jsx81
-rw-r--r--src/lib/product/components/Product/ProductDesktop.jsx81
-rw-r--r--src/lib/product/components/Product/ProductMobile.jsx59
-rw-r--r--src/lib/product/components/ProductCard.jsx20
-rw-r--r--src/pages/shop/product/[slug].jsx10
7 files changed, 136 insertions, 119 deletions
diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx
index dca2e930..a757c260 100644
--- a/src/core/components/elements/Navbar/TopBanner.jsx
+++ b/src/core/components/elements/Navbar/TopBanner.jsx
@@ -6,7 +6,7 @@ import { TopBannerSkeleton } from '../Skeleton/TopBannerSkeleton'
const TopBanner = () => {
const fetchTopBanner = async () => await odooApi('GET', '/api/v1/banner?type=top-banner')
- const topBanner = useQuery('topBanner', fetchTopBanner)
+ const topBanner = useQuery('topBanner', fetchTopBanner, { refetchOnWindowFocus: false })
if (topBanner.isLoading) {
return <TopBannerSkeleton />
diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx
index 884a871f..af696d42 100644
--- a/src/lib/category/components/Category.jsx
+++ b/src/lib/category/components/Category.jsx
@@ -10,7 +10,7 @@ const Category = () => {
useEffect(() => {
const loadCategories = async () => {
let dataCategories = await odooApi('GET', '/api/v1/category/tree')
- dataCategories = dataCategories.map((category) => {
+ dataCategories = dataCategories?.map((category) => {
category.childs = category.childs.map((child1Category) => {
return {
...child1Category,
diff --git a/src/lib/product/components/Product/ColumnsSLA.jsx b/src/lib/product/components/Product/ColumnsSLA.jsx
new file mode 100644
index 00000000..33da703a
--- /dev/null
+++ b/src/lib/product/components/Product/ColumnsSLA.jsx
@@ -0,0 +1,81 @@
+import odooApi from '@/core/api/odooApi'
+import { createSlug } from '@/core/utils/slug'
+import whatsappUrl from '@/core/utils/whatsappUrl'
+import { Button, Spinner } from 'flowbite-react'
+import { memo, useEffect, useState } from 'react'
+import { useQuery } from 'react-query'
+
+const ColumnSLA = ({ variant, product }) => {
+ const fetchSLA = async () => await odooApi('GET', `/api/v1/product_variant/${variant.id}/stock`)
+ const dataSLA = useQuery(`VariantSLA-${variant.id}`, fetchSLA, { refetchOnWindowFocus: false })
+
+ return (
+ <>
+ <td>
+ {dataSLA.isFetching ? (
+ <div className='text-center'>
+ <Spinner aria-label='Center-aligned spinner example' />
+ </div>
+ ) : dataSLA?.data?.qty > 0 ? (
+ dataSLA?.data?.qty
+ ) : (
+ <a
+ href={whatsappUrl('product', {
+ name: variant.name,
+ manufacture: product.manufacture?.name,
+ url: createSlug('/shop/product/', product.name, product.id, true)
+ })}
+ className='text-danger-500 font-medium'
+ target='_blank'
+ rel='noreferrer noopener'
+ >
+ Tanya Admin
+ </a>
+ )}
+ </td>
+ <td className='flex justify-center'>
+ {dataSLA.isFetching ? (
+ <Button color='gray'>
+ <Spinner aria-label='Alternate spinner button example' />
+ <span className='pl-3'>Loading...</span>
+ </Button>
+ ) : dataSLA?.data?.slaDate != '-' ? (
+ <button
+ type='button'
+ title={`Masa Persiapan Barang ${dataSLA?.data?.slaDate}`}
+ className={`flex gap-x-1 items-center p-2 rounded-lg w-full ${
+ dataSLA?.data?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light'
+ }`}
+ >
+ <div
+ className={`flex-1 text-caption-1 ${
+ dataSLA?.data?.slaDate === 'indent' ? 'text-white' : ''
+ }`}
+ >
+ {dataSLA?.data?.slaDate}
+ </div>
+ <div className='flex-end'>
+ <svg
+ aria-hidden='true'
+ fill='none'
+ stroke='currentColor'
+ stroke-width='1.5'
+ className={`w-7 h-7 ${dataSLA?.data?.slaDate === 'indent' ? 'text-white' : ''}`}
+ >
+ <path
+ d='M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z'
+ stroke-linecap='round'
+ stroke-linejoin='round'
+ ></path>
+ </svg>
+ </div>
+ </button>
+ ) : (
+ '-'
+ )}
+ </td>
+ </>
+ )
+}
+
+export default memo(ColumnSLA)
diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx
index 618c35f5..937f2746 100644
--- a/src/lib/product/components/Product/ProductDesktop.jsx
+++ b/src/lib/product/components/Product/ProductDesktop.jsx
@@ -20,7 +20,8 @@ import PromotionType from '@/lib/promotinProgram/components/PromotionType'
import useAuth from '@/core/hooks/useAuth'
import ImageNext from 'next/image'
import CountDown2 from '@/core/components/elements/CountDown/CountDown2'
-import CountDown from '@/core/components/elements/CountDown/CountDown'
+import { LazyLoadComponent } from 'react-lazy-load-image-component'
+import ColumnsSLA from './ColumnsSLA'
const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
const router = useRouter()
@@ -184,7 +185,7 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
setIsLoadingSLA(false)
}
- fetchData()
+ if (product.variantTotal == 1) fetchData()
}, [product])
return (
@@ -219,7 +220,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
height={10}
/>
<span className='text-white text-lg font-semibold'>
- {product.flashSale.tag || 'FLASH SALE'}
+ {product?.flashSale?.tag != 'false' || product?.flashSale?.tag
+ ? product?.flashSale?.tag
+ : 'FLASH SALE'}
</span>
</div>
<div>
@@ -450,7 +453,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
height={10}
/>
<span className='text-white text-xs font-semibold'>
- {product.flashSale.tag || 'FLASH SALE'}
+ {product?.flashSale?.tag != 'false' || product?.flashSale?.tag
+ ? product?.flashSale?.tag
+ : 'FLASH SALE'}
</span>
</div>
)}
@@ -564,71 +569,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
{variant.code}
</td>
<td>{variant.attributes.join(', ') || '-'}</td>
- <td>
- {isLoadingSLA ? (
- <div className='text-center'>
- <Spinner aria-label='Center-aligned spinner example' />
- </div>
- ) : variant?.sla?.qty > 0 ? (
- variant?.sla?.qty
- ) : (
- <a
- href={whatsappUrl('product', {
- name: variant.name,
- manufacture: product.manufacture?.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
- })}
- className='text-danger-500 font-medium'
- target='_blank'
- rel='noreferrer noopener'
- >
- Tanya Admin
- </a>
- )}
- </td>
- <td className='flex justify-center'>
- {isLoadingSLA ? (
- <Button color='gray'>
- <Spinner aria-label='Alternate spinner button example' />
- <span className='pl-3'>Loading...</span>
- </Button>
- ) : variant?.sla?.slaDate != '-' ? (
- <button
- type='button'
- title={`Masa Persiapan Barang ${variant?.sla?.slaDate}`}
- className={`flex gap-x-1 items-center p-2 rounded-lg w-full ${
- variant?.sla?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light'
- }`}
- >
- <div
- className={`flex-1 text-caption-1 ${
- variant?.sla?.slaDate === 'indent' ? 'text-white' : ''
- }`}
- >
- {variant?.sla?.slaDate}
- </div>
- <div className='flex-end'>
- <svg
- aria-hidden='true'
- fill='none'
- stroke='currentColor'
- stroke-width='1.5'
- className={`w-7 h-7 ${
- variant?.sla?.slaDate === 'indent' ? 'text-white' : ''
- }`}
- >
- <path
- d='M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z'
- stroke-linecap='round'
- stroke-linejoin='round'
- ></path>
- </svg>
- </div>
- </button>
- ) : (
- '-'
- )}
- </td>
+ <LazyLoadComponent>
+ <ColumnsSLA variant={variant} product={product} />
+ </LazyLoadComponent>
<td>
{variant.price.discountPercentage > 0 &&
variant.price.priceDiscount > 0 && (
diff --git a/src/lib/product/components/Product/ProductMobile.jsx b/src/lib/product/components/Product/ProductMobile.jsx
index 56f20aac..6b0b27a5 100644
--- a/src/lib/product/components/Product/ProductMobile.jsx
+++ b/src/lib/product/components/Product/ProductMobile.jsx
@@ -83,35 +83,6 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
})
useEffect(() => {
- const fetchData = async () => {
- const promises = product.variants.map(async (variant) => {
- const dataSLA = await odooApi('GET', `/api/v1/product_variant/${variant.id}/stock`)
- return {
- ...variant,
- sla: dataSLA
- }
- })
- const variantData = await Promise.all(promises)
- product.variants = variantData
-
- setIsLoadingSLA(false)
- if (product.variants.length === 1) {
- setActiveVariant({
- id: product.variants[0].id,
- code: product.variants[0].code,
- name: product.variants[0].parent.name,
- price: product.variants[0].price,
- stock: product.variants[0].stock,
- weight: product.variants[0].weight,
- sla: product.variants[0].sla,
- hasProgram: product.variants[0].hasProgram
- })
- }
- }
- fetchData()
- }, [product])
-
- useEffect(() => {
if (!selectedVariant && variantOptions.length == 1) {
setSelectedVariant(variantOptions[0])
}
@@ -123,16 +94,23 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
const variantAttributes =
variant.attributes.length > 0 ? ' - ' + variant.attributes.join(', ') : ''
- setActiveVariant({
+ const newActiveVariant = {
id: variant.id,
code: variant.code,
name: variant.parent.name + variantAttributes,
price: variant.price,
stock: variant.stock,
weight: variant.weight,
- sla: variant.sla,
hasProgram: variant.hasProgram
- })
+ }
+
+ setActiveVariant(newActiveVariant)
+
+ const fetchSLA = async () => {
+ const dataSLA = await odooApi('GET', `/api/v1/product_variant/${variant.id}/stock`)
+ setActiveVariant({ ...newActiveVariant, sla: dataSLA })
+ }
+ fetchSLA()
}
}, [selectedVariant, product])
@@ -208,7 +186,9 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
height={10}
/>
<span className='text-white text-lg font-semibold'>
- {product.flashSale.tag || 'FLASH SALE'}
+ {product?.flashSale?.tag != 'false' || product?.flashSale?.tag
+ ? product?.flashSale?.tag
+ : 'FLASH SALE'}
</span>
</div>
<div>
@@ -353,12 +333,7 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
>
<SpecificationContent label='Ketersediaan'>
<span>
- {isLoadingSLA ? (
- <Button color='gray'>
- <Spinner aria-label='Alternate spinner button example' />
- <span className='pl-3'>Loading...</span>
- </Button>
- ) : selectedVariant ? (
+ {selectedVariant ? (
activeVariant?.sla?.slaDate != '-' ? (
<button
type='button'
@@ -410,13 +385,13 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
<span>{activeVariant?.code || '-'}</span>
</SpecificationContent>
<SpecificationContent label='Stok'>
- {activeVariant?.stock > 0 && (
+ {activeVariant?.sla?.qty > 0 && (
<span className='flex gap-x-1.5'>
<div className='badge-solid-red'>Ready Stock</div>
- <div className='badge-gray'>{activeVariant?.stock > 5 ? '> 5' : '< 5'}</div>
+ <div className='badge-gray'>{activeVariant?.sla?.qty}</div>
</span>
)}
- {activeVariant?.stock == 0 && (
+ {activeVariant?.sla?.qty == 0 && (
<a
href={whatsappUrl('product', {
name: product.name,
diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx
index abf462a1..10ffdaec 100644
--- a/src/lib/product/components/ProductCard.jsx
+++ b/src/lib/product/components/ProductCard.jsx
@@ -8,7 +8,7 @@ import { useRouter } from 'next/router'
const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
const router = useRouter()
-
+
const callForPriceWhatsapp = whatsappUrl('product', {
name: product.name,
url: createSlug('/shop/product/', product.name, product.id, true)
@@ -29,7 +29,12 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
{router.pathname != '/' && product?.flashSale?.id > 0 && (
<div className='absolute bottom-0 w-full grid'>
<div className='absolute bottom-0 w-full h-full'>
- <ImageNext src='/images/GAMBAR-BG-FLASH-SALE.jpg' className='h-full' width={1000} height={100} />
+ <ImageNext
+ src='/images/GAMBAR-BG-FLASH-SALE.jpg'
+ className='h-full'
+ width={1000}
+ height={100}
+ />
</div>
<div className='relative'>
<div className='flex gap-x-1 items-center p-2 justify-center'>
@@ -45,7 +50,9 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
height={5}
/>
<span className='text-white text-[9px] md:text-[10px] font-semibold'>
- {product?.flashSale?.tag != "false" || product?.flashSale?.tag != product?.flashSale?.tag ? product?.flashSale?.tag : 'FLASH SALE'}
+ {product?.flashSale?.tag != 'false' || product?.flashSale?.tag
+ ? product?.flashSale?.tag
+ : 'FLASH SALE'}
</span>
</div>
</div>
@@ -138,7 +145,12 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
width={15}
height={10}
/>
- <span className='text-white text-xs font-semibold'>{product?.flashSale?.tag != "false" || product?.flashSale?.tag != product?.flashSale?.tag ? product?.flashSale?.tag : 'FLASH SALE'}</span>
+ <span className='text-white text-xs font-semibold'>
+ {' '}
+ {product?.flashSale?.tag != 'false' || product?.flashSale?.tag
+ ? product?.flashSale?.tag
+ : 'FLASH SALE'}
+ </span>
</div>
)}
{product?.manufacture?.name ? (
diff --git a/src/pages/shop/product/[slug].jsx b/src/pages/shop/product/[slug].jsx
index 5d706dec..af20413f 100644
--- a/src/pages/shop/product/[slug].jsx
+++ b/src/pages/shop/product/[slug].jsx
@@ -6,6 +6,7 @@ import PageNotFound from '@/pages/404'
import dynamic from 'next/dynamic'
import { useRouter } from 'next/router'
import cookie from 'cookie'
+import axios from 'axios'
const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout'))
const Product = dynamic(() => import('@/lib/product/components/Product/Product'))
@@ -17,7 +18,12 @@ export async function getServerSideProps(context) {
const auth = cookieObj.auth ? JSON.parse(cookieObj.auth) : {}
const authToken = auth?.token || ''
- let product = await productApi({ id: getIdFromSlug(slug), headers: { Token: authToken } })
+ let response = await axios(
+ `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-detail?id=`+getIdFromSlug(slug)
+ )
+ let product = response.data
+ // let productSolr = await productApi({ id: getIdFromSlug(slug), headers: { Token: authToken } })
+ // let productSolr = null
if (product?.length == 1) {
product = product[0]
const regexHtmlTags = /(<([^>]+)>)/gi
@@ -35,7 +41,7 @@ export async function getServerSideProps(context) {
}
}
-export default function ProductDetail({ product }) {
+export default function ProductDetail({ product}) {
const router = useRouter()
if (!product) return <PageNotFound />