summaryrefslogtreecommitdiff
path: root/src-migrate
diff options
context:
space:
mode:
authorFIN-IT_AndriFP <andrifebriyadiputra@gmail.com>2026-01-08 10:08:55 +0700
committerFIN-IT_AndriFP <andrifebriyadiputra@gmail.com>2026-01-08 10:08:55 +0700
commit1e4aa525ec325a23d7617133c5532ad874fe309f (patch)
treebe1f7d63fe5a971f2c7ddfdc26439a6aad7c7112 /src-migrate
parent44afa589c9ced88aa4dcd93181d9e068d79603ea (diff)
(andri) fix table spec desktop
Diffstat (limited to 'src-migrate')
-rw-r--r--src-migrate/modules/product-detail/components/ProductDetail.tsx204
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>
);