summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-migrate/modules/product-card/components/ProductCard.tsx176
-rw-r--r--src-migrate/modules/product-detail/components/Image.tsx118
-rw-r--r--src-migrate/types/product.ts1
-rw-r--r--src/lib/cart/components/Cartheader.jsx354
-rw-r--r--src/lib/product/components/ProductCard.jsx13
-rw-r--r--src/utils/solrMapping.js1
6 files changed, 386 insertions, 277 deletions
diff --git a/src-migrate/modules/product-card/components/ProductCard.tsx b/src-migrate/modules/product-card/components/ProductCard.tsx
index 0febfadb..a439cdc8 100644
--- a/src-migrate/modules/product-card/components/ProductCard.tsx
+++ b/src-migrate/modules/product-card/components/ProductCard.tsx
@@ -1,95 +1,108 @@
-import style from '../styles/product-card.module.css'
+import style from '../styles/product-card.module.css';
import ImageNext from 'next/image';
-import clsx from 'clsx'
-import Link from 'next/link'
-import React, { useEffect, useMemo, useState } from 'react'
-import Image from '~/components/ui/image'
-import useUtmSource from '~/hooks/useUtmSource'
-import clsxm from '~/libs/clsxm'
-import formatCurrency from '~/libs/formatCurrency'
-import { formatToShortText } from '~/libs/formatNumber'
-import { createSlug } from '~/libs/slug'
-import { IProduct } from '~/types/product'
-
+import clsx from 'clsx';
+import Link from 'next/link';
+import React, { useEffect, useMemo, useState } from 'react';
+import Image from '~/components/ui/image';
+import useUtmSource from '~/hooks/useUtmSource';
+import clsxm from '~/libs/clsxm';
+import formatCurrency from '~/libs/formatCurrency';
+import { formatToShortText } from '~/libs/formatNumber';
+import { createSlug } from '~/libs/slug';
+import { IProduct } from '~/types/product';
+import useDevice from '@/core/hooks/useDevice';
type Props = {
- product: IProduct
- layout?: 'vertical' | 'horizontal'
-}
+ product: IProduct;
+ layout?: 'vertical' | 'horizontal';
+};
const ProductCard = ({ product, layout = 'vertical' }: Props) => {
- const utmSource = useUtmSource()
-
+ const utmSource = useUtmSource();
+ const { isDesktop, isMobile } = useDevice();
const URL = {
- product: createSlug('/shop/product/', product.name, product.id.toString()) + `?utm_source=${utmSource}`,
- manufacture: createSlug('/shop/brands/', product.manufacture.name, product.manufacture.id.toString()),
- }
+ product:
+ createSlug('/shop/product/', product.name, product.id.toString()) +
+ `?utm_source=${utmSource}`,
+ manufacture: createSlug(
+ '/shop/brands/',
+ product.manufacture.name,
+ product.manufacture.id.toString()
+ ),
+ };
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]);
return (
- <div className={clsxm(style['wrapper'], {
- [style['wrapper-v']]: layout === 'vertical',
- [style['wrapper-h']]: layout === 'horizontal',
- })}
+ <div
+ className={clsxm(style['wrapper'], {
+ [style['wrapper-v']]: layout === 'vertical',
+ [style['wrapper-h']]: layout === 'horizontal',
+ })}
>
- <div className={clsxm('relative', {
- [style['image-v']]: layout === 'vertical',
- [style['image-h']]: layout === 'horizontal',
- })}>
+ <div
+ className={clsxm('relative', {
+ [style['image-v']]: layout === 'vertical',
+ [style['image-h']]: layout === 'horizontal',
+ })}
+ >
<Link href={URL.product}>
-
- <div className="relative">
- <Image
- src={image}
- alt={product.name}
- width={128}
- height={128}
- className='object-contain object-center h-full w-full'
- />
- <div className="absolute top-0 right-0 flex mt-2">
- <div className="gambarB ">
- {product.isSni && (
- <ImageNext
- src="/images/sni-logo.png"
- alt="SNI Logo"
- className="w-3 h-4 object-contain object-top sm:h-4"
- width={50}
- height={50}
- />
- )}
- </div>
- <div className="gambarC ">
- {product.isTkdn && (
- <ImageNext
- src="/images/TKDN.png"
- alt="TKDN"
- className="w-5 h-4 object-contain object-top ml-1 mr-1 sm:h-6"
- width={50}
- height={50}
- />
- )}
+ <div className='relative'>
+ <Image
+ src={image}
+ alt={product.name}
+ width={128}
+ height={128}
+ className='object-contain object-center h-full w-full'
+ />
+ <div className='absolute top-0 right-0 flex mt-2'>
+ <div className='gambarB '>
+ {product.isSni && (
+ <ImageNext
+ src='/images/sni-logo.png'
+ alt='SNI Logo'
+ className='w-3 h-4 object-contain object-top sm:h-4'
+ width={50}
+ height={50}
+ />
+ )}
+ </div>
+ <div className='gambarC '>
+ {product.isTkdn && (
+ <ImageNext
+ src='/images/TKDN.png'
+ alt='TKDN'
+ className='w-5 h-4 object-contain object-top ml-1 mr-1 sm:h-6'
+ width={50}
+ height={50}
+ />
+ )}
+ </div>
</div>
</div>
- </div>
{product.variant_total > 1 && (
- <div className={style['variant-badge']}>{product.variant_total} Varian</div>
+ <div className={style['variant-badge']}>
+ {product.variant_total} Varian
+ </div>
)}
</Link>
</div>
- <div className={clsxm({
- [style['content-v']]: layout === 'vertical',
- [style['content-h']]: layout === 'horizontal',
- })}>
- <Link
- href={URL.manufacture}
- className={style['brand']}
- >
+ <div
+ className={clsxm({
+ [style['content-v']]: layout === 'vertical',
+ [style['content-h']]: layout === 'horizontal',
+ })}
+ >
+ <Link href={URL.manufacture} className={style['brand']}>
{product.manufacture.name}
</Link>
@@ -113,17 +126,15 @@ const ProductCard = ({ product, layout = 'vertical' }: Props) => {
<div className='h-1.5' />
<div className={style['price-inc']}>
- Inc PPN:
- Rp {formatCurrency(Math.round(product.lowest_price.price * 1.11))}
+ Inc PPN: Rp{' '}
+ {formatCurrency(Math.round(product.lowest_price.price * 1.11))}
</div>
<div className='h-1' />
<div className='flex items-center gap-x-2.5'>
{product.stock_total > 0 && (
- <div className={style['ready-stock']}>
- Ready Stock
- </div>
+ <div className={style['ready-stock']}>Ready Stock</div>
)}
{product.qty_sold > 0 && (
<div className={style['sold']}>
@@ -131,14 +142,11 @@ const ProductCard = ({ product, layout = 'vertical' }: Props) => {
</div>
)}
</div>
-
</div>
</div>
- )
-}
-
-const classPrefix = ({ layout }: Props) => {
+ );
+};
-}
+const classPrefix = ({ layout }: Props) => {};
-export default ProductCard \ No newline at end of file
+export default ProductCard;
diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx
index 30ca0d34..96ae2027 100644
--- a/src-migrate/modules/product-detail/components/Image.tsx
+++ b/src-migrate/modules/product-detail/components/Image.tsx
@@ -1,22 +1,22 @@
import style from '../styles/image.module.css';
import ImageNext from 'next/image';
-import React, { useEffect, useMemo, useState } from 'react'
-import { InfoIcon } from 'lucide-react'
-import { Tooltip } from '@chakra-ui/react'
+import React, { useEffect, useMemo, useState } from 'react';
+import { InfoIcon } from 'lucide-react';
+import { Tooltip } from '@chakra-ui/react';
-import { IProductDetail } from '~/types/product'
-import ImageUI from '~/components/ui/image'
+import { IProductDetail } from '~/types/product';
+import ImageUI from '~/components/ui/image';
import moment from 'moment';
-
+import useDevice from '@/core/hooks/useDevice';
type Props = {
- product: IProductDetail
-}
+ product: IProductDetail;
+};
const Image = ({ product }: Props) => {
- const flashSale = product.flash_sale
+ const flashSale = product.flash_sale;
const [count, setCount] = useState(flashSale?.remaining_time || 0);
-
+ const { isDesktop, isMobile } = useDevice();
useEffect(() => {
let interval: NodeJS.Timeout;
@@ -34,59 +34,60 @@ const Image = ({ product }: Props) => {
};
}, [flashSale?.remaining_time]);
- const duration = moment.duration(count, 'seconds')
-
+ const duration = moment.duration(count, 'seconds');
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]);
return (
<div className={style['wrapper']}>
{/* <div className="relative"> */}
- <ImageUI
- src={image}
- alt={product.name}
- width={256}
- height={256}
- className={style['image']}
- loading='eager'
- priority
- />
- <div className="absolute top-4 right-10 flex ">
- <div className="gambarB ">
- {product.isSni && (
- <ImageNext
- src="/images/sni-logo.png"
- alt="SNI Logo"
- className="w-12 h-8 object-contain object-top sm:h-6"
- width={50}
- height={50}
- />
- )}
- </div>
- <div className="gambarC ">
- {product.isTkdn && (
- <ImageNext
- src="/images/TKDN.png"
- alt="TKDN"
- className="w-16 h-8 object-contain object-top ml-1 mr-1 sm:h-6"
- width={50}
- height={50}
- />
- )}
- </div>
- </div>
- {/* </div> */}
-
-
+ <ImageUI
+ src={image}
+ alt={product.name}
+ width={256}
+ height={256}
+ className={style['image']}
+ loading='eager'
+ priority
+ />
+ <div className='absolute top-4 right-10 flex '>
+ <div className='gambarB '>
+ {product.isSni && (
+ <ImageNext
+ src='/images/sni-logo.png'
+ alt='SNI Logo'
+ className='w-12 h-8 object-contain object-top sm:h-6'
+ width={50}
+ height={50}
+ />
+ )}
+ </div>
+ <div className='gambarC '>
+ {product.isTkdn && (
+ <ImageNext
+ src='/images/TKDN.png'
+ alt='TKDN'
+ className='w-16 h-8 object-contain object-top ml-1 mr-1 sm:h-6'
+ width={50}
+ height={50}
+ />
+ )}
+ </div>
+ </div>
+ {/* </div> */}
<div className={style['absolute-info']}>
<Tooltip
placement='bottom-end'
label='Gambar atau foto berperan sebagai ilustrasi produk. Kadang tidak sesuai dengan kondisi terbaru dengan berbagai perubahan dan perbaikan. Hubungi admin kami untuk informasi yang lebih baik perihal gambar.'
>
- <div className="text-gray-600">
+ <div className='text-gray-600'>
<InfoIcon size={20} />
</div>
</Tooltip>
@@ -94,7 +95,7 @@ const Image = ({ product }: Props) => {
{flashSale.remaining_time > 0 && (
<div className='absolute bottom-0 w-full h-14'>
- <div className="relative w-full h-full">
+ <div className='relative w-full h-full'>
<ImageUI
src='/images/BG-FLASH-SALE.jpg'
alt='Flash Sale Indoteknik'
@@ -105,7 +106,9 @@ const Image = ({ product }: Props) => {
<div className={style['flashsale']}>
<div className='flex items-center gap-x-3'>
- <div className={style['disc-badge']}>{Math.floor(product.lowest_price.discount_percentage)}%</div>
+ <div className={style['disc-badge']}>
+ {Math.floor(product.lowest_price.discount_percentage)}%
+ </div>
<div className={style['flashsale-text']}>
<ImageUI
src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg'
@@ -122,12 +125,11 @@ const Image = ({ product }: Props) => {
<span>{duration.seconds().toString().padStart(2, '0')}</span>
</div>
</div>
-
</div>
</div>
)}
</div>
- )
-}
+ );
+};
-export default Image \ No newline at end of file
+export default Image;
diff --git a/src-migrate/types/product.ts b/src-migrate/types/product.ts
index 31ea0ce1..e43a5ebb 100644
--- a/src-migrate/types/product.ts
+++ b/src-migrate/types/product.ts
@@ -3,6 +3,7 @@ import { IProductVariantDetail } from './productVariant';
export interface IProduct {
id: number;
image: string;
+ image_mobile: string;
code: string;
display_name: string;
name: string;
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 (
<div className='relative group'>
@@ -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'
>
<div className='p-2 flex justify-between items-center'>
- <h5 className='text-base font-semibold leading-none'>Keranjang Belanja</h5>
- <Link href='/shop/cart' class='text-sm font-medium text-red-600 underline'>
+ <h5 className='text-base font-semibold leading-none'>
+ Keranjang Belanja
+ </h5>
+ <Link
+ href='/shop/cart'
+ class='text-sm font-medium text-red-600 underline'
+ >
Lihat Semua
</Link>
</div>
@@ -163,7 +178,10 @@ const Cardheader = (cartCount) => {
<div className='justify-center p-4'>
<p className='text-gray-500 text-center '>
Silahkan{' '}
- <Link href='/login' className='text-red-600 underline leading-6'>
+ <Link
+ href='/login'
+ className='text-red-600 underline leading-6'
+ >
Login
</Link>{' '}
Untuk Melihat Daftar Keranjang Belanja Anda
@@ -172,7 +190,11 @@ const Cardheader = (cartCount) => {
)}
{isLoading &&
itemLoading.map((item) => (
- <div key={item} role='status' className='max-w-sm animate-pulse'>
+ <div
+ key={item}
+ role='status'
+ className='max-w-sm animate-pulse'
+ >
<div className='flex items-center space-x-4 mb- 2'>
<div className='flex-shrink-0'>
<PhotoIcon className='h-16 w-16 text-gray-500' />
@@ -194,14 +216,17 @@ const Cardheader = (cartCount) => {
)}
{auth && products.length > 0 && !isLoading && (
<>
- <ul role='list' className='divide-y divide-gray-200 dark:divide-gray-700'>
+ <ul
+ role='list'
+ className='divide-y divide-gray-200 dark:divide-gray-700'
+ >
{products &&
products?.map((product, index) => (
<>
<li className='py-1 sm:py-2'>
<div className='flex items-center space-x-4'>
<div className='bagian gambar flex-shrink-0'>
- {product.cartType === 'promotion' && (
+ {product.cartType === 'promotion' && (
<Image
src={product.imageProgram[0]}
alt={product.name}
@@ -227,10 +252,10 @@ const Cardheader = (cartCount) => {
</div>
<div className='bagian tulisan dan harga flex-1 min-w-0'>
{product.cartType === 'promotion' && (
- <p className='text-caption-2 font-medium text-gray-900 truncate dark:text-white'>
- {product.name}
- </p>
- )}
+ <p className='text-caption-2 font-medium text-gray-900 truncate dark:text-white'>
+ {product.name}
+ </p>
+ )}
{product.cartType === 'product' && (
<Link
href={createSlug(
@@ -252,27 +277,32 @@ const Cardheader = (cartCount) => {
{product?.price?.discountPercentage}%
</div>
<div className='text-gray_r-11 line-through text-caption-2'>
- {currencyFormat(product?.price?.price)}
+ {currencyFormat(
+ product?.price?.price
+ )}
</div>
</div>
)}
-
+
<div className='flex justify-between items-center'>
<div className='font-semibold text-sm text-red-600'>
{product?.price?.priceDiscount > 0 ? (
- currencyFormat(product?.price?.priceDiscount)
+ currencyFormat(
+ product?.price?.priceDiscount
+ )
) : (
<span className='text-gray_r-12/90 font-normal text-caption-1'>
<a
href={whatsappUrl('product', {
name: product.name,
- manufacture: product.manufacture?.name,
+ manufacture:
+ product.manufacture?.name,
url: createSlug(
'/shop/product/',
product.name,
product.id,
true
- )
+ ),
})}
className='text-danger-500 underline'
rel='noopener noreferrer'
@@ -286,56 +316,112 @@ const Cardheader = (cartCount) => {
</div>
</div>
</div>
- <div className="flex flex-col w-3/4">
- {product.products?.map((product) =>
- <div key={product.id} className='md:ml-8 ml-4 mt-2 flex'>
- <Link href={createSlug('/shop/product/', product.parent.name, product.parent.id.toString())} 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 && <Image src={product.image} alt={product.name} width={40} height={40} className='w-full h-full object-fill' />}
- </Link>
-
- <div className="ml-4 w-full flex flex-col gap-y-1">
- <Link href={createSlug('/shop/product/', product.parent.name, product.parent.id.toString())} className="text-caption-2 font-medium text-gray-900 truncate dark:text-white">
- {product.displayName}
- </Link>
-
- <div className='flex w-full'>
- <div className="flex flex-col">
- {/* <div className="text-gray-500 text-caption-1">{product.code}</div> */}
- <div>
- <span className="text-gray-500 text-caption-1">Berat Barang: </span>
- <span className="text-gray-500 text-caption-1">{product.packageWeight} Kg</span>
- </div>
- </div>
+ <div className='flex flex-col w-3/4'>
+ {product.products?.map((product) => (
+ <div
+ key={product.id}
+ className='md:ml-8 ml-4 mt-2 flex'
+ >
+ <Link
+ href={createSlug(
+ '/shop/product/',
+ product.parent.name,
+ product.parent.id.toString()
+ )}
+ 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 && (
+ <Image
+ src={product.image}
+ alt={product.name}
+ width={40}
+ height={40}
+ className='w-full h-full object-fill'
+ />
+ )}
+ </Link>
+
+ <div className='ml-4 w-full flex flex-col gap-y-1'>
+ <Link
+ href={createSlug(
+ '/shop/product/',
+ product.parent.name,
+ product.parent.id.toString()
+ )}
+ className='text-caption-2 font-medium text-gray-900 truncate dark:text-white'
+ >
+ {product.displayName}
+ </Link>
+
+ <div className='flex w-full'>
+ <div className='flex flex-col'>
+ {/* <div className="text-gray-500 text-caption-1">{product.code}</div> */}
+ <div>
+ <span className='text-gray-500 text-caption-1'>
+ Berat Barang:{' '}
+ </span>
+ <span className='text-gray-500 text-caption-1'>
+ {product.packageWeight} Kg
+ </span>
</div>
</div>
-
</div>
+ </div>
+ </div>
+ ))}
+ {product.freeProducts?.map((product) => (
+ <div
+ key={product.id}
+ className='md:ml-8 ml-4 mt-2 flex'
+ >
+ <Link
+ href={createSlug(
+ '/shop/product/',
+ product.parent.name,
+ product.parent.id.toString()
)}
- {product.freeProducts?.map((product) =>
- <div key={product.id} className='md:ml-8 ml-4 mt-2 flex'>
- <Link href={createSlug('/shop/product/', product.parent.name, product.parent.id.toString())} 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 && <Image src={product.image} alt={product.name} width={40} height={40} className='w-full h-full object-fill' />}
+ 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 && (
+ <Image
+ src={product.image}
+ alt={product.name}
+ width={40}
+ height={40}
+ className='w-full h-full object-fill'
+ />
+ )}
+ </Link>
+
+ <div className='ml-4 w-full flex flex-col gap-y-1'>
+ <Link
+ href={createSlug(
+ '/shop/product/',
+ product.parent.name,
+ product.parent.id.toString()
+ )}
+ className='text-caption-2 font-medium text-gray-900 truncate dark:text-white'
+ >
+ {product.displayName}
</Link>
-
- <div className="ml-4 w-full flex flex-col gap-y-1">
- <Link href={createSlug('/shop/product/', product.parent.name, product.parent.id.toString())} className="text-caption-2 font-medium text-gray-900 truncate dark:text-white">
- {product.displayName}
- </Link>
-
- <div className='flex w-full'>
- <div className="flex flex-col">
- {/* <div className="text-gray-500 text-caption-1">{product.code}</div> */}
- <div>
- <span className="text-gray-500 text-caption-1">Berat Barang: </span>
- <span className="text-gray-500 text-caption-1">{product.packageWeight} Kg</span>
- </div>
- </div>
+
+ <div className='flex w-full'>
+ <div className='flex flex-col'>
+ {/* <div className="text-gray-500 text-caption-1">{product.code}</div> */}
+ <div>
+ <span className='text-gray-500 text-caption-1'>
+ Berat Barang:{' '}
+ </span>
+ <span className='text-gray-500 text-caption-1'>
+ {product.packageWeight} Kg
+ </span>
</div>
</div>
-
</div>
- )}
+ </div>
</div>
+ ))}
+ </div>
</li>
</>
))}
@@ -347,8 +433,12 @@ const Cardheader = (cartCount) => {
{auth && products.length > 0 && !isLoading && (
<>
<div className='mt-3'>
- <span className='text-gray-400 text-caption-2'>Subtotal Sebelum PPN : </span>
- <span className='font-semibold text-red-600'>{currencyFormat(subTotal)}</span>
+ <span className='text-gray-400 text-caption-2'>
+ Subtotal Sebelum PPN :{' '}
+ </span>
+ <span className='font-semibold text-red-600'>
+ {currencyFormat(subTotal)}
+ </span>
</div>
<div className='mt-5 mb-2'>
<button
@@ -357,7 +447,9 @@ const Cardheader = (cartCount) => {
onClick={handleCheckout}
disabled={buttonLoading}
>
- {buttonLoading ? 'Loading...' : 'Lanjutkan Ke Pembayaran'}
+ {buttonLoading
+ ? 'Loading...'
+ : 'Lanjutkan Ke Pembayaran'}
</button>
</div>
</>
@@ -368,7 +460,7 @@ const Cardheader = (cartCount) => {
)}
</AnimatePresence>
</div>
- )
-}
+ );
+};
-export default Cardheader
+export default Cardheader;
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:
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 || '',