summaryrefslogtreecommitdiff
path: root/src-migrate
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2024-01-18 16:24:54 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2024-01-18 16:24:54 +0700
commit5ac82c38ed3ec4db1fe4ae96e7493a55154716ef (patch)
treef493df6c4c9d96b6efa86896fd6d27d2995726c4 /src-migrate
parent7298d8e811a68cb92c02a7d810f412498d1609d8 (diff)
Update product detail page
Diffstat (limited to 'src-migrate')
-rw-r--r--src-migrate/modules/product-detail/components/Image.tsx69
-rw-r--r--src-migrate/modules/product-detail/components/PriceAction.tsx18
-rw-r--r--src-migrate/modules/product-detail/components/VariantList.tsx10
-rw-r--r--src-migrate/modules/product-detail/styles/image.module.css35
-rw-r--r--src-migrate/modules/product-detail/styles/price-action.module.css8
-rw-r--r--src-migrate/modules/product-detail/styles/variant-list.module.css8
-rw-r--r--src-migrate/services/product.ts1
-rw-r--r--src-migrate/types/product.ts5
8 files changed, 140 insertions, 14 deletions
diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx
index 6ec715d8..2ab3ff59 100644
--- a/src-migrate/modules/product-detail/components/Image.tsx
+++ b/src-migrate/modules/product-detail/components/Image.tsx
@@ -1,27 +1,53 @@
-import React from 'react'
+import style from '../styles/image.module.css';
+
+import React, { useEffect, 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 moment from 'moment';
type Props = {
product: IProductDetail
}
const Image = ({ product }: Props) => {
+ const flashSale = product.flash_sale
+
+ const [count, setCount] = useState(flashSale?.remaining_time || 0);
+
+ useEffect(() => {
+ let interval: NodeJS.Timeout;
+
+ if (flashSale?.remaining_time && flashSale.remaining_time > 0) {
+ setCount(flashSale.remaining_time);
+
+ interval = setInterval(() => {
+ setCount((prevCount) => prevCount - 1);
+ }, 1000);
+ }
+
+ return () => {
+ clearInterval(interval);
+ };
+ }, [flashSale?.remaining_time]);
+
+ const duration = moment.duration(count, 'seconds')
+
return (
- <div className='h-[250px] md:h-[340px] flex items-center justify-center border border-gray-200 rounded-lg p-4 relative'>
+ <div className={style['wrapper']}>
<ImageUI
src={product.image || '/images/noimage.jpeg'}
alt={product.name}
width={256}
height={256}
- className='object-contain object-center h-full w-full'
+ className={style['image']}
loading='eager'
priority
/>
- <div className='absolute hidden md:block top-4 right-4'>
+
+ <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.'
@@ -31,6 +57,41 @@ const Image = ({ product }: Props) => {
</div>
</Tooltip>
</div>
+
+ {flashSale.remaining_time > 0 && (
+ <div className='absolute bottom-0 w-full h-14'>
+ <div className="relative w-full h-full">
+ <ImageUI
+ src='/images/GAMBAR-BG-FLASH-SALE.jpg'
+ alt='Flash Sale Indoteknik'
+ width={200}
+ height={100}
+ className={style['flashsale-bg']}
+ />
+
+ <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['flashsale-text']}>
+ <ImageUI
+ src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg'
+ alt='Icon Flash Sale'
+ width={20}
+ height={20}
+ />
+ {product.flash_sale.tag}
+ </div>
+ </div>
+ <div className={style['countdown']}>
+ <span>{duration.hours().toString().padStart(2, '0')}</span>
+ <span>{duration.minutes().toString().padStart(2, '0')}</span>
+ <span>{duration.seconds().toString().padStart(2, '0')}</span>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ )}
</div>
)
}
diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx
index cade21b8..f25847a5 100644
--- a/src-migrate/modules/product-detail/components/PriceAction.tsx
+++ b/src-migrate/modules/product-detail/components/PriceAction.tsx
@@ -29,13 +29,25 @@ const PriceAction = ({ product }: Props) => {
<div className='block md:sticky top-[150px] bg-white py-0 md:py-6 z-10' id='price-section'>
{!!activePrice && activePrice.price > 0 && (
<>
- <div className={style['main-price']}>
- Rp {formatCurrency(activePrice.price || 0)}
+ <div className='flex items-end gap-x-2'>
+ {activePrice.discount_percentage > 0 && (
+ <>
+ <div className={style['disc-badge']}>
+ {Math.floor(activePrice.discount_percentage)}%
+ </div>
+ <div className={style['disc-price']}>
+ Rp {formatCurrency(activePrice.price || 0)}
+ </div>
+ </>
+ )}
+ <div className={style['main-price']}>
+ Rp {formatCurrency(activePrice.price_discount || 0)}
+ </div>
</div>
<div className='h-1' />
<div className={style['secondary-text']}>
Termasuk PPN: {' '}
- Rp {formatCurrency(Math.round(activePrice.price * 1.11))}
+ Rp {formatCurrency(Math.round(activePrice.price_discount * 1.11))}
</div>
</>
)}
diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx
index 1da478e7..3d5b9b74 100644
--- a/src-migrate/modules/product-detail/components/VariantList.tsx
+++ b/src-migrate/modules/product-detail/components/VariantList.tsx
@@ -89,8 +89,14 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => {
{variant.weight > 0 ? `${variant.weight} Kg` : '-'}
</div>
<div className='w-3/12'>
- {variant.price.price > 0 && `Rp ${formatCurrency(variant.price.price)}`}
- {variant.price.price === 0 && '-'}
+ {variant.price.discount_percentage > 0 && (
+ <div className='flex items-center gap-x-1'>
+ <div className={style['disc-badge']}>{Math.floor(variant.price.discount_percentage)}%</div>
+ <div className={style['disc-price']}>Rp {formatCurrency(variant.price.price)}</div>
+ </div>
+ )}
+ {variant.price.price_discount > 0 && `Rp ${formatCurrency(variant.price.price_discount)}`}
+ {variant.price.price_discount === 0 && '-'}
</div>
<div className='w-1/12 sticky right-0 bg-white md:bg-transparent'>
<Button
diff --git a/src-migrate/modules/product-detail/styles/image.module.css b/src-migrate/modules/product-detail/styles/image.module.css
new file mode 100644
index 00000000..e472fe8d
--- /dev/null
+++ b/src-migrate/modules/product-detail/styles/image.module.css
@@ -0,0 +1,35 @@
+.wrapper {
+ @apply h-[250px] md:h-[340px] flex items-center justify-center border border-gray-200 rounded-lg p-4 relative;
+}
+
+.image {
+ @apply object-contain object-center h-full w-full;
+}
+
+.absolute-info {
+ @apply absolute hidden md:block top-4 right-4;
+}
+
+.disc-badge {
+ @apply bg-warning-500 py-1 px-3 w-fit font-semibold rounded-full;
+}
+
+.countdown {
+ @apply flex gap-x-1;
+}
+
+.countdown span {
+ @apply py-0.5 w-8 bg-warning-500 rounded-md text-center;
+}
+
+.flashsale-text {
+ @apply flex items-center gap-x-2 text-white font-medium text-caption-1;
+}
+
+.flashsale-bg {
+ @apply absolute top-0 w-full h-full object-cover object-center z-10;
+}
+
+.flashsale {
+ @apply absolute top-0 w-full h-full z-20 flex items-center justify-between px-3;
+}
diff --git a/src-migrate/modules/product-detail/styles/price-action.module.css b/src-migrate/modules/product-detail/styles/price-action.module.css
index a8ec0ed3..651de958 100644
--- a/src-migrate/modules/product-detail/styles/price-action.module.css
+++ b/src-migrate/modules/product-detail/styles/price-action.module.css
@@ -14,3 +14,11 @@
.contact-us {
@apply text-danger-500 font-medium underline;
}
+
+.disc-badge {
+ @apply bg-danger-500 px-2 py-1.5 rounded text-white text-caption-2;
+}
+
+.disc-price {
+ @apply line-through text-gray-600 text-caption-2;
+}
diff --git a/src-migrate/modules/product-detail/styles/variant-list.module.css b/src-migrate/modules/product-detail/styles/variant-list.module.css
index a56822c1..6d46df84 100644
--- a/src-migrate/modules/product-detail/styles/variant-list.module.css
+++ b/src-migrate/modules/product-detail/styles/variant-list.module.css
@@ -25,3 +25,11 @@
.stock-ready {
@apply bg-green-50 border border-green-500 text-green-800;
}
+
+.disc-badge {
+ @apply bg-danger-500 p-1 rounded text-white text-caption-2;
+}
+
+.disc-price {
+ @apply text-caption-2 line-through text-gray-600;
+}
diff --git a/src-migrate/services/product.ts b/src-migrate/services/product.ts
index 4ef027e1..fe415d11 100644
--- a/src-migrate/services/product.ts
+++ b/src-migrate/services/product.ts
@@ -15,7 +15,6 @@ export const getProductById = async (
.then((res) => res.json())
.then((res) => {
if (res.length > 0) return snakeCase(res[0]) as IProductDetail;
-
return null;
});
};
diff --git a/src-migrate/types/product.ts b/src-migrate/types/product.ts
index b411224b..08de98e0 100644
--- a/src-migrate/types/product.ts
+++ b/src-migrate/types/product.ts
@@ -17,10 +17,7 @@ export interface IProduct {
}[];
flash_sale: {
id: string;
- remaining_time: {
- remaining_time: number;
- is_flashsale: boolean;
- };
+ remaining_time: number;
tag: string;
};
lowest_price: {