From cc12fccc972dc4f5533a05742090bd0f1c5a3d4b Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Thu, 8 Jan 2026 14:42:37 +0700 Subject: (andri) fix sort table spec --- .../product-detail/components/ProductDetail.tsx | 37 ++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx index a98cb0a4..387a7e5f 100644 --- a/src-migrate/modules/product-detail/components/ProductDetail.tsx +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -2,7 +2,8 @@ import style from '../styles/product-detail.module.css'; import Link from 'next/link'; import { useRouter } from 'next/router'; -import { useEffect, useRef, useState, UIEvent } from 'react'; +// Import useMemo +import { useEffect, useRef, useState, UIEvent, useMemo } from 'react'; // Import komponen Chakra UI import { @@ -329,6 +330,37 @@ const ProductDetail = ({ product }: Props) => { setMainImage(allImages[i] || ''); }; + const sortedVariants = useMemo(() => { + if (!product?.variants) return []; + + return [...product.variants].sort((a, b) => { + const labelA = a.attributes && a.attributes.length > 0 + ? a.attributes.join(' - ') + : a.code || ''; + + const labelB = b.attributes && b.attributes.length > 0 + ? b.attributes.join(' - ') + : b.code || ''; + + const getNumber = (str: string) => { + const match = String(str).match(/(\d+(\.\d+)?)/); + return match ? parseFloat(match[0]) : null; + }; + + const numA = getNumber(labelA); + const numB = getNumber(labelB); + + if (numA !== null && numB !== null && numA !== numB) { + return numA - numB; + } + + return String(labelA).localeCompare(String(labelB), undefined, { + numeric: true, + sensitivity: 'base' + }); + }); + }, [product.variants]); + const activeMagentoDesc = selectedVariant?.id ? descriptionMap[String(selectedVariant.id)] : ''; const finalDescription = activeMagentoDesc || product.description || 'Deskripsi produk tidak tersedia.'; const cleanDescription = finalDescription === '


' ? 'Deskripsi produk tidak tersedia.' : finalDescription; @@ -589,7 +621,8 @@ const ProductDetail = ({ product }: Props) => { - {product.variants.map((v, vIdx) => ( + {/* MENGGUNAKAN sortedVariants HASIL REVISI */} + {sortedVariants.map((v, vIdx) => ( {/* 1. KOLOM JUDUL VARIANT (Sticky Kiri) */}