From f56cc888934d4b4ef962e967d40533ab5ded2414 Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Mon, 19 Jan 2026 09:39:25 +0700
Subject: (andri) fix view mobile compare

---
 .../components/ProductComparisonModal.tsx          | 527 ++++++++++++---------
 1 file changed, 302 insertions(+), 225 deletions(-)

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

diff --git a/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx b/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
index 00eaebe5..b26be520 100644
--- a/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
+++ b/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
@@ -6,6 +6,12 @@ import {
   ModalHeader,
   ModalBody,
   ModalCloseButton,
+  Drawer, // Tambahan untuk Mobile
+  DrawerOverlay,
+  DrawerContent,
+  DrawerHeader,
+  DrawerBody,
+  DrawerCloseButton,
   Button,
   Text,
   Box,
@@ -26,7 +32,9 @@ import {
   List,
   ListItem,
   useToast,
-  useOutsideClick
+  useOutsideClick,
+  useBreakpointValue, // Tambahan untuk Mobile
+  Divider // Tambahan untuk Mobile
 } from '@chakra-ui/react';
 
 import {
@@ -36,7 +44,7 @@ import {
   AutoCompleteList,
 } from '@choc-ui/chakra-autocomplete';
 
-import { Search, Trash2, ChevronDown } from 'lucide-react';
+import { Search, Trash2, ChevronDown, X } from 'lucide-react';
 
 // --- HELPER FORMATTING ---
 const formatPrice = (price: number) => {
@@ -82,6 +90,8 @@ type Props = {
 
 const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant }: Props) => {
   const toast = useToast();
+  // Deteksi Mobile
+  const isMobile = useBreakpointValue({ base: true, md: false });
 
   const [products, setProducts] = useState<(any | null)[]>([null, null, null, null]);
   const [specsMatrix, setSpecsMatrix] = useState<any[]>([]);
@@ -150,7 +160,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
       
       const tempActiveVar = { 
         code: displayCode, 
-        name: displayName,
+        name: displayName, 
         displayName: displayName,
         attributes: activeItem.attributes || [] 
       };
@@ -273,7 +283,6 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
     const currentProduct = products[slotIndex];
     if (!currentProduct || !currentProduct.variants) return;
 
-    // Cari varian yang labelnya cocok dengan string input
     const selectedVar = currentProduct.variants.find((v: any) => {
       return getVariantLabel(v) === selectedValueString;
     });
@@ -334,11 +343,10 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
       }
     }
 
-    // Siapkan object sementara untuk generate Label (Memanfaatkan Extract Attribute)
     const tempVar = { 
         code: codeToAdd, 
         name: nameToAdd, 
-        displayName: searchItem.displayName || nameToAdd, // Pastikan ada displayName untuk diparsing
+        displayName: searchItem.displayName || nameToAdd, 
         attributes: searchItem.attributes || [] 
     };
     const initialLabel = getVariantLabel(tempVar);
@@ -354,7 +362,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
         id: idToAdd,
         code: codeToAdd,
         name: nameToAdd,
-        displayName: searchItem.displayName || nameToAdd, // Simpan untuk varian sendiri
+        displayName: searchItem.displayName || nameToAdd,
         price: priceToAdd,
         image: imageToAdd,
         attributes: searchItem.attributes || []
@@ -391,10 +399,10 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
               id: s.variantId || s.productIdI || s.id,
               code: s.defaultCode || s.default_code || s.code,
               name: s.displayName || s.name || s.nameS,
-              displayName: s.displayName, // Wajib disimpan agar extractAttribute bisa bekerja
+              displayName: s.displayName, 
               price: s.lowestPrice?.price || s.priceTier1V2F || 0,
               image: s.image || s.imageS,
-              attributes: [] // Biarkan kosong, nanti dihandle extractAttribute via displayName
+              attributes: [] 
             }));
 
             allVariants.sort((a: any, b: any) =>
@@ -426,6 +434,290 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
     if (newProducts.every(p => p === null)) setSpecsMatrix([]);
   };
 
+  // --- RENDER SLOT ITEM ---
+  const renderProductSlot = (product: any, index: number) => {
+    if (product) {
+      return (
+        <VStack align="stretch" spacing={3} h="100%">
+          {index !== 0 && (
+            <IconButton
+              aria-label="Hapus" icon={<Trash2 size={16} />}
+              size="xs" position="absolute" top={-2} right={-2}
+              colorScheme="red" onClick={() => handleRemoveProduct(index)} zIndex={2}
+            />
+          )}
+          <Box h="160px" display="flex" alignItems="center" justifyContent="center" bg="gray.50" borderRadius="md" p={2}>
+            <Image
+              src={product.image || '/images/no-image-compare.svg'}
+              alt={product.name} maxH="100%" objectFit="contain"
+              onError={(e) => { (e.target as HTMLImageElement).src = '/images/no-image-compare.svg'; }}
+            />
+          </Box>
+          <Box>
+            <Text color="red.600" fontWeight="bold" fontSize="md">
+              {product.price > 0 ? formatPrice(product.price) : 'Hubungi Admin'}
+            </Text>
+            <Text fontSize="xs" fontWeight="bold" noOfLines={3} h="45px" title={product.name} mb={2}>
+              {product.name}
+            </Text>
+          </Box>
+
+          <Box w="100%">
+            <AutoComplete
+              openOnFocus
+              disableFilter={disableVariantFilter}
+              onChange={(val) => handleVariantChange(index, val)}
+              value={product.inputValue}
+            >
+              <InputGroup size="sm">
+                <AutoCompleteInput
+                  variant="outline"
+                  fontSize="xs"
+                  borderRadius="md"
+                  placeholder="Cari Varian..."
+                  value={product.inputValue}
+                  onChange={(e) => handleInputChange(index, e.target.value)}
+                  onFocus={() => setDisableVariantFilter(true)}
+                />
+                <InputRightElement h="100%" pointerEvents="none">
+                  <Icon as={ChevronDown} color="gray.400" size={14} />
+                </InputRightElement>
+              </InputGroup>
+
+              <AutoCompleteList fontSize="xs" maxH="250px" overflowY="auto" p={0}>
+                {product.variants && product.variants.map((v: any, vIdx: number) => {
+                  const attributeText = extractAttribute(v);
+                  const label = `${v.code} - ${attributeText}`;
+                  return (
+                    <AutoCompleteItem
+                      key={`option-${vIdx}`}
+                      value={label}
+                      textTransform="capitalize"
+                      _selected={{ bg: 'red.50', borderLeft: '3px solid red' }}
+                      _focus={{ bg: 'gray.50' }}
+                      p={2}
+                      borderBottom="1px dashed"
+                      borderColor="gray.200"
+                    >
+                      <Flex justify="space-between" align="start" w="100%">
+                        <Box flex={1} mr={2} overflow="hidden">
+                          <Text fontWeight="bold" fontSize="xs" color="gray.700">{v.code}</Text>
+                          <Text fontSize="xs" color="gray.500" noOfLines={1} title={attributeText} textTransform="capitalize">
+                            {attributeText}
+                          </Text>
+                        </Box>
+                        <Text color="red.600" fontWeight="bold" fontSize="xs" whiteSpace="nowrap" bg="red.50" px={2} py={0.5} borderRadius="md" h="fit-content">
+                          {formatPrice(v.price)}
+                        </Text>
+                      </Flex>
+                    </AutoCompleteItem>
+                  );
+                })}
+              </AutoCompleteList>
+            </AutoComplete>
+          </Box>
+
+          <HStack spacing={2}>
+            <IconButton
+              aria-label="Cart"
+              icon={<Image src="/images/keranjang.svg" w="15px" h="15px" objectFit="contain" />}
+              variant="outline"
+              colorScheme="red"
+              size="sm"
+            />
+            <Button as="a" href={`/product/${product.id}`} target="_blank" colorScheme="red" size="sm" flex={1} fontSize="xs">
+              Beli Sekarang
+            </Button>
+          </HStack>
+        </VStack>
+      );
+    } 
+    
+    return (
+      <VStack align="stretch" spacing={3} h="100%" position="relative">
+        <Box position="relative" w="100%" ref={activeSearchSlot === index ? searchWrapperRef : null}>
+          <InputGroup size="sm">
+            <InputLeftElement pointerEvents="none"><Icon as={Search} color="gray.300" /></InputLeftElement>
+            <Input
+              placeholder="Cari Produk..." borderRadius="md"
+              value={activeSearchSlot === index ? searchQuery : ''}
+              onFocus={() => { setActiveSearchSlot(index); setSearchQuery(''); }}
+              onChange={(e) => setSearchQuery(e.target.value)}
+            />
+            {activeSearchSlot === index && searchQuery && (
+                <InputRightElement cursor="pointer" onClick={() => { setSearchQuery(''); setActiveSearchSlot(null); }}>
+                    <Icon as={X} color="gray.400" size={14}/>
+                </InputRightElement>
+            )}
+          </InputGroup>
+
+          {activeSearchSlot === index && (
+            <Box position="absolute" top="35px" left={0} right={0} bg="white" boxShadow="lg" zIndex={10} borderRadius="md" border="1px solid" borderColor="gray.200" maxH="250px" overflowY="auto">
+              {!selectedVariant?.attribute_set_id && !mainProduct?.attribute_set_id ? (
+                <Box p={4} fontSize="xs" color="orange.600" textAlign="center" bg="orange.50">
+                  <Text fontWeight="bold" mb={1}>Perbandingan Tidak Tersedia</Text>
+                  <Text>Produk utama tidak memiliki data kategori yang valid untuk dibandingkan.</Text>
+                </Box>
+              ) : (
+                <>
+                  {isSearching ? (
+                    <Box p={4} textAlign="center"><Spinner size="sm" color="red.500" /></Box>
+                  ) : searchResults.length > 0 ? (
+                    <List spacing={0}>
+                      {searchResults.map((res) => (
+                        <ListItem
+                          key={res.id}
+                          p={3}
+                          borderBottom="1px solid #f0f0f0"
+                          _hover={{ bg: 'red.50', cursor: 'pointer' }}
+                          onClick={() => handleAddProduct(res, index)}
+                        >
+                          <Flex align="flex-start" gap={3}>
+                            <Image
+                              src={res.image || '/images/no-image-compare.svg'}
+                              boxSize="40px"
+                              objectFit="contain"
+                              onError={(e) => { (e.target as HTMLImageElement).src = '/images/no-image-compare.svg'; }}
+                              flexShrink={0}
+                              mt={1}
+                            />
+                            <Box flex={1} w="0">
+                              <Text fontSize="xs" fontWeight="bold" noOfLines={2} lineHeight="shorter" whiteSpace="normal" mb={1} title={res.displayName || res.name}>
+                                {res.displayName || res.name}
+                              </Text>
+                              <Text fontSize="xs" color="red.500" fontWeight="bold">
+                                {formatPrice(res.lowestPrice?.price || 0)}
+                              </Text>
+                            </Box>
+                          </Flex>
+                        </ListItem>
+                      ))}
+                    </List>
+                  ) : (
+                    <Box p={3} fontSize="xs" color="gray.500" textAlign="center">
+                      {searchQuery === '' ? 'Menampilkan rekomendasi...' : 'Produk tidak ditemukan.'}
+                    </Box>
+                  )}
+                </>
+              )}
+            </Box>
+          )}
+        </Box>
+
+        <Flex
+          direction="column"
+          align="center"
+          justify="center"
+          flex={1}
+          bg="gray.50"
+          borderRadius="md"
+        >
+          <Image
+            src="/images/no-image-compare.svg"
+            alt="Empty Slot"
+            boxSize="125px"
+            mb={2}
+            opacity={0.6}
+          />
+          <Text fontSize="xs" color="gray.500" textAlign="center">
+            Produk Belum Ditambahkan
+          </Text>
+        </Flex>
+      </VStack>
+    );
+  };
+
+  // --- RENDER MOBILE CONTENT ---
+  const renderMobileContent = () => {
+    const mobileProducts = products.slice(0, 2); 
+
+    return (
+      <Box pb={6}>
+        {/* Sticky Header */}
+        <Box 
+          position="sticky" top="-16px" zIndex={10} 
+          bg="white" pt={4} pb={2} mx="-16px" px="16px" 
+          borderBottom="1px solid" borderColor="gray.100" shadow="sm"
+        >
+            <Grid templateColumns="1fr 1fr" gap={4} mb={4}>
+               {mobileProducts.map((p, i) => (
+                 <GridItem key={i} position="relative">
+                    {renderProductSlot(p, i)} 
+                 </GridItem>
+               ))}
+            </Grid>
+            
+            <Flex justify="center" align="center" gap={2}>
+                <Text fontSize="md" fontWeight="bold" color="gray.700">
+                  Spesifikasi Teknis
+                </Text>
+                {/* Loader Header Hapus saja, kita pindah ke per-item */}
+            </Flex>
+        </Box>
+        
+        {/* Specs List with Loader per Line */}
+        <Box mt={4}>
+            {specsMatrix.length > 0 ? (
+               <VStack spacing={0} align="stretch" divider={<Divider />}>
+                  {specsMatrix.map((row, rIdx) => (
+                     <Box key={rIdx} py={4}>
+                        <Grid templateColumns="1fr 1fr" gap={4}>
+                           {mobileProducts.map((p, cIdx) => {
+                              const val = p ? (row.values[String(p.sku)] || '-') : '-';
+                              // Logic Loader Per Item
+                              const isItemLoading = isLoadingMatrix && p && !row.values[String(p.sku)];
+
+                              return (
+                                 <VStack key={cIdx} spacing={1} align="center">
+                                    {/* VALUE (SPINNER JIKA LOADING) */}
+                                    {isItemLoading ? (
+                                        <Spinner size="xs" color="red.500" />
+                                    ) : (
+                                        <Text fontWeight="semibold" fontSize="s" color="gray.800" textAlign="center" lineHeight="shorter">
+                                            {renderSpecValue(val)}
+                                        </Text>
+                                    )}
+                                    
+                                    {/* LABEL */}
+                                    <Text fontSize="xs" color="gray.600" fontWeight="normal" textAlign="center">
+                                       {row.label}
+                                    </Text>
+                                 </VStack>
+                              )
+                           })}
+                        </Grid>
+                     </Box>
+                  ))}
+               </VStack>
+            ) : (
+               <Box textAlign="center" py={10} color="gray.500">
+                  {isLoadingMatrix ? <VStack><Spinner color="red.500" /><Text fontSize="xs">Memuat data...</Text></VStack> : "Data spesifikasi tidak tersedia"}
+               </Box>
+            )}
+        </Box>
+      </Box>
+    );
+  };
+
+  // --- MAIN RENDER ---
+  
+  // Tampilan Mobile (Drawer 75%)
+  if (isMobile) {
+     return (
+        <Drawer isOpen={isOpen} placement="bottom" onClose={onClose}>
+           <DrawerOverlay />
+           <DrawerContent borderTopRadius="20px" h="88vh" bg="white">
+              <DrawerCloseButton zIndex={20} />
+              <DrawerHeader borderBottomWidth="1px" fontSize="md" textAlign="center">Bandingkan Produk</DrawerHeader>
+              <DrawerBody p={4} overflowY="auto">
+                 {renderMobileContent()}
+              </DrawerBody>
+           </DrawerContent>
+        </Drawer>
+     );
+  }
+
+  // Tampilan Desktop (Modal 6XL)
   return (
     <Modal isOpen={isOpen} onClose={onClose} size="6xl" scrollBehavior="inside">
       <ModalOverlay />
@@ -448,222 +740,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
             <GridItem />
             {products.map((product, index) => (
               <GridItem key={index} position="relative" minW="0">
-                {product ? (
-                  <VStack align="stretch" spacing={3} h="100%">
-                    {index !== 0 && (
-                      <IconButton
-                        aria-label="Hapus" icon={<Trash2 size={16} />}
-                        size="xs" position="absolute" top={-2} right={-2}
-                        colorScheme="red" onClick={() => handleRemoveProduct(index)} zIndex={2}
-                      />
-                    )}
-                    <Box h="160px" display="flex" alignItems="center" justifyContent="center" bg="gray.50" borderRadius="md" p={2}>
-                      <Image
-                        src={product.image || '/images/no-image-compare.svg'}
-                        alt={product.name} maxH="100%" objectFit="contain"
-                        onError={(e) => { (e.target as HTMLImageElement).src = '/images/no-image-compare.svg'; }}
-                      />
-                    </Box>
-                    <Box>
-                      <Text color="red.600" fontWeight="bold" fontSize="md">
-                        {product.price > 0 ? formatPrice(product.price) : 'Hubungi Admin'}
-                      </Text>
-                      <Text fontSize="xs" fontWeight="bold" noOfLines={3} h="45px" title={product.name} mb={2}>
-                        {product.name}
-                      </Text>
-                    </Box>
-
-                    {/* --- AUTOCOMPLETE DROPDOWN (FINAL FIX) --- */}
-                    <Box w="100%">
-                      <AutoComplete
-                        openOnFocus
-                        disableFilter={disableVariantFilter}
-                        onChange={(val) => handleVariantChange(index, val)}
-                        value={product.inputValue}
-                      >
-                        <InputGroup size="sm">
-                          <AutoCompleteInput
-                            variant="outline"
-                            fontSize="xs"
-                            borderRadius="md"
-                            placeholder="Cari Varian..."
-                            value={product.inputValue}
-                            onChange={(e) => handleInputChange(index, e.target.value)}
-                            onFocus={() => setDisableVariantFilter(true)}
-                          />
-                          <InputRightElement h="100%" pointerEvents="none">
-                            <Icon as={ChevronDown} color="gray.400" size={14} />
-                          </InputRightElement>
-                        </InputGroup>
-
-                        {/* Dropdown List dengan Style Information.tsx */}
-                        <AutoCompleteList fontSize="xs" maxH="250px" overflowY="auto" p={0}>
-                          {product.variants && product.variants.map((v: any, vIdx: number) => {
-                            
-                            // Gunakan Helper extractAttribute untuk mendapatkan teks spesifikasi
-                            // Ini akan bekerja baik untuk Slot 1 (pakai attributes) 
-                            // maupun Slot Search (parsing displayName)
-                            const attributeText = extractAttribute(v);
-                            const label = `${v.code} - ${attributeText}`;
-
-                            return (
-                              <AutoCompleteItem
-                                key={`option-${vIdx}`}
-                                value={label}
-                                textTransform="capitalize"
-                                _selected={{ bg: 'red.50', borderLeft: '3px solid red' }}
-                                _focus={{ bg: 'gray.50' }}
-                                p={2}
-                                borderBottom="1px dashed" // Style dashed border
-                                borderColor="gray.200"
-                              >
-                                <Flex justify="space-between" align="start" w="100%">
-                                  {/* KIRI: KODE & ATRIBUT */}
-                                  <Box flex={1} mr={2} overflow="hidden">
-                                    <Text fontWeight="bold" fontSize="xs" color="gray.700">
-                                      {v.code}
-                                    </Text>
-                                    <Text 
-                                      fontSize="xs" 
-                                      color="gray.500" 
-                                      noOfLines={1} 
-                                      title={attributeText}
-                                      textTransform="capitalize"
-                                    >
-                                      {attributeText}
-                                    </Text>
-                                  </Box>
-
-                                  {/* KANAN: HARGA */}
-                                  <Text 
-                                    color="red.600" 
-                                    fontWeight="bold" 
-                                    fontSize="xs" 
-                                    whiteSpace="nowrap"
-                                    bg="red.50"
-                                    px={2}
-                                    py={0.5}
-                                    borderRadius="md"
-                                    h="fit-content"
-                                  >
-                                    {formatPrice(v.price)}
-                                  </Text>
-                                </Flex>
-                              </AutoCompleteItem>
-                            );
-                          })}
-                        </AutoCompleteList>
-                      </AutoComplete>
-                    </Box>
-
-                    <HStack spacing={2}>
-                      <IconButton
-                        aria-label="Cart"
-                        icon={<Image src="/images/keranjang-compare.svg" w="15px" h="15px" objectFit="contain" />}
-                        variant="outline"
-                        colorScheme="red"
-                        size="sm"
-                      />
-                      <Button as="a" href={`/product/${product.id}`} target="_blank" colorScheme="red" size="sm" flex={1} fontSize="xs">
-                        Beli Sekarang
-                      </Button>
-                    </HStack>
-                  </VStack>
-                ) : (
-                  <VStack align="stretch" spacing={3} h="100%" position="relative">
-                    <Box position="relative" w="100%" ref={activeSearchSlot === index ? searchWrapperRef : null}>
-                      <InputGroup size="sm">
-                        <InputLeftElement pointerEvents="none"><Icon as={Search} color="gray.300" /></InputLeftElement>
-                        <Input
-                          placeholder="Cari Produk..." borderRadius="md"
-                          value={activeSearchSlot === index ? searchQuery : ''}
-                          onFocus={() => { setActiveSearchSlot(index); setSearchQuery(''); }}
-                          onChange={(e) => setSearchQuery(e.target.value)}
-                        />
-                      </InputGroup>
-
-                      {activeSearchSlot === index && (
-                        <Box position="absolute" top="35px" left={0} right={0} bg="white" boxShadow="lg" zIndex={10} borderRadius="md" border="1px solid" borderColor="gray.200" maxH="250px" overflowY="auto">
-                          {!selectedVariant?.attribute_set_id && !mainProduct?.attribute_set_id ? (
-                            <Box p={4} fontSize="xs" color="orange.600" textAlign="center" bg="orange.50">
-                              <Text fontWeight="bold" mb={1}>Perbandingan Tidak Tersedia</Text>
-                              <Text>Produk utama tidak memiliki data kategori yang valid untuk dibandingkan.</Text>
-                            </Box>
-                          ) : (
-                            <>
-                              {isSearching ? (
-                                <Box p={4} textAlign="center"><Spinner size="sm" color="red.500" /></Box>
-                              ) : searchResults.length > 0 ? (
-                                <List spacing={0}>
-                                  {searchResults.map((res) => (
-                                    <ListItem
-                                      key={res.id}
-                                      p={3}
-                                      borderBottom="1px solid #f0f0f0"
-                                      _hover={{ bg: 'red.50', cursor: 'pointer' }}
-                                      onClick={() => handleAddProduct(res, index)}
-                                    >
-                                      <Flex align="flex-start" gap={3}>
-                                        <Image
-                                          src={res.image || '/images/no-image-compare.svg'}
-                                          boxSize="40px"
-                                          objectFit="contain"
-                                          onError={(e) => { (e.target as HTMLImageElement).src = '/images/no-image-compare.svg'; }}
-                                          flexShrink={0}
-                                          mt={1}
-                                        />
-                                        <Box flex={1} w="0">
-                                          <Text
-                                            fontSize="xs"
-                                            fontWeight="bold"
-                                            noOfLines={2}
-                                            lineHeight="shorter"
-                                            whiteSpace="normal"
-                                            mb={1}
-                                            title={res.displayName || res.name}
-                                          >
-                                            {res.displayName || res.name}
-                                          </Text>
-                                          <Text fontSize="xs" color="red.500" fontWeight="bold">
-                                            {formatPrice(res.lowestPrice?.price || 0)}
-                                          </Text>
-                                        </Box>
-                                      </Flex>
-                                    </ListItem>
-                                  ))}
-                                </List>
-                              ) : (
-                                <Box p={3} fontSize="xs" color="gray.500" textAlign="center">
-                                  {searchQuery === '' ? 'Menampilkan rekomendasi...' : 'Produk tidak ditemukan.'}
-                                </Box>
-                              )}
-                            </>
-                          )}
-                        </Box>
-                      )}
-                    </Box>
-
-                    <Flex
-                      direction="column"
-                      align="center"
-                      justify="center"
-                      flex={1}
-                      bg="gray.50"
-                      borderRadius="md"
-                    >
-                      <Image
-                        src="/images/no-image-compare.svg"
-                        alt="Empty Slot"
-                        boxSize="125px"
-                        mb={2}
-                        opacity={0.6}
-                      />
-                      <Text fontSize="xs" color="gray.500" textAlign="center">
-                        Produk Belum Ditambahkan
-                      </Text>
-                    </Flex>
-                  </VStack>
-                )}
+                {renderProductSlot(product, index)}
               </GridItem>
             ))}
 
-- 
cgit v1.2.3

