From fbbff6a25ed39b721927a79ce905f4d1e06e522b Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Tue, 23 Dec 2025 14:44:11 +0700
Subject: (andri) fix sticky kolom pertama specs

---
 .../product-detail/components/ProductDetail.tsx    | 198 ++++++++++++---------
 1 file changed, 118 insertions(+), 80 deletions(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 3beb75b4..1c9c39e0 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -460,88 +460,126 @@ const ProductDetail = ({ product }: Props) => {
                     </div>
                   </TabPanel>
 
-                  {/* SPESIFIKASI (LOGIKA GROUPING + RATA TENGAH) */}
+                  {/* SPESIFIKASI (LOGIKA GROUPING + RATA TENGAH + STICKY FIRST COLUMN) */}
                   <TabPanel px={0} py={2}>
                     <Box border="1px solid" borderColor="gray.200" borderRadius="sm" overflowX="auto">
-                        {loadingSpecs ? (
-                            <Center py={6}><Spinner color='red.500' /></Center>
-                        ) : specsMatrix.length > 0 ? (
-                            (() => {
-                                const isSingleVariant = product.variants.length === 1;
-                                const globalAlign = isSingleVariant ? "left" : "center";
-                                
-                                return (
-                                    <Table variant="simple" size="md">
-                                        <Thead bg="red.600">
-                                            <Tr>
-                                                <Th width={isSingleVariant ? "30%" : "20%"} borderColor="whiteAlpha.300" color="white" fontSize="sm" textTransform="none" verticalAlign="middle">
-                                                    Spesifikasi
-                                                </Th>
-                                                {product.variants.map(v => (
-                                                    <Th key={v.id} borderColor="whiteAlpha.300" color="white" textAlign={globalAlign} fontSize="sm" textTransform="none" verticalAlign="middle">
-                                                        {isSingleVariant ? 'Detail' : (v.attributes && v.attributes.length > 0 ? v.attributes.join(' - ') : v.code)}
-                                                    </Th>
-                                                ))}
-                                            </Tr>
-                                        </Thead>
-                                        <Tbody>
-                                            {specsMatrix.map((row, i) => {
-                                                
-                                                // CASE 1: GROUPING (Label punya ' : ')
-                                                if (row.type === 'group') {
-                                                    return (
-                                                        <Tr key={i}>
-                                                            {/* Header Group Kiri */}
-                                                            <Td fontWeight="bold" borderColor="gray.200" fontSize="sm" verticalAlign="middle">{row.label}</Td>
-                                                            
-                                                            {/* Content Group Kanan */}
-                                                            {product.variants.map(v => (
-                                                                <Td key={v.id} borderColor="gray.200" textAlign={globalAlign} fontSize="sm" verticalAlign="middle">
-                                                                    <div className={`inline-block text-left`}>
-                                                                        <div className="flex flex-col gap-0">
-                                                                            {row.children.map((child: any, idx: number) => {
-                                                                                const rawVal = child.values[v.id];
-                                                                                if (!rawVal || rawVal === '-') return null;
-                                                                                
-                                                                                return (
-                                                                                    <div key={idx} className="grid grid-cols-[auto_auto] gap-x-2">
-                                                                                        <span className="font-semibold text-gray-600 whitespace-nowrap">
-                                                                                            {child.label}:
-                                                                                        </span>
-                                                                                        <span>{renderSpecValue(rawVal)}</span>
-                                                                                    </div>
-                                                                                );
-                                                                            })}
-                                                                        </div>
-                                                                    </div>
-                                                                </Td>
-                                                            ))}
-                                                        </Tr>
-                                                    );
-                                                }
-
-                                                // CASE 2: SINGLE ITEM
-                                                return (
-                                                    <Tr key={i}>
-                                                        <Td fontWeight="bold" borderColor="gray.200" fontSize="sm" verticalAlign="middle">{row.label}</Td>
-                                                        {product.variants.map(v => {
-                                                            const rawValue = row.values[v.id] || '-';
-                                                            return (
-                                                                <Td key={v.id} borderColor="gray.200" textAlign={globalAlign} fontSize="sm" verticalAlign="middle">
-                                                                    {renderSpecValue(rawValue)}
-                                                                </Td>
-                                                            );
-                                                        })}
-                                                    </Tr>
-                                                );
-                                            })}
-                                        </Tbody>
-                                    </Table>
-                                );
-                            })()
-                        ) : (
-                            <Box p={4} color="gray.500" fontSize="sm"><Text>Spesifikasi teknis belum tersedia.</Text></Box>
-                        )}
+                      {loadingSpecs ? (
+                        <Center py={6}><Spinner color='red.500' /></Center>
+                      ) : specsMatrix.length > 0 ? (
+                        (() => {
+                          const isSingleVariant = product.variants.length === 1;
+                          const globalAlign = isSingleVariant ? "left" : "center";
+
+                          return (
+                            <Table variant="simple" size="md">
+                              <Thead bg="red.600">
+                                <Tr>
+                                  {/* 1. STICKY HEADER KOLOM PERTAMA */}
+                                  <Th 
+                                      position="sticky" 
+                                      left={0} 
+                                      zIndex={10} 
+                                      bg="red.600"
+                                      width={isSingleVariant ? "30%" : "20%"} 
+                                      borderColor="whiteAlpha.300" 
+                                      color="white" 
+                                      fontSize="sm" 
+                                      textTransform="none" 
+                                      verticalAlign="middle"
+                                      boxShadow="2px 0 5px -2px rgba(0,0,0,0.1)" // Optional: bayangan tipis pembatas
+                                  >
+                                    Spesifikasi
+                                  </Th>
+                                  {product.variants.map(v => (
+                                    <Th key={v.id} borderColor="whiteAlpha.300" color="white" textAlign={globalAlign} fontSize="sm" textTransform="none" verticalAlign="middle">
+                                      {isSingleVariant ? 'Detail' : (v.attributes && v.attributes.length > 0 ? v.attributes.join(' - ') : v.code)}
+                                    </Th>
+                                  ))}
+                                </Tr>
+                              </Thead>
+                              <Tbody>
+                                {specsMatrix.map((row, i) => {
+
+                                  // CASE 1: GROUPING
+                                  if (row.type === 'group') {
+                                    return (
+                                      <Tr key={i}>
+                                        {/* 2. STICKY BODY KOLOM PERTAMA (GROUP) */}
+                                        <Td 
+                                          position="sticky" 
+                                          left={0} 
+                                          zIndex={5} 
+                                          bg="white"
+                                          fontWeight="bold" 
+                                          borderColor="gray.200" 
+                                          fontSize="sm" 
+                                          verticalAlign="middle"
+                                          boxShadow="2px 0 5px -2px rgba(0,0,0,0.05)"
+                                        >
+                                          {row.label}
+                                        </Td>
+
+                                        {product.variants.map(v => (
+                                          <Td key={v.id} borderColor="gray.200" textAlign={globalAlign} fontSize="sm" verticalAlign="middle">
+                                            <div className={`inline-block text-left`}>
+                                              <div className="flex flex-col gap-0">
+                                                {row.children.map((child: any, idx: number) => {
+                                                  const rawVal = child.values[v.id];
+                                                  if (!rawVal || rawVal === '-') return null;
+
+                                                  return (
+                                                    <div key={idx} className="grid grid-cols-[auto_auto] gap-x-2">
+                                                      <span className="font-semibold text-gray-600 whitespace-nowrap">
+                                                        {child.label}:
+                                                      </span>
+                                                      <span>{renderSpecValue(rawVal)}</span>
+                                                    </div>
+                                                  );
+                                                })}
+                                              </div>
+                                            </div>
+                                          </Td>
+                                        ))}
+                                      </Tr>
+                                    );
+                                  }
+
+                                  // CASE 2: SINGLE ITEM
+                                  return (
+                                    <Tr key={i}>
+                                      {/* 3. STICKY BODY KOLOM PERTAMA (SINGLE) */}
+                                      <Td 
+                                          position="sticky" 
+                                          left={0} 
+                                          zIndex={5} 
+                                          bg="white"
+                                          fontWeight="bold" 
+                                          borderColor="gray.200" 
+                                          fontSize="sm" 
+                                          verticalAlign="middle"
+                                          boxShadow="2px 0 5px -2px rgba(0,0,0,0.05)"
+                                      >
+                                          {row.label}
+                                      </Td>
+                                      
+                                      {product.variants.map(v => {
+                                        const rawValue = row.values[v.id] || '-';
+                                        return (
+                                          <Td key={v.id} borderColor="gray.200" textAlign={globalAlign} fontSize="sm" verticalAlign="middle">
+                                            {renderSpecValue(rawValue)}
+                                          </Td>
+                                        );
+                                      })}
+                                    </Tr>
+                                  );
+                                })}
+                              </Tbody>
+                            </Table>
+                          );
+                        })()
+                      ) : (
+                        <Box p={4} color="gray.500" fontSize="sm"><Text>Spesifikasi teknis belum tersedia.</Text></Box>
+                      )}
                     </Box>
                   </TabPanel>
                   
-- 
cgit v1.2.3


From ddc308aa4e5da482763f97e16ab92fe777e8dfeb Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Tue, 23 Dec 2025 14:48:48 +0700
Subject: (andri) fix scrolltoindex

---
 src-migrate/modules/product-detail/components/ProductDetail.tsx | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 1c9c39e0..82b99697 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -312,10 +312,9 @@ const ProductDetail = ({ product }: Props) => {
   };
 
   const scrollToIndex = (i: number) => {
-    const el = sliderRef.current;
-    if (!el) return;
-    const elRef = sliderRef.current;
-    elRef.scrollTo({ left: i * elRef.clientWidth, behavior: 'smooth' });
+    const el = sliderRef.current; 
+    if (!el) return; 
+    el.scrollTo({ left: i * el.clientWidth, behavior: 'smooth' });
     setCurrentIdx(i);
     setMainImage(allImages[i] || '');
   };
-- 
cgit v1.2.3


From fd50180ac301916c6feb5e93598f3fc59ecb78a8 Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Mon, 5 Jan 2026 10:41:39 +0700
Subject: (andri) get desc variant product from magento

---
 .../modules/product-detail/components/ProductDetail.tsx       | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 82b99697..4cc082d8 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -71,6 +71,7 @@ const ProductDetail = ({ product }: Props) => {
   const [specsMatrix, setSpecsMatrix] = useState<any[]>([]); 
   const [upsellIds, setUpsellIds] = useState<number[]>([]);
   const [relatedIds, setRelatedIds] = useState<number[]>([]); 
+  const [descriptionMap, setDescriptionMap] = useState<Record<string, string>>({});
   
   const [loadingSpecs, setLoadingSpecs] = useState(false);
 
@@ -174,6 +175,10 @@ const ProductDetail = ({ product }: Props) => {
            setSpecsMatrix([]);
         }
 
+        if (data.descriptions){
+          setDescriptionMap(data.descriptions);
+        }
+
         // 2. Upsell & Related
         if (data.upsell_ids && Array.isArray(data.upsell_ids)) setUpsellIds(data.upsell_ids);
         else setUpsellIds([]);
@@ -319,6 +324,10 @@ const ProductDetail = ({ product }: Props) => {
     setMainImage(allImages[i] || '');
   };
 
+  const activeMagentoDesc = selectedVariant?.id ? descriptionMap[String(selectedVariant.id)] : '';
+  const finalDescription = activeMagentoDesc || product.description || 'Deskripsi produk tidak tersedia.';
+  const cleanDescription = finalDescription === '<p><br></p>' ? 'Deskripsi produk tidak tersedia.' : finalDescription;
+
   return (
     <>
       <div className='relative'>
@@ -455,7 +464,7 @@ const ProductDetail = ({ product }: Props) => {
                   {/* DESKRIPSI */}
                   <TabPanel px={0} py={6}>
                     <div className='overflow-x-auto text-sm text-gray-700'>
-                      <div className={style['description']} dangerouslySetInnerHTML={{ __html: !product.description || product.description === '<p><br></p>' ? '<p>Lorem ipsum dolor sit amet.</p>' : product.description, }} />
+                      <div className={style['description']} dangerouslySetInnerHTML={{ __html: cleanDescription }} />
                     </div>
                   </TabPanel>
 
-- 
cgit v1.2.3


From 1e4aa525ec325a23d7617133c5532ad874fe309f Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Thu, 8 Jan 2026 10:08:55 +0700
Subject: (andri) fix table spec desktop

---
 .../product-detail/components/ProductDetail.tsx    | 204 ++++++++++++---------
 1 file changed, 116 insertions(+), 88 deletions(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 4cc082d8..3a4d9c7e 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -468,119 +468,147 @@ const ProductDetail = ({ product }: Props) => {
                     </div>
                   </TabPanel>
 
-                  {/* SPESIFIKASI (LOGIKA GROUPING + RATA TENGAH + STICKY FIRST COLUMN) */}
+                  {/* SPESIFIKASI */}
                   <TabPanel px={0} py={2}>
-                    <Box border="1px solid" borderColor="gray.200" borderRadius="sm" overflowX="auto">
+                    <Box 
+                      border="1px solid" 
+                      borderColor="gray.200" 
+                      borderRadius="sm" 
+                      overflowX="auto"
+                      overflowY="auto"   
+                      maxHeight="500px"  
+                      css={{
+                        '&::-webkit-scrollbar': {
+                          width: '12px',  
+                          height: '12px', 
+                        },
+                        '&::-webkit-scrollbar-track': {
+                          background: '#f1f1f1',
+                        },
+                        '&::-webkit-scrollbar-thumb': {
+                          backgroundColor: '#a0aec0', 
+                          borderRadius: '8px',
+                          border: '4px solid transparent',
+                          backgroundClip: 'content-box',
+                        },
+                        '&::-webkit-scrollbar-thumb:hover': {
+                          backgroundColor: '#718096', 
+                        },
+                      }}
+                    >
                       {loadingSpecs ? (
                         <Center py={6}><Spinner color='red.500' /></Center>
                       ) : specsMatrix.length > 0 ? (
                         (() => {
-                          const isSingleVariant = product.variants.length === 1;
-                          const globalAlign = isSingleVariant ? "left" : "center";
+                          const topHeaders: any[] = [];
+                          const subHeaders: any[] = [];
+                          const flatSpecs: any[] = [];
+
+                          specsMatrix.forEach(row => {
+                            if (row.type === 'group') {
+                                topHeaders.push({ 
+                                    label: row.label, 
+                                    type: 'group', 
+                                    colSpan: row.children.length, 
+                                    rowSpan: 1 
+                                });
+                                row.children.forEach((child: any) => {
+                                    subHeaders.push(child);
+                                    flatSpecs.push(child);
+                                });
+                            } else {
+                                topHeaders.push({ 
+                                    label: row.label, 
+                                    type: 'single', 
+                                    colSpan: 1, 
+                                    rowSpan: 2 
+                                });
+                                flatSpecs.push(row);
+                            }
+                          });
 
                           return (
                             <Table variant="simple" size="md">
-                              <Thead bg="red.600">
+                              <Thead bg="red.600" position="sticky" top={0} zIndex={20}>
                                 <Tr>
-                                  {/* 1. STICKY HEADER KOLOM PERTAMA */}
                                   <Th 
-                                      position="sticky" 
-                                      left={0} 
-                                      zIndex={10} 
-                                      bg="red.600"
-                                      width={isSingleVariant ? "30%" : "20%"} 
-                                      borderColor="whiteAlpha.300" 
+                                    position="sticky" left={0} top={0} zIndex={21} bg="red.600"
+                                    rowSpan={2}
+                                    width="25%" 
+                                    borderColor="whiteAlpha.300" color="white" 
+                                    fontSize="sm" textTransform="none" verticalAlign="middle"
+                                    boxShadow="2px 0 5px -2px rgba(0,0,0,0.1)"
+                                  >
+                                    Tipe / Variant
+                                  </Th>
+
+                                  {topHeaders.map((th, idx) => (
+                                    <Th 
+                                      key={`top-${idx}`}
+                                      position="sticky" top={0} zIndex={20} bg="red.600" 
+                                      colSpan={th.colSpan}
+                                      rowSpan={th.rowSpan}
+                                      // borderColor="whiteAlpha.300" 
                                       color="white" 
+                                      textAlign="center" 
                                       fontSize="sm" 
                                       textTransform="none" 
+                                      fontWeight="800"
+                                      letterSpacing="wide"
                                       verticalAlign="middle"
-                                      boxShadow="2px 0 5px -2px rgba(0,0,0,0.1)" // Optional: bayangan tipis pembatas
-                                  >
-                                    Spesifikasi
-                                  </Th>
-                                  {product.variants.map(v => (
-                                    <Th key={v.id} borderColor="whiteAlpha.300" color="white" textAlign={globalAlign} fontSize="sm" textTransform="none" verticalAlign="middle">
-                                      {isSingleVariant ? 'Detail' : (v.attributes && v.attributes.length > 0 ? v.attributes.join(' - ') : v.code)}
+                                    >
+                                      {th.label}
+                                    </Th>
+                                  ))}
+                                </Tr>
+                                <Tr>
+                                  {subHeaders.map((sub, idx) => (
+                                    <Th 
+                                      key={`sub-${idx}`}
+                                      // borderColor="whiteAlpha.300" 
+                                      color="white" 
+                                      textAlign="center" 
+                                      fontSize="xs"
+                                      textTransform="none" 
+                                      verticalAlign="middle"
+                                      whiteSpace="nowrap"
+                                      bg="red.600"
+                                      pt={1} pb={1}
+                                    >
+                                      {sub.label}
                                     </Th>
                                   ))}
                                 </Tr>
                               </Thead>
+                              
                               <Tbody>
-                                {specsMatrix.map((row, i) => {
-
-                                  // CASE 1: GROUPING
-                                  if (row.type === 'group') {
-                                    return (
-                                      <Tr key={i}>
-                                        {/* 2. STICKY BODY KOLOM PERTAMA (GROUP) */}
+                                {product.variants.map((v, vIdx) => (
+                                  <Tr key={v.id} bg={vIdx % 2 === 0 ? 'white' : 'gray.50'}>
+                                    <Td 
+                                      position="sticky" left={0} zIndex={15} 
+                                      bg={vIdx % 2 === 0 ? 'white' : 'gray.50'}
+                                      fontWeight="bold" borderColor="gray.200" fontSize="sm" verticalAlign="middle" textAlign="center" textTransform="uppercase"
+                                      boxShadow="2px 0 5px -2px rgba(0,0,0,0.05)"
+                                    >
+                                      {v.attributes && v.attributes.length > 0 ? v.attributes.join(' - ') : v.code}
+                                    </Td>
+
+                                    {flatSpecs.map((spec, sIdx) => {
+                                      const rawValue = spec.values[v.id] || '-';
+                                      return (
                                         <Td 
-                                          position="sticky" 
-                                          left={0} 
-                                          zIndex={5} 
-                                          bg="white"
-                                          fontWeight="bold" 
+                                          key={sIdx} 
                                           borderColor="gray.200" 
+                                          textAlign="center" 
                                           fontSize="sm" 
                                           verticalAlign="middle"
-                                          boxShadow="2px 0 5px -2px rgba(0,0,0,0.05)"
                                         >
-                                          {row.label}
+                                          {renderSpecValue(rawValue)}
                                         </Td>
-
-                                        {product.variants.map(v => (
-                                          <Td key={v.id} borderColor="gray.200" textAlign={globalAlign} fontSize="sm" verticalAlign="middle">
-                                            <div className={`inline-block text-left`}>
-                                              <div className="flex flex-col gap-0">
-                                                {row.children.map((child: any, idx: number) => {
-                                                  const rawVal = child.values[v.id];
-                                                  if (!rawVal || rawVal === '-') return null;
-
-                                                  return (
-                                                    <div key={idx} className="grid grid-cols-[auto_auto] gap-x-2">
-                                                      <span className="font-semibold text-gray-600 whitespace-nowrap">
-                                                        {child.label}:
-                                                      </span>
-                                                      <span>{renderSpecValue(rawVal)}</span>
-                                                    </div>
-                                                  );
-                                                })}
-                                              </div>
-                                            </div>
-                                          </Td>
-                                        ))}
-                                      </Tr>
-                                    );
-                                  }
-
-                                  // CASE 2: SINGLE ITEM
-                                  return (
-                                    <Tr key={i}>
-                                      {/* 3. STICKY BODY KOLOM PERTAMA (SINGLE) */}
-                                      <Td 
-                                          position="sticky" 
-                                          left={0} 
-                                          zIndex={5} 
-                                          bg="white"
-                                          fontWeight="bold" 
-                                          borderColor="gray.200" 
-                                          fontSize="sm" 
-                                          verticalAlign="middle"
-                                          boxShadow="2px 0 5px -2px rgba(0,0,0,0.05)"
-                                      >
-                                          {row.label}
-                                      </Td>
-                                      
-                                      {product.variants.map(v => {
-                                        const rawValue = row.values[v.id] || '-';
-                                        return (
-                                          <Td key={v.id} borderColor="gray.200" textAlign={globalAlign} fontSize="sm" verticalAlign="middle">
-                                            {renderSpecValue(rawValue)}
-                                          </Td>
-                                        );
-                                      })}
-                                    </Tr>
-                                  );
-                                })}
+                                      );
+                                    })}
+                                  </Tr>
+                                ))}
                               </Tbody>
                             </Table>
                           );
-- 
cgit v1.2.3


From 8004947c70f9e963f942aed75e6e99c7c6e82b65 Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Thu, 8 Jan 2026 13:16:35 +0700
Subject: (andri) add minmax width td body

---
 .../modules/product-detail/components/ProductDetail.tsx  | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 3a4d9c7e..a18e70bb 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -535,6 +535,7 @@ const ProductDetail = ({ product }: Props) => {
                                     position="sticky" left={0} top={0} zIndex={21} bg="red.600"
                                     rowSpan={2}
                                     width="25%" 
+                                    minW="100px" 
                                     borderColor="whiteAlpha.300" color="white" 
                                     fontSize="sm" textTransform="none" verticalAlign="middle"
                                     boxShadow="2px 0 5px -2px rgba(0,0,0,0.1)"
@@ -584,15 +585,20 @@ const ProductDetail = ({ product }: Props) => {
                               <Tbody>
                                 {product.variants.map((v, vIdx) => (
                                   <Tr key={v.id} bg={vIdx % 2 === 0 ? 'white' : 'gray.50'}>
+                                    {/* 1. KOLOM JUDUL VARIANT (Sticky Kiri) */}
                                     <Td 
                                       position="sticky" left={0} zIndex={15} 
                                       bg={vIdx % 2 === 0 ? 'white' : 'gray.50'}
-                                      fontWeight="bold" borderColor="gray.200" fontSize="sm" verticalAlign="middle" textAlign="center" textTransform="uppercase"
+                                      fontWeight="bold" borderColor="gray.200" fontSize="sm" 
+                                      verticalAlign="middle"
                                       boxShadow="2px 0 5px -2px rgba(0,0,0,0.05)"
+                                      minW="100px"         
+                                      whiteSpace="normal" 
+                                      py={4}               
                                     >
                                       {v.attributes && v.attributes.length > 0 ? v.attributes.join(' - ') : v.code}
                                     </Td>
-
+                                    {/* 2. KOLOM DATA SPESIFIKASI */}
                                     {flatSpecs.map((spec, sIdx) => {
                                       const rawValue = spec.values[v.id] || '-';
                                       return (
@@ -602,6 +608,12 @@ const ProductDetail = ({ product }: Props) => {
                                           textAlign="center" 
                                           fontSize="sm" 
                                           verticalAlign="middle"
+                                          px={2}
+                                          py={3} 
+                                          minW="100px"   
+                                          maxW="150px"        
+                                          whiteSpace="normal" 
+                                          overflowWrap="break-word"
                                         >
                                           {renderSpecValue(rawValue)}
                                         </Td>
-- 
cgit v1.2.3


From 3a93af1298a725f4f399659be88bac15b8a7ca82 Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Thu, 8 Jan 2026 13:20:21 +0700
Subject: fix

---
 src-migrate/modules/product-detail/components/ProductDetail.tsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index a18e70bb..2652106c 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -538,9 +538,10 @@ const ProductDetail = ({ product }: Props) => {
                                     minW="100px" 
                                     borderColor="whiteAlpha.300" color="white" 
                                     fontSize="sm" textTransform="none" verticalAlign="middle"
+                                    textAlign="center"
                                     boxShadow="2px 0 5px -2px rgba(0,0,0,0.1)"
                                   >
-                                    Tipe / Variant
+                                    Variant
                                   </Th>
 
                                   {topHeaders.map((th, idx) => (
@@ -593,6 +594,7 @@ const ProductDetail = ({ product }: Props) => {
                                       verticalAlign="middle"
                                       boxShadow="2px 0 5px -2px rgba(0,0,0,0.05)"
                                       minW="100px"         
+                                      textAlign="center"
                                       whiteSpace="normal" 
                                       py={4}               
                                     >
-- 
cgit v1.2.3


From e7faa6bb5dc33f576cb53cd1f4716bf2c6b03571 Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Thu, 8 Jan 2026 13:27:25 +0700
Subject: (andri) hide brand in specs

---
 src-migrate/modules/product-detail/components/ProductDetail.tsx | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 2652106c..a98cb0a4 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -169,8 +169,13 @@ const ProductDetail = ({ product }: Props) => {
 
         // 1. Specs Matrix (Processed Grouping)
         if (data.specsMatrix && Array.isArray(data.specsMatrix)) {
-           const processed = processMatrixData(data.specsMatrix);
-           setSpecsMatrix(processed);
+            const filteredMatrix = data.specsMatrix.filter((item: any) => {
+            const code = item.code || '';
+            return !code.includes('z_brand');
+        });
+
+        const processed = processMatrixData(filteredMatrix);
+        setSpecsMatrix(processed);
         } else {
            setSpecsMatrix([]);
         }
-- 
cgit v1.2.3


From cc12fccc972dc4f5533a05742090bd0f1c5a3d4b Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
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(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

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 === '<p><br></p>' ? 'Deskripsi produk tidak tersedia.' : finalDescription;
@@ -589,7 +621,8 @@ const ProductDetail = ({ product }: Props) => {
                               </Thead>
                               
                               <Tbody>
-                                {product.variants.map((v, vIdx) => (
+                                {/* MENGGUNAKAN sortedVariants HASIL REVISI */}
+                                {sortedVariants.map((v, vIdx) => (
                                   <Tr key={v.id} bg={vIdx % 2 === 0 ? 'white' : 'gray.50'}>
                                     {/* 1. KOLOM JUDUL VARIANT (Sticky Kiri) */}
                                     <Td 
-- 
cgit v1.2.3


From b45835a01655b67f52ebd933f3d2c07d803f6aaf Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Fri, 9 Jan 2026 10:33:14 +0700
Subject: (andri) ganti sticky variant kolom pertama menjadi attribute code
 pertama dari magento

---
 .../product-detail/components/ProductDetail.tsx    | 58 ++++++++++------------
 1 file changed, 25 insertions(+), 33 deletions(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 387a7e5f..983cb843 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -567,27 +567,20 @@ const ProductDetail = ({ product }: Props) => {
                           return (
                             <Table variant="simple" size="md">
                               <Thead bg="red.600" position="sticky" top={0} zIndex={20}>
+                                {/* Baris 1: Header Utama */}
                                 <Tr>
-                                  <Th 
-                                    position="sticky" left={0} top={0} zIndex={21} bg="red.600"
-                                    rowSpan={2}
-                                    width="25%" 
-                                    minW="100px" 
-                                    borderColor="whiteAlpha.300" color="white" 
-                                    fontSize="sm" textTransform="none" verticalAlign="middle"
-                                    textAlign="center"
-                                    boxShadow="2px 0 5px -2px rgba(0,0,0,0.1)"
-                                  >
-                                    Variant
-                                  </Th>
-
                                   {topHeaders.map((th, idx) => (
                                     <Th 
                                       key={`top-${idx}`}
-                                      position="sticky" top={0} zIndex={20} bg="red.600" 
+                                      // STICKY HEADER BARIS 1 
+                                      position={idx === 0 ? "sticky" : "static"}
+                                      left={idx === 0 ? 0 : undefined}
+                                      zIndex={idx === 0 ? 22 : 20} 
+                                      boxShadow={idx === 0 ? "2px 0 5px -2px rgba(0,0,0,0.2)" : "none"}
+                                      
+                                      bg="red.600" 
                                       colSpan={th.colSpan}
                                       rowSpan={th.rowSpan}
-                                      // borderColor="whiteAlpha.300" 
                                       color="white" 
                                       textAlign="center" 
                                       fontSize="sm" 
@@ -600,11 +593,16 @@ const ProductDetail = ({ product }: Props) => {
                                     </Th>
                                   ))}
                                 </Tr>
+
+                                {/* Baris 2: Sub Header */}
                                 <Tr>
                                   {subHeaders.map((sub, idx) => (
                                     <Th 
                                       key={`sub-${idx}`}
-                                      // borderColor="whiteAlpha.300" 
+                                      position={idx === 0 ? "sticky" : "static"}
+                                      left={idx === 0 ? 0 : undefined}
+                                      zIndex={idx === 0 ? 21 : 1} 
+                                      boxShadow={idx === 0 ? "2px 0 5px -2px rgba(0,0,0,0.2)" : "none"}
                                       color="white" 
                                       textAlign="center" 
                                       fontSize="xs"
@@ -621,39 +619,33 @@ const ProductDetail = ({ product }: Props) => {
                               </Thead>
                               
                               <Tbody>
-                                {/* MENGGUNAKAN sortedVariants HASIL REVISI */}
                                 {sortedVariants.map((v, vIdx) => (
                                   <Tr key={v.id} bg={vIdx % 2 === 0 ? 'white' : 'gray.50'}>
-                                    {/* 1. KOLOM JUDUL VARIANT (Sticky Kiri) */}
-                                    <Td 
-                                      position="sticky" left={0} zIndex={15} 
-                                      bg={vIdx % 2 === 0 ? 'white' : 'gray.50'}
-                                      fontWeight="bold" borderColor="gray.200" fontSize="sm" 
-                                      verticalAlign="middle"
-                                      boxShadow="2px 0 5px -2px rgba(0,0,0,0.05)"
-                                      minW="100px"         
-                                      textAlign="center"
-                                      whiteSpace="normal" 
-                                      py={4}               
-                                    >
-                                      {v.attributes && v.attributes.length > 0 ? v.attributes.join(' - ') : v.code}
-                                    </Td>
-                                    {/* 2. KOLOM DATA SPESIFIKASI */}
                                     {flatSpecs.map((spec, sIdx) => {
                                       const rawValue = spec.values[v.id] || '-';
+                                      const isFirstCol = sIdx === 0; 
                                       return (
                                         <Td 
                                           key={sIdx} 
+                                          // === LOGIC STICKY DATA PERTAMA ===
+                                          position={isFirstCol ? "sticky" : "static"}
+                                          left={isFirstCol ? 0 : undefined}
+                                          zIndex={isFirstCol ? 10 : 1}
+                                          bg={vIdx % 2 === 0 ? 'white' : 'gray.50'} 
+                                          boxShadow={isFirstCol ? "2px 0 5px -2px rgba(0,0,0,0.1)" : "none"}
+                                          // =================================
+                                          
                                           borderColor="gray.200" 
                                           textAlign="center" 
                                           fontSize="sm" 
                                           verticalAlign="middle"
                                           px={2}
                                           py={3} 
-                                          minW="100px"   
+                                          minW="100px"
                                           maxW="150px"        
                                           whiteSpace="normal" 
                                           overflowWrap="break-word"
+                                          fontWeight={isFirstCol ? "bold" : "normal"} 
                                         >
                                           {renderSpecValue(rawValue)}
                                         </Td>
-- 
cgit v1.2.3


From bab9bfaeeab2ba13bba1d7ed02e25b5384919bf9 Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Fri, 9 Jan 2026 10:57:14 +0700
Subject: (andri) fix sticky header

---
 .../product-detail/components/ProductDetail.tsx    | 46 ++++++++++++----------
 1 file changed, 25 insertions(+), 21 deletions(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 983cb843..5a2ad093 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -572,10 +572,9 @@ const ProductDetail = ({ product }: Props) => {
                                   {topHeaders.map((th, idx) => (
                                     <Th 
                                       key={`top-${idx}`}
-                                      // STICKY HEADER BARIS 1 
                                       position={idx === 0 ? "sticky" : "static"}
                                       left={idx === 0 ? 0 : undefined}
-                                      zIndex={idx === 0 ? 22 : 20} 
+                                      zIndex={idx === 0 ? 22 : 20}
                                       boxShadow={idx === 0 ? "2px 0 5px -2px rgba(0,0,0,0.2)" : "none"}
                                       
                                       bg="red.600" 
@@ -596,25 +595,30 @@ const ProductDetail = ({ product }: Props) => {
 
                                 {/* Baris 2: Sub Header */}
                                 <Tr>
-                                  {subHeaders.map((sub, idx) => (
-                                    <Th 
-                                      key={`sub-${idx}`}
-                                      position={idx === 0 ? "sticky" : "static"}
-                                      left={idx === 0 ? 0 : undefined}
-                                      zIndex={idx === 0 ? 21 : 1} 
-                                      boxShadow={idx === 0 ? "2px 0 5px -2px rgba(0,0,0,0.2)" : "none"}
-                                      color="white" 
-                                      textAlign="center" 
-                                      fontSize="xs"
-                                      textTransform="none" 
-                                      verticalAlign="middle"
-                                      whiteSpace="nowrap"
-                                      bg="red.600"
-                                      pt={1} pb={1}
-                                    >
-                                      {sub.label}
-                                    </Th>
-                                  ))}
+                                  {subHeaders.map((sub, idx) => { 
+                                    const isFirstHeaderGroup = topHeaders[0]?.type === 'group';
+                                    const shouldSticky = idx === 0 && isFirstHeaderGroup;
+                                    return (
+                                      <Th 
+                                        key={`sub-${idx}`}
+                                        position={shouldSticky ? "sticky" : "static"}
+                                        left={shouldSticky ? 0 : undefined}
+                                        zIndex={shouldSticky ? 21 : 1}
+                                        boxShadow={shouldSticky ? "2px 0 5px -2px rgba(0,0,0,0.2)" : "none"}
+                                        
+                                        color="white" 
+                                        textAlign="center" 
+                                        fontSize="xs"
+                                        textTransform="none" 
+                                        verticalAlign="middle"
+                                        whiteSpace="nowrap"
+                                        bg="red.600"
+                                        pt={1} pb={1}
+                                      >
+                                        {sub.label}
+                                      </Th>
+                                    );
+                                  })}
                                 </Tr>
                               </Thead>
                               
-- 
cgit v1.2.3


From 6c2de1aa1cc655b1da525015ac0280fd4c72731f Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Fri, 9 Jan 2026 14:29:26 +0700
Subject: border bottom none

---
 src-migrate/modules/product-detail/components/ProductDetail.tsx | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 5a2ad093..7ca2f9a7 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -587,6 +587,7 @@ const ProductDetail = ({ product }: Props) => {
                                       fontWeight="800"
                                       letterSpacing="wide"
                                       verticalAlign="middle"
+                                      borderBottom="none"
                                     >
                                       {th.label}
                                     </Th>
-- 
cgit v1.2.3

