summaryrefslogtreecommitdiff
path: root/src-migrate/modules
diff options
context:
space:
mode:
authorMiqdad <ahmadmiqdad27@gmail.com>2025-10-24 12:15:25 +0700
committerMiqdad <ahmadmiqdad27@gmail.com>2025-10-24 12:15:25 +0700
commit54dacd110fdbd0f40961c884ec02b1a37189b218 (patch)
treef4ef28a76b6e4c2a37a6eef53a3a10bb1145f9d5 /src-migrate/modules
parentdd16b65c603420d3965edcb4ee5a4a8df0cfadfc (diff)
<MIqdad> try show voucher prod detail
Diffstat (limited to 'src-migrate/modules')
-rw-r--r--src-migrate/modules/product-detail/components/ProductDetail.tsx93
1 files changed, 74 insertions, 19 deletions
diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index f32bb38e..cfc27ffd 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -22,16 +22,17 @@ import PriceAction from './PriceAction';
import SimilarBottom from './SimilarBottom';
import SimilarSide from './SimilarSide';
import dynamic from 'next/dynamic';
-
+import { TicketIcon } from '@heroicons/react/24/solid';
import { gtagProductDetail } from '@/core/utils/googleTag';
+import currencyFormat from '@/core/utils/currencyFormat';
type Props = {
product: IProductDetail;
};
const RWebShare = dynamic(
- () => import('react-web-share').then(m => m.RWebShare),
+ () => import('react-web-share').then((m) => m.RWebShare),
{ ssr: false }
);
@@ -42,7 +43,9 @@ const ProductDetail = ({ product }: Props) => {
const router = useRouter();
const [auth, setAuth] = useState<any>(null);
useEffect(() => {
- try { setAuth(getAuth() ?? null); } catch { }
+ try {
+ setAuth(getAuth() ?? null);
+ } catch {}
}, []);
const canShare =
@@ -87,7 +90,6 @@ const ProductDetail = ({ product }: Props) => {
setSelectedVariant(selectedVariant);
}, []);
-
const allImages = (() => {
const arr: string[] = [];
if (product?.image) arr.push(product.image);
@@ -95,7 +97,6 @@ const ProductDetail = ({ product }: Props) => {
Array.isArray(product?.image_carousel) &&
product.image_carousel.length
) {
-
const set = new Set(arr);
for (const img of product.image_carousel) {
if (!set.has(img)) {
@@ -110,13 +111,11 @@ const ProductDetail = ({ product }: Props) => {
const [mainImage, setMainImage] = useState(allImages[0] || '');
useEffect(() => {
-
if (!allImages.includes(mainImage)) {
setMainImage(allImages[0] || '');
}
}, [allImages]);
-
const sliderRef = useRef<HTMLDivElement | null>(null);
const [currentIdx, setCurrentIdx] = useState(0);
@@ -137,7 +136,48 @@ const ProductDetail = ({ product }: Props) => {
setCurrentIdx(i);
setMainImage(allImages[i] || '');
};
+ // ====== Ambil voucher & hitung potongan (persis seperti ProductCard) ======
+ const voucherRaw = Array.isArray(product?.voucher_pasti_hemat)
+ ? product.voucher_pasti_hemat[0]
+ : product?.voucher_pasti_hemat;
+
+ // kalau backend kadang kirim string JSON
+ let voucher: any = voucherRaw;
+ if (typeof voucherRaw === 'string') {
+ try {
+ voucher = JSON.parse(voucherRaw.replace(/'/g, '"'));
+ } catch {
+ voucher = null;
+ }
+ }
+ // normalisasi nama properti (camelCase vs snake_case)
+ const discountType = voucher?.discountType ?? voucher?.discount_type ?? ''; // 'percentage' atau 'fixed'
+ const discountAmount = Number(
+ voucher?.discountAmount ?? voucher?.discount_amount ?? 0
+ );
+ const maxDiscount = Number(
+ voucher?.maxDiscount ?? voucher?.max_discount ?? 0
+ );
+
+ // base price -> samakan dengan ProductCard: pakai price_discount
+ const basePrice =
+ Number(product?.lowest_price?.price_discount ?? 0) ||
+ Number(product?.lowest_price?.price ?? 0);
+
+ let voucherDiscount = 0;
+ if (discountType === 'percentage') {
+ voucherDiscount = basePrice * (discountAmount / 100);
+ if (maxDiscount > 0 && voucherDiscount > maxDiscount) {
+ voucherDiscount = maxDiscount;
+ }
+ } else {
+ // fixed
+ voucherDiscount = discountAmount;
+ }
+ voucherDiscount = Math.max(0, Math.floor(voucherDiscount));
+
+ const priceAfterVoucher = Math.max(0, basePrice - voucherDiscount);
return (
<>
@@ -165,7 +205,6 @@ const ProductDetail = ({ product }: Props) => {
>
{allImages.length > 0 ? (
allImages.map((img, i) => (
-
<div
key={i}
className='w-full flex-shrink-0 snap-center flex justify-center items-center'
@@ -200,8 +239,9 @@ const ProductDetail = ({ product }: Props) => {
<button
key={i}
aria-label={`Ke slide ${i + 1}`}
- className={`w-2 h-2 rounded-full ${currentIdx === i ? 'bg-gray-800' : 'bg-gray-300'
- }`}
+ className={`w-2 h-2 rounded-full ${
+ currentIdx === i ? 'bg-gray-800' : 'bg-gray-300'
+ }`}
onClick={() => scrollToIndex(i)}
/>
))}
@@ -220,10 +260,11 @@ const ProductDetail = ({ product }: Props) => {
{allImages.map((img, index) => (
<div
key={index}
- className={`flex-shrink-0 w-16 h-16 cursor-pointer border-2 rounded-md transition-colors ${mainImage === img
- ? 'border-red-500 ring-2 ring-red-200'
- : 'border-gray-200 hover:border-gray-300'
- }`}
+ className={`flex-shrink-0 w-16 h-16 cursor-pointer border-2 rounded-md transition-colors ${
+ mainImage === img
+ ? 'border-red-500 ring-2 ring-red-200'
+ : 'border-gray-200 hover:border-gray-300'
+ }`}
onClick={() => setMainImage(img)}
>
<img
@@ -249,6 +290,15 @@ const ProductDetail = ({ product }: Props) => {
{/* ===== Kolom kanan: info ===== */}
<div className='md:w-8/12 px-4 md:pl-6'>
<div className='h-6 md:h-0' />
+ <div className='text text-sm'>
+ <TicketIcon className='inline text-yellow-300 w-5 h-5' />
+ Pakai{' '}
+ <span className='text-green-600 font-extrabold'>
+ {' '}
+ Voucher belanja hemat {currencyFormat(voucherDiscount)} saat
+ checkout
+ </span>
+ </div>
<h1 className={style['title']}>{product.name}</h1>
<div className='h-3 md:h-0' />
<Information product={product} />
@@ -281,7 +331,8 @@ const ProductDetail = ({ product }: Props) => {
className={style['description']}
dangerouslySetInnerHTML={{
__html:
- !product.description || product.description == '<p><br></p>'
+ !product.description ||
+ product.description == '<p><br></p>'
? 'Belum ada deskripsi'
: product.description,
}}
@@ -317,10 +368,16 @@ const ProductDetail = ({ product }: Props) => {
data={{
text: 'Check out this product',
title: `${product.name} - Indoteknik.com`,
- url: (process.env.NEXT_PUBLIC_SELF_HOST || '') + (router?.asPath || '/'),
+ url:
+ (process.env.NEXT_PUBLIC_SELF_HOST || '') +
+ (router?.asPath || '/'),
}}
>
- <Button variant='link' colorScheme='gray' leftIcon={<Share2Icon size={18} />}>
+ <Button
+ variant='link'
+ colorScheme='gray'
+ leftIcon={<Share2Icon size={18} />}
+ >
Share
</Button>
</RWebShare>
@@ -350,8 +407,6 @@ const ProductDetail = ({ product }: Props) => {
</div>
</>
);
-
-
};
export default ProductDetail;