diff options
| author | FIN-IT_AndriFP <andrifebriyadiputra@gmail.com> | 2026-01-08 10:08:55 +0700 |
|---|---|---|
| committer | FIN-IT_AndriFP <andrifebriyadiputra@gmail.com> | 2026-01-08 10:08:55 +0700 |
| commit | 1e4aa525ec325a23d7617133c5532ad874fe309f (patch) | |
| tree | be1f7d63fe5a971f2c7ddfdc26439a6aad7c7112 /src-migrate/modules | |
| parent | 44afa589c9ced88aa4dcd93181d9e068d79603ea (diff) | |
(andri) fix table spec desktop
Diffstat (limited to 'src-migrate/modules')
| -rw-r--r-- | src-migrate/modules/product-detail/components/ProductDetail.tsx | 204 |
1 files changed, 116 insertions, 88 deletions
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> ); |
