From 0c745c513765b23ee200eb61ebfe13086a1ea700 Mon Sep 17 00:00:00 2001
From: FIN-IT_AndriFP <andrifebriyadiputra@gmail.com>
Date: Tue, 16 Dec 2025 15:57:30 +0700
Subject: (andri) try search with q* solr

---
 .../components/ProductComparisonModal.tsx          | 133 ++++++++-------------
 1 file changed, 50 insertions(+), 83 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 a58ad5b2..3ee61c9d 100644
--- a/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
+++ b/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
@@ -80,6 +80,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
       }
 
       const targetId = activeItem.id;
+      // Ambil code dari properti yang tersedia
       const displayCode = activeItem.default_code || activeItem.code || activeItem.sku || mainProduct.default_code || mainProduct.code;
 
       const variantOptions = mainProduct.variants?.map((v: any) => ({
@@ -102,8 +103,8 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
 
       const productSlot1 = {
          id: targetId,
-         sku: targetId, // ID untuk API
-         realCode: displayCode, 
+         sku: targetId, // ID untuk API & Key
+         realCode: displayCode, // String untuk Tampilan
          name: mainProduct.name, 
          price: activeItem.price?.price || activeItem.price || mainProduct.lowest_price?.price || 0,
          image: activeItem.image || mainProduct.image,
@@ -130,6 +131,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
     const fetchSpecs = async () => {
         setIsLoadingMatrix(true);
         try {
+            // Kirim ID ke API
             const allSkus = validProducts.map(p => p.sku).join(',');
             const mainSku = validProducts[0]?.sku;
 
@@ -151,7 +153,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
   }, [products, isOpen]);
 
   // ===========================================================================
-  // 3. SEARCH LOGIC
+  // 3. SEARCH LOGIC (MATCHED WITH API JSON)
   // ===========================================================================
   useEffect(() => {
      const delayDebounceFn = setTimeout(async () => {
@@ -163,16 +165,21 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
         setIsSearching(true);
         try {
             const attrSetId = selectedVariant?.attribute_set_id || mainProduct?.attribute_set_id;
+            
             const params = new URLSearchParams({
                 source: 'compare',
-                q: searchQuery,
+                q: '*',
                 limit: '5',
+                // Filter kategori aktif agar Apple-to-Apple
                 fq: attrSetId ? `attribute_set_id_i:${attrSetId}` : ''
             });
 
-            const res = await fetch(`/api/search?${params.toString()}`);
+            // Gunakan endpoint yang benar: /api/shop/search
+            const res = await fetch(`/api/shop/search?${params.toString()}`);
+            
             if (res.ok) {
                 const data = await res.json();
+                // Data sudah CamelCase dari Backend
                 setSearchResults(data.response?.products || []);
             } else {
                 setSearchResults([]);
@@ -210,12 +217,19 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
       }
   };
 
-  const handleAddProduct = (solrProduct: any, slotIndex: number) => {
+  const handleAddProduct = (searchItem: any, slotIndex: number) => {
       const newProducts = [...products];
       
-      const idToAdd = solrProduct.product_id_i || solrProduct.id;
-      const codeToAdd = solrProduct.default_code_s || solrProduct.sku;
+      // [FIX] MAPPING DARI JSON API ANDA (CAMELCASE)
+      // JSON: { id: 88019, code: "RX-SP0006", displayName: "...", lowestPrice: { price: ... } }
+      
+      const idToAdd = searchItem.id;
+      const codeToAdd = searchItem.code; // Langsung 'code', bukan 'default_code_s'
+      const nameToAdd = searchItem.displayName || searchItem.name;
+      const imageToAdd = searchItem.image;
+      const priceToAdd = searchItem.lowestPrice?.price || 0; 
 
+      // Cek Duplikat
       if (newProducts.find(p => p && String(p.id) === String(idToAdd))) {
           toast({ title: "Produk sudah ada", status: "warning", position: "top" });
           return;
@@ -223,17 +237,17 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
 
       newProducts[slotIndex] = {
           id: idToAdd,
-          sku: idToAdd, 
-          realCode: codeToAdd,
-          name: solrProduct.display_name_s || solrProduct.name_s,
-          price: solrProduct.price_tier1_v2_f || 0,
-          image: solrProduct.image_s,
+          sku: idToAdd, // ID untuk API
+          realCode: codeToAdd, // Code String untuk Tampilan
+          name: nameToAdd,
+          price: priceToAdd,
+          image: imageToAdd,
           variants: [{
               id: idToAdd,
               code: codeToAdd,
-              name: solrProduct.name_s,
-              price: solrProduct.price_tier1_v2_f,
-              image: solrProduct.image_s
+              name: nameToAdd,
+              price: priceToAdd,
+              image: imageToAdd
           }]
       };
 
@@ -269,17 +283,11 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
 
         <ModalBody p={6} bg="white">
           <Grid templateColumns="200px repeat(4, 1fr)" gap={4}>
-            
-            {/* Cell 1: Kosong */}
             <GridItem />
-
-            {/* Loop Slot Produk */}
             {products.map((product, index) => (
               <GridItem key={index} position="relative" minW="0">
                 {product ? (
                   <VStack align="stretch" spacing={3} h="100%">
-                    
-                    {/* Tombol Hapus */}
                     {index !== 0 && (
                         <IconButton 
                             aria-label="Hapus" icon={<Trash2 size={16}/>} 
@@ -287,46 +295,33 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
                             colorScheme="red" onClick={() => handleRemoveProduct(index)} zIndex={2}
                         />
                     )}
-
-                    {/* Gambar */}
                     <Box h="160px" display="flex" alignItems="center" justifyContent="center" bg="gray.50" borderRadius="md" p={2}>
                       <Image 
                         src={product.image || '/images/noimage.jpeg'} 
-                        alt={product.name} 
-                        maxH="100%" objectFit="contain" 
-                        onError={(e) => { (e.target as HTMLImageElement).src = '/images/noimage.jpeg'; }}
+                        alt={product.name} maxH="100%" objectFit="contain" 
+                        onError={(e) => { (e.target as HTMLImageElement).src = '/images/no-image-compare.svg'; }}
                       />
                     </Box>
-
-                    {/* Info Harga & Nama */}
                     <Box>
                       <Text color="red.600" fontWeight="bold" fontSize="md">
                         {product.price > 0 ? formatPrice(product.price) : 'Hubungi Admin'}
                       </Text>
-                      {/* Margin Bottom agar tidak tertutup dropdown */}
                       <Text fontSize="xs" fontWeight="bold" noOfLines={2} h="35px" title={product.name} mb={2}>
                         {product.name}
                       </Text>
                     </Box>
-
-                    {/* Dropdown Varian */}
+                    
                     <Select 
-                        size="sm" 
-                        borderRadius="md" 
-                        fontSize="xs"
+                        size="sm" borderRadius="md" fontSize="xs"
                         value={product.id} 
                         onChange={(e) => handleVariantChange(index, e.target.value)}
-                        isDisabled={false} 
-                        bg="white"
+                        isDisabled={false} bg="white"
                     >
                         {product.variants && product.variants.map((v: any) => (
-                            <option key={v.id} value={v.id}>
-                                {v.code}
-                            </option>
+                            <option key={v.id} value={v.id}>{v.code}</option>
                         ))}
                     </Select>
 
-                    {/* Tombol */}
                     <HStack spacing={2}>
                         <IconButton aria-label="Cart" icon={<Icon as={ShoppingCart} />} variant="outline" colorScheme="red" size="sm" />
                         <Button as="a" href={`/product/${product.id}`} target="_blank" colorScheme="red" size="sm" flex={1} fontSize="xs">
@@ -335,7 +330,6 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
                     </HStack>
                   </VStack>
                 ) : (
-                  // SLOT KOSONG
                   <VStack align="stretch" spacing={3} h="100%" position="relative">
                      <InputGroup size="sm">
                       <InputLeftElement pointerEvents="none"><Icon as={Search} color="gray.300" /></InputLeftElement>
@@ -347,6 +341,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
                       />
                     </InputGroup>
 
+                    {/* --- HASIL SEARCH (MAPPING FIX) --- */}
                     {activeSearchSlot === index && searchQuery.length > 0 && (
                         <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">
                             {isSearching ? (
@@ -355,16 +350,20 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
                                 <List spacing={0}>
                                     {searchResults.map((res) => (
                                         <ListItem 
-                                            key={res.product_id_i || res.id} 
+                                            key={res.id} 
                                             p={2} borderBottom="1px solid #f0f0f0" 
                                             _hover={{ bg: 'red.50', cursor: 'pointer' }}
                                             onClick={() => handleAddProduct(res, index)}
                                         >
                                             <Flex align="center" gap={2}>
-                                                <Image src={res.image_s || '/images/noimage.jpeg'} boxSize="30px" objectFit="contain" onError={(e) => { (e.target as HTMLImageElement).src = '/images/noimage.jpeg'; }} />
+                                                <Image src={res.image || '/images/noimage.jpeg'} boxSize="30px" objectFit="contain" onError={(e) => { (e.target as HTMLImageElement).src = '/images/noimage.jpeg'; }} />
                                                 <Box>
-                                                    <Text fontSize="xs" fontWeight="bold" noOfLines={1}>{res.display_name_s || res.name_s}</Text>
-                                                    <Text fontSize="xs" color="red.500">{formatPrice(res.price_tier1_v2_f || 0)}</Text>
+                                                    {/* [FIX] Gunakan displayName atau name */}
+                                                    <Text fontSize="xs" fontWeight="bold" noOfLines={1}>{res.displayName || res.name}</Text>
+                                                    {/* [FIX] Gunakan lowestPrice.price */}
+                                                    <Text fontSize="xs" color="red.500">
+                                                        {formatPrice(res.lowestPrice?.price || 0)}
+                                                    </Text>
                                                 </Box>
                                             </Flex>
                                         </ListItem>
@@ -385,51 +384,22 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
               </GridItem>
             ))}
 
-            {/* --- BAGIAN SPESIFIKASI --- */}
             <GridItem colSpan={5} py={6}>
-               <Box borderBottom="2px solid" borderColor="gray.100" pb={2}>
-                  <Text fontSize="lg" fontWeight="bold">Spesifikasi Teknis</Text>
-               </Box>
+               <Box borderBottom="2px solid" borderColor="gray.100" pb={2}><Text fontSize="lg" fontWeight="bold">Spesifikasi Teknis</Text></Box>
             </GridItem>
 
             {isLoadingMatrix ? (
-                 <GridItem colSpan={5} textAlign="center" py={10}>
-                     <Spinner color="red.500" thickness="4px" size="xl" />
-                     <Text mt={2} color="gray.500">Memuat data...</Text>
-                 </GridItem>
+                 <GridItem colSpan={5} textAlign="center" py={10}><Spinner color="red.500" thickness="4px" size="xl" /><Text mt={2} color="gray.500">Memuat data...</Text></GridItem>
             ) : specsMatrix.length > 0 ? (
                 specsMatrix.map((row, rowIndex) => (
                   <React.Fragment key={row.code || rowIndex}>
-                    {/* Label (Kiri) */}
-                    <GridItem 
-                        py={3} 
-                        px={2}
-                        borderBottom="1px solid" 
-                        borderColor="gray.100" 
-                        bg={rowIndex % 2 !== 0 ? "white" : "gray.50"}
-                        display="flex"
-                        alignItems="center"
-                    >
+                    <GridItem py={3} px={2} borderBottom="1px solid" borderColor="gray.100" bg={rowIndex % 2 !== 0 ? "white" : "gray.50"} display="flex" alignItems="center">
                       <Text fontWeight="bold" fontSize="sm" color="gray.700">{row.label}</Text>
                     </GridItem>
-
-                    {/* Value (Rata Tengah) */}
                     {products.map((product, colIndex) => {
                         const val = product ? (row.values[String(product.sku)] || '-') : '';
-                        
                         return (
-                          <GridItem 
-                            key={`${row.code}-${colIndex}`} 
-                            py={3} 
-                            px={2}
-                            borderBottom="1px solid" 
-                            borderColor="gray.100" 
-                            bg={rowIndex % 2 !== 0 ? "white" : "gray.50"}
-                            display="flex" // [FIX] Flex untuk centering
-                            alignItems="center" // [FIX] Vertical Center
-                            justifyContent="center" // [FIX] Horizontal Center
-                            textAlign="center" // [FIX] Text Align Center
-                          >
+                          <GridItem key={`${row.code}-${colIndex}`} py={3} px={2} borderBottom="1px solid" borderColor="gray.100" bg={rowIndex % 2 !== 0 ? "white" : "gray.50"} display="flex" alignItems="center" justifyContent="center" textAlign="center">
                             <Text fontSize="sm" color="gray.600">{renderSpecValue(val)}</Text>
                           </GridItem>
                         );
@@ -437,11 +407,8 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
                   </React.Fragment>
                 ))
             ) : (
-                <GridItem colSpan={5} py={10} textAlign="center" color="gray.500" bg="gray.50">
-                    <Text>Data spesifikasi belum tersedia untuk produk ini.</Text>
-                </GridItem>
+                <GridItem colSpan={5} py={10} textAlign="center" color="gray.500" bg="gray.50"><Text>Data spesifikasi belum tersedia untuk produk ini.</Text></GridItem>
             )}
-
           </Grid>
         </ModalBody>
       </ModalContent>
-- 
cgit v1.2.3

