From e07a57651649cb2493e5b00a361797cf1392a186 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 1 Aug 2024 11:59:26 +0700 Subject: update template switch --- .../components/Product/ProductDesktopVariant.jsx | 66 ++++++++++++++++++-- .../components/Product/ProductMobileVariant.jsx | 71 +++++++++++++++++++--- 2 files changed, 123 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 09b30a44..882673f4 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -6,6 +6,11 @@ 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'; @@ -18,11 +23,14 @@ 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, @@ -32,7 +40,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); @@ -53,6 +61,20 @@ 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 ); @@ -154,6 +176,7 @@ const ProductDesktopVariant = ({ return (
+
@@ -263,9 +286,42 @@ const ProductDesktopVariant = ({
+
+
+ + + + + + + +
+ -
+ +

Informasi Produk

-
+
{product?.isFlashsale > 0 && product?.price?.discountPercentage > 0 ? ( <> @@ -359,7 +415,7 @@ const ProductDesktopVariant = ({ Beli
-
+ {/*
+
*/}
Produk Serupa diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx index af9e52bb..ce836d5b 100644 --- a/src/lib/product/components/Product/ProductMobileVariant.jsx +++ b/src/lib/product/components/Product/ProductMobileVariant.jsx @@ -16,9 +16,15 @@ 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 + const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { const router = useRouter(); @@ -28,7 +34,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 = () => { @@ -60,6 +66,20 @@ 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) { @@ -120,14 +140,17 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { return ( +
+ +
{product.name}
-
+
{product.manufacture?.name ? ( { ) : (
-
)} - + + + + + + +
+ {/* + */}
-

{activeVariant?.name}

+

{activeVariant?.name}

{activeVariant.isFlashSale && activeVariant?.price?.discountPercentage > 0 ? ( @@ -173,11 +226,11 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
) : ( -

+

{activeVariant?.price?.price > 0 ? ( <> {currencyFormat(activeVariant?.price?.price)} -
+
Termasuk PPN:{' '} {currencyFormat( activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN -- cgit v1.2.3 From 77d01b81d46dfb2d20fec48246be4293f1d8fe69 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 09:30:38 +0700 Subject: update error code --- src/lib/cart/components/Cartheader.jsx | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index f76634ce..6915d4f6 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -7,9 +7,6 @@ import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' -import currencyFormat from '@/core/utils/currencyFormat' -import Image from '@/core/components/elements/Image/Image' -import { createSlug } from '@/core/utils/slug' import whatsappUrl from '@/core/utils/whatsappUrl' import { AnimatePresence, motion } from 'framer-motion' import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css' -- cgit v1.2.3 From 574754df6366cd693fbe2cd04a7a50fdf9597d1e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 09:35:30 +0700 Subject: update error --- src/lib/cart/components/Cartheader.jsx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index 6915d4f6..f76634ce 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -7,6 +7,9 @@ import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' +import currencyFormat from '@/core/utils/currencyFormat' +import Image from '@/core/components/elements/Image/Image' +import { createSlug } from '@/core/utils/slug' import whatsappUrl from '@/core/utils/whatsappUrl' import { AnimatePresence, motion } from 'framer-motion' import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css' -- cgit v1.2.3 From 04c73b4da52658b0060a20bbd100a8fdacd68ef9 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 09:47:26 +0700 Subject: Revert " update error code" This reverts commit 70ec90799154dab2da475e840d8277d85648483b. --- src/lib/cart/components/Cartheader.jsx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index c7a8f0b8..30e89317 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -6,6 +6,9 @@ import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' +import currencyFormat from '@/core/utils/currencyFormat' +import Image from '@/core/components/elements/Image/Image' +import { createSlug } from '@/core/utils/slug' import Image from '@/core/components/elements/Image/Image' import whatsappUrl from '@/core/utils/whatsappUrl' import { AnimatePresence, motion } from 'framer-motion' -- cgit v1.2.3 From 53d4cc076bbf52b1c4220df912755513e4bb5864 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 5 Aug 2024 09:53:48 +0700 Subject: Revert " update error code" This reverts commit 70ec90799154dab2da475e840d8277d85648483b. --- src/lib/cart/components/Cartheader.jsx | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index 30e89317..c7a8f0b8 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -6,9 +6,6 @@ import useAuth from '@/core/hooks/useAuth' import { useRouter } from 'next/router' import odooApi from '@/core/api/odooApi' import { useProductCartContext } from '@/contexts/ProductCartContext' -import currencyFormat from '@/core/utils/currencyFormat' -import Image from '@/core/components/elements/Image/Image' -import { createSlug } from '@/core/utils/slug' import Image from '@/core/components/elements/Image/Image' import whatsappUrl from '@/core/utils/whatsappUrl' import { AnimatePresence, motion } from 'framer-motion' -- cgit v1.2.3 From 6bfa8b7b0c6afaec7eb3d81983d0f012953b07f2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 11:49:54 +0700 Subject: add pop up semua promo --- .../components/elements/Navbar/NavbarDesktop.jsx | 70 ++++++++++++++++++---- src/core/components/elements/Navbar/TopBanner.jsx | 9 ++- 2 files changed, 65 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 7d9e4264..ff43d4a0 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -10,11 +10,12 @@ import { ChevronDownIcon, DocumentCheckIcon, HeartIcon, + ArrowUpRightIcon, } from '@heroicons/react/24/outline'; import dynamic from 'next/dynamic'; import Image from 'next/image'; import { useRouter } from 'next/router'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import DesktopView from '../../views/DesktopView'; import Link from '../Link/Link'; import NavbarUserDropdown from './NavbarUserDropdown'; @@ -47,6 +48,46 @@ const NavbarDesktop = () => { const { product } = useProductContext(); const { isOpen, onOpen, onClose } = useDisclosure(); + const [showPopup, setShowPopup] = useState(false); + const [isTop, setIsTop] = useState(true); + + const handleTopBannerLoad = useCallback(() => { + const showTimer = setTimeout(() => { + setShowPopup(true); + }, 500); + + const hideTimer = setTimeout(() => { + setShowPopup(false); + }, 9500); + + return () => { + clearTimeout(showTimer); + clearTimeout(hideTimer); + }; + }, []); + + useEffect(() => { + const handleScroll = () => { + setIsTop(window.scrollY < 100); + }; + + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + + useEffect(() => { + const handleScroll = () => { + setIsTop(window.scrollY < 100); + }; + + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + useEffect(() => { if (router.pathname === '/shop/product/[slug]') { setPayloadWa({ @@ -79,7 +120,7 @@ const NavbarDesktop = () => { return ( - +
@@ -204,6 +245,7 @@ const NavbarDesktop = () => {
+ { rel="noreferrer" >

Semua Promo

- {/*
- promo -
*/} - + {showPopup && router.pathname === '/' && ( +
+

+ Penawaran Terbatas +

+
+ )} + {/* {showPopup && router.pathname === '/' && ( +
+ +
+ )} */} + { +const TopBanner = ({ onLoad }) => { const topBanner = useQuery({ queryKey: 'topBanner', queryFn: async () => await odooApi('GET', '/api/v1/banner?type=top-banner'), @@ -16,6 +17,12 @@ const TopBanner = () => { const hasData = topBanner.data?.length > 0; const data = topBanner.data?.[0] || null; + useEffect(() => { + if (hasData) { + onLoad(); + } + }, [hasData, onLoad]); + return ( Date: Wed, 7 Aug 2024 13:14:27 +0700 Subject: add penwaran terbatas popup --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index ff43d4a0..78e7f54a 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -57,7 +57,7 @@ const NavbarDesktop = () => { }, 500); const hideTimer = setTimeout(() => { - setShowPopup(false); + // setShowPopup(false); }, 9500); return () => { @@ -256,18 +256,22 @@ const NavbarDesktop = () => { >

Semua Promo

- {showPopup && router.pathname === '/' && ( + {/* {showPopup && router.pathname === '/' && (

Penawaran Terbatas

- )} - {/* {showPopup && router.pathname === '/' && ( -
- -
)} */} + {showPopup && router.pathname === '/' && ( + penawaran terbatas + )} Date: Wed, 7 Aug 2024 15:22:39 +0700 Subject: update all promo --- .../components/elements/Navbar/NavbarDesktop.jsx | 19 ++++--- .../flashSale/components/FlashSaleNonDisplay.jsx | 66 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 src/lib/flashSale/components/FlashSaleNonDisplay.jsx (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 78e7f54a..cc5ea611 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -255,6 +255,16 @@ const NavbarDesktop = () => { rel="noreferrer" >

Semua Promo

+ {showPopup && ( + penawaran terbatas + )} {/* {showPopup && router.pathname === '/' && (
@@ -263,15 +273,6 @@ const NavbarDesktop = () => {

)} */} - {showPopup && router.pathname === '/' && ( - penawaran terbatas - )} { + const [flashSales, setFlashSales] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const loadFlashSales = async () => { + const dataFlashSales = await flashSaleApi(); + setFlashSales(dataFlashSales); + setIsLoading(false); + }; + loadFlashSales(); + }, []); + + if (isLoading) { + return ; + } + + return ( + flashSales?.length > 0 && ( +
+ {flashSales.map((flashSale, index) => ( +
+
+
+ Penawaran Terbatas +
+
+ +
+ +
+
+ ))} +
+ ) + ); +}; + +const FlashSaleProduct = ({ flashSaleId }) => { + const [products, setProducts] = useState(null); + + useEffect(() => { + const loadProducts = async () => { + const dataProducts = await productSearchApi({ + query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500&orderBy=flashsale_discount_f desc`, + operation: 'AND', + }); + setProducts(dataProducts.response); + }; + loadProducts(); + }, [flashSaleId]); + + return ; +}; + +export default FlashSaleNonDisplay; -- cgit v1.2.3 From 085dcb058ef4b92cea8b4044e65dd940580f3f42 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 15:26:32 +0700 Subject: merge all promotion --- .../components/elements/Footer/BasicFooter.jsx | 2 +- .../components/elements/Navbar/NavbarDesktop.jsx | 75 ++++++++++++++++++---- src/core/components/elements/Navbar/TopBanner.jsx | 9 ++- .../flashSale/components/FlashSaleNonDisplay.jsx | 66 +++++++++++++++++++ src/lib/product/components/ProductCard.jsx | 4 +- 5 files changed, 139 insertions(+), 17 deletions(-) create mode 100644 src/lib/flashSale/components/FlashSaleNonDisplay.jsx (limited to 'src') diff --git a/src/core/components/elements/Footer/BasicFooter.jsx b/src/core/components/elements/Footer/BasicFooter.jsx index 6129143d..4beea604 100644 --- a/src/core/components/elements/Footer/BasicFooter.jsx +++ b/src/core/components/elements/Footer/BasicFooter.jsx @@ -259,7 +259,7 @@ const InformationCenter = () => (
  • - (021) 2933-8828 / 29 + (021) 2933-8828
  • diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 7d9e4264..cc5ea611 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -10,11 +10,12 @@ import { ChevronDownIcon, DocumentCheckIcon, HeartIcon, + ArrowUpRightIcon, } from '@heroicons/react/24/outline'; import dynamic from 'next/dynamic'; import Image from 'next/image'; import { useRouter } from 'next/router'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import DesktopView from '../../views/DesktopView'; import Link from '../Link/Link'; import NavbarUserDropdown from './NavbarUserDropdown'; @@ -47,6 +48,46 @@ const NavbarDesktop = () => { const { product } = useProductContext(); const { isOpen, onOpen, onClose } = useDisclosure(); + const [showPopup, setShowPopup] = useState(false); + const [isTop, setIsTop] = useState(true); + + const handleTopBannerLoad = useCallback(() => { + const showTimer = setTimeout(() => { + setShowPopup(true); + }, 500); + + const hideTimer = setTimeout(() => { + // setShowPopup(false); + }, 9500); + + return () => { + clearTimeout(showTimer); + clearTimeout(hideTimer); + }; + }, []); + + useEffect(() => { + const handleScroll = () => { + setIsTop(window.scrollY < 100); + }; + + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + + useEffect(() => { + const handleScroll = () => { + setIsTop(window.scrollY < 100); + }; + + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + useEffect(() => { if (router.pathname === '/shop/product/[slug]') { setPayloadWa({ @@ -79,7 +120,7 @@ const NavbarDesktop = () => { return ( - +
    @@ -204,6 +245,7 @@ const NavbarDesktop = () => {
    + { rel="noreferrer" >

    Semua Promo

    - {/*
    - promo -
    */} + {showPopup && ( + penawaran terbatas + )} - + {/* {showPopup && router.pathname === '/' && ( +
    +

    + Penawaran Terbatas +

    +
    + )} */} + { +const TopBanner = ({ onLoad }) => { const { isDesktop, isMobile } = useDevice() const topBanner = useQuery({ queryKey: 'topBanner', @@ -17,6 +18,12 @@ const TopBanner = () => { const hasData = topBanner.data?.length > 0; const data = topBanner.data?.[0] || null; + useEffect(() => { + if (hasData) { + onLoad(); + } + }, [hasData, onLoad]); + return ( { + const [flashSales, setFlashSales] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const loadFlashSales = async () => { + const dataFlashSales = await flashSaleApi(); + setFlashSales(dataFlashSales); + setIsLoading(false); + }; + loadFlashSales(); + }, []); + + if (isLoading) { + return ; + } + + return ( + flashSales?.length > 0 && ( +
    + {flashSales.map((flashSale, index) => ( +
    +
    +
    + Penawaran Terbatas +
    +
    + +
    + +
    +
    + ))} +
    + ) + ); +}; + +const FlashSaleProduct = ({ flashSaleId }) => { + const [products, setProducts] = useState(null); + + useEffect(() => { + const loadProducts = async () => { + const dataProducts = await productSearchApi({ + query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500&orderBy=flashsale_discount_f desc`, + operation: 'AND', + }); + setProducts(dataProducts.response); + }; + loadProducts(); + }, [flashSaleId]); + + return ; +}; + +export default FlashSaleNonDisplay; diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 94db144d..35e2a665 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -17,8 +17,8 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { const [discount, setDiscount] = useState(0); let voucherPastiHemat = 0; - - if (product?.voucherPastiHemat?.length > 0) { + + if (product?.voucherPastiHemat ? product?.voucherPastiHemat.length : voucherPastiHemat > 0) { const stringVoucher = product?.voucherPastiHemat[0]; const validJsonString = stringVoucher.replace(/'/g, '"'); voucherPastiHemat = JSON.parse(validJsonString); -- cgit v1.2.3 From c08901721ea5bf61aa5dca9ada1abaf480d8a1ee Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 16:06:41 +0700 Subject: update pop up --- .../components/elements/Navbar/NavbarDesktop.jsx | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index cc5ea611..a09989a5 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -254,17 +254,20 @@ const NavbarDesktop = () => { target="_blank" rel="noreferrer" > -

    Semua Promo

    {showPopup && ( - penawaran terbatas +
    + penawaran terbatas +
    )} +

    Semua Promo

    {/* {showPopup && router.pathname === '/' && (
    -- cgit v1.2.3 From 43aee0ade51076a49ac998a1ae1357a12a03d31e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 16:09:50 +0700 Subject: merge all promotion --- .../components/elements/Navbar/NavbarDesktop.jsx | 22 +++++++++++++--------- src/core/components/elements/Navbar/TopBanner.jsx | 1 + 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index cc5ea611..e09c13c3 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -11,6 +11,7 @@ import { DocumentCheckIcon, HeartIcon, ArrowUpRightIcon, + ArrowUpRightIcon, } from '@heroicons/react/24/outline'; import dynamic from 'next/dynamic'; import Image from 'next/image'; @@ -254,17 +255,20 @@ const NavbarDesktop = () => { target="_blank" rel="noreferrer" > -

    Semua Promo

    {showPopup && ( - penawaran terbatas +
    + penawaran terbatas +
    )} +

    Semua Promo

    {/* {showPopup && router.pathname === '/' && (
    diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index 265dfb5e..28cfad21 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -4,6 +4,7 @@ import odooApi from '@/core/api/odooApi'; import SmoothRender from '~/components/ui/smooth-render'; import Link from '../Link/Link'; import { useEffect } from 'react'; +import { useEffect } from 'react'; import { background } from '@chakra-ui/react'; const TopBanner = ({ onLoad }) => { -- cgit v1.2.3 From 3bf7a3f59586105d4ee02a43b9c354b06083a7d3 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 16:11:30 +0700 Subject: update error code --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 1 - src/core/components/elements/Navbar/TopBanner.jsx | 1 - 2 files changed, 2 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index e09c13c3..a09989a5 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -11,7 +11,6 @@ import { DocumentCheckIcon, HeartIcon, ArrowUpRightIcon, - ArrowUpRightIcon, } from '@heroicons/react/24/outline'; import dynamic from 'next/dynamic'; import Image from 'next/image'; diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index 28cfad21..265dfb5e 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -4,7 +4,6 @@ import odooApi from '@/core/api/odooApi'; import SmoothRender from '~/components/ui/smooth-render'; import Link from '../Link/Link'; import { useEffect } from 'react'; -import { useEffect } from 'react'; import { background } from '@chakra-ui/react'; const TopBanner = ({ onLoad }) => { -- cgit v1.2.3 From 0fc1ee076d3a59b406f79716c343f15301c1066a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 17:06:58 +0700 Subject: update all promotion card flashSale --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 2 +- src/lib/flashSale/components/FlashSaleNonDisplay.jsx | 2 +- src/pages/api/shop/search.js | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index a09989a5..76012694 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -263,7 +263,7 @@ const NavbarDesktop = () => { height={160} quality={100} // className={`fixed ${isTop ? 'md:top-[145px] lg:top-[160px] ' : 'lg:top-[85px] top-[80px]'} rounded-3xl md:left-1/4 lg:left-1/4 xl:left-1/4 left-2/3 w-40 h-12 p-2 z-50 transition-all duration-300 animate-pulse`} - className={`inline-block relative -top-4 transition-all duration-300 z-20 animate-pulse`} + className={`inline-block relative -top-5 transition-all duration-300 z-20 animate-pulse`} />
    )} diff --git a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx index 85807fad..8dc15b05 100644 --- a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx +++ b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx @@ -52,7 +52,7 @@ const FlashSaleProduct = ({ flashSaleId }) => { useEffect(() => { const loadProducts = async () => { const dataProducts = await productSearchApi({ - query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500&orderBy=flashsale_discount_f desc`, + query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500&orderBy=flashsale-discount-desc`, operation: 'AND', }); setProducts(dataProducts.response); diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 29471f7b..8dc72559 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -3,6 +3,7 @@ import axios from 'axios'; import camelcaseObjectDeep from 'camelcase-object-deep'; export default async function handler(req, res) { + const { q = '*', page = 1, @@ -20,6 +21,9 @@ export default async function handler(req, res) { let paramOrderBy = ''; switch (orderBy) { + case 'flashsale-discount-desc': + paramOrderBy += 'flashsale_discount_f DESC'; + break; case 'price-asc': paramOrderBy += 'price_tier1_v2_f ASC'; break; @@ -59,6 +63,7 @@ export default async function handler(req, res) { `fq=-publish_b:false, product_rating_f:[13 TO *], discount_tier1_v2_f:[1 TO *]`, ]; + if (priceFrom > 0 || priceTo > 0) { parameter.push( `fq=price_tier1_v2_f:[${priceFrom == '' ? '*' : priceFrom} TO ${ @@ -99,6 +104,7 @@ export default async function handler(req, res) { let result = await axios( process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&') ); + console.log("result",result) try { result.data.response.products = productMappingSolr( result.data.response.docs, -- cgit v1.2.3 From f2e11c985f467cfe28b6f4c8c9ae9c7fabf85d94 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 17:07:59 +0700 Subject: delete console log --- src/pages/api/shop/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 8dc72559..87d7c580 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -104,7 +104,7 @@ export default async function handler(req, res) { let result = await axios( process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&') ); - console.log("result",result) + try { result.data.response.products = productMappingSolr( result.data.response.docs, -- cgit v1.2.3 From 538f2ef24eb8c6ae21a07f27614ce1b944553283 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 17:13:30 +0700 Subject: merge all promotion --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 5 ++--- src/lib/flashSale/components/FlashSaleNonDisplay.jsx | 2 +- src/pages/api/shop/search.js | 6 ++++++ 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index a09989a5..6a51a178 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -10,12 +10,11 @@ import { ChevronDownIcon, DocumentCheckIcon, HeartIcon, - ArrowUpRightIcon, } from '@heroicons/react/24/outline'; import dynamic from 'next/dynamic'; import Image from 'next/image'; import { useRouter } from 'next/router'; -import { useCallback, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import DesktopView from '../../views/DesktopView'; import Link from '../Link/Link'; import NavbarUserDropdown from './NavbarUserDropdown'; @@ -263,7 +262,7 @@ const NavbarDesktop = () => { height={160} quality={100} // className={`fixed ${isTop ? 'md:top-[145px] lg:top-[160px] ' : 'lg:top-[85px] top-[80px]'} rounded-3xl md:left-1/4 lg:left-1/4 xl:left-1/4 left-2/3 w-40 h-12 p-2 z-50 transition-all duration-300 animate-pulse`} - className={`inline-block relative -top-4 transition-all duration-300 z-20 animate-pulse`} + className={`inline-block relative -top-5 transition-all duration-300 z-20 animate-pulse`} />
    )} diff --git a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx index 85807fad..8dc15b05 100644 --- a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx +++ b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx @@ -52,7 +52,7 @@ const FlashSaleProduct = ({ flashSaleId }) => { useEffect(() => { const loadProducts = async () => { const dataProducts = await productSearchApi({ - query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500&orderBy=flashsale_discount_f desc`, + query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500&orderBy=flashsale-discount-desc`, operation: 'AND', }); setProducts(dataProducts.response); diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 29471f7b..87d7c580 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -3,6 +3,7 @@ import axios from 'axios'; import camelcaseObjectDeep from 'camelcase-object-deep'; export default async function handler(req, res) { + const { q = '*', page = 1, @@ -20,6 +21,9 @@ export default async function handler(req, res) { let paramOrderBy = ''; switch (orderBy) { + case 'flashsale-discount-desc': + paramOrderBy += 'flashsale_discount_f DESC'; + break; case 'price-asc': paramOrderBy += 'price_tier1_v2_f ASC'; break; @@ -59,6 +63,7 @@ export default async function handler(req, res) { `fq=-publish_b:false, product_rating_f:[13 TO *], discount_tier1_v2_f:[1 TO *]`, ]; + if (priceFrom > 0 || priceTo > 0) { parameter.push( `fq=price_tier1_v2_f:[${priceFrom == '' ? '*' : priceFrom} TO ${ @@ -99,6 +104,7 @@ export default async function handler(req, res) { let result = await axios( process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&') ); + try { result.data.response.products = productMappingSolr( result.data.response.docs, -- cgit v1.2.3 From 718babe0efd96c33ba2b8fd0cb458c57d67abe9c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 7 Aug 2024 17:15:58 +0700 Subject: update position --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 76012694..2ddf5efe 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -263,7 +263,7 @@ const NavbarDesktop = () => { height={160} quality={100} // className={`fixed ${isTop ? 'md:top-[145px] lg:top-[160px] ' : 'lg:top-[85px] top-[80px]'} rounded-3xl md:left-1/4 lg:left-1/4 xl:left-1/4 left-2/3 w-40 h-12 p-2 z-50 transition-all duration-300 animate-pulse`} - className={`inline-block relative -top-5 transition-all duration-300 z-20 animate-pulse`} + className={`inline-block relative -top-8 transition-all duration-300 z-20 animate-pulse`} />
    )} -- cgit v1.2.3 From de3422dc076e11724d423f80c1005d5188ed4e3e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 8 Aug 2024 10:44:07 +0700 Subject: add motion --- src/core/components/layouts/BasicLayout.jsx | 75 ++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/core/components/layouts/BasicLayout.jsx b/src/core/components/layouts/BasicLayout.jsx index a4f3a856..4d995a3a 100644 --- a/src/core/components/layouts/BasicLayout.jsx +++ b/src/core/components/layouts/BasicLayout.jsx @@ -1,12 +1,13 @@ import dynamic from 'next/dynamic'; import Image from 'next/image'; import { useRouter } from 'next/router'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useRef } from 'react'; import { useProductContext } from '@/contexts/ProductContext'; import odooApi from '@/core/api/odooApi'; import whatsappUrl from '@/core/utils/whatsappUrl'; import Navbar from '../elements/Navbar/Navbar'; +import { AnimatePresence, motion } from 'framer-motion'; const AnimationLayout = dynamic(() => import('./AnimationLayout'), { ssr: false, @@ -19,8 +20,10 @@ const BasicLayout = ({ children }) => { const [templateWA, setTemplateWA] = useState(null); const [payloadWA, setPayloadWa] = useState(null); const [urlPath, setUrlPath] = useState(null); + const [isVisible, setIsVisible] = useState(true); const router = useRouter(); + const whatsappRef = useRef(null); const { product } = useProductContext(); useEffect(() => { @@ -58,33 +61,81 @@ const BasicLayout = ({ children }) => { recordActivity(router.pathname); }, [router.pathname]); + useEffect(() => { + const handleMouseOut = (event) => { + if (event.clientY <= 0) { + setIsVisible(false); + } else { + setIsVisible(true); + } + }; + + window.addEventListener('mouseout', handleMouseOut); + + return () => { + window.removeEventListener('mouseout', handleMouseOut); + }; + }, []); + + const getWhatsappPosition = () => { + if (whatsappRef.current) { + const rect = whatsappRef.current.getBoundingClientRect(); + return { + x: rect.left + 80, + y: rect.top + 40, + width: rect.width, + height: rect.height, + }; + } + return { x: 0, y: 0, width: 0, height: 0 }; + }; + return ( <> + {!isVisible && ( + + + + )} {children} -
    + -- cgit v1.2.3 From 7e762fee7c9125ef2ce7e1cc0942ce8d1c1cb290 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 8 Aug 2024 15:47:07 +0700 Subject: back to original --- src/core/components/layouts/BasicLayout.jsx | 77 +++++------------------------ 1 file changed, 13 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/core/components/layouts/BasicLayout.jsx b/src/core/components/layouts/BasicLayout.jsx index 4d995a3a..ba51022d 100644 --- a/src/core/components/layouts/BasicLayout.jsx +++ b/src/core/components/layouts/BasicLayout.jsx @@ -1,13 +1,12 @@ import dynamic from 'next/dynamic'; import Image from 'next/image'; import { useRouter } from 'next/router'; -import { useEffect, useState, useRef } from 'react'; +import { useEffect, useState } from 'react'; import { useProductContext } from '@/contexts/ProductContext'; import odooApi from '@/core/api/odooApi'; import whatsappUrl from '@/core/utils/whatsappUrl'; import Navbar from '../elements/Navbar/Navbar'; -import { AnimatePresence, motion } from 'framer-motion'; const AnimationLayout = dynamic(() => import('./AnimationLayout'), { ssr: false, @@ -20,10 +19,8 @@ const BasicLayout = ({ children }) => { const [templateWA, setTemplateWA] = useState(null); const [payloadWA, setPayloadWa] = useState(null); const [urlPath, setUrlPath] = useState(null); - const [isVisible, setIsVisible] = useState(true); const router = useRouter(); - const whatsappRef = useRef(null); const { product } = useProductContext(); useEffect(() => { @@ -61,81 +58,33 @@ const BasicLayout = ({ children }) => { recordActivity(router.pathname); }, [router.pathname]); - useEffect(() => { - const handleMouseOut = (event) => { - if (event.clientY <= 0) { - setIsVisible(false); - } else { - setIsVisible(true); - } - }; - - window.addEventListener('mouseout', handleMouseOut); - - return () => { - window.removeEventListener('mouseout', handleMouseOut); - }; - }, []); - - const getWhatsappPosition = () => { - if (whatsappRef.current) { - const rect = whatsappRef.current.getBoundingClientRect(); - return { - x: rect.left + 80, - y: rect.top + 40, - width: rect.width, - height: rect.height, - }; - } - return { x: 0, y: 0, width: 0, height: 0 }; - }; - return ( <> - {!isVisible && ( - - - - )} {children} -
    + @@ -144,4 +93,4 @@ const BasicLayout = ({ children }) => { ); }; -export default BasicLayout; +export default BasicLayout; \ No newline at end of file -- cgit v1.2.3 From e33a7e612a3c2c871f6a0a84d0d04d6f6ddc357a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 9 Aug 2024 10:51:10 +0700 Subject: update template switch & delete console log --- .../components/Product/ProductDesktopVariant.jsx | 17 ++--------------- src/lib/quotation/components/Quotation.jsx | 2 -- .../components/products-recomendatison.jsx | 4 ---- 3 files changed, 2 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 882673f4..b8ec0580 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -176,7 +176,7 @@ const ProductDesktopVariant = ({ return (
    - +
    @@ -415,24 +415,11 @@ const ProductDesktopVariant = ({ Beli
    - {/*
    - -
    */}
    Produk Serupa
    -
    +
    {productSimilarInBrand && productSimilarInBrand?.map((product) => (
    diff --git a/src/lib/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx index 8855c6c4..5f197d16 100644 --- a/src/lib/quotation/components/Quotation.jsx +++ b/src/lib/quotation/components/Quotation.jsx @@ -277,9 +277,7 @@ const Quotation = () => { estimated_arrival_days: splitDuration(etd), delivery_service_type: selectedExpedisiService, }; - console.log('data checkout', data); const isSuccess = await checkoutApi({ data }); - console.log('isSuccess', isSuccess); setIsLoading(false); if (isSuccess?.id) { for (const product of products) deleteItemCart({ productId: product.id }); diff --git a/src/pages/my/recomendation/components/products-recomendatison.jsx b/src/pages/my/recomendation/components/products-recomendatison.jsx index d39d2a99..a610cf0d 100644 --- a/src/pages/my/recomendation/components/products-recomendatison.jsx +++ b/src/pages/my/recomendation/components/products-recomendatison.jsx @@ -80,7 +80,6 @@ const ProductsRecomendation = ({ id }) => { } }); - console.log('ini result', searchProduct.data.response); } return resultMapping; @@ -112,7 +111,6 @@ const ProductsRecomendation = ({ id }) => { setIsLoading(false); } else { setIsLoading(false); - console.log('No excel data available'); } }; @@ -129,7 +127,6 @@ const ProductsRecomendation = ({ id }) => { const jsonData = XLSX.utils.sheet_to_json(worksheet); setExcelData(jsonData); - console.log('ini json data', jsonData); setIsLoading(false); }; @@ -152,7 +149,6 @@ const ProductsRecomendation = ({ id }) => { }; const handlingOtherRec = ({ product }) => { - console.log('ini product', product); const result = async () => await searchRecomendation({ product, index: 0, operator: 'OR' }); -- cgit v1.2.3 From bbbd7ccaab3102558dc82cbd051947b0e579360c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 9 Aug 2024 10:55:01 +0700 Subject: back to code to avoid conflict --- src/lib/quotation/components/Quotation.jsx | 2 ++ src/pages/my/recomendation/components/products-recomendatison.jsx | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/lib/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx index 5f197d16..8855c6c4 100644 --- a/src/lib/quotation/components/Quotation.jsx +++ b/src/lib/quotation/components/Quotation.jsx @@ -277,7 +277,9 @@ const Quotation = () => { estimated_arrival_days: splitDuration(etd), delivery_service_type: selectedExpedisiService, }; + console.log('data checkout', data); const isSuccess = await checkoutApi({ data }); + console.log('isSuccess', isSuccess); setIsLoading(false); if (isSuccess?.id) { for (const product of products) deleteItemCart({ productId: product.id }); diff --git a/src/pages/my/recomendation/components/products-recomendatison.jsx b/src/pages/my/recomendation/components/products-recomendatison.jsx index a610cf0d..d39d2a99 100644 --- a/src/pages/my/recomendation/components/products-recomendatison.jsx +++ b/src/pages/my/recomendation/components/products-recomendatison.jsx @@ -80,6 +80,7 @@ const ProductsRecomendation = ({ id }) => { } }); + console.log('ini result', searchProduct.data.response); } return resultMapping; @@ -111,6 +112,7 @@ const ProductsRecomendation = ({ id }) => { setIsLoading(false); } else { setIsLoading(false); + console.log('No excel data available'); } }; @@ -127,6 +129,7 @@ const ProductsRecomendation = ({ id }) => { const jsonData = XLSX.utils.sheet_to_json(worksheet); setExcelData(jsonData); + console.log('ini json data', jsonData); setIsLoading(false); }; @@ -149,6 +152,7 @@ const ProductsRecomendation = ({ id }) => { }; const handlingOtherRec = ({ product }) => { + console.log('ini product', product); const result = async () => await searchRecomendation({ product, index: 0, operator: 'OR' }); -- cgit v1.2.3 From 8dd5502ca3ed4f2d74f74ea396b9424bd1390e5e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 9 Aug 2024 14:35:55 +0700 Subject: uptade code to avoid error --- src/core/components/elements/Navbar/TopBanner.jsx | 2 +- src/lib/category/components/PopularBrand.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index 302db5c4..b035eea4 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -5,7 +5,7 @@ import SmoothRender from '~/components/ui/smooth-render'; import Link from '../Link/Link'; import { useEffect } from 'react'; -const TopBanner = ({ onLoad }) => { +const TopBanner = ({ onLoad = () => {} }) => { const topBanner = useQuery({ queryKey: 'topBanner', queryFn: async () => await odooApi('GET', '/api/v1/banner?type=top-banner'), diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx index dca731e8..09c0f8a1 100644 --- a/src/lib/category/components/PopularBrand.jsx +++ b/src/lib/category/components/PopularBrand.jsx @@ -17,7 +17,7 @@ const PopularBrand = ({ category }) => { const fetchTopBrands = async () => { try { - const items = await fetchPromoItemsSolr(`category_id_ids:(${category.categoryDataIds.join(' OR ')})`); + const items = await fetchPromoItemsSolr(`category_id_ids:(${category?.categoryDataIds?.join(' OR ')})`); // console.log("id",items) // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas const getTop12UniqueBrands = (prod) => { -- cgit v1.2.3 From dec5fa876bffd4010febc7a16fa9ed20633cb42c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 9 Aug 2024 14:45:09 +0700 Subject: add handling to avoid error --- src/core/components/elements/Navbar/TopBanner.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index 7bc8fb6a..6cce6b03 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -6,7 +6,7 @@ import SmoothRender from '~/components/ui/smooth-render'; import Link from '../Link/Link'; import { useEffect } from 'react'; -const TopBanner = ({ onLoad }) => { +const TopBanner = ({ onLoad = () => {} }) => { const topBanner = useQuery({ queryKey: 'topBanner', queryFn: async () => await odooApi('GET', '/api/v1/banner?type=top-banner'), -- cgit v1.2.3 From 544f0321f069254b64ea080d11724ab3e4a92bce Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 14 Aug 2024 11:34:38 +0700 Subject: update button lanjutkan transaksi & status quotation logic after upload po --- src/lib/transaction/api/checkoutPoApi.js | 4 ++-- src/lib/transaction/components/Transaction.jsx | 29 +++++++++++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/lib/transaction/api/checkoutPoApi.js b/src/lib/transaction/api/checkoutPoApi.js index 04421368..af41d277 100644 --- a/src/lib/transaction/api/checkoutPoApi.js +++ b/src/lib/transaction/api/checkoutPoApi.js @@ -1,11 +1,11 @@ import odooApi from '@/core/api/odooApi' import { getAuth } from '@/core/utils/auth' -const checkoutPoApi = async ({ id }) => { +const checkoutPoApi = async ({ id, status }) => { const auth = getAuth() const dataCheckout = await odooApi( 'POST', - `/api/v1/partner/${auth?.partnerId}/sale_order/${id}/checkout` + `/api/v1/partner/${auth?.partnerId}/sale_order/${id}/checkout`,{status} ) return dataCheckout } diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index 85f6163b..88f11fd4 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -5,6 +5,8 @@ import useTransaction from '../hooks/useTransaction'; import TransactionStatusBadge from './TransactionStatusBadge'; import Divider from '@/core/components/elements/Divider/Divider'; import { useEffect, useMemo, useRef, useState } from 'react'; +import { Button, Tooltip } from '@chakra-ui/react'; +import clsxm from '~/libs/clsxm'; import ImageNext from 'next/image'; import { downloadPurchaseOrder, @@ -107,7 +109,7 @@ const Transaction = ({ id }) => { toast.error('Mohon upload dokumen PO anda sebelum melanjutkan pesanan'); return; } - await checkoutPoApi({ id }); + await checkoutPoApi({ id, status: true }); toast.success('Berhasil melanjutkan pesanan'); transaction.refetch(); }; @@ -563,10 +565,27 @@ const Transaction = ({ id }) => { )} {transaction.data?.status == 'draft' && !auth?.feature.soApproval && ( - - )} +
    + + + + +
    + )} {transaction.data?.status != 'draft' && !auth?.feature.soApproval && (
  • )}
    - - + setQuantityInput(e.target.value)} + className=' w-24 h-10 text-center border border-gray-300 rounded focus:outline-none' + /> + +
    +
    +
    + - +
    - +
    + + + | + + + + | + + + + +
    -- cgit v1.2.3 From 78d568e5978a60f5e7916cb022463a6e27dd4d54 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Thu, 3 Oct 2024 09:42:50 +0700 Subject: back to ssr --- src/pages/index.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pages/index.jsx b/src/pages/index.jsx index ac925b4e..cc4d68db 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -60,11 +60,11 @@ const CategoryHomeId = dynamic(() => ); const CategoryDynamic = dynamic(() => - import('@/lib/home/components/CategoryDynamic'), {ssr : false} + import('@/lib/home/components/CategoryDynamic') ); const CategoryDynamicMobile = dynamic(() => -import('@/lib/home/components/CategoryDynamicMobile'), {ssr: false} +import('@/lib/home/components/CategoryDynamicMobile') ); const CustomerReviews = dynamic(() => -- cgit v1.2.3 From ca30c28dd0b19977eb771fc32ff5e520cdef1068 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Thu, 3 Oct 2024 16:47:37 +0700 Subject: product varian --- .../components/Product/ProductDesktopVariant.jsx | 185 +++++++++++---------- src/pages/api/shop/variant-detail.js | 2 +- src/pages/shop/product/variant/[slug].jsx | 7 - src/utils/solrMapping.js | 1 + 4 files changed, 103 insertions(+), 92 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 2f2caa56..55effdfb 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -18,10 +18,13 @@ import currencyFormat from '@/core/utils/currencyFormat'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; +import { RWebShare } from 'react-web-share'; import productSimilarApi from '../../api/productSimilarApi'; import ProductCard from '../ProductCard'; import ProductSimilar from '../ProductSimilar'; -import { RWebShare } from 'react-web-share'; +import ProductPromoSection from '~/modules/product-promo/components/Section'; + +const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST; const ProductDesktopVariant = ({ product, @@ -44,11 +47,18 @@ const ProductDesktopVariant = ({ const [quantityInput, setQuantityInput] = useState(1); + 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, + }); + const getLowestPrice = useCallback(() => { const lowest = product.price; - /* const lowest = prices.reduce((lowest, price) => { - return price.priceDiscount < lowest.priceDiscount ? price : lowest - }, prices[0])*/ return lowest; }, [product]); @@ -81,7 +91,7 @@ const ProductDesktopVariant = ({ router.push(`/login?next=/shop/product/${slug}`); return; } - const quantity = variantQuantityRefs.current[product.id].value; + const quantity = quantityInput; if (!validQuantity(quantity)) return; updateItemCart({ productId: product.id, @@ -96,7 +106,7 @@ const ProductDesktopVariant = ({ }; const handleBuy = (variant) => { - const quantity = variantQuantityRefs.current[product.id].value; + const quantity = quantityInput; if (!validQuantity(quantity)) return; updateItemCart({ @@ -177,71 +187,26 @@ const ProductDesktopVariant = ({
    Item Code
    {product.code}
    -
    +
    Manufacture
    - {product.manufacture?.name ? ( - - {product.manufacture?.name} - - ) : ( -
    -
    - )} -
    -
    - -
    -
    - Persiapan Barang -
    -
    - {!product?.sla && } - {product?.sla && ( - - - {product?.sla?.slaDate} - - - - )} + + {product.manufacture.name} +
    - {/*
    -
    Stock
    -
    - {!product?.sla && } - {product?.sla?.qty > 0 && {product?.sla?.qty}} - {product?.sla?.qty == 0 && ( - - Tanya Admin - - )} -
    -
    */} - -
    +
    Berat Barang
    {product?.weight > 0 && {product?.weight} KG} @@ -263,24 +228,52 @@ const ProductDesktopVariant = ({ )}
    +
    +
    Terjual
    +
    -
    +
    + +
    +
    + Persiapan Barang +
    +
    + {!product?.sla && } + {product?.sla && ( + + + {product?.sla?.slaDate} + + + + )} +
    +
    -
    -

    - Informasi Produk -

    -
    -

    ' - ? 'Belum ada deskripsi' - : product.parent.description, - }} - /> +
    + + +
    +

    + Informasi Produk +

    +
    +

    ' + ? 'Belum ada deskripsi' + : product.parent.description, + }} + /> +
    @@ -341,7 +334,7 @@ const ProductDesktopVariant = ({ )} )} -
    +
    +
    + + {' '} + Stock : {product?.sla?.qty}{' '} + +
    +
    + {product?.sla?.qty > 0 && ( + + pickup now + + )} +
    -
    +
    -
    +
    +
    + + ( + + )} + /> +
    + {errors.state?.message} +
    +
    +
    ( - + )} />
    @@ -270,6 +303,7 @@ const validationSchema = Yup.object().shape({ mobile: Yup.string().required('Harus di-isi'), street: Yup.string().required('Harus di-isi'), zip: Yup.string().required('Harus di-isi'), + state: Yup.string().required('Harus di-pilih'), city: Yup.string().required('Harus di-pilih'), district: Yup.string().required('Harus di-pilih'), }); @@ -280,6 +314,7 @@ const defaultValues = { email: '', mobile: '', street: '', + state: '', city: '', district: '', subDistrict: '', diff --git a/src/lib/address/components/EditAddress.jsx b/src/lib/address/components/EditAddress.jsx index 182c8a31..23cf72a9 100644 --- a/src/lib/address/components/EditAddress.jsx +++ b/src/lib/address/components/EditAddress.jsx @@ -13,6 +13,7 @@ import { toast } from 'react-hot-toast'; import Menu from '@/lib/auth/components/Menu'; import useAuth from '@/core/hooks/useAuth'; import odooApi from '@/core/api/odooApi'; +import stateApi from '../api/stateApi'; const EditAddress = ({ id, defaultValues }) => { const auth = useAuth(); @@ -29,9 +30,11 @@ const EditAddress = ({ id, defaultValues }) => { resolver: yupResolver(validationSchema), defaultValues, }); + + const [states, setStates] = useState([]); const [cities, setCities] = useState([]); const [districts, setDistricts] = useState([]); - const [subDistricts, setSubDistricts] = useState([]); + const [subDistricts, setSubDistricts] = useState([]); useEffect(() => { const loadProfile = async () => { @@ -48,16 +51,38 @@ const EditAddress = ({ id, defaultValues }) => { }, [auth?.parentId]); useEffect(() => { - const loadCities = async () => { - let dataCities = await cityApi(); - dataCities = dataCities.map((city) => ({ - value: city.id, - label: city.name, + const loadStates = async () => { + let dataStates = await stateApi(); + dataStates = dataStates.map((state) => ({ + value: state.id, + label: state.name, })); - setCities(dataCities); + setStates(dataStates); }; - loadCities(); - }, []); + loadStates(); + },[]) + + const watchState = watch('state'); + useEffect(() => { + setValue('city', ''); + if(watchState) { + const loadCities = async () => { + let dataCities = await cityApi({ stateId: watchState }); + dataCities = dataCities.map((city) => ({ + value: city.id, + label: city.name, + })); + setCities(dataCities); + let oldCity = getValues('oldCity'); + if (oldCity) { + setValue('city', oldCity); + setValue('oldCity', ''); + } + }; + loadCities(); + } + + }, [watchState, setValue, getValues]); const watchCity = watch('city'); useEffect(() => { @@ -107,6 +132,7 @@ const EditAddress = ({ id, defaultValues }) => { const data = { ...values, phone: values.mobile, + state_id: values.state, city_id: values.city, district_id: values.district, sub_district_id: values.subDistrict, @@ -241,13 +267,27 @@ const EditAddress = ({ id, defaultValues }) => {
    +
    + + ( + + )} + /> +
    + {errors.state?.message} +
    +
    +
    ( - + )} />
    @@ -308,6 +348,7 @@ const validationSchema = Yup.object().shape({ mobile: Yup.string().required('Harus di-isi'), street: Yup.string().required('Harus di-isi'), zip: Yup.string().required('Harus di-isi'), + state : Yup.string().required('Harus di-pilih'), city: Yup.string().required('Harus di-pilih'), district: Yup.string().required('Harus di-pilih'), }); diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 4c7e852f..a1b0116a 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -67,6 +67,7 @@ const Checkout = () => { const getAddresses = async () => { const dataAddresses = await addressesApi(); + console.log('ini adalah adress',dataAddresses); setAddresses(dataAddresses); }; @@ -1664,7 +1665,7 @@ const SectionAddress = ({ address, label, url }) => ( ); const SectionValidation = ({ address }) => - address?.rajaongkirCityId == 0 && ( + address?.stateId == null && (
    Mohon untuk memperbarui alamat Anda dengan mengklik tombol di bawah ini.{' '} diff --git a/src/pages/my/address/[id]/edit.jsx b/src/pages/my/address/[id]/edit.jsx index c552659b..c126b290 100644 --- a/src/pages/my/address/[id]/edit.jsx +++ b/src/pages/my/address/[id]/edit.jsx @@ -37,12 +37,15 @@ export async function getServerSideProps(context) { mobile: address.mobile, street: address.street, zip: address.zip, - city: address.city?.id || '', + state: address.stateId?.id || '', + oldCity: address.city?.id || '', + city: '', oldDistrict: address.district?.id || '', district: '', oldSubDistrict: address.subDistrict?.id || '', subDistrict: '', business_name: '', }; + console.log('ini default',defaultValues); return { props: { id, defaultValues } }; } -- cgit v1.2.3 From e324ef760f1e8c6e523c79082e35f69ce16cee1d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 8 Oct 2024 10:01:15 +0700 Subject: update category management to store data to local storage --- src/lib/home/api/categoryManagementApi.js | 8 +++ src/lib/home/components/CategoryDynamic.jsx | 93 +++++++++++++++++++---------- 2 files changed, 68 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/lib/home/api/categoryManagementApi.js b/src/lib/home/api/categoryManagementApi.js index 2ff4fdfc..4101f87a 100644 --- a/src/lib/home/api/categoryManagementApi.js +++ b/src/lib/home/api/categoryManagementApi.js @@ -42,3 +42,11 @@ const map = async (promotions) => { return productMapped; }); }; + +export const fetchCategoryManagementVersion = async () => { + const response = await fetch( + '/solr/admin/cores?action=STATUS&core=category_management' + ); + const data = await response.json(); + return data.status.category_management.index.version; +}; diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 49a9a93f..412c6153 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -1,5 +1,8 @@ import React, { useEffect, useState, useCallback } from 'react'; -import { fetchCategoryManagementSolr } from '../api/categoryManagementApi'; +import { + fetchCategoryManagementSolr, + fetchCategoryManagementVersion, +} from '../api/categoryManagementApi'; import NextImage from 'next/image'; import Link from 'next/link'; import { createSlug } from '@/core/utils/slug'; @@ -10,47 +13,71 @@ import 'swiper/css/navigation'; import 'swiper/css/pagination'; import { Pagination } from 'swiper'; -const CategoryDynamic = () => { - const [categoryManagement, setCategoryManagement] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const loadBrand = useCallback(async () => { - setIsLoading(true); - const items = await fetchCategoryManagementSolr(); +const saveToLocalStorage = (key, data, version, expiryInHours) => { + const now = new Date(); + const item = { + value: data, + version: version, + expiry: now.getTime() + expiryInHours * 60 * 60 * 1000, + }; + localStorage.setItem(key, JSON.stringify(item)); +}; - setIsLoading(false); - setCategoryManagement(items); - }, []); +const getFromLocalStorage = (key) => { + const itemStr = localStorage.getItem(key); + if (!itemStr) return null; - useEffect(() => { - loadBrand(); - }, [loadBrand]); + const item = JSON.parse(itemStr); + return item; +}; - // const [categoryData, setCategoryData] = useState({}); - // const [subCategoryData, setSubCategoryData] = useState({}); +const isExpired = (expiry) => { + const now = new Date(); + return now.getTime() > expiry; +}; - // useEffect(() => { - // const fetchCategoryData = async () => { - // if (categoryManagement && categoryManagement.data) { - // const updatedCategoryData = {}; - // const updatedSubCategoryData = {}; +const CategoryDynamic = () => { + const [categoryManagement, setCategoryManagement] = useState([]); + const [isLoading, setIsLoading] = useState(false); - // for (const category of categoryManagement.data) { - // const countLevel1 = await odooApi('GET', `/api/v1/category/numFound?parent_id=${category.categoryIdI}`); + const loadBrand = useCallback(async () => { + const cachedData = getFromLocalStorage('categoryManagementData'); - // updatedCategoryData[category.categoryIdI] = countLevel1?.numFound; + // apakah data sudah kadaluarsa + const dataExpired = cachedData ? isExpired(cachedData.expiry) : true; - // for (const subCategory of countLevel1?.children) { - // updatedSubCategoryData[subCategory.id] = subCategory?.numFound; - // } - // } + // Jika belum kadaluarsa, pakai data dari localStorage + if (cachedData && !dataExpired) { + setCategoryManagement(cachedData.value); + } else { + // Jika kadaluarsa, cek versi terbaru dari API + const latestVersion = await fetchCategoryManagementVersion(); - // setCategoryData(updatedCategoryData); - // setSubCategoryData(updatedSubCategoryData); - // } - // }; + if (cachedData && cachedData.version === latestVersion) { + // Jika versinya sama, reset expiry + saveToLocalStorage( + 'categoryManagementData', + cachedData.value, + latestVersion, + 24 + ); + setCategoryManagement(cachedData.value); + } else { + // Jika versinya beda, lakukan fetch data baru + setIsLoading(true); + const items = await fetchCategoryManagementSolr(); + setIsLoading(false); - // fetchCategoryData(); - // }, [categoryManagement.isLoading]); + // Simpan data baru + saveToLocalStorage('categoryManagementData', items, latestVersion, 24); + setCategoryManagement(items); + } + } + }, []); + + useEffect(() => { + loadBrand(); // Load data saat komponen pertama kali dimuat + }, [loadBrand]); const swiperBanner = { modules: [Pagination], -- cgit v1.2.3 From e8e7275a25939bfaeacaf2a9cbf508b514647057 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 8 Oct 2024 10:31:13 +0700 Subject: update category management to storage on local --- src/lib/home/components/CategoryDynamic.jsx | 11 ++- src/lib/home/components/CategoryDynamicMobile.jsx | 111 ++++++++++++++++------ 2 files changed, 90 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 412c6153..596b18f2 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -41,7 +41,7 @@ const CategoryDynamic = () => { const [isLoading, setIsLoading] = useState(false); const loadBrand = useCallback(async () => { - const cachedData = getFromLocalStorage('categoryManagementData'); + const cachedData = getFromLocalStorage('homepage_categoryDynamic'); // nama key namaPage_namaKomopnen // apakah data sudah kadaluarsa const dataExpired = cachedData ? isExpired(cachedData.expiry) : true; @@ -56,7 +56,7 @@ const CategoryDynamic = () => { if (cachedData && cachedData.version === latestVersion) { // Jika versinya sama, reset expiry saveToLocalStorage( - 'categoryManagementData', + 'homepage_categoryDynamic', cachedData.value, latestVersion, 24 @@ -69,7 +69,12 @@ const CategoryDynamic = () => { setIsLoading(false); // Simpan data baru - saveToLocalStorage('categoryManagementData', items, latestVersion, 24); + saveToLocalStorage( + 'homepage_categoryDynamic', + items, + latestVersion, + 24 + ); setCategoryManagement(items); } } diff --git a/src/lib/home/components/CategoryDynamicMobile.jsx b/src/lib/home/components/CategoryDynamicMobile.jsx index 4a8f13cf..075e9444 100644 --- a/src/lib/home/components/CategoryDynamicMobile.jsx +++ b/src/lib/home/components/CategoryDynamicMobile.jsx @@ -4,52 +4,105 @@ import Link from 'next/link'; import { createSlug } from '@/core/utils/slug'; import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; -import { fetchCategoryManagementSolr } from '../api/categoryManagementApi'; +import { + fetchCategoryManagementSolr, + fetchCategoryManagementVersion, +} from '../api/categoryManagementApi'; + +const saveToLocalStorage = (key, data, version, expiryInHours) => { + const now = new Date(); + const item = { + value: data, + version: version, + expiry: now.getTime() + expiryInHours * 60 * 60 * 1000, + }; + localStorage.setItem(key, JSON.stringify(item)); +}; + +const getFromLocalStorage = (key) => { + const itemStr = localStorage.getItem(key); + if (!itemStr) return null; + + const item = JSON.parse(itemStr); + const now = new Date(); + + if (now.getTime() > item.expiry) { + localStorage.removeItem(key); + return null; + } + + return item; +}; + +const isExpired = (expiry) => { + const now = new Date(); + return now.getTime() > expiry; +}; const CategoryDynamicMobile = () => { const [selectedCategory, setSelectedCategory] = useState({}); const [categoryManagement, setCategoryManagement] = useState([]); const [isLoading, setIsLoading] = useState(false); - const loadBrand = useCallback(async () => { - setIsLoading(true); - const items = await fetchCategoryManagementSolr(); + const loadCategoryManagement = useCallback(async () => { + const cachedData = getFromLocalStorage('homepage_categoryDynamic'); // nama key namaPage_namaKomopnen + const cachedVersion = cachedData?.version; + // apakah data sudah kadaluarsa + const dataExpired = cachedData ? isExpired(cachedData.expiry) : true; + + if (cachedData && !dataExpired) { + setCategoryManagement(cachedData.value); + } else { + // Jika kadaluarsa, cek versi terbaru dari API + const latestVersion = await fetchCategoryManagementVersion(); + + if (cachedData && cachedData.version === latestVersion) { + // Jika versinya sama, reset expiry + saveToLocalStorage( + 'homepage_categoryDynamic', + cachedData.value, + latestVersion, + 24 + ); + setCategoryManagement(cachedData.value); + } else { + // Jika versinya beda, lakukan fetch data baru + setIsLoading(true); + const items = await fetchCategoryManagementSolr(); + setIsLoading(false); - setIsLoading(false); - setCategoryManagement(items); + // Simpan data baru + saveToLocalStorage( + 'homepage_categoryDynamic', + items, + latestVersion, + 24 + ); + setCategoryManagement(items); + } + } }, []); useEffect(() => { - loadBrand(); - }, [loadBrand]); + loadCategoryManagement(); + }, [loadCategoryManagement]); useEffect(() => { - const loadPromo = async () => { - try { - if (categoryManagement?.length > 0) { - const initialSelections = categoryManagement.reduce( - (acc, category) => { - if (category.categories.length > 0) { - acc[category.id] = category.categories[0].id_level_2; - } - return acc; - }, - {} - ); - setSelectedCategory(initialSelections); + if (categoryManagement?.length > 0) { + const initialSelections = categoryManagement.reduce((acc, category) => { + if (category.categories.length > 0) { + acc[category.id] = category.categories[0].id_level_2; } - } catch (loadError) { - // console.error("Error loading promo items:", loadError); - } - }; - - loadPromo(); + return acc; + }, {}); + setSelectedCategory(initialSelections); + } }, [categoryManagement]); - const handleCategoryLevel2Click = (categoryIdI, idLevel2) => { + const handleCategoryLevel2Click = (categoryId, idLevel2) => { setSelectedCategory((prev) => ({ ...prev, - [categoryIdI]: idLevel2, + [categoryId]: idLevel2, })); }; -- cgit v1.2.3 From 3a4e4d2d9c74bf84bd287235f4f3799b4a332097 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 8 Oct 2024 14:26:13 +0700 Subject: update category management fetch data --- src/lib/home/components/CategoryDynamic.jsx | 75 +++++++++-------------- src/lib/home/components/CategoryDynamicMobile.jsx | 70 +++++++++------------ 2 files changed, 56 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index 596b18f2..e62575f7 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -13,12 +13,12 @@ import 'swiper/css/navigation'; import 'swiper/css/pagination'; import { Pagination } from 'swiper'; -const saveToLocalStorage = (key, data, version, expiryInHours) => { +const saveToLocalStorage = (key, data, version) => { const now = new Date(); const item = { value: data, version: version, - expiry: now.getTime() + expiryInHours * 60 * 60 * 1000, + lastFetchedTime: now.getTime(), }; localStorage.setItem(key, JSON.stringify(item)); }; @@ -31,9 +31,9 @@ const getFromLocalStorage = (key) => { return item; }; -const isExpired = (expiry) => { +const getElapsedTime = (lastFetchedTime) => { const now = new Date(); - return now.getTime() > expiry; + return now.getTime() - lastFetchedTime; }; const CategoryDynamic = () => { @@ -41,47 +41,39 @@ const CategoryDynamic = () => { const [isLoading, setIsLoading] = useState(false); const loadBrand = useCallback(async () => { - const cachedData = getFromLocalStorage('homepage_categoryDynamic'); // nama key namaPage_namaKomopnen + const cachedData = getFromLocalStorage('homepage_categoryDynamic'); - // apakah data sudah kadaluarsa - const dataExpired = cachedData ? isExpired(cachedData.expiry) : true; + if (cachedData) { + // Hitung selisih waktu antara saat ini dengan waktu terakhir data di-fetch + const elapsedTime = getElapsedTime(cachedData.lastFetchedTime); - // Jika belum kadaluarsa, pakai data dari localStorage - if (cachedData && !dataExpired) { + if (elapsedTime < 24 * 60 * 60 * 1000) { + setCategoryManagement(cachedData.value); + return; + } + } + + const latestVersion = await fetchCategoryManagementVersion(); + if (cachedData && cachedData.version === latestVersion) { + // perbarui waktu + saveToLocalStorage( + 'homepage_categoryDynamic', + cachedData.value, + latestVersion + ); setCategoryManagement(cachedData.value); } else { - // Jika kadaluarsa, cek versi terbaru dari API - const latestVersion = await fetchCategoryManagementVersion(); + setIsLoading(true); + const items = await fetchCategoryManagementSolr(); + setIsLoading(false); - if (cachedData && cachedData.version === latestVersion) { - // Jika versinya sama, reset expiry - saveToLocalStorage( - 'homepage_categoryDynamic', - cachedData.value, - latestVersion, - 24 - ); - setCategoryManagement(cachedData.value); - } else { - // Jika versinya beda, lakukan fetch data baru - setIsLoading(true); - const items = await fetchCategoryManagementSolr(); - setIsLoading(false); - - // Simpan data baru - saveToLocalStorage( - 'homepage_categoryDynamic', - items, - latestVersion, - 24 - ); - setCategoryManagement(items); - } + saveToLocalStorage('homepage_categoryDynamic', items, latestVersion); + setCategoryManagement(items); } }, []); useEffect(() => { - loadBrand(); // Load data saat komponen pertama kali dimuat + loadBrand(); }, [loadBrand]); const swiperBanner = { @@ -99,7 +91,6 @@ const CategoryDynamic = () => {
    {categoryManagement && categoryManagement?.map((category) => { - // const countLevel1 = categoryData[category.categoryIdI] || 0; return (
    @@ -107,9 +98,6 @@ const CategoryDynamic = () => {

    {category.name}

    - {/* -

    {countLevel1} Produk tersedia

    -
    */} { {/* Swiper for SubCategories */} {category.categories.map((subCategory) => { - // const countLevel2 = subCategoryData[subCategory.idLevel2] || 0; - return (
    @@ -147,11 +133,6 @@ const CategoryDynamic = () => {

    {subCategory?.name}

    - {/* -

    - {countLevel2} Produk tersedia -

    -
    */} { +const saveToLocalStorage = (key, data, version) => { const now = new Date(); const item = { value: data, version: version, - expiry: now.getTime() + expiryInHours * 60 * 60 * 1000, + lastFetchedTime: now.getTime(), }; localStorage.setItem(key, JSON.stringify(item)); }; @@ -24,19 +24,12 @@ const getFromLocalStorage = (key) => { if (!itemStr) return null; const item = JSON.parse(itemStr); - const now = new Date(); - - if (now.getTime() > item.expiry) { - localStorage.removeItem(key); - return null; - } - return item; }; -const isExpired = (expiry) => { +const getElapsedTime = (lastFetchedTime) => { const now = new Date(); - return now.getTime() > expiry; + return now.getTime() - lastFetchedTime; }; const CategoryDynamicMobile = () => { @@ -45,42 +38,35 @@ const CategoryDynamicMobile = () => { const [isLoading, setIsLoading] = useState(false); const loadCategoryManagement = useCallback(async () => { - const cachedData = getFromLocalStorage('homepage_categoryDynamic'); // nama key namaPage_namaKomopnen - const cachedVersion = cachedData?.version; - // apakah data sudah kadaluarsa - const dataExpired = cachedData ? isExpired(cachedData.expiry) : true; + const cachedData = getFromLocalStorage('homepage_categoryDynamic'); - if (cachedData && !dataExpired) { - setCategoryManagement(cachedData.value); - } else { - // Jika kadaluarsa, cek versi terbaru dari API - const latestVersion = await fetchCategoryManagementVersion(); + if (cachedData) { + // Hitung selisih waktu antara saat ini dengan waktu terakhir data di-fetch + const elapsedTime = getElapsedTime(cachedData.lastFetchedTime); - if (cachedData && cachedData.version === latestVersion) { - // Jika versinya sama, reset expiry - saveToLocalStorage( - 'homepage_categoryDynamic', - cachedData.value, - latestVersion, - 24 - ); + if (elapsedTime < 24 * 60 * 60 * 1000) { setCategoryManagement(cachedData.value); - } else { - // Jika versinya beda, lakukan fetch data baru - setIsLoading(true); - const items = await fetchCategoryManagementSolr(); - setIsLoading(false); - - // Simpan data baru - saveToLocalStorage( - 'homepage_categoryDynamic', - items, - latestVersion, - 24 - ); - setCategoryManagement(items); + return; } } + + const latestVersion = await fetchCategoryManagementVersion(); + if (cachedData && cachedData.version === latestVersion) { + // perbarui waktu + saveToLocalStorage( + 'homepage_categoryDynamic', + cachedData.value, + latestVersion + ); + setCategoryManagement(cachedData.value); + } else { + setIsLoading(true); + const items = await fetchCategoryManagementSolr(); + setIsLoading(false); + + saveToLocalStorage('homepage_categoryDynamic', items, latestVersion); + setCategoryManagement(items); + } }, []); useEffect(() => { -- cgit v1.2.3 From f09a72f90c049b5e1a8478f737062a24d9c7a3df Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Tue, 8 Oct 2024 14:56:00 +0700 Subject: cache localstorage --- src/lib/home/components/BannerSection.jsx | 34 +++++++++++++++++++---- src/lib/home/components/PromotionProgram.jsx | 39 +++++++++++++++++++++------ src/lib/review/components/CustomerReviews.jsx | 25 +++++++++++++++-- 3 files changed, 83 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/BannerSection.jsx b/src/lib/home/components/BannerSection.jsx index f83c36fc..60d38f8f 100644 --- a/src/lib/home/components/BannerSection.jsx +++ b/src/lib/home/components/BannerSection.jsx @@ -1,18 +1,42 @@ import Link from '@/core/components/elements/Link/Link'; import Image from 'next/image'; +import { useEffect, useState } from 'react'; +import { bannerApi } from '../../../api/bannerApi'; const { useQuery } = require('react-query'); const { default: bannerSectionApi } = require('../api/bannerSectionApi'); const BannerSection = () => { - const fetchBannerSection = async () => await bannerSectionApi(); - const bannerSection = useQuery('bannerSection', fetchBannerSection); + const [data, setData] = useState(null); + const [shouldFetch, setShouldFetch] = useState(false); + + useEffect(() => { + const localData = localStorage.getItem('Homepage_bannerSection'); + if (localData) { + setData(JSON.parse(localData)); + }else{ + setShouldFetch(true); + } + }, []); + + // const fetchBannerSection = async () => await bannerSectionApi(); + const getBannerSection = useQuery('bannerSection', bannerApi({ type: 'home-banner' }), { + enabled: shouldFetch, + onSuccess: (data) => { + if (data) { + localStorage.setItem('Homepage_bannerSection', JSON.stringify(data)); + setData(data); + } + }, + }); + + const bannerSection = data; return ( - bannerSection.data && - bannerSection.data?.length > 0 && ( + bannerSection && + bannerSection?.length > 0 && (
    - {bannerSection.data?.map((banner) => ( + {bannerSection?.map((banner) => ( { - const promotionProgram = useQuery( + const { isMobile, isDesktop } = useDevice(); + const [data, setData] = useState(null); + const [shouldFetch, setShouldFetch] = useState(false); + + useEffect(() => { + const localData = localStorage.getItem('Homepage_promotionProgram'); + if (localData) { + setData(JSON.parse(localData)); + }else{ + setShouldFetch(true); + } + },[]) + + const getPromotionProgram = useQuery( 'promotionProgram', - bannerApi({ type: 'banner-promotion' }) + bannerApi({ type: 'banner-promotion' }),{ + enabled: shouldFetch, + onSuccess: (data) => { + if (data) { + localStorage.setItem('Homepage_promotionProgram', JSON.stringify(data)); + setData(data); + } + } + } ); - const { isMobile, isDesktop } = useDevice(); - if (promotionProgram.isLoading) { + const promotionProgram = data + + if (getPromotionProgram?.isLoading && !data) { return ; } @@ -40,10 +63,10 @@ const BannerSection = () => { )}
    {isDesktop && - promotionProgram.data && - promotionProgram.data?.length > 0 && ( + promotionProgram && + promotionProgram?.length > 0 && (
    - {promotionProgram.data?.map((banner) => ( + {promotionProgram?.map((banner) => ( { {isMobile && ( - {promotionProgram.data?.map((banner) => ( + {promotionProgram?.map((banner) => ( { - const { data: customerReviews } = useQuery( + const [data, setData] = useState(null); + + useEffect(() => { + const localData = localStorage.getItem('Homepage_customerReviews'); + if (localData) { + setData(JSON.parse(localData)); + } + },[]) + + + const { data: fetchCustomerReviews } = useQuery( 'customerReviews', - getCustomerReviews + getCustomerReviews,{ + enabled: !data, + onSuccess: (data) => { + if (data) { + localStorage.setItem('Homepage_customerReviews', JSON.stringify(data)); + setData(data); + } + } + } ); + const customerReviews = data + return (

    -- cgit v1.2.3 From 94a96e371f554c7d87e2a6edbc6bdb7fe9228fd6 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 16 Oct 2024 13:19:45 +0700 Subject: add CR tambahin info jumlah barang ready stock yang bisa di pick up --- src/lib/checkout/components/Checkout.jsx | 1 + src/lib/transaction/components/Transaction.jsx | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 4c7e852f..e872b7f6 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -442,6 +442,7 @@ const Checkout = () => { const productOrder = products.map((product) => ({ product_id: product.id, quantity: product.quantity, + available_quantity: product?.availableQuantity, })); let data = { // partner_shipping_id: auth.partnerId, diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index 4d401037..d001c7f4 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -778,6 +778,10 @@ const Transaction = ({ id }) => { ? `| ${product?.attributes.join(', ')}` : ''}

    +
    + {product.availableQuantity} barang ini bisa di + pickup maksimal pukul 16.00 +
    {/* @@ -879,7 +883,7 @@ const Transaction = ({ id }) => {
    - )} + )} {transaction?.data?.productsRejectLine.length > 0 && (
    -- cgit v1.2.3 From 6d89fa79c9fdbb1961b15a463250f28e5c684b4a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 16 Oct 2024 13:33:00 +0700 Subject: delete console log --- src/lib/product/components/Product/ProductDesktopVariant.jsx | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 55effdfb..2e005eea 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -36,8 +36,6 @@ const ProductDesktopVariant = ({ const auth = useAuth(); const { slug } = router.query; - console.log('ini product variant', product); - const [lowestPrice, setLowestPrice] = useState(null); const [addCartAlert, setAddCartAlert] = useState(false); -- cgit v1.2.3 From fc77794a015f8fed5e8af4c9a320ca8b0fbb7d23 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 16 Oct 2024 13:42:39 +0700 Subject: update tampilan mobile --- src/lib/variant/components/VariantCard.jsx | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/variant/components/VariantCard.jsx b/src/lib/variant/components/VariantCard.jsx index 68cdf54f..08b7a97e 100644 --- a/src/lib/variant/components/VariantCard.jsx +++ b/src/lib/variant/components/VariantCard.jsx @@ -103,30 +103,42 @@ const VariantCard = ({ product, openOnClick = true, buyMore = false }) => {
    -
    -

    {product.parent.name}

    +

    + {product.parent.name} +

    {product.code || '-'} - {product.attributes.length > 0 ? ` ・ ${product.attributes.join(', ')}` : ''} + {product.attributes.length > 0 + ? ` ・ ${product.attributes.join(', ')}` + : ''}

    Berat Item : {product?.weight} Kg x {product?.quantity} Barang

    +

    + {product.availableQuantity} barang ini bisa di pickup maksimal pukul + 16.00 +

    {product.hasFlashsale && ( <>

    {currencyFormat(product.price.price)}

    - {product.price.discountPercentage}% + + {product.price.discountPercentage}% + )}

    {product.price.priceDiscount > 0 - ? currencyFormat(product.price.priceDiscount) + ' × ' + product.quantity + ' Barang' + ? currencyFormat(product.price.priceDiscount) + + ' × ' + + product.quantity + + ' Barang' : ''}

    -- cgit v1.2.3 From dca7af433ca57e976b29620c58de98e94388e2b9 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 22 Oct 2024 14:24:31 +0700 Subject: CR variant beli langsung --- src/lib/checkout/components/Checkout.jsx | 3 +- .../components/Product/ProductDesktopVariant.jsx | 34 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index a1b0116a..0e180d9c 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -67,7 +67,6 @@ const Checkout = () => { const getAddresses = async () => { const dataAddresses = await addressesApi(); - console.log('ini adalah adress',dataAddresses); setAddresses(dataAddresses); }; @@ -1665,7 +1664,7 @@ const SectionAddress = ({ address, label, url }) => ( ); const SectionValidation = ({ address }) => - address?.stateId == null && ( + address?.stateId == 0 && (

    Mohon untuk memperbarui alamat Anda dengan mengklik tombol di bawah ini.{' '} diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 09b30a44..4dd2ce3e 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -1,4 +1,3 @@ - import { Box, Skeleton, Tooltip } from '@chakra-ui/react'; import { HeartIcon } from '@heroicons/react/24/outline'; import { Info } from 'lucide-react'; @@ -18,6 +17,7 @@ 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 { getAuth } from '~/libs/auth'; import productSimilarApi from '../../api/productSimilarApi'; import ProductCard from '../ProductCard'; @@ -30,7 +30,7 @@ const ProductDesktopVariant = ({ isVariant, }) => { const router = useRouter(); - const auth = useAuth(); + let auth = useAuth(); const { slug } = router.query; const [lowestPrice, setLowestPrice] = useState(null); @@ -91,8 +91,34 @@ const ProductDesktopVariant = ({ setAddCartAlert(true); }; - const handleBuy = (variant) => { - const quantity = variantQuantityRefs.current[product.id].value; + const handleBuy = async (variant) => { + const quantity = variantQuantityRefs?.current[product.id]?.value; + let isLoggedIn = typeof auth === 'object'; + + if (!isLoggedIn) { + const currentUrl = encodeURIComponent(router.asPath); + await router.push(`/login?next=${currentUrl}`); + + // Tunggu login berhasil, misalnya dengan memantau perubahan status auth. + const authCheckInterval = setInterval(() => { + const newAuth = getAuth(); + if (typeof newAuth === 'object') { + isLoggedIn = true; + auth = newAuth; // Update nilai auth setelah login + clearInterval(authCheckInterval); + } + }, 500); // Periksa status login setiap 500ms + + await new Promise((resolve) => { + const checkLogin = setInterval(() => { + if (isLoggedIn) { + clearInterval(checkLogin); + resolve(null); + } + }, 500); + }); + } + if (!validQuantity(quantity)) return; updateItemCart({ -- cgit v1.2.3 From 744405d8e62135372acb6c73fd7b66254309d0aa Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 23 Oct 2024 13:25:20 +0700 Subject: update when tambah keranjang --- .../components/Product/ProductDesktopVariant.jsx | 11 +++--- .../components/Product/ProductMobileVariant.jsx | 42 +++++++++++++++++++--- 2 files changed, 45 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 4dd2ce3e..4ecd15c8 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -32,7 +32,7 @@ const ProductDesktopVariant = ({ const router = useRouter(); let auth = useAuth(); const { slug } = router.query; - + const { srsltid } = router.query; const [lowestPrice, setLowestPrice] = useState(null); const [addCartAlert, setAddCartAlert] = useState(false); @@ -74,7 +74,7 @@ const ProductDesktopVariant = ({ const handleAddToCart = (variant) => { if (!auth) { - router.push(`/login?next=/shop/product/${slug}`); + router.push(`/login?next=/shop/product/${slug}?srsltid=${srsltid}`); return; } const quantity = variantQuantityRefs.current[product.id].value; @@ -292,13 +292,16 @@ const ProductDesktopVariant = ({
    -

    Informasi Produk

    +

    + Informasi Produk +


    ' + !product.parent.description || + product.parent.description == '


    ' ? 'Belum ada deskripsi' : product.parent.description, }} diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx index af9e52bb..c1d7ffe0 100644 --- a/src/lib/product/components/Product/ProductMobileVariant.jsx +++ b/src/lib/product/components/Product/ProductMobileVariant.jsx @@ -16,12 +16,15 @@ 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 { getAuth } from '~/libs/auth'; import ProductSimilar from '../ProductSimilar'; const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { const router = useRouter(); - + const { slug } = router.query; + const { srsltid } = router.query; + let auth = getAuth(); const [quantity, setQuantity] = useState('1'); const [selectedVariant, setSelectedVariant] = useState(product.id); const [informationTab, setInformationTab] = useState( @@ -73,11 +76,16 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { return isValid; }; - const handleClickCart = () => { + const handleClickCart = async () => { + if (!auth) { + router.push(`/login?next=/shop/product/${slug}?srsltid=${srsltid}`); + return; + } + if (!validAction()) return; gtagAddToCart(activeVariant, quantity); updateItemCart({ - productId: variant, + productId: product.id, quantity, programLineId: null, selected: true, @@ -86,7 +94,33 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { setAddCartAlert(true); }; - const handleClickBuy = () => { + const handleClickBuy = async () => { + let isLoggedIn = typeof auth === 'object'; + + if (!isLoggedIn) { + const currentUrl = encodeURIComponent(router.asPath); + await router.push(`/login?next=${currentUrl}`); + + // Tunggu login berhasil, misalnya dengan memantau perubahan status auth. + const authCheckInterval = setInterval(() => { + const newAuth = getAuth(); + if (typeof newAuth === 'object') { + isLoggedIn = true; + auth = newAuth; // Update nilai auth setelah login + clearInterval(authCheckInterval); + } + }, 500); // Periksa status login setiap 500ms + + await new Promise((resolve) => { + const checkLogin = setInterval(() => { + if (isLoggedIn) { + clearInterval(checkLogin); + resolve(null); + } + }, 500); + }); + } + if (!validAction()) return; updateItemCart({ -- cgit v1.2.3 From c8fef0308a258c27338b80a9b19e187fa68403ca Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 24 Oct 2024 08:50:18 +0700 Subject: delete console log --- src/pages/my/address/[id]/edit.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/my/address/[id]/edit.jsx b/src/pages/my/address/[id]/edit.jsx index c126b290..19d7af41 100644 --- a/src/pages/my/address/[id]/edit.jsx +++ b/src/pages/my/address/[id]/edit.jsx @@ -46,6 +46,6 @@ export async function getServerSideProps(context) { subDistrict: '', business_name: '', }; - console.log('ini default',defaultValues); + // console.log('ini default',defaultValues); return { props: { id, defaultValues } }; } -- cgit v1.2.3 From 7350eb1edcfb7e9776fec70849ee0c64a795eda3 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 24 Oct 2024 11:35:14 +0700 Subject: add penawaran instan mobile --- .../components/Product/ProductDesktopVariant.jsx | 31 +++++++++++++++++++- .../components/Product/ProductMobileVariant.jsx | 33 ++++++++++++++++++++-- src/lib/quotation/components/Quotation.jsx | 5 +++- 3 files changed, 65 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 55effdfb..e04e0d16 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -17,7 +17,7 @@ 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 ImageNext from 'next/image'; import { RWebShare } from 'react-web-share'; import productSimilarApi from '../../api/productSimilarApi'; import ProductCard from '../ProductCard'; @@ -119,6 +119,20 @@ const ProductDesktopVariant = ({ router.push(`/shop/checkout?source=buy`); }; + const handleButton = (variant) => { + const quantity = quantityInput; + if (!validQuantity(quantity)) return; + + updateItemCart({ + productId: variant, + quantity, + programLineId: null, + selected: true, + source: 'buy', + }); + router.push('/shop/quotation?source=buy'); + }; + const variantSectionRef = useRef(null); const goToVariantSection = () => { if (variantSectionRef.current) { @@ -403,6 +417,21 @@ const ProductDesktopVariant = ({ Beli
    +
    +
    diff --git a/src/lib/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx index cf0ad41f..5a2f63a5 100644 --- a/src/lib/quotation/components/Quotation.jsx +++ b/src/lib/quotation/components/Quotation.jsx @@ -39,9 +39,12 @@ const { getProductsCheckout } = require('@/lib/checkout/api/checkoutApi'); const Quotation = () => { const router = useRouter(); const auth = useAuth(); + const query = router.query.source ?? null; const { data: cartCheckout } = useQuery('cartCheckout', () => - getProductsCheckout() + getProductsCheckout({ + source: query, + }) ); const { setRefreshCart } = useProductCartContext(); -- cgit v1.2.3 From f0d03727f69a84daff484ea9a7944d9c29daa5c3 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Thu, 24 Oct 2024 15:02:04 +0700 Subject: done page category brand --- src/pages/api/shop/search.js | 9 ++++-- src/pages/api/shop/url-category_brand.js | 17 +++++++++++ src/pages/shop/find/[slug].jsx | 51 ++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 src/pages/api/shop/url-category_brand.js create mode 100644 src/pages/shop/find/[slug].jsx (limited to 'src') diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 49a5fe69..bc1c014b 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -88,7 +88,10 @@ export default async function handler(req, res) { 'price_tier1_v2_f:[1 TO *]', ]; - const fq_ = filterQueries.join('AND '); + if(fq){ + filterQueries.push(fq); + } + const fq_ = filterQueries.join(' AND '); let offset = (page - 1) * limit; let parameter = [ @@ -106,7 +109,7 @@ export default async function handler(req, res) { : formattedQuery }`, `defType=edismax`, - 'qf=name_s description_clean_t category_name manufacture_name_s variants_code_t variants_name_t category_id_ids default_code_s', + 'qf=name_s description_clean_t category_name manufacture_name_s variants_code_t variants_name_t category_id_ids default_code_s manufacture_id_i category_id_i ', `start=${parseInt(offset)}`, `rows=${limit}`, `sort=${paramOrderBy}`, @@ -149,7 +152,7 @@ export default async function handler(req, res) { if (stock) parameter.push(`fq=stock_total_f:{1 TO *}`); // Single fq in url params - if (typeof fq === 'string') parameter.push(`fq=${encodeURIComponent(fq)}`); + // if (typeof fq === 'string') parameter.push(`fq=${encodeURIComponent(fq)}`); // Multi fq in url params if (Array.isArray(fq)) parameter = parameter.concat( diff --git a/src/pages/api/shop/url-category_brand.js b/src/pages/api/shop/url-category_brand.js new file mode 100644 index 00000000..cfcc7d73 --- /dev/null +++ b/src/pages/api/shop/url-category_brand.js @@ -0,0 +1,17 @@ +import axios from 'axios'; + +export default async function handler(req, res) { + const { url = '' } = req.query; + + const params = [`q.op=AND`, `q=url_s:"${url}"`, `indent=true`]; + try { + let result = await axios( + process.env.SOLR_HOST + + `/solr/url_category_brand/select?` + + params.join('&') + ); + res.status(200).json(result.data); + } catch (error) { + res.status(500).json({ error: 'Internal Server Error' }); + } +} diff --git a/src/pages/shop/find/[slug].jsx b/src/pages/shop/find/[slug].jsx new file mode 100644 index 00000000..4666add5 --- /dev/null +++ b/src/pages/shop/find/[slug].jsx @@ -0,0 +1,51 @@ +import axios from 'axios'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import Seo from '@/core/components/Seo'; +import dynamic from 'next/dynamic'; + +const BasicLayout = dynamic(() => + import('@/core/components/layouts/BasicLayout') +); +const ProductSearch = dynamic(() => + import('@/lib/product/components/ProductSearch') +); + +const BASE_URL = 'https://indoteknik.com'; +export default function FindPage() { + const route = useRouter(); + const url = BASE_URL + route.asPath; + const [result, setResult] = useState(null); + const [query, setQuery] = useState(null); + + const getUrls = async (url) => { + try { + let response = await axios( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/url-category_brand?url=${url}` + ); + let result = response?.data?.response?.docs[0] || null; + setResult(result); + } catch (error) { + console.error('Error fetching data:', error); + } + }; + + useEffect(() => { + getUrls(url); + }, []); + + useEffect(() => { + if (result) { + let fq = `category_parent_ids:${result.category_id_i} AND manufacture_id_i:${result.brand_id_i}`; + setQuery({ + fq : fq + }); + } + }, [result]); + + return ( + + {query && } + + ); +} -- cgit v1.2.3 From 2657955cb4dc4cbe703d77bb43a6394a8ee98f74 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Thu, 24 Oct 2024 16:27:54 +0700 Subject: add seo --- src/pages/shop/find/[slug].jsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/shop/find/[slug].jsx b/src/pages/shop/find/[slug].jsx index 4666add5..50797153 100644 --- a/src/pages/shop/find/[slug].jsx +++ b/src/pages/shop/find/[slug].jsx @@ -3,6 +3,8 @@ import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; import Seo from '@/core/components/Seo'; import dynamic from 'next/dynamic'; +import { get } from 'lodash-contrib'; +import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -18,6 +20,7 @@ export default function FindPage() { const [result, setResult] = useState(null); const [query, setQuery] = useState(null); + const slug = getNameFromSlug( route.query.slug) +' '+ getIdFromSlug( route.query.slug) const getUrls = async (url) => { try { let response = await axios( @@ -38,13 +41,24 @@ export default function FindPage() { if (result) { let fq = `category_parent_ids:${result.category_id_i} AND manufacture_id_i:${result.brand_id_i}`; setQuery({ - fq : fq + fq: fq, }); } }, [result]); return ( + {query && } ); -- cgit v1.2.3 From bb2fc00e1f399be919d7b777dd0ae17edd6b2a2e Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Fri, 25 Oct 2024 10:04:34 +0700 Subject: sitemap categories brand --- src/pages/api/shop/url-category_brand.js | 7 +++-- src/pages/shop/find/[slug].jsx | 3 +- src/pages/sitemap/categories-brand.xml.js | 35 ++++++++++++++++++++++ src/pages/sitemap/categories-brand/[page].js | 43 ++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/pages/sitemap/categories-brand.xml.js create mode 100644 src/pages/sitemap/categories-brand/[page].js (limited to 'src') diff --git a/src/pages/api/shop/url-category_brand.js b/src/pages/api/shop/url-category_brand.js index cfcc7d73..160aa166 100644 --- a/src/pages/api/shop/url-category_brand.js +++ b/src/pages/api/shop/url-category_brand.js @@ -1,9 +1,12 @@ import axios from 'axios'; export default async function handler(req, res) { - const { url = '' } = req.query; + const { url = '', page = 1, limit = 30 } = req.query; + + let offset = (page - 1) * limit; - const params = [`q.op=AND`, `q=url_s:"${url}"`, `indent=true`]; + const params = [`q.op=AND`, `q=${url ? `"${url}"` : '*'}`, `indent=true`, `rows=${limit}`, `start=${offset}`]; + try { let result = await axios( process.env.SOLR_HOST + diff --git a/src/pages/shop/find/[slug].jsx b/src/pages/shop/find/[slug].jsx index 50797153..85e780ff 100644 --- a/src/pages/shop/find/[slug].jsx +++ b/src/pages/shop/find/[slug].jsx @@ -16,11 +16,12 @@ const ProductSearch = dynamic(() => const BASE_URL = 'https://indoteknik.com'; export default function FindPage() { const route = useRouter(); + const qSlug = route?.query?.slug || null; const url = BASE_URL + route.asPath; const [result, setResult] = useState(null); const [query, setQuery] = useState(null); - const slug = getNameFromSlug( route.query.slug) +' '+ getIdFromSlug( route.query.slug) + const slug = qSlug ? getNameFromSlug(route?.query?.slug) +' '+ getIdFromSlug(route?.query?.slug) : ''; const getUrls = async (url) => { try { let response = await axios( diff --git a/src/pages/sitemap/categories-brand.xml.js b/src/pages/sitemap/categories-brand.xml.js new file mode 100644 index 00000000..b23363e9 --- /dev/null +++ b/src/pages/sitemap/categories-brand.xml.js @@ -0,0 +1,35 @@ +import productSearchApi from '@/lib/product/api/productSearchApi' +import { create } from 'xmlbuilder' +import _ from 'lodash-contrib' +import axios from 'axios' + +export async function getServerSideProps({ res }) { + const baseUrl = process.env.SELF_HOST + '/sitemap/categories-brand' + const limit = 500 + const categories = await axios( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/url-category_brand?limit=${limit}` + ) + const pageCount = Math.ceil(categories.data.response.numFound / limit) + const pages = Array.from({ length: pageCount }, (_, i) => i + 1) + const sitemapIndex = create('sitemapindex', { encoding: 'UTF-8' }).att( + 'xmlns', + 'http://www.sitemaps.org/schemas/sitemap/0.9' + ) + + const date = new Date() + pages.forEach((page) => { + const sitemap = sitemapIndex.ele('sitemap') + sitemap.ele('loc', `${baseUrl}/${page}.xml`) + sitemap.ele('lastmod', date.toISOString().slice(0, 10)) + }) + + res.setHeader('Content-Type', 'text/xml') + res.write(sitemapIndex.end()) + res.end() + + return { props: {} } +} + +export default function SitemapProducts() { + return null +} diff --git a/src/pages/sitemap/categories-brand/[page].js b/src/pages/sitemap/categories-brand/[page].js new file mode 100644 index 00000000..6b55e426 --- /dev/null +++ b/src/pages/sitemap/categories-brand/[page].js @@ -0,0 +1,43 @@ + +import productSearchApi from '@/lib/product/api/productSearchApi' +import { create } from 'xmlbuilder' +import _ from 'lodash-contrib' +import { createSlug } from '@/core/utils/slug' +import axios from 'axios' + +export async function getServerSideProps({ query, res }) { + const baseUrl = process.env.SELF_HOST + '/shop/product/' + const { page } = query + const limit = 500 + const categories = await axios( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/url-category_brand?limit=${limit}&page=${page.replace( + '.xml', + '' + )}` + ) + + const sitemap = create('urlset', { encoding: 'utf-8' }).att( + 'xmlns', + 'http://www.sitemaps.org/schemas/sitemap/0.9' + ) + + const date = new Date() + categories.data.response.docs.forEach((product) => { + const url = sitemap.ele('url') + const loc = product.url_s; + url.ele('loc', loc) + url.ele('lastmod', date.toISOString().slice(0, 10)) + url.ele('changefreq', 'daily') + url.ele('priority', '0.8') + }) + + res.setHeader('Content-Type', 'text/xml') + res.write(sitemap.end()) + res.end() + + return { props: {} } +} + +export default function SitemapProducts() { + return null +} -- cgit v1.2.3 From 16e46197ee2c9879ae8ef9a68d4ce67ae68843e3 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Fri, 25 Oct 2024 10:24:24 +0700 Subject: seo title --- src/pages/shop/find/[slug].jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/shop/find/[slug].jsx b/src/pages/shop/find/[slug].jsx index 85e780ff..e7b8bd48 100644 --- a/src/pages/shop/find/[slug].jsx +++ b/src/pages/shop/find/[slug].jsx @@ -50,7 +50,7 @@ export default function FindPage() { return ( Date: Fri, 25 Oct 2024 15:03:53 +0700 Subject: update revisi CR --- src/lib/product/components/Product/ProductDesktopVariant.jsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 2e005eea..32ce345e 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -364,14 +364,16 @@ const ProductDesktopVariant = ({
    - - {' '} Stock : {product?.sla?.qty}{' '} - +
    {product?.sla?.qty > 0 && ( -- cgit v1.2.3 From dda4a5a1aff91f186cda930242bf408d64e14adb Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 25 Oct 2024 15:47:18 +0700 Subject: update tampilan mobile --- src/lib/product/components/Product/ProductMobileVariant.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx index c1d7ffe0..4018ac15 100644 --- a/src/lib/product/components/Product/ProductMobileVariant.jsx +++ b/src/lib/product/components/Product/ProductMobileVariant.jsx @@ -183,7 +183,9 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { )}
    -

    {activeVariant?.name}

    +

    + {activeVariant?.name} +

    {activeVariant.isFlashSale && activeVariant?.price?.discountPercentage > 0 ? ( -- cgit v1.2.3 From 5cfc93d26d29c131564853810dcc3fac7167780a Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Mon, 28 Oct 2024 09:33:24 +0700 Subject: capitalizeEachWord --- src/pages/shop/find/[slug].jsx | 9 ++++++--- src/utils/capializeFIrstWord.js | 9 +++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 src/utils/capializeFIrstWord.js (limited to 'src') diff --git a/src/pages/shop/find/[slug].jsx b/src/pages/shop/find/[slug].jsx index e7b8bd48..7174a9fb 100644 --- a/src/pages/shop/find/[slug].jsx +++ b/src/pages/shop/find/[slug].jsx @@ -5,6 +5,7 @@ import Seo from '@/core/components/Seo'; import dynamic from 'next/dynamic'; import { get } from 'lodash-contrib'; import { getIdFromSlug, getNameFromSlug } from '@/core/utils/slug'; +import { capitalizeEachWord } from '../../../utils/capializeFIrstWord'; const BasicLayout = dynamic(() => import('@/core/components/layouts/BasicLayout') @@ -17,11 +18,13 @@ const BASE_URL = 'https://indoteknik.com'; export default function FindPage() { const route = useRouter(); const qSlug = route?.query?.slug || null; - const url = BASE_URL + route.asPath; + const url = BASE_URL + route.asPath.split('?')[0]; const [result, setResult] = useState(null); const [query, setQuery] = useState(null); - const slug = qSlug ? getNameFromSlug(route?.query?.slug) +' '+ getIdFromSlug(route?.query?.slug) : ''; + const __slug = qSlug ? getNameFromSlug(route?.query?.slug) +' '+ getIdFromSlug(route?.query?.slug) : ''; + const slug = capitalizeEachWord(__slug); + const getUrls = async (url) => { try { let response = await axios( @@ -50,7 +53,7 @@ export default function FindPage() { return ( { + return str + .split(' ') // Pisahkan string menjadi array kata-kata + .map((word) => // Ubah huruf pertama setiap kata menjadi besar + word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() + ) + .join(' '); // Gabungkan kembali menjadi string + }; + \ No newline at end of file -- cgit v1.2.3 From 2d30aea4e9d225298594ee92f474a38225b91206 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 28 Oct 2024 12:07:09 +0700 Subject: update informasi product varian --- .../components/Product/ProductDesktopVariant.jsx | 84 ++++++++++++++++------ .../components/Product/ProductMobileVariant.jsx | 12 +++- src/pages/api/shop/search.js | 2 +- 3 files changed, 73 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 4ecd15c8..a4cc62dd 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -4,8 +4,11 @@ import { Info } from 'lucide-react'; import { useRouter } from 'next/router'; import { useCallback, useEffect, useRef, useState } from 'react'; import { toast } from 'react-hot-toast'; +import { MessageCircleIcon, Share2Icon } from 'lucide-react'; +import AddToWishlist from '../../../../../src-migrate/modules/product-detail/components/AddToWishlist'; +import { RWebShare } from 'react-web-share'; import LazyLoad from 'react-lazy-load'; - +import { Button } from '@chakra-ui/react'; import { useProductCartContext } from '@/contexts/ProductCartContext'; import odooApi from '@/core/api/odooApi'; import Image from '@/core/components/elements/Image/Image'; @@ -18,11 +21,11 @@ import currencyFormat from '@/core/utils/currencyFormat'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; import { getAuth } from '~/libs/auth'; - +import SimilarBottom from '~/modules/product-detail/components/SimilarBottom'; 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, @@ -33,6 +36,7 @@ const ProductDesktopVariant = ({ let auth = useAuth(); const { slug } = router.query; const { srsltid } = router.query; + const [askAdminUrl, setAskAdminUrl, isApproval] = useState(); const [lowestPrice, setLowestPrice] = useState(null); const [addCartAlert, setAddCartAlert] = useState(false); @@ -40,6 +44,20 @@ const ProductDesktopVariant = ({ const { setRefreshCart } = useProductCartContext(); + 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 getLowestPrice = useCallback(() => { const lowest = product.price; /* const lowest = prices.reduce((lowest, price) => { @@ -190,7 +208,7 @@ const ProductDesktopVariant = ({ />
    -
    +

    {product?.name}

    @@ -289,9 +307,40 @@ const ProductDesktopVariant = ({
    +
    +
    + + + + + + + +
    -
    +

    Informasi Produk

    @@ -388,24 +437,11 @@ const ProductDesktopVariant = ({ Beli
    -
    - -
    Produk Serupa
    -
    +
    {productSimilarInBrand && productSimilarInBrand?.map((product) => (
    @@ -422,8 +458,11 @@ const ProductDesktopVariant = ({ Kamu Mungkin Juga Suka
    - + + {/* + + */}
    - + + {/* + + */}
    diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx index 4018ac15..790dbbe0 100644 --- a/src/lib/product/components/Product/ProductMobileVariant.jsx +++ b/src/lib/product/components/Product/ProductMobileVariant.jsx @@ -17,7 +17,7 @@ import { gtagAddToCart } from '@/core/utils/googleTag'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; import { getAuth } from '~/libs/auth'; - +import SimilarBottom from '~/modules/product-detail/components/SimilarBottom'; import ProductSimilar from '../ProductSimilar'; const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => { @@ -411,8 +411,11 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {

    Kamu Mungkin Juga Suka

    - + + {/* + + */}
    { Kamu Mungkin Juga Suka
    - + + {/* + + */}
    diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index bc1c014b..ace281f7 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -88,7 +88,7 @@ export default async function handler(req, res) { 'price_tier1_v2_f:[1 TO *]', ]; - if(fq){ + if (fq && source != 'similar') { filterQueries.push(fq); } const fq_ = filterQueries.join(' AND '); -- cgit v1.2.3 From 90b5b3f35e230f863b5bd7e44154497283759f03 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Tue, 29 Oct 2024 14:19:42 +0700 Subject: CR meta title page category brand --- src/pages/shop/find/[slug].jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/shop/find/[slug].jsx b/src/pages/shop/find/[slug].jsx index 7174a9fb..dc243b73 100644 --- a/src/pages/shop/find/[slug].jsx +++ b/src/pages/shop/find/[slug].jsx @@ -53,7 +53,7 @@ export default function FindPage() { return ( Date: Wed, 30 Oct 2024 10:03:28 +0700 Subject: page garansi resmi & pembayaran tempo --- src/lib/home/components/ServiceList.jsx | 4 ++-- src/pages/garansi-resmi.jsx | 13 +++++++++++++ src/pages/pembayaran-tempo.jsx | 13 +++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/pages/garansi-resmi.jsx create mode 100644 src/pages/pembayaran-tempo.jsx (limited to 'src') diff --git a/src/lib/home/components/ServiceList.jsx b/src/lib/home/components/ServiceList.jsx index 5b16915d..b3cc8fe5 100644 --- a/src/lib/home/components/ServiceList.jsx +++ b/src/lib/home/components/ServiceList.jsx @@ -32,7 +32,7 @@ const ServiceList = () => {
    @@ -57,7 +57,7 @@ const ServiceList = () => {
    diff --git a/src/pages/garansi-resmi.jsx b/src/pages/garansi-resmi.jsx new file mode 100644 index 00000000..7384a89d --- /dev/null +++ b/src/pages/garansi-resmi.jsx @@ -0,0 +1,13 @@ +import Seo from '@/core/components/Seo' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import IframeContent from '@/lib/iframe/components/IframeContent' + +export default function GaransiResmi() { + return ( + + + + + + ) +} diff --git a/src/pages/pembayaran-tempo.jsx b/src/pages/pembayaran-tempo.jsx new file mode 100644 index 00000000..363e3099 --- /dev/null +++ b/src/pages/pembayaran-tempo.jsx @@ -0,0 +1,13 @@ +import Seo from '@/core/components/Seo' +import BasicLayout from '@/core/components/layouts/BasicLayout' +import IframeContent from '@/lib/iframe/components/IframeContent' + +export default function PembnayaranTempo() { + return ( + + + + + + ) +} -- cgit v1.2.3 From 4e48c548c9802046cf319873a9472149b32017be Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Fri, 1 Nov 2024 13:50:53 +0700 Subject: cr seo page find category brand --- src/pages/shop/find/[slug].jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/pages/shop/find/[slug].jsx b/src/pages/shop/find/[slug].jsx index dc243b73..268b1e56 100644 --- a/src/pages/shop/find/[slug].jsx +++ b/src/pages/shop/find/[slug].jsx @@ -53,12 +53,12 @@ export default function FindPage() { return ( Date: Tue, 5 Nov 2024 15:49:45 +0700 Subject: add redis --- src/components/ui/HeroBanner.jsx | 37 ++-- src/lib/home/components/BannerSection.jsx | 38 +++-- src/lib/home/components/CategoryDynamic.jsx | 247 +++++++++++---------------- src/lib/home/components/PromotionProgram.jsx | 96 ++++++----- src/pages/api/banner-section.js | 44 +++++ src/pages/api/category-management.js | 85 +++++++++ src/pages/api/hero-banner.js | 45 +++++ src/pages/api/shop/brands.js | 42 +++-- 8 files changed, 406 insertions(+), 228 deletions(-) create mode 100644 src/pages/api/banner-section.js create mode 100644 src/pages/api/category-management.js create mode 100644 src/pages/api/hero-banner.js (limited to 'src') diff --git a/src/components/ui/HeroBanner.jsx b/src/components/ui/HeroBanner.jsx index 64838b85..2eea5915 100644 --- a/src/components/ui/HeroBanner.jsx +++ b/src/components/ui/HeroBanner.jsx @@ -6,7 +6,7 @@ import 'swiper/css/pagination'; import { Swiper, SwiperSlide } from 'swiper/react'; import Image from 'next/image'; -import { useMemo } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { useQuery } from 'react-query'; import { bannerApi } from '@/api/bannerApi'; @@ -27,7 +27,20 @@ const swiperBanner = { }; const HeroBanner = () => { - const heroBanner = useQuery('heroBanner', bannerApi({ type: 'index-a-1' })); + // const heroBanner = useQuery('heroBanner', bannerApi({ type: 'index-a-1' })); + const [data, setData] = useState(null); + useEffect(() => { + const fetchData = async () => { + const res = await fetch(`/api/hero-banner?type=index-a-1`); + const { data } = await res.json(); + if (data) { + setData(data); + } + }; + + fetchData(); + }, []); + const heroBanner = data; const swiperBannerMobile = { ...swiperBanner, @@ -44,9 +57,9 @@ const HeroBanner = () => { }; const BannerComponent = useMemo(() => { - if (!heroBanner.data) return null; + if (!heroBanner) return null; - return heroBanner.data.map((banner, index) => ( + return heroBanner.map((banner, index) => ( { width={1152} height={768} className='w-full h-auto' - priority={index === 0} - loading={index === 0 ? 'eager' : 'lazy'} - placeholder="blur" - blurDataURL="/images/indoteknik-placeholder.png" - sizes="(max-width: 768px) 100vw, 50vw" + priority={index === 0} + loading={index === 0 ? 'eager' : 'lazy'} + placeholder='blur' + blurDataURL='/images/indoteknik-placeholder.png' + sizes='(max-width: 768px) 100vw, 50vw' /> )); - }, [heroBanner.data]); + }, [heroBanner]); return ( <> 0} + isLoaded={heroBanner?.length > 0} height='68vw' duration='750ms' delay='100ms' @@ -81,7 +94,7 @@ const HeroBanner = () => { - {heroBanner.data?.length > 0 && ( + {heroBanner?.length > 0 && ( {BannerComponent} )} diff --git a/src/lib/home/components/BannerSection.jsx b/src/lib/home/components/BannerSection.jsx index 60d38f8f..303b5c4b 100644 --- a/src/lib/home/components/BannerSection.jsx +++ b/src/lib/home/components/BannerSection.jsx @@ -11,27 +11,33 @@ const BannerSection = () => { const [shouldFetch, setShouldFetch] = useState(false); useEffect(() => { - const localData = localStorage.getItem('Homepage_bannerSection'); - if (localData) { - setData(JSON.parse(localData)); - }else{ - setShouldFetch(true); - } - }, []); - - // const fetchBannerSection = async () => await bannerSectionApi(); - const getBannerSection = useQuery('bannerSection', bannerApi({ type: 'home-banner' }), { - enabled: shouldFetch, - onSuccess: (data) => { + const fetchCategoryData = async () => { + const res = await fetch('/api/banner-section'); + const { data } = await res.json(); if (data) { - localStorage.setItem('Homepage_bannerSection', JSON.stringify(data)); setData(data); } - }, - }); + }; - const bannerSection = data; + fetchCategoryData(); + }, []); + // const fetchBannerSection = async () => await bannerSectionApi(); + const getBannerSection = useQuery( + 'bannerSection', + bannerApi({ type: 'home-banner' }), + { + enabled: shouldFetch, + onSuccess: (data) => { + if (data) { + localStorage.setItem('Homepage_bannerSection', JSON.stringify(data)); + setData(data); + } + }, + } + ); + + const bannerSection = data; return ( bannerSection && bannerSection?.length > 0 && ( diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index e62575f7..cc4f42b7 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -1,81 +1,33 @@ -import React, { useEffect, useState, useCallback } from 'react'; -import { - fetchCategoryManagementSolr, - fetchCategoryManagementVersion, -} from '../api/categoryManagementApi'; +import React, { useEffect, useState } from 'react'; +import { fetchCategoryManagementSolr } from '../api/categoryManagementApi'; +import { Skeleton } from '@chakra-ui/react'; import NextImage from 'next/image'; import Link from 'next/link'; import { createSlug } from '@/core/utils/slug'; -import { Skeleton } from '@chakra-ui/react'; import { Swiper, SwiperSlide } from 'swiper/react'; import 'swiper/css'; import 'swiper/css/navigation'; import 'swiper/css/pagination'; import { Pagination } from 'swiper'; -const saveToLocalStorage = (key, data, version) => { - const now = new Date(); - const item = { - value: data, - version: version, - lastFetchedTime: now.getTime(), - }; - localStorage.setItem(key, JSON.stringify(item)); -}; - -const getFromLocalStorage = (key) => { - const itemStr = localStorage.getItem(key); - if (!itemStr) return null; - - const item = JSON.parse(itemStr); - return item; -}; - -const getElapsedTime = (lastFetchedTime) => { - const now = new Date(); - return now.getTime() - lastFetchedTime; -}; - const CategoryDynamic = () => { const [categoryManagement, setCategoryManagement] = useState([]); - const [isLoading, setIsLoading] = useState(false); - - const loadBrand = useCallback(async () => { - const cachedData = getFromLocalStorage('homepage_categoryDynamic'); - - if (cachedData) { - // Hitung selisih waktu antara saat ini dengan waktu terakhir data di-fetch - const elapsedTime = getElapsedTime(cachedData.lastFetchedTime); - - if (elapsedTime < 24 * 60 * 60 * 1000) { - setCategoryManagement(cachedData.value); - return; - } - } + const [isLoading, setIsLoading] = useState(true); - const latestVersion = await fetchCategoryManagementVersion(); - if (cachedData && cachedData.version === latestVersion) { - // perbarui waktu - saveToLocalStorage( - 'homepage_categoryDynamic', - cachedData.value, - latestVersion - ); - setCategoryManagement(cachedData.value); - } else { + useEffect(() => { + const fetchCategoryData = async () => { setIsLoading(true); - const items = await fetchCategoryManagementSolr(); + const res = await fetch('/api/category-management'); + const { data } = await res.json(); + if (data) { + setCategoryManagement(data); + } setIsLoading(false); + }; - saveToLocalStorage('homepage_categoryDynamic', items, latestVersion); - setCategoryManagement(items); - } + fetchCategoryData(); }, []); - useEffect(() => { - loadBrand(); - }, [loadBrand]); - const swiperBanner = { modules: [Pagination], classNames: 'mySwiper', @@ -90,104 +42,99 @@ const CategoryDynamic = () => { return (
    {categoryManagement && - categoryManagement?.map((category) => { - return ( - -
    -
    -

    - {category.name} -

    - - Lihat Semua - -
    + categoryManagement.map((category) => ( + +
    +
    +

    + {category.name} +

    + + Lihat Semua + +
    - {/* Swiper for SubCategories */} - - {category.categories.map((subCategory) => { - return ( - -
    -
    -
    - -
    -

    - {subCategory?.name} -

    + + {category?.categories?.map((subCategory) => ( + +
    +
    +
    + +
    +

    + {subCategory?.name} +

    + + Lihat Semua + +
    +
    +
    + {subCategory.child_frontend_id_i.map( + (childCategory) => ( +
    - Lihat Semua + +
    +

    + {childCategory.name} +

    +
    -
    -
    - {subCategory.child_frontend_id_i.map( - (childCategory) => ( -
    - - -
    -

    - {childCategory.name} -

    -
    - -
    - ) - )} -
    -
    + ) + )}
    -
    - ); - })} -
    -
    - - ); - })} +
    +
    + + ))} + +
    + + ))}
    ); }; diff --git a/src/lib/home/components/PromotionProgram.jsx b/src/lib/home/components/PromotionProgram.jsx index 7433e7f0..562fa138 100644 --- a/src/lib/home/components/PromotionProgram.jsx +++ b/src/lib/home/components/PromotionProgram.jsx @@ -10,32 +10,50 @@ const BannerSection = () => { const { isMobile, isDesktop } = useDevice(); const [data, setData] = useState(null); const [shouldFetch, setShouldFetch] = useState(false); - useEffect(() => { - const localData = localStorage.getItem('Homepage_promotionProgram'); - if (localData) { - setData(JSON.parse(localData)); - }else{ - setShouldFetch(true); - } - },[]) - - const getPromotionProgram = useQuery( - 'promotionProgram', - bannerApi({ type: 'banner-promotion' }),{ - enabled: shouldFetch, - onSuccess: (data) => { - if (data) { - localStorage.setItem('Homepage_promotionProgram', JSON.stringify(data)); - setData(data); - } + const fetchData = async () => { + const res = await fetch(`/api/hero-banner?type=banner-promotion`); + const { data } = await res.json(); + if (data) { + setData(data); } - } - ); + }; + + fetchData(); + }, []); + + // useEffect(() => { + // const localData = localStorage.getItem('Homepage_promotionProgram'); + // if (localData) { + // setData(JSON.parse(localData)); + // } else { + // setShouldFetch(true); + // } + // }, []); - const promotionProgram = data + // const getPromotionProgram = useQuery( + // 'promotionProgram', + // bannerApi({ type: 'banner-promotion' }), + // { + // enabled: shouldFetch, + // onSuccess: (data) => { + // if (data) { + // localStorage.setItem( + // 'Homepage_promotionProgram', + // JSON.stringify(data) + // ); + // setData(data); + // } + // }, + // } + // ); - if (getPromotionProgram?.isLoading && !data) { + const promotionProgram = data; + + // if (getPromotionProgram?.isLoading && !data) { + // return ; + // } + if (!data) { return ; } @@ -62,24 +80,22 @@ const BannerSection = () => { )}
    - {isDesktop && - promotionProgram && - promotionProgram?.length > 0 && ( -
    - {promotionProgram?.map((banner) => ( - - {banner.name} - - ))} -
    - )} + {isDesktop && promotionProgram && promotionProgram?.length > 0 && ( +
    + {promotionProgram?.map((banner) => ( + + {banner.name} + + ))} +
    + )} {isMobile && ( diff --git a/src/pages/api/banner-section.js b/src/pages/api/banner-section.js new file mode 100644 index 00000000..7d7040c0 --- /dev/null +++ b/src/pages/api/banner-section.js @@ -0,0 +1,44 @@ +import odooApi from '@/core/api/odooApi'; +import { createClient } from 'redis'; + +const client = createClient(); + +client.on('error', (err) => console.error('Redis Client Error', err)); + +const connectRedis = async () => { + if (!client.isOpen) { + await client.connect(); + } +}; + +export default async function handler(req, res) { + try { + await connectRedis(); + const cacheKey = 'hero-banner'; + // await client.del(cacheKey); + let cachedData = await client.get(cacheKey); + + if (cachedData) { + const data = JSON.parse(cachedData); + return res.status(200).json({ data }); + } else { + const dataBannerSections = await odooApi( + 'GET', + '/api/v1/banner?type=home-banner' + ); + + // Simpan hasil fetch ke Redis dengan masa kadaluarsa 3 hari (259200 detik) + await client.set( + cacheKey, + JSON.stringify(dataBannerSections), + 'EX', + 259200 + ); + + return res.status(200).json({ data: dataBannerSections }); + } + } catch (error) { + console.error('Error interacting with Redis or fetching data:', error); + return res.status(500).json({ error: 'Internal Server Error' }); + } +} diff --git a/src/pages/api/category-management.js b/src/pages/api/category-management.js new file mode 100644 index 00000000..f05d8644 --- /dev/null +++ b/src/pages/api/category-management.js @@ -0,0 +1,85 @@ +import { createClient } from 'redis'; +// import { fetchCategoryManagementSolr } from '../../lib/home/api/categoryManagementApi'; +const client = createClient(); +client.on('error', (err) => console.error('Redis Client Error', err)); + +const connectRedis = async () => { + if (!client.isOpen) { + await client.connect(); + } +}; + +export default async function handler(req, res) { + try { + await connectRedis(); + // await client.del('homepage_categoryDynamic'); + + let cachedData; + if (req.method === 'GET') { + cachedData = await client.get('homepage_categoryDynamic'); + + if (!cachedData) { + const items = await fetchCategoryManagementSolr(); + await client.set( + 'homepage_categoryDynamic', + JSON.stringify(items), + 'EX', + 259200 // Expiry 3 hari + ); + cachedData = await client.get('homepage_categoryDynamic'); + } + const data = cachedData ? JSON.parse(cachedData) : null; + res.status(200).json({ data }); + } else { + res.setHeader('Allow', ['GET']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } + } catch (error) { + console.error('Error interacting with Redis:', error); + res.status(500).json({ error: 'Error interacting with Redis' }); + } +} + +const fetchCategoryManagementSolr = async () => { + let sort = 'sort=sequence_i asc'; + try { + const response = await fetch( + `http://34.101.189.218:8983/solr/category_management/query?q=*:*&q.op=OR&indent=true&${sort}&&rows=20` + ); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + const promotions = await map(data.response.docs); + return promotions; + } catch (error) { + console.error('Error fetching promotion data:', error); + return []; + } +}; +const map = async (promotions) => { + return promotions.map((promotion) => { + let parsedCategories = promotion.categories.map((category) => { + // Parse string JSON utama + let parsedCategory = JSON.parse(category); + + // Parse setiap elemen di child_frontend_id_i jika ada + if (parsedCategory.child_frontend_id_i) { + parsedCategory.child_frontend_id_i = + parsedCategory.child_frontend_id_i.map((child) => JSON.parse(child)); + } + + return parsedCategory; + }); + let productMapped = { + id: promotion.id, + name: promotion.name_s, + image: promotion.image_s, + sequence: promotion.sequence_i, + numFound: promotion.numFound_i, + categories: parsedCategories, + category_id: promotion.category_id_i, + }; + return productMapped; + }); +}; diff --git a/src/pages/api/hero-banner.js b/src/pages/api/hero-banner.js new file mode 100644 index 00000000..b57f86e0 --- /dev/null +++ b/src/pages/api/hero-banner.js @@ -0,0 +1,45 @@ +import odooApi from '@/core/api/odooApi'; +import { createClient } from 'redis'; + +const client = createClient(); + +client.on('error', (err) => console.error('Redis Client Error', err)); + +const connectRedis = async () => { + if (!client.isOpen) { + await client.connect(); + } +}; + +export default async function handler(req, res) { + const { type } = req.query; + try { + await connectRedis(); + const cacheKey = `homepage_bannerSection_${type}`; + // await client.del(cacheKey); + let cachedData = await client.get(cacheKey); + + if (cachedData) { + const data = JSON.parse(cachedData); + return res.status(200).json({ data }); + } else { + const dataBannerSections = await odooApi( + 'GET', + `/api/v1/banner?type=${type}` + ); + + // Simpan hasil fetch ke Redis dengan masa kadaluarsa 3 hari (259200 detik) + await client.set( + cacheKey, + JSON.stringify(dataBannerSections), + 'EX', + 259200 + ); + + return res.status(200).json({ data: dataBannerSections }); + } + } catch (error) { + console.error('Error interacting with Redis or fetching data:', error); + return res.status(500).json({ error: 'Internal Server Error' }); + } +} diff --git a/src/pages/api/shop/brands.js b/src/pages/api/shop/brands.js index 9c2824b3..380b3369 100644 --- a/src/pages/api/shop/brands.js +++ b/src/pages/api/shop/brands.js @@ -1,8 +1,20 @@ import axios from 'axios'; +import { createClient } from 'redis'; const SOLR_HOST = process.env.SOLR_HOST; +const client = createClient(); + +client.on('error', (err) => console.error('Redis Client Error', err)); + +const connectRedis = async () => { + if (!client.isOpen) { + await client.connect(); + } +}; export default async function handler(req, res) { + await connectRedis(); + try { let params = '*:*'; let sort = @@ -11,12 +23,12 @@ export default async function handler(req, res) { if (req.query.params) { rows = 100; - switch (req?.query?.params) { + switch (req.query.params) { case 'level_s': params = 'level_s:prioritas'; break; case 'search': - params = `name_s:"${req?.query?.q.toLowerCase()}"`; + params = `name_s:"${req.query.q.toLowerCase()}"`; sort = ''; rows = 1; break; @@ -24,11 +36,23 @@ export default async function handler(req, res) { params = `name_s:${req.query.params}`.toLowerCase(); } } - if(req.query.rows) rows = req.query.rows; - + if (req.query.rows) rows = req.query.rows; + + const cacheKey = `brands_home`; + let cachedData = await client.get(cacheKey); + + if (cachedData) { + console.log('Retrieving data from Redis cache'); + return res.status(200).json(JSON.parse(cachedData)); + } + + // Fetch data from Solr const url = `${SOLR_HOST}/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}`; - let brands = await axios(url); - let dataBrands = responseMap(brands.data.response.docs); + const brands = await axios(url); + const dataBrands = responseMap(brands.data.response.docs); + + // Store fetched data in Redis with 3-day expiration + await client.set(cacheKey, JSON.stringify(dataBrands), 'EX', 259200); res.status(200).json(dataBrands); } catch (error) { @@ -39,13 +63,11 @@ export default async function handler(req, res) { const responseMap = (brands) => { return brands.map((brand) => { - let brandMapping = { + return { id: brand.id, name: brand.display_name_s, logo: brand.image_s || '', - sequance: brand.sequence_i || '', + sequence: brand.sequence_i || '', }; - - return brandMapping; }); }; -- cgit v1.2.3 From bb9004a6fc830162dba2d00df850f7c5603a234a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 6 Nov 2024 09:51:17 +0700 Subject: update bug products_inactive on user carts --- src/lib/cart/components/Cartheader.jsx | 354 +++++++++++++++++++++------------ 1 file changed, 223 insertions(+), 131 deletions(-) (limited to 'src') diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx index ddb77c1f..1c30bb13 100644 --- a/src/lib/cart/components/Cartheader.jsx +++ b/src/lib/cart/components/Cartheader.jsx @@ -1,105 +1,115 @@ -import { useCallback, useEffect, useMemo, useState } from 'react' -import { getCartApi } from '../api/CartApi' -import currencyFormat from '@/core/utils/currencyFormat' -import { createSlug } from '@/core/utils/slug' -import useAuth from '@/core/hooks/useAuth' -import { useRouter } from 'next/router' -import odooApi from '@/core/api/odooApi' -import { useProductCartContext } from '@/contexts/ProductCartContext' -import Image from '@/core/components/elements/Image/Image' -import whatsappUrl from '@/core/utils/whatsappUrl' -import { AnimatePresence, motion } from 'framer-motion' -import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css' -const { ShoppingCartIcon, PhotoIcon } = require('@heroicons/react/24/outline') -const { default: Link } = require('next/link') +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { getCartApi } from '../api/CartApi'; +import currencyFormat from '@/core/utils/currencyFormat'; +import { createSlug } from '@/core/utils/slug'; +import useAuth from '@/core/hooks/useAuth'; +import { useRouter } from 'next/router'; +import odooApi from '@/core/api/odooApi'; +import { useProductCartContext } from '@/contexts/ProductCartContext'; +import Image from '@/core/components/elements/Image/Image'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import { AnimatePresence, motion } from 'framer-motion'; +import style from '../../../../src-migrate/modules/cart/styles/item-promo.module.css'; +const { ShoppingCartIcon, PhotoIcon } = require('@heroicons/react/24/outline'); +const { default: Link } = require('next/link'); const Cardheader = (cartCount) => { - - const router = useRouter() - const [subTotal, setSubTotal] = useState(null) - const [buttonLoading, SetButtonTerapkan] = useState(false) - const itemLoading = [1, 2, 3] - const auth = useAuth() - const [countCart, setCountCart] = useState(null) - const { productCart, setRefreshCart, setProductCart, refreshCart, isLoading, setIsloading } = - useProductCartContext() + const router = useRouter(); + const [subTotal, setSubTotal] = useState(null); + const [buttonLoading, SetButtonTerapkan] = useState(false); + const itemLoading = [1, 2, 3]; + const auth = useAuth(); + const [countCart, setCountCart] = useState(null); + const { + productCart, + setRefreshCart, + setProductCart, + refreshCart, + isLoading, + setIsloading, + } = useProductCartContext(); - const [isHovered, setIsHovered] = useState(false) - const [isTop, setIsTop] = useState(true) + const [isHovered, setIsHovered] = useState(false); + const [isTop, setIsTop] = useState(true); const products = useMemo(() => { - return productCart?.products || [] - }, [productCart]) + return productCart?.products || []; + }, [productCart]); const handleMouseEnter = () => { - setIsHovered(true) - getCart() - } + setIsHovered(true); + getCart(); + }; const handleMouseLeave = () => { - setIsHovered(false) - } + setIsHovered(false); + }; const getCart = () => { if (!productCart && auth) { - refreshCartf() + refreshCartf(); } - } + }; const refreshCartf = useCallback(async () => { - setIsloading(true) - let cart = await getCartApi() - setProductCart(cart) - setCountCart(cart?.productTotal) - setIsloading(false) - }, [setProductCart, setIsloading]) + setIsloading(true); + let cart = await getCartApi(); + setProductCart(cart); + setCountCart(cart?.products?.length); + setIsloading(false); + }, [setProductCart, setIsloading]); useEffect(() => { - if (!products) return + if (!products) return; - let calculateTotalPriceBeforeTax = 0 - let calculateTotalTaxAmount = 0 - let calculateTotalDiscountAmount = 0 + let calculateTotalPriceBeforeTax = 0; + let calculateTotalTaxAmount = 0; + let calculateTotalDiscountAmount = 0; for (const product of products) { - if (product.quantity == '') continue + if (product.quantity == '') continue; - let priceBeforeTax = product.price.price / 1.11 - calculateTotalPriceBeforeTax += priceBeforeTax * product.quantity - calculateTotalTaxAmount += (product.price.price - priceBeforeTax) * product.quantity + let priceBeforeTax = product.price.price / 1.11; + calculateTotalPriceBeforeTax += priceBeforeTax * product.quantity; + calculateTotalTaxAmount += + (product.price.price - priceBeforeTax) * product.quantity; calculateTotalDiscountAmount += - (product.price.price - product.price.priceDiscount) * product.quantity + (product.price.price - product.price.priceDiscount) * product.quantity; } let subTotal = - calculateTotalPriceBeforeTax - calculateTotalDiscountAmount + calculateTotalTaxAmount - setSubTotal(subTotal) - }, [products]) + calculateTotalPriceBeforeTax - + calculateTotalDiscountAmount + + calculateTotalTaxAmount; + setSubTotal(subTotal); + }, [products]); useEffect(() => { if (refreshCart) { - refreshCartf() + refreshCartf(); } - setRefreshCart(false) - }, [refreshCart, refreshCartf, setRefreshCart]) + setRefreshCart(false); + }, [refreshCart, refreshCartf, setRefreshCart]); useEffect(() => { - setCountCart(cartCount.cartCount) - setRefreshCart(false) - }, [cartCount]) + setCountCart(cartCount.cartCount); + setRefreshCart(false); + }, [cartCount]); useEffect(() => { const handleScroll = () => { - setIsTop(window.scrollY === 0) - } - window.addEventListener('scroll', handleScroll) + setIsTop(window.scrollY === 0); + }; + window.addEventListener('scroll', handleScroll); return () => { - window.removeEventListener('scroll', handleScroll) - } - }, []) + window.removeEventListener('scroll', handleScroll); + }; + }, []); const handleCheckout = async () => { - SetButtonTerapkan(true) - let checkoutAll = await odooApi('POST', `/api/v1/user/${auth.id}/cart/select-all`) - router.push('/shop/checkout') - } - + SetButtonTerapkan(true); + let checkoutAll = await odooApi( + 'POST', + `/api/v1/user/${auth.id}/cart/select-all` + ); + router.push('/shop/checkout'); + }; return (
    @@ -152,8 +162,13 @@ const Cardheader = (cartCount) => { className='w-full max-w-md p-2 bg-white border border-gray-200 rounded-lg shadow overflow-hidden' >
    -
    Keranjang Belanja
    - +
    + Keranjang Belanja +
    + Lihat Semua
    @@ -163,7 +178,10 @@ const Cardheader = (cartCount) => {

    Silahkan{' '} - + Login {' '} Untuk Melihat Daftar Keranjang Belanja Anda @@ -172,7 +190,11 @@ const Cardheader = (cartCount) => { )} {isLoading && itemLoading.map((item) => ( -

    +
    @@ -194,14 +216,17 @@ const Cardheader = (cartCount) => { )} {auth && products.length > 0 && !isLoading && ( <> -
      +
        {products && products?.map((product, index) => ( <>
      • - {product.cartType === 'promotion' && ( + {product.cartType === 'promotion' && ( {product.name} {
        {product.cartType === 'promotion' && ( -

        - {product.name} -

        - )} +

        + {product.name} +

        + )} {product.cartType === 'product' && ( { {product?.price?.discountPercentage}%
        - {currencyFormat(product?.price?.price)} + {currencyFormat( + product?.price?.price + )}
        )} - +
        {product?.price?.priceDiscount > 0 ? ( - currencyFormat(product?.price?.priceDiscount) + currencyFormat( + product?.price?.priceDiscount + ) ) : ( {
    -
    - {product.products?.map((product) => -
    - - {product?.image && {product.name}} - - -
    - - {product.displayName} - - -
    -
    - {/*
    {product.code}
    */} -
    - Berat Barang: - {product.packageWeight} Kg -
    -
    +
    + {product.products?.map((product) => ( +
    + + {product?.image && ( + {product.name} + )} + + +
    + + {product.displayName} + + +
    +
    + {/*
    {product.code}
    */} +
    + + Berat Barang:{' '} + + + {product.packageWeight} Kg +
    -
    +
    +
    + ))} + {product.freeProducts?.map((product) => ( +
    + -
    - - {product?.image && {product.name}} + className='md:h-12 md:w-12 md:min-w-[48px] h-10 w-10 min-w-[40px] border border-gray-300 rounded ' + > + {product?.image && ( + {product.name} + )} + + +
    + + {product.displayName} - -
    - - {product.displayName} - - -
    -
    - {/*
    {product.code}
    */} -
    - Berat Barang: - {product.packageWeight} Kg -
    -
    + +
    +
    + {/*
    {product.code}
    */} +
    + + Berat Barang:{' '} + + + {product.packageWeight} Kg +
    -
    - )} +
    + ))} +
    ))} @@ -347,8 +433,12 @@ const Cardheader = (cartCount) => { {auth && products.length > 0 && !isLoading && ( <>
    - Subtotal Sebelum PPN : - {currencyFormat(subTotal)} + + Subtotal Sebelum PPN :{' '} + + + {currencyFormat(subTotal)} +
    @@ -368,7 +460,7 @@ const Cardheader = (cartCount) => { )}
    - ) -} + ); +}; -export default Cardheader +export default Cardheader; -- cgit v1.2.3 From 337e0f377624e5a0b46aa0ed3c3c16ba4e289965 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 6 Nov 2024 16:36:57 +0700 Subject: update mobile view --- src/core/components/layouts/BasicLayout.jsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/components/layouts/BasicLayout.jsx b/src/core/components/layouts/BasicLayout.jsx index d6b96f36..1b62bf05 100644 --- a/src/core/components/layouts/BasicLayout.jsx +++ b/src/core/components/layouts/BasicLayout.jsx @@ -24,6 +24,7 @@ const BasicLayout = ({ children }) => { const [highlight, setHighlight] = useState(false); const [buttonPosition, setButtonPosition] = useState(null); const [wobble, setWobble] = useState(false); + const [isProductPage, setIsProductPage] = useState(false); const { isDesktop, isMobile } = useDevice(); @@ -46,6 +47,9 @@ const BasicLayout = ({ children }) => { setUrlPath(router.asPath); } + if (router.pathname.includes('/shop/product/')) { + setIsProductPage(true); + } }, [product, router]); useEffect(() => { @@ -111,7 +115,11 @@ const BasicLayout = ({ children }) => { {children} -
    +
    Date: Thu, 7 Nov 2024 08:35:30 +0700 Subject: update mobile type --- src/utils/solrMapping.js | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/utils/solrMapping.js b/src/utils/solrMapping.js index f73e966a..d4b3f08c 100644 --- a/src/utils/solrMapping.js +++ b/src/utils/solrMapping.js @@ -43,6 +43,7 @@ export const productMappingSolr = (products, pricelist) => { let productMapped = { id: product.product_id_i || '', image: product.image_s || '', + imageMobile: product.image_mobile_s || '', code: product.default_code_s || '', description: product.description_t || '', displayName: product.display_name_s || '', -- cgit v1.2.3 From 982a18543beefdd33f20c294b06b7a1a87103b2f Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 7 Nov 2024 09:16:51 +0700 Subject: update mobile image --- src/lib/product/components/ProductCard.jsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index d3b50302..a480bbdd 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -10,12 +10,13 @@ import { sellingProductFormat } from '@/core/utils/formatValue'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; import useUtmSource from '~/hooks/useUtmSource'; +import useDevice from '@/core/hooks/useDevice'; const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { const router = useRouter(); const utmSource = useUtmSource(); const [discount, setDiscount] = useState(0); - + const { isDesktop, isMobile } = useDevice(); let voucherPastiHemat = 0; voucherPastiHemat = product?.newVoucherPastiHemat[0]; @@ -26,9 +27,13 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { }); const image = useMemo(() => { - if (product.image) return product.image + '?ratio=square'; - return '/images/noimage.jpeg'; - }, [product.image]); + if (!isDesktop && product.image_mobile) { + return product.image_mobile + '?ratio=square'; + } else { + if (product.image) return product.image + '?ratio=square'; + return '/images/noimage.jpeg'; + } + }, [product.image, product.image_mobile]); const URL = { product: -- cgit v1.2.3 From ccc224e8a6261e40e2ea1db08e21a49d280fd1c4 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 7 Nov 2024 15:23:42 +0700 Subject: update fetch data logic --- src/pages/api/shop/variant-detail.js | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/pages/api/shop/variant-detail.js b/src/pages/api/shop/variant-detail.js index 08ce75b8..af3525b3 100644 --- a/src/pages/api/shop/variant-detail.js +++ b/src/pages/api/shop/variant-detail.js @@ -1,21 +1,28 @@ -import { productMappingSolr, variantsMappingSolr } from '@/utils/solrMapping' -import axios from 'axios' +import { productMappingSolr, variantsMappingSolr } from '@/utils/solrMapping'; +import axios from 'axios'; export default async function handler(req, res) { try { let productVariants = await axios( process.env.SOLR_HOST + `/solr/variants/select?q=id:${req.query.id}&q.op=OR&indent=true` - ) - let auth = req.query.auth === 'false' ? JSON.parse(req.query.auth) : req.query.auth + ); + let template_id = productVariants.data.response.docs[0].template_id_i; + let auth = + req.query.auth === 'false' ? JSON.parse(req.query.auth) : req.query.auth; let productTemplate = await axios( - process.env.SOLR_HOST + `/solr/product/select?q=id:${req.query.id}&q.op=OR&indent=true` - ) - let result = variantsMappingSolr(productTemplate.data.response.docs, productVariants.data.response.docs, auth || false) - - res.status(200).json(result) + process.env.SOLR_HOST + + `/solr/product/select?q=id:${template_id}&q.op=OR&indent=true` + ); + let result = variantsMappingSolr( + productTemplate.data.response.docs, + productVariants.data.response.docs, + auth || false + ); + + res.status(200).json(result); } catch (error) { - console.error('Error fetching data from Solr:', error) - res.status(500).json({ error: 'Internal Server Error' }) + console.error('Error fetching data from Solr:', error); + res.status(500).json({ error: 'Internal Server Error' }); } -} \ No newline at end of file +} -- cgit v1.2.3 From 0ecb7ba546cd1fdd3811f76aa09b20642ab4952c Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 11 Nov 2024 11:21:47 +0700 Subject: update redis category management mobile --- src/lib/home/components/CategoryDynamicMobile.jsx | 40 +++++------------------ 1 file changed, 9 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/CategoryDynamicMobile.jsx b/src/lib/home/components/CategoryDynamicMobile.jsx index 55654b0e..6ede1147 100644 --- a/src/lib/home/components/CategoryDynamicMobile.jsx +++ b/src/lib/home/components/CategoryDynamicMobile.jsx @@ -37,42 +37,20 @@ const CategoryDynamicMobile = () => { const [categoryManagement, setCategoryManagement] = useState([]); const [isLoading, setIsLoading] = useState(false); - const loadCategoryManagement = useCallback(async () => { - const cachedData = getFromLocalStorage('homepage_categoryDynamic'); - - if (cachedData) { - // Hitung selisih waktu antara saat ini dengan waktu terakhir data di-fetch - const elapsedTime = getElapsedTime(cachedData.lastFetchedTime); - - if (elapsedTime < 24 * 60 * 60 * 1000) { - setCategoryManagement(cachedData.value); - return; - } - } - - const latestVersion = await fetchCategoryManagementVersion(); - if (cachedData && cachedData.version === latestVersion) { - // perbarui waktu - saveToLocalStorage( - 'homepage_categoryDynamic', - cachedData.value, - latestVersion - ); - setCategoryManagement(cachedData.value); - } else { + useEffect(() => { + const fetchCategoryData = async () => { setIsLoading(true); - const items = await fetchCategoryManagementSolr(); + const res = await fetch('/api/category-management'); + const { data } = await res.json(); + if (data) { + setCategoryManagement(data); + } setIsLoading(false); + }; - saveToLocalStorage('homepage_categoryDynamic', items, latestVersion); - setCategoryManagement(items); - } + fetchCategoryData(); }, []); - useEffect(() => { - loadCategoryManagement(); - }, [loadCategoryManagement]); - useEffect(() => { if (categoryManagement?.length > 0) { const initialSelections = categoryManagement.reduce((acc, category) => { -- cgit v1.2.3 From 0d3c0cf6a00ef81bfdb944490e48f16af41fc029 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 13 Nov 2024 10:08:16 +0700 Subject: add radis --- src/components/ui/HeroBannerSecondary.jsx | 69 +++++++++++++++-------- src/core/components/elements/Navbar/TopBanner.jsx | 53 ++++++++++------- src/lib/home/components/CategoryDynamicMobile.jsx | 23 -------- src/pages/api/hero-banner.js | 4 +- src/pages/api/page-content.js | 44 +++++++++++++++ src/pages/api/shop/brands.js | 3 - 6 files changed, 123 insertions(+), 73 deletions(-) create mode 100644 src/pages/api/page-content.js (limited to 'src') diff --git a/src/components/ui/HeroBannerSecondary.jsx b/src/components/ui/HeroBannerSecondary.jsx index a7b32a4a..6074c9a6 100644 --- a/src/components/ui/HeroBannerSecondary.jsx +++ b/src/components/ui/HeroBannerSecondary.jsx @@ -1,39 +1,58 @@ -import Link from '@/core/components/elements/Link/Link' -import { getRandomInt } from '@/utils/getRandomInt' -import Image from 'next/image' -import { useMemo } from 'react' -import { useQuery } from 'react-query' -import { HeroBannerSkeleton } from '../skeleton/BannerSkeleton' -import { bannerApi } from '@/api/bannerApi' +import Link from '@/core/components/elements/Link/Link'; +import { getRandomInt } from '@/utils/getRandomInt'; +import Image from 'next/image'; +import { useMemo, useEffect, useState } from 'react'; +import { useQuery } from 'react-query'; +import { HeroBannerSkeleton } from '../skeleton/BannerSkeleton'; +import { bannerApi } from '@/api/bannerApi'; const HeroBannerSecondary = () => { - const heroBannerSecondary = useQuery('heroBannerSecondary', bannerApi({ type: 'index-a-2' })) + const [heroBannerSecondary, setHeroBannerSecondary] = useState([]); + const [isLoading, setIsLoading] = useState(false); + // const heroBannerSecondary = useQuery( + // 'heroBannerSecondary', + // bannerApi({ type: 'index-a-2' }) + // ); - const randomIndex = useMemo(() => { - if (!heroBannerSecondary.data) return null - const length = heroBannerSecondary.data?.length - return getRandomInt(length) - }, [heroBannerSecondary.data]) + useEffect(() => { + const fetchData = async () => { + setIsLoading(true); + const res = await fetch(`/api/hero-banner?type=index-a-2`); + const { data } = await res.json(); + if (data) { + setHeroBannerSecondary(data); + } + setIsLoading(false); + }; + + fetchData(); + }, []); - if (heroBannerSecondary.isLoading) return + const randomIndex = useMemo(() => { + if (!heroBannerSecondary) return null; + const length = heroBannerSecondary?.length; + return getRandomInt(length); + }, [heroBannerSecondary]); + if (isLoading) return ; return ( - heroBannerSecondary.data && randomIndex !== null && ( - + heroBannerSecondary && + randomIndex !== null && ( + {heroBannerSecondary.data[randomIndex].name} ) ); -} +}; -export default HeroBannerSecondary +export default HeroBannerSecondary; diff --git a/src/core/components/elements/Navbar/TopBanner.jsx b/src/core/components/elements/Navbar/TopBanner.jsx index f438ae67..709495ce 100644 --- a/src/core/components/elements/Navbar/TopBanner.jsx +++ b/src/core/components/elements/Navbar/TopBanner.jsx @@ -1,22 +1,37 @@ import Image from 'next/image'; -import { useQuery } from 'react-query';import useDevice from '@/core/hooks/useDevice' +import { useQuery } from 'react-query'; +import useDevice from '@/core/hooks/useDevice'; import odooApi from '@/core/api/odooApi'; import SmoothRender from '~/components/ui/smooth-render'; import Link from '../Link/Link'; import { background } from '@chakra-ui/react'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; const TopBanner = ({ onLoad = () => {} }) => { - const { isDesktop, isMobile } = useDevice() - const topBanner = useQuery({ - queryKey: 'topBanner', - queryFn: async () => await odooApi('GET', '/api/v1/banner?type=top-banner'), - refetchOnWindowFocus: false, - }); + const [topBanner, setTopBanner] = useState([]); + const { isDesktop, isMobile } = useDevice(); + + useEffect(() => { + const fetchData = async () => { + const res = await fetch(`/api/hero-banner?type=top-banner`); + const { data } = await res.json(); + if (data) { + setTopBanner(data); + } + }; + + fetchData(); + }, []); + + // const topBanner = useQuery({ + // queryKey: 'topBanner', + // queryFn: async () => await odooApi('GET', '/api/v1/banner?type=top-banner'), + // refetchOnWindowFocus: false, + // }); // const backgroundColor = topBanner.data?.[0]?.backgroundColor || 'transparent'; - const hasData = topBanner.data?.length > 0; - const data = topBanner.data?.[0] || null; + const hasData = topBanner?.length > 0; + const data = topBanner?.[0] || null; useEffect(() => { if (hasData) { @@ -31,17 +46,15 @@ const TopBanner = ({ onLoad = () => {} }) => { duration='700ms' delay='300ms' className='h-auto' - > + > - - - + href={data?.url} + className='block bg-cover bg-center h-3 md:h-6 lg:h-[36px]' + style={{ + backgroundImage: `url('${data?.image}')`, + }} + > + ); }; diff --git a/src/lib/home/components/CategoryDynamicMobile.jsx b/src/lib/home/components/CategoryDynamicMobile.jsx index 6ede1147..67ae6f5f 100644 --- a/src/lib/home/components/CategoryDynamicMobile.jsx +++ b/src/lib/home/components/CategoryDynamicMobile.jsx @@ -9,29 +9,6 @@ import { fetchCategoryManagementVersion, } from '../api/categoryManagementApi'; -const saveToLocalStorage = (key, data, version) => { - const now = new Date(); - const item = { - value: data, - version: version, - lastFetchedTime: now.getTime(), - }; - localStorage.setItem(key, JSON.stringify(item)); -}; - -const getFromLocalStorage = (key) => { - const itemStr = localStorage.getItem(key); - if (!itemStr) return null; - - const item = JSON.parse(itemStr); - return item; -}; - -const getElapsedTime = (lastFetchedTime) => { - const now = new Date(); - return now.getTime() - lastFetchedTime; -}; - const CategoryDynamicMobile = () => { const [selectedCategory, setSelectedCategory] = useState({}); const [categoryManagement, setCategoryManagement] = useState([]); diff --git a/src/pages/api/hero-banner.js b/src/pages/api/hero-banner.js index b57f86e0..7a348cfa 100644 --- a/src/pages/api/hero-banner.js +++ b/src/pages/api/hero-banner.js @@ -35,8 +35,8 @@ export default async function handler(req, res) { 'EX', 259200 ); - - return res.status(200).json({ data: dataBannerSections }); + cachedData = await client.get(cacheKey); + return res.status(200).json({ data: cachedData }); } } catch (error) { console.error('Error interacting with Redis or fetching data:', error); diff --git a/src/pages/api/page-content.js b/src/pages/api/page-content.js new file mode 100644 index 00000000..3cb8a237 --- /dev/null +++ b/src/pages/api/page-content.js @@ -0,0 +1,44 @@ +import { createClient } from 'redis'; +import { getPageContent } from '~/services/pageContent'; +// import { fetchCategoryManagementSolr } from '../../lib/home/api/categoryManagementApi'; +const client = createClient(); +client.on('error', (err) => console.error('Redis Client Error', err)); + +const connectRedis = async () => { + if (!client.isOpen) { + await client.connect(); + } +}; + +export default async function handler(req, res) { + const { path } = req.query; + try { + await connectRedis(); + // await client.del('onbording-popup'); + + let cachedData; + if (req.method === 'GET') { + cachedData = await client.get(`page-content:${path}`); + + if (!cachedData) { + const items = await getPageContent({ path }); + console.log('items', items); + await client.set( + `page-content:${path}`, + JSON.stringify(items), + 'EX', + 604800 // Expiry 1 minggu + ); + cachedData = await client.get(`page-content:${path}`); + } + const data = cachedData ? JSON.parse(cachedData) : null; + res.status(200).json({ data }); + } else { + res.setHeader('Allow', ['GET']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } + } catch (error) { + console.error('Error interacting with Redis:', error); + res.status(500).json({ error: 'Error interacting with Redis' }); + } +} diff --git a/src/pages/api/shop/brands.js b/src/pages/api/shop/brands.js index 380b3369..219f2cb0 100644 --- a/src/pages/api/shop/brands.js +++ b/src/pages/api/shop/brands.js @@ -42,16 +42,13 @@ export default async function handler(req, res) { let cachedData = await client.get(cacheKey); if (cachedData) { - console.log('Retrieving data from Redis cache'); return res.status(200).json(JSON.parse(cachedData)); } - // Fetch data from Solr const url = `${SOLR_HOST}/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}`; const brands = await axios(url); const dataBrands = responseMap(brands.data.response.docs); - // Store fetched data in Redis with 3-day expiration await client.set(cacheKey, JSON.stringify(dataBrands), 'EX', 259200); res.status(200).json(dataBrands); -- cgit v1.2.3 From 4368e38cce90e401a0ba141f2b20d23db1886cf8 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 13 Nov 2024 11:05:25 +0700 Subject: fix bug ao shipment pagination --- .../components/Product/ProductDesktopVariant.jsx | 1 - src/lib/shipment/components/Shipments.jsx | 204 +++++++++++++-------- 2 files changed, 128 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index cca8ec5e..f4569574 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -231,7 +231,6 @@ const ProductDesktopVariant = ({ }; fetchData(); }, [product]); - console.log('product', product); return ( diff --git a/src/lib/shipment/components/Shipments.jsx b/src/lib/shipment/components/Shipments.jsx index 115bbd3a..20dbb013 100644 --- a/src/lib/shipment/components/Shipments.jsx +++ b/src/lib/shipment/components/Shipments.jsx @@ -1,62 +1,83 @@ -import DesktopView from '@/core/components/views/DesktopView' -import MobileView from '@/core/components/views/MobileView' -import Menu from '@/lib/auth/components/Menu' -import { EllipsisVerticalIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline' -import ImageNext from 'next/image' -import { useRouter } from 'next/router' -import { useQuery } from 'react-query' -import _, { forEach } from 'lodash-contrib' -import Spinner from '@/core/components/elements/Spinner/Spinner' -import Manifest from '@/lib/treckingAwb/component/Manifest' -import { useState } from 'react' -import Pagination from '@/core/components/elements/Pagination/Pagination' -import Link from 'next/link' -import TransactionStatusBadge from '@/lib/transaction/components/TransactionStatusBadge' +import DesktopView from '@/core/components/views/DesktopView'; +import MobileView from '@/core/components/views/MobileView'; +import Menu from '@/lib/auth/components/Menu'; +import { + EllipsisVerticalIcon, + MagnifyingGlassIcon, +} from '@heroicons/react/24/outline'; +import ImageNext from 'next/image'; +import { useEffect } from 'react'; +import { useRouter } from 'next/router'; +import { useQuery } from 'react-query'; +import _, { forEach } from 'lodash-contrib'; +import Spinner from '@/core/components/elements/Spinner/Spinner'; +import Manifest from '@/lib/treckingAwb/component/Manifest'; +import { useState } from 'react'; +import Pagination from '@/core/components/elements/Pagination/Pagination'; +import Link from 'next/link'; +import TransactionStatusBadge from '@/lib/transaction/components/TransactionStatusBadge'; -const { listShipments } = require('../api/listShipment') +const { listShipments } = require('../api/listShipment'); const Shipments = () => { - const router = useRouter() - const { q = '', page = 1 } = router.query - const [paramStatus, setParamStatus] = useState(null) - - const limit = 15 + const router = useRouter(); + const { q = '', page = 1, status = null } = router.query; + const [paramStatus, setParamStatus] = useState(status); + const limit = 15; const query = { q: q, status: paramStatus, offset: (page - 1) * limit, - limit - } - const [inputQuery, setInputQuery] = useState(q) - const queryString = _.toQuery(query) + limit, + }; + const [inputQuery, setInputQuery] = useState(q); + const queryString = _.toQuery(query); const { data: shipments } = useQuery('shipments' + queryString, () => listShipments({ query: queryString }) - ) - const [idAWB, setIdAWB] = useState(null) + ); + const [idAWB, setIdAWB] = useState(null); - const pageCount = Math.ceil(shipments?.pickingTotal / limit) - let pageQuery = _.omit(query, ['limit', 'offset', 'context']) - pageQuery = _.pickBy(pageQuery, _.identity) - pageQuery = _.toQuery(pageQuery) + const pageCount = Math.ceil(shipments?.pickingTotal / limit); + let pageQuery = _.omit(query, ['limit', 'offset', 'context']); + pageQuery = _.pickBy(pageQuery, _.identity); + pageQuery = _.toQuery(pageQuery); const closePopup = () => { - setIdAWB(null) - } + setIdAWB(null); + }; const handleSubmit = async (e) => { - e.preventDefault() - router.push(`${router.pathname}?q=${inputQuery}`) - } + e.preventDefault(); + router.push(`${router.pathname}?q=${inputQuery}`); + }; const filterStatus = async (status) => { if (status === paramStatus) { - setParamStatus(null) + setParamStatus(null); } else { - setParamStatus(status) + setParamStatus(status); } - } + }; + + useEffect(() => { + const resetQuery = () => { + const newQuery = { + status: paramStatus || undefined, + q: '', + page: 1, + }; + router.push({ + pathname: router.pathname, + query: newQuery, + }); + }; + + if (paramStatus !== status) { + resetQuery(); + } + }, [paramStatus]); return ( <> @@ -84,7 +105,10 @@ const Shipments = () => { {shipments?.pickings.map((shipment) => ( -
    +

    @@ -93,7 +117,9 @@ const Shipments = () => { {shipment.carrierName || '-'}

    -

    No. Resi : {shipment.trackingNumber || '-'}

    +

    + No. Resi : {shipment.trackingNumber || '-'} +

    {shipment?.status === 'completed' && ( @@ -116,11 +142,17 @@ const Shipments = () => {
    - No. Transaksi + + No. Transaksi + -

    {shipment.saleOrder.name}

    +

    + {shipment.saleOrder.name} +

    - {shipment.date} + + {shipment.date} +
    @@ -176,7 +212,8 @@ const Shipments = () => {
    - Lacak pengiriman untuk setiap transaksi anda semakin mudah di Indoteknik.com + Lacak pengiriman untuk setiap transaksi anda semakin mudah di + Indoteknik.com
    @@ -190,7 +227,9 @@ const Shipments = () => {
    -

    Detail Pengiriman

    +

    + Detail Pengiriman +

    { value={inputQuery} onChange={(e) => setInputQuery(e.target.value)} /> -
    @@ -254,7 +296,7 @@ const Shipments = () => {
    @@ -263,16 +305,16 @@ const Shipments = () => { - ) -} + ); +}; const CardStatus = ({ device, paramStatus, shipments, filterStatus }) => { - const status = [`pending`, `shipment`, `completed`] + const status = [`pending`, `shipment`, `completed`]; return ( <> {status.map((value) => { - const statusData = getStatusLabel(device, value, shipments) + const statusData = getStatusLabel(device, value, shipments); if (device === 'desktop') { return (
    { }`} onClick={() => filterStatus(value)} > -

    {statusData.label}

    +

    + {statusData.label} +

    {statusData.image}

    {statusData.shipCount} Pesanan

    - ) + ); } else { return (
    { {statusData.shipCount} {'>'}
    - ) + ); } })} - ) -} + ); +}; const getStatusLabel = (device, status, shipments) => { - let images = null + let images = null; switch (status) { case 'pending': if (device === 'desktop') { @@ -328,40 +372,48 @@ const getStatusLabel = (device, status, shipments) => { />
    - ) + ); } else { images = (
    - ) + ); } return { label: 'Pending', shipCount: shipments?.summary?.pendingCount, - image: images - } + image: images, + }; case 'shipment': if (device === 'desktop') { images = (
    - +
    - ) + ); } else { images = (
    - +
    - ) + ); } return { label: 'Pengiriman', shipCount: shipments?.summary?.shipmentCount, - image: images - } + image: images, + }; case 'completed': if (device === 'desktop') { images = ( @@ -375,22 +427,22 @@ const getStatusLabel = (device, status, shipments) => { />
    - ) + ); } else { images = (
    - ) + ); } return { label: 'Pesanan Tiba', shipCount: shipments?.summary?.completedCount, - image: images - } + image: images, + }; default: - return 'Status Tidak Dikenal' + return 'Status Tidak Dikenal'; } -} +}; -export default Shipments +export default Shipments; -- cgit v1.2.3 From 1c37bf46eadd0ba26713933b65d9f1c2fdd7b33f Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 14 Nov 2024 09:51:08 +0700 Subject: comnent alt --- src/core/components/elements/Navbar/NavbarDesktop.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/core/components/elements/Navbar/NavbarDesktop.jsx b/src/core/components/elements/Navbar/NavbarDesktop.jsx index 04cf76d1..fa3df5bf 100644 --- a/src/core/components/elements/Navbar/NavbarDesktop.jsx +++ b/src/core/components/elements/Navbar/NavbarDesktop.jsx @@ -391,7 +391,7 @@ const SocialMedias = () => ( > @@ -403,7 +403,7 @@ const SocialMedias = () => ( > @@ -423,7 +423,7 @@ const SocialMedias = () => ( > @@ -435,7 +435,7 @@ const SocialMedias = () => ( > @@ -447,7 +447,7 @@ const SocialMedias = () => ( > @@ -459,7 +459,7 @@ const SocialMedias = () => ( > -- cgit v1.2.3 From 6e7aa296bae3e290785da7ad941c521a685be1e9 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Thu, 14 Nov 2024 10:58:15 +0700 Subject: add google tag ads --- src/lib/checkout/components/Checkout.jsx | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index e83e719c..afbf1e6c 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -413,7 +413,12 @@ const Checkout = () => { Math.round(parseInt(finalShippingAmt * 1.1) / 1000) * 1000; const finalGT = GT < 0 ? 0 : GT; setGrandTotal(finalGT); - }, [biayaKirim, cartCheckout?.grandTotal, activeVoucher, activeVoucherShipping]); + }, [ + biayaKirim, + cartCheckout?.grandTotal, + activeVoucher, + activeVoucherShipping, + ]); const checkout = async () => { const file = poFile.current.files[0]; @@ -484,6 +489,11 @@ const Checkout = () => { transaction_id: isCheckouted.id, }); + gtag('set', 'user_data', { + email: auth.email, + phone_number: auth.mobile ?? auth.phone, + }); + for (const product of products) deleteItemCart({ productId: product.id }); if (grandTotal > 0) { const payment = await axios.post( @@ -501,7 +511,7 @@ const Checkout = () => { } } - /* const midtrans = async () => { + /* const midtrans = async () => { for (const product of products) deleteItemCart({ productId: product.id }); if (grandTotal > 0) { const payment = await axios.post( @@ -1193,7 +1203,11 @@ const Checkout = () => {
    Biaya Kirim

    {etdFix}

    -
    {currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)}
    +
    + {currencyFormat( + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + )} +
    {activeVoucherShipping && voucherShippingAmt && (
    @@ -1494,7 +1508,11 @@ const Checkout = () => { Biaya Kirim

    {etdFix}

    -
    {currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000) }
    +
    + {currencyFormat( + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + )} +
    {activeVoucherShipping && voucherShippingAmt && (
    -- cgit v1.2.3 From 90eb9e8ea858be3b38a6481050a029a32980f417 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 14 Nov 2024 11:57:01 +0700 Subject: update bug no flash sale --- src/pages/api/shop/search.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index ace281f7..1f0ff504 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -89,7 +89,8 @@ export default async function handler(req, res) { ]; if (fq && source != 'similar') { - filterQueries.push(fq); + // filterQueries.push(fq); + fq.push(...filterQueries); } const fq_ = filterQueries.join(' AND '); -- cgit v1.2.3 From ff9a983d8b179308075bc7bd8833d1901c30486d Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 14 Nov 2024 14:20:48 +0700 Subject: change code name brand to truncate --- src/lib/product/components/ProductCard.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index d3b50302..936d4ee0 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -143,7 +143,7 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
    {product?.manufacture?.name ? ( - + {product.manufacture.name} ) : ( -- cgit v1.2.3 From 36871796910127a2bbda3cedab00a150a24375e4 Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Thu, 14 Nov 2024 15:47:03 +0700 Subject: CR - text WA --- src/core/utils/whatsappUrl.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/core/utils/whatsappUrl.js b/src/core/utils/whatsappUrl.js index 7a129aa6..c840e105 100644 --- a/src/core/utils/whatsappUrl.js +++ b/src/core/utils/whatsappUrl.js @@ -2,28 +2,31 @@ import { getAuth } from "./auth" const whatsappUrl = (template = 'default', payload, urlPath = null) => { let user = getAuth() - if(!user){ - if(urlPath) return `/login?next=${urlPath}` - if(!urlPath) return '/login' - } + // if(!user){ + // if(urlPath) return `/login?next=${urlPath}` + // if(!urlPath) return '/login' + // } let parentName = user.parentName || '-' let url = 'https://wa.me/6281717181922' let text = 'Hallo Indoteknik.com,' + if(user){ + text += `Saya ${user.name}, Saya dari ${parentName}` + } switch (template) { case 'product': - text += ` Saya ${user.name} , Saya dari ${parentName} Saya mencari barang dibawah ini\n\n: Brand = ${payload?.manufacture}\n\n Item Name = ${payload?.name}\n\nLink : ${payload?.url}` + text += ` Saya mencari barang dibawah ini\n\n: Brand = ${payload?.manufacture}\n\n Item Name = ${payload?.name}\n\nLink : ${payload?.url}` break case 'productWeight': - text += ` Saya ${user.name} , Saya dari ${parentName} Saya mencari barang dibawah ini\n\n: Brand = ${payload?.manufacture}\n\n Item Name = ${payload?.name}\n\nLink : ${payload?.url}` + text += ` Saya mencari barang dibawah ini\n\n: Brand = ${payload?.manufacture}\n\n Item Name = ${payload?.name}\n\nLink : ${payload?.url}` break case 'productSearch': - text += `Saya lagi cari-cari produk ${payload?.name}, bisa bantu saya cari produknya?` + text += ` Saya lagi cari-cari produk ${payload?.name}, bisa bantu saya cari produknya?` break case null: - text += `Saya ${user.name}, Saya dari ${parentName} Bisa tolong bantu kebutuhan saya?` + text += ` Bisa tolong bantu kebutuhan saya?` break; default: - text += `Saya ${user.name}, Saya dari ${parentName} Bisa tolong bantu kebutuhan saya?` + text += ` Bisa tolong bantu kebutuhan saya?` break } if (text) url += `?text=${encodeURI(text)}` -- cgit v1.2.3 From 31fca1b5d023abb96aad53ac2e26b77ce16e51e1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 15 Nov 2024 09:23:29 +0700 Subject: update error code --- src/lib/product/components/Product/ProductDesktopVariant.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index f4569574..6fe75fff 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -434,7 +434,7 @@ const ProductDesktopVariant = ({
    Date: Fri, 15 Nov 2024 09:52:30 +0700 Subject: if has image brand then show brand image else brand name --- .../product/components/Product/ProductDesktopVariant.jsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 6fe75fff..5dfd452b 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -264,11 +264,17 @@ const ProductDesktopVariant = ({ product.manufacture.id.toString() )} > - {product.manufacture.name} + {product?.manufacture.logo ? ( + {product.manufacture.name} + ) : ( +

    + {product.manufacture.name} +

    + )}
    -- cgit v1.2.3 From c69b71c16ff7cc7a347394710d069ef711db08bb Mon Sep 17 00:00:00 2001 From: trisusilo48 Date: Fri, 15 Nov 2024 14:55:36 +0700 Subject: cr logic generate keywords --- src/pages/api/shop/search.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 1f0ff504..a789b469 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -73,8 +73,9 @@ export default async function handler(req, res) { const formattedQuery = `(${newQ .split(' ') - .map((term) => `${term}*`) + .map((term) => (term.length < 2 ? term : `${term}*`)) // Tambahkan '*' hanya jika panjang kata >= 2 .join(' ')})`; + const mm = checkQ.length > 2 ? checkQ.length > 5 @@ -94,6 +95,17 @@ export default async function handler(req, res) { } const fq_ = filterQueries.join(' AND '); + let keywords = newQ; + if (source === 'similar' || checkQ.length < 3) { + if (checkQ.length < 2 || checkQ[1].length < 2) { + keywords = newQ ; + } else { + keywords = newQ + '*'; + } + } else { + keywords = formattedQuery; + } + let offset = (page - 1) * limit; let parameter = [ 'facet.field=manufacture_name_s', @@ -102,13 +114,7 @@ export default async function handler(req, res) { 'indent=true', `facet.query=${escapeSolrQuery(q)}`, `q.op=OR`, - `q=${ - source == 'similar' || checkQ.length < 3 - ? checkQ.length < 2 - ? newQ - : newQ + '*' - : formattedQuery - }`, + `q=${keywords}`, `defType=edismax`, 'qf=name_s description_clean_t category_name manufacture_name_s variants_code_t variants_name_t category_id_ids default_code_s manufacture_id_i category_id_i ', `start=${parseInt(offset)}`, -- cgit v1.2.3 From d50e637383087cf03d2ad94ad6d076f30f3490c5 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 15 Nov 2024 15:36:38 +0700 Subject: delete cached --- src/pages/api/shop/brands.js | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/pages/api/shop/brands.js b/src/pages/api/shop/brands.js index 219f2cb0..d56e4b13 100644 --- a/src/pages/api/shop/brands.js +++ b/src/pages/api/shop/brands.js @@ -38,19 +38,10 @@ export default async function handler(req, res) { } if (req.query.rows) rows = req.query.rows; - const cacheKey = `brands_home`; - let cachedData = await client.get(cacheKey); - - if (cachedData) { - return res.status(200).json(JSON.parse(cachedData)); - } - const url = `${SOLR_HOST}/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}`; const brands = await axios(url); const dataBrands = responseMap(brands.data.response.docs); - await client.set(cacheKey, JSON.stringify(dataBrands), 'EX', 259200); - res.status(200).json(dataBrands); } catch (error) { console.error('Error fetching data from Solr:', error); -- cgit v1.2.3 From 48441ffd9a92827ffedf5e0b0f4e490132e02c82 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 15 Nov 2024 15:59:52 +0700 Subject: update radis error code preferredBrand --- src/lib/home/components/PreferredBrand.jsx | 82 ++++++++++++++++-------------- src/pages/api/shop/preferredBrand.js | 46 +++++++++++++++++ 2 files changed, 90 insertions(+), 38 deletions(-) create mode 100644 src/pages/api/shop/preferredBrand.js (limited to 'src') diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index eefced60..5a6a0570 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -1,49 +1,51 @@ -import { Swiper, SwiperSlide } from 'swiper/react' -import { Navigation, Pagination, Autoplay } from 'swiper'; -import { useCallback, useEffect, useState } from 'react' -import usePreferredBrand from '../hooks/usePreferredBrand' -import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton' -import BrandCard from '@/lib/brand/components/BrandCard' -import useDevice from '@/core/hooks/useDevice' -import Link from '@/core/components/elements/Link/Link' -import axios from 'axios' +import { Swiper, SwiperSlide } from 'swiper/react'; +import { Navigation, Pagination, Autoplay } from 'swiper'; +import { useCallback, useEffect, useState } from 'react'; +import usePreferredBrand from '../hooks/usePreferredBrand'; +import PreferredBrandSkeleton from './Skeleton/PreferredBrandSkeleton'; +import BrandCard from '@/lib/brand/components/BrandCard'; +import useDevice from '@/core/hooks/useDevice'; +import Link from '@/core/components/elements/Link/Link'; +import axios from 'axios'; const PreferredBrand = () => { - let query = '' - let params = 'prioritas' - const [isLoading, setIsLoading] = useState(true) - const [startWith, setStartWith] = useState(null) - const [manufactures, setManufactures] = useState([]) + let query = ''; + let params = 'prioritas'; + const [isLoading, setIsLoading] = useState(true); + const [startWith, setStartWith] = useState(null); + const [manufactures, setManufactures] = useState([]); const loadBrand = useCallback(async () => { - setIsLoading(true) - const name = startWith ? `${startWith}*` : '' - const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?rows=20`) - - setIsLoading(false) - setManufactures((manufactures) => [...result.data]) - }, [startWith]) + setIsLoading(true); + const name = startWith ? `${startWith}*` : ''; + const result = await axios( + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/preferredBrand?rows=20` + ); + + setIsLoading(false); + setManufactures((manufactures) => [...result.data]); + }, [startWith]); const toggleStartWith = (alphabet) => { - setManufactures([]) + setManufactures([]); if (alphabet == startWith) { - setStartWith(null) - return + setStartWith(null); + return; } - setStartWith(alphabet) - } + setStartWith(alphabet); + }; useEffect(() => { - loadBrand() - }, []) + loadBrand(); + }, []); // const { preferredBrands } = usePreferredBrand(query) - const { isMobile, isDesktop } = useDevice() + const { isMobile, isDesktop } = useDevice(); const swiperBanner = { - modules:[Navigation, Pagination, Autoplay], + modules: [Navigation, Pagination, Autoplay], autoplay: { delay: 4000, - disableOnInteraction: false + disableOnInteraction: false, }, loop: true, className: 'h-[70px] md:h-[100px] w-full', @@ -53,13 +55,17 @@ const PreferredBrand = () => { dynamicBullets: true, dynamicMainBullets: isMobile ? 6 : 8, clickable: true, - } - } - const preferredBrandsData = manufactures ? manufactures.slice(0, 20) : [] + }, + }; + const preferredBrandsData = manufactures ? manufactures.slice(0, 20) : []; return (
    -

    Brand Pilihan

    +

    + + Brand Pilihan + +

    {isDesktop && ( Lihat Semua @@ -79,7 +85,7 @@ const PreferredBrand = () => { )}
    - ) -} + ); +}; -export default PreferredBrand \ No newline at end of file +export default PreferredBrand; diff --git a/src/pages/api/shop/preferredBrand.js b/src/pages/api/shop/preferredBrand.js new file mode 100644 index 00000000..9480c63b --- /dev/null +++ b/src/pages/api/shop/preferredBrand.js @@ -0,0 +1,46 @@ +import odooApi from '@/core/api/odooApi'; +import { createClient } from 'redis'; + +const client = createClient(); + +client.on('error', (err) => console.error('Redis Client Error', err)); + +const connectRedis = async () => { + if (!client.isOpen) { + await client.connect(); + } +}; + +export default async function handler(req, res) { + try { + await connectRedis(); + // await client.del('preferredBrand'); + + let cachedData; + if (req.method === 'GET') { + cachedData = await client.get('preferredBrand'); + + if (!cachedData) { + const items = await odooApi( + 'GET', + '/api/v1/manufacture?level=prioritas' + ); + await client.set( + 'preferredBrand', + JSON.stringify(items), + 'EX', + 259200 // Expiry 3 hari + ); + cachedData = await client.get('preferredBrand'); + } + const data = cachedData ? JSON.parse(cachedData) : null; + res.status(200).json({ data }); + } else { + res.setHeader('Allow', ['GET']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } + } catch (error) { + console.error('Error interacting with Redis:', error); + res.status(500).json({ error: 'Error interacting with Redis' }); + } +} -- cgit v1.2.3 From 9e967a55c575d24b740620325838ab857e7eef04 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 15 Nov 2024 16:04:05 +0700 Subject: back to code --- src/lib/home/components/PreferredBrand.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 5a6a0570..9fb1228a 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -19,7 +19,7 @@ const PreferredBrand = () => { setIsLoading(true); const name = startWith ? `${startWith}*` : ''; const result = await axios( - `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/preferredBrand?rows=20` + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?rows=20` ); setIsLoading(false); -- cgit v1.2.3 From 607ddd5050b5ee900606984b60e74d094fbe89f9 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 15 Nov 2024 16:17:13 +0700 Subject: update fix code --- src/lib/home/components/PreferredBrand.jsx | 3 +- src/pages/api/shop/preferredBrand.js | 69 ++++++++++++++++++------------ 2 files changed, 43 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx index 9fb1228a..b7a30503 100644 --- a/src/lib/home/components/PreferredBrand.jsx +++ b/src/lib/home/components/PreferredBrand.jsx @@ -19,9 +19,8 @@ const PreferredBrand = () => { setIsLoading(true); const name = startWith ? `${startWith}*` : ''; const result = await axios( - `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?rows=20` + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/preferredBrand?rows=20` ); - setIsLoading(false); setManufactures((manufactures) => [...result.data]); }, [startWith]); diff --git a/src/pages/api/shop/preferredBrand.js b/src/pages/api/shop/preferredBrand.js index 9480c63b..4cb35c84 100644 --- a/src/pages/api/shop/preferredBrand.js +++ b/src/pages/api/shop/preferredBrand.js @@ -1,6 +1,7 @@ -import odooApi from '@/core/api/odooApi'; +import axios from 'axios'; import { createClient } from 'redis'; +const SOLR_HOST = process.env.SOLR_HOST; const client = createClient(); client.on('error', (err) => console.error('Redis Client Error', err)); @@ -12,35 +13,49 @@ const connectRedis = async () => { }; export default async function handler(req, res) { + await connectRedis(); + try { - await connectRedis(); - // await client.del('preferredBrand'); - - let cachedData; - if (req.method === 'GET') { - cachedData = await client.get('preferredBrand'); - - if (!cachedData) { - const items = await odooApi( - 'GET', - '/api/v1/manufacture?level=prioritas' - ); - await client.set( - 'preferredBrand', - JSON.stringify(items), - 'EX', - 259200 // Expiry 3 hari - ); - cachedData = await client.get('preferredBrand'); + let params = '*:*'; + let sort = + 'sort=if(exists(sequence_i),0,1) asc,sequence_i asc, if(exists(image_s),0,1) asc '; + let rows = 20; + + if (req.query.params) { + rows = 20; + switch (req.query.params) { + case 'level_s': + params = 'level_s:prioritas'; + break; + case 'search': + params = `name_s:"${req.query.q.toLowerCase()}"`; + sort = ''; + rows = 1; + break; + default: + params = `name_s:${req.query.params}`.toLowerCase(); } - const data = cachedData ? JSON.parse(cachedData) : null; - res.status(200).json({ data }); - } else { - res.setHeader('Allow', ['GET']); - res.status(405).end(`Method ${req.method} Not Allowed`); } + if (req.query.rows) rows = req.query.rows; + + const url = `${SOLR_HOST}/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}`; + const brands = await axios(url); + const dataBrands = responseMap(brands.data.response.docs); + + res.status(200).json(dataBrands); } catch (error) { - console.error('Error interacting with Redis:', error); - res.status(500).json({ error: 'Error interacting with Redis' }); + console.error('Error fetching data from Solr:', error); + res.status(500).json({ error: 'Internal Server Error' }); } } + +const responseMap = (brands) => { + return brands.map((brand) => { + return { + id: brand.id, + name: brand.display_name_s, + logo: brand.image_s || '', + sequence: brand.sequence_i || '', + }; + }); +}; -- cgit v1.2.3 From d47c3be772016dfcc2906ff024d53e9a2b27876e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 16 Nov 2024 11:07:24 +0700 Subject: add tag google --- src/pages/_document.jsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/pages/_document.jsx b/src/pages/_document.jsx index 6af6294f..4b67c3f9 100644 --- a/src/pages/_document.jsx +++ b/src/pages/_document.jsx @@ -115,6 +115,19 @@ export default function MyDocument() { }} /> +