summaryrefslogtreecommitdiff
path: root/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src-migrate/modules/product-detail/components/ProductComparisonModal.tsx')
-rw-r--r--src-migrate/modules/product-detail/components/ProductComparisonModal.tsx145
1 files changed, 126 insertions, 19 deletions
diff --git a/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx b/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
index bc4c5415..4f1fcd82 100644
--- a/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
+++ b/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
@@ -100,7 +100,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
const variantOptions = mainProduct.variants?.map((v: any) => ({
id: v.id,
code: v.default_code || v.code || v.sku,
- name: v.name,
+ name: v.name || v.displayName || v.display_name,
price: v.price?.price || v.price || 0,
image: v.image
})) || [];
@@ -115,11 +115,13 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
});
}
+ const displayName = activeItem.name || activeItem.displayName || mainProduct.name;
+
const productSlot1 = {
id: targetId,
sku: targetId,
realCode: displayCode,
- name: mainProduct.name,
+ name: displayName,
price: activeItem.price?.price || activeItem.price || mainProduct.lowest_price?.price || 0,
image: activeItem.image || mainProduct.image,
variants: variantOptions
@@ -230,6 +232,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
...currentProduct,
id: selectedVar.id,
sku: selectedVar.id,
+ name: selectedVar.name,
realCode: selectedVar.code,
price: selectedVar.price,
image: selectedVar.image
@@ -238,21 +241,55 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
}
};
- const handleAddProduct = (searchItem: any, slotIndex: number) => {
- const newProducts = [...products];
-
- const idToAdd = searchItem.id;
- const codeToAdd = searchItem.code;
- const nameToAdd = searchItem.displayName || searchItem.name;
- const imageToAdd = searchItem.image;
- const priceToAdd = searchItem.lowestPrice?.price || 0;
- if (newProducts.find(p => p && String(p.id) === String(idToAdd))) {
+
+ const handleAddProduct = async (searchItem: any, slotIndex: number) => {
+
+ if (products.find(p => p && String(p.id) === String(searchItem.id))) {
toast({ title: "Produk sudah ada", status: "warning", position: "top" });
return;
}
- newProducts[slotIndex] = {
+ const idToAdd = searchItem.id;
+ const codeToAdd = searchItem.defaultCode || searchItem.default_code || searchItem.code;
+ const nameToAdd = searchItem.displayName || searchItem.name;
+ const imageToAdd = searchItem.image || searchItem.imageS || searchItem.image_s;
+ const priceToAdd = searchItem.lowestPrice?.price || searchItem.priceTier1V2F || searchItem.price || 0;
+
+ let parentId = searchItem.templateId ||
+ searchItem.templateIdI ||
+ searchItem.template_id_i ||
+ searchItem.template_id;
+
+ if (!parentId) {
+ try {
+ const checkParams = new URLSearchParams({
+ source: 'upsell',
+ q: '*:*',
+ fq: `id:${idToAdd}`
+ });
+
+ const checkRes = await fetch(`/api/shop/search?${checkParams.toString()}`);
+ if (checkRes.ok) {
+ const checkData = await checkRes.json();
+ const freshItem = checkData.response?.products?.[0];
+
+ if (freshItem) {
+ const serverReturnedId = freshItem.id;
+ if (String(serverReturnedId) !== String(idToAdd)) {
+ parentId = serverReturnedId;
+ } else {
+ parentId = freshItem.templateId || freshItem.templateIdI || idToAdd;
+ }
+ }
+ }
+ } catch (e) {
+ console.error("Gagal validasi parent:", e);
+ parentId = idToAdd;
+ }
+ }
+
+ const newProductEntry = {
id: idToAdd,
sku: idToAdd,
realCode: codeToAdd,
@@ -268,10 +305,59 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
}]
};
- setProducts(newProducts);
+ setProducts((prev) => {
+ const newSlots = [...prev];
+ newSlots[slotIndex] = newProductEntry;
+ return newSlots;
+ });
+
setActiveSearchSlot(null);
setSearchQuery('');
setSearchResults([]);
+
+ if (parentId) {
+ try {
+ const params = new URLSearchParams({
+ source: 'upsell',
+ limit: '100',
+ fq: `template_id_i:${parentId}`
+ });
+
+ const res = await fetch(`/api/shop/search?${params.toString()}`);
+
+ if (res.ok) {
+ const data = await res.json();
+ const siblings = data.response?.products || [];
+
+ if (siblings.length > 0) {
+ const allVariants = siblings.map((s: any) => ({
+ id: s.variantId || s.productIdI || s.id,
+ code: s.defaultCode || s.default_code || s.code,
+ name: s.displayName || s.name || s.nameS,
+ price: s.lowestPrice?.price || s.priceTier1V2F || 0,
+ image: s.image || s.imageS
+ }));
+
+ allVariants.sort((a: any, b: any) =>
+ String(a.code).localeCompare(String(b.code))
+ );
+
+ setProducts((prev) => {
+ const updated = [...prev];
+ if (updated[slotIndex] && String(updated[slotIndex].id) === String(idToAdd)) {
+ updated[slotIndex] = {
+ ...updated[slotIndex],
+ variants: allVariants
+ };
+ }
+ return updated;
+ });
+ }
+ }
+ } catch (error) {
+ console.error("Gagal fetch variant lain:", error);
+ }
+ }
};
const handleRemoveProduct = (index: number) => {
@@ -387,15 +473,36 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
{searchResults.map((res) => (
<ListItem
key={res.id}
- p={2} borderBottom="1px solid #f0f0f0"
+ p={3}
+ borderBottom="1px solid #f0f0f0"
_hover={{ bg: 'red.50', cursor: 'pointer' }}
onClick={() => handleAddProduct(res, index)}
>
- <Flex align="center" gap={2}>
- <Image src={res.image || '/images/no-image-compare.svg'} boxSize="30px" objectFit="contain" onError={(e) => { (e.target as HTMLImageElement).src = '/images/no-image-compare.svg'; }} />
- <Box>
- <Text fontSize="xs" fontWeight="bold" noOfLines={1}>{res.displayName || res.name}</Text>
- <Text fontSize="xs" color="red.500">
+ <Flex align="flex-start" gap={3}> {/* Align top biar rapi kalau teks panjang */}
+ {/* GAMBAR */}
+ <Image
+ src={res.image || '/images/no-image-compare.svg'}
+ boxSize="40px" // Gambar sedikit dibesarkan
+ objectFit="contain"
+ onError={(e) => { (e.target as HTMLImageElement).src = '/images/no-image-compare.svg'; }}
+ flexShrink={0} // Mencegah gambar gepeng
+ mt={1}
+ />
+
+ {/* TEXT CONTAINER */}
+ <Box flex={1} w="0"> {/* w="0" adalah trik CSS agar text-overflow bekerja di dalam Flex */}
+ <Text
+ fontSize="xs"
+ fontWeight="bold"
+ noOfLines={2} // [SOLUSI UTAMA] Ijinkan maksimal 2 baris
+ lineHeight="shorter" // Spasi antar baris dirapatkan
+ whiteSpace="normal" // Pastikan text wrapping aktif
+ mb={1}
+ title={res.displayName || res.name} // Menampilkan tooltip native saat hover
+ >
+ {res.displayName || res.name}
+ </Text>
+ <Text fontSize="xs" color="red.500" fontWeight="bold">
{formatPrice(res.lowestPrice?.price || 0)}
</Text>
</Box>