diff options
| author | Mqdd <ahmadmiqdad27@gmail.com> | 2026-01-31 23:48:37 +0700 |
|---|---|---|
| committer | Mqdd <ahmadmiqdad27@gmail.com> | 2026-01-31 23:48:37 +0700 |
| commit | dc14a5fd2c97d50b19b043a44d61786d98fda48b (patch) | |
| tree | 585d7fff4f656b510baa8e8e2d8c5ca9df9aaa81 /src-migrate/modules/product-detail/components/Information.tsx | |
| parent | 8c6f1b3bf6eac52041337b33e746888933e1e34a (diff) | |
<Miqdad> remove console log
Diffstat (limited to 'src-migrate/modules/product-detail/components/Information.tsx')
| -rw-r--r-- | src-migrate/modules/product-detail/components/Information.tsx | 393 |
1 files changed, 248 insertions, 145 deletions
diff --git a/src-migrate/modules/product-detail/components/Information.tsx b/src-migrate/modules/product-detail/components/Information.tsx index ce848267..757cd473 100644 --- a/src-migrate/modules/product-detail/components/Information.tsx +++ b/src-migrate/modules/product-detail/components/Information.tsx @@ -12,7 +12,16 @@ import { useEffect, useRef, useState } from 'react'; import axios from 'axios'; import currencyFormat from '@/core/utils/currencyFormat'; -import { InputGroup, InputRightElement, SimpleGrid, Flex, Text, Box, Center, Icon } from '@chakra-ui/react'; +import { + InputGroup, + InputRightElement, + SimpleGrid, + Flex, + Text, + Box, + Center, + Icon, +} from '@chakra-ui/react'; import { ChevronDownIcon } from '@heroicons/react/24/outline'; import ImageNext from 'next/image'; import { formatToShortText } from '~/libs/formatNumber'; @@ -28,7 +37,7 @@ import MobileView from '@/core/components/views/MobileView'; // Pastikan path im import ProductComparisonModal from './ProductComparisonModal'; const Skeleton = dynamic(() => - import('@chakra-ui/react').then((mod) => mod.Skeleton) + import('@chakra-ui/react').then((mod) => mod.Skeleton), ); type Props = { @@ -36,7 +45,8 @@ type Props = { }; const Information = ({ product }: Props) => { - const { selectedVariant, setSelectedVariant, setSla, sla } = useProductDetail(); + const { selectedVariant, setSelectedVariant, setSla, sla } = + useProductDetail(); const [inputValue, setInputValue] = useState<string>(''); const [disableFilter, setDisableFilter] = useState<boolean>(false); @@ -45,7 +55,7 @@ const Information = ({ product }: Props) => { // source of truth // const variantOptions = product.variants; const [variantOptions, setVariantOptions] = useState<any[]>( - product?.variants + product?.variants, ); const variantId = selectedVariant?.id; @@ -59,25 +69,25 @@ const Information = ({ product }: Props) => { useEffect(() => { const fetchWarrantyDirectly = async () => { - if (!product?.variants || product.variants.length === 0) return; - - setLoadingWarranty(true); - try { - const skus = product.variants.map((v) => v.id).join(','); - const mainSku = product.variants[0].id; - - const res = await axios.get('/api/magento-product', { - params: { skus, main_sku: mainSku } - }); - - if (res.data && res.data.warranties) { - setWarranties(res.data.warranties); - } - } catch (error) { - console.error("Gagal ambil garansi:", error); - } finally { - setLoadingWarranty(false); - } + if (!product?.variants || product.variants.length === 0) return; + + setLoadingWarranty(true); + try { + const skus = product.variants.map((v) => v.id).join(','); + const mainSku = product.variants[0].id; + + const res = await axios.get('/api/magento-product', { + params: { skus, main_sku: mainSku }, + }); + + if (res.data && res.data.warranties) { + setWarranties(res.data.warranties); + } + } catch (error) { + // console.error("Gagal ambil garansi:", error); + } finally { + setLoadingWarranty(false); + } }; fetchWarrantyDirectly(); @@ -90,7 +100,7 @@ const Information = ({ product }: Props) => { selectedVariant.code + (selectedVariant.attributes?.[0] ? ` - ${selectedVariant.attributes[0]}` - : '') + : ''), ); }, [selectedVariant]); @@ -114,14 +124,14 @@ const Information = ({ product }: Props) => { setDisableFilter(true); let code = vals.replace(/\s-\s.*$/, '').trim(); let variant = product?.variants.find((item) => item.code === code); - + if (variant) { setSelectedVariant(variant); setInputValue( variant?.code + - (variant?.attributes[0] ? ' - ' + variant?.attributes[0] : '') + (variant?.attributes[0] ? ' - ' + variant?.attributes[0] : ''), ); - setVariantOptions(product?.variants); + setVariantOptions(product?.variants); } }; @@ -135,7 +145,7 @@ const Information = ({ product }: Props) => { fontSize: '13px', borderBottom: '1px dashed #e2e8f0', padding: '8px 0', - marginBottom: '0px' + marginBottom: '0px', }; return ( @@ -173,96 +183,126 @@ const Information = ({ product }: Props) => { <AutoCompleteList> {variantOptions .sort((a: any, b: any) => { - return a.code.localeCompare(b.code, undefined, { numeric: true, sensitivity: 'base' }); + return a.code.localeCompare(b.code, undefined, { + numeric: true, + sensitivity: 'base', + }); }) .map((option, cid) => ( - <AutoCompleteItem - key={option.id} - // value={String(option.id)} - value={option.code + - (option.attributes?.[0] ? ` - ${option.attributes[0]}` : '') - } - _selected={ - option.id === selectedVariant?.id - ? { bg: 'gray.300' } - : undefined - } - > - <div className='flex gap-x-2 w-full justify-between px-3 items-center p-2'> - <div className='text-small'> - {option.code} - {option.attributes?.[0] ? ` - ${option.attributes[0]}` : ''} - </div> - <div className={option?.price?.discount_percentage ? 'flex gap-x-4 items-center justify-between' : ''}> - {option?.price?.discount_percentage > 0 && ( - <> - <div className='badge-solid-red text-xs'> - {Math.floor(option.price.discount_percentage)}% - </div> - <div className='min-w-16 sm:min-w-24 text-gray_r-11 line-through text-[11px] sm:text-caption-2'> - {currencyFormat(option.price.price)} - </div> - </> - )} - <div className='min-w-20 sm:min-w-28 text-danger-500 font-semibold'> - {currencyFormat(option.price.price_discount)} + <AutoCompleteItem + key={option.id} + // value={String(option.id)} + value={ + option.code + + (option.attributes?.[0] ? ` - ${option.attributes[0]}` : '') + } + _selected={ + option.id === selectedVariant?.id + ? { bg: 'gray.300' } + : undefined + } + > + <div className='flex gap-x-2 w-full justify-between px-3 items-center p-2'> + <div className='text-small'> + {option.code} + {option.attributes?.[0] + ? ` - ${option.attributes[0]}` + : ''} + </div> + <div + className={ + option?.price?.discount_percentage + ? 'flex gap-x-4 items-center justify-between' + : '' + } + > + {option?.price?.discount_percentage > 0 && ( + <> + <div className='badge-solid-red text-xs'> + {Math.floor(option.price.discount_percentage)}% + </div> + <div className='min-w-16 sm:min-w-24 text-gray_r-11 line-through text-[11px] sm:text-caption-2'> + {currencyFormat(option.price.price)} + </div> + </> + )} + <div className='min-w-20 sm:min-w-28 text-danger-500 font-semibold'> + {currencyFormat(option.price.price_discount)} + </div> </div> </div> - </div> - </AutoCompleteItem> - ))} + </AutoCompleteItem> + ))} </AutoCompleteList> </AutoComplete> {/* === TOMBOL BANDINGKAN PRODUK (HANYA MOBILE) === */} <MobileView> - <div - className="w-full flex items-center justify-between py-3 px-1 mt-3 bg-white border-t border-b border-black-100 cursor-pointer hover:bg-gray-50 transition-colors group" - onClick={() => setIsCompareOpen(true)} - > - <div className="flex items-center gap-3"> - <div className="bg-red-50 p-2 rounded-full group-hover:bg-red-100 transition-colors"> - <ImageNext src="/images/logo-bandingkan.svg" width={15} height={15} alt="bandingkan" /> - </div> - <div className="flex flex-col"> - <span className="text-sm font-bold text-gray-800">Bandingkan Produk</span> - <span className="text-xs text-gray-500">Coba bandingkan dengan produk lainnya</span> - </div> - </div> - <div className="flex items-center gap-2"> - <span className="bg-red-600 text-white text-[10px] font-bold px-2 py-0.5 rounded-full">Baru</span> - <Icon as={ChevronDownIcon} className="w-4 h-4 text-gray-400 transform -rotate-90" /> - </div> + <div + className='w-full flex items-center justify-between py-3 px-1 mt-3 bg-white border-t border-b border-black-100 cursor-pointer hover:bg-gray-50 transition-colors group' + onClick={() => setIsCompareOpen(true)} + > + <div className='flex items-center gap-3'> + <div className='bg-red-50 p-2 rounded-full group-hover:bg-red-100 transition-colors'> + <ImageNext + src='/images/logo-bandingkan.svg' + width={15} + height={15} + alt='bandingkan' + /> + </div> + <div className='flex flex-col'> + <span className='text-sm font-bold text-gray-800'> + Bandingkan Produk + </span> + <span className='text-xs text-gray-500'> + Coba bandingkan dengan produk lainnya + </span> + </div> + </div> + <div className='flex items-center gap-2'> + <span className='bg-red-600 text-white text-[10px] font-bold px-2 py-0.5 rounded-full'> + Baru + </span> + <Icon + as={ChevronDownIcon} + className='w-4 h-4 text-gray-400 transform -rotate-90' + /> </div> + </div> </MobileView> {/* Render Modal (Logic open/close ada di dalam component) */} {isCompareOpen && ( - <ProductComparisonModal - isOpen={isCompareOpen} - onClose={() => setIsCompareOpen(false)} - mainProduct={product} - selectedVariant={selectedVariant} - /> + <ProductComparisonModal + isOpen={isCompareOpen} + onClose={() => setIsCompareOpen(false)} + mainProduct={product} + selectedVariant={selectedVariant} + /> )} </div> {/* ITEM CODE */} <div className={style['row']} style={rowStyle}> - <div className={style['label']} style={{ color: '#6b7280' }}>Item Code</div> + <div className={style['label']} style={{ color: '#6b7280' }}> + Item Code + </div> <div className={style['value']}>{selectedVariant?.code}</div> </div> {/* MANUFACTURE */} <div className={style['row']} style={rowStyle}> - <div className={style['label']} style={{ color: '#6b7280' }}>Manufacture</div> + <div className={style['label']} style={{ color: '#6b7280' }}> + Manufacture + </div> <div className={style['value']}> {!!product.manufacture.name ? ( <Link href={createSlug( '/shop/brands/', product.manufacture.name, - product.manufacture.id.toString() + product.manufacture.id.toString(), )} > {product?.manufacture.logo ? ( @@ -287,81 +327,144 @@ const Information = ({ product }: Props) => { {/* BERAT BARANG */} <div className={style['row']} style={rowStyle}> - <div className={style['label']} style={{ color: '#6b7280' }}>Berat Barang</div> + <div className={style['label']} style={{ color: '#6b7280' }}> + Berat Barang + </div> <div className={style['value']}> {selectedVariant?.weight > 0 ? `${selectedVariant.weight} Kg` : '-'} </div> </div> {/* TERJUAL */} - <div className={style['row']} style={{ ...rowStyle, borderBottom: 'none' }}> - <div className={style['label']} style={{ color: '#6b7280' }}>Terjual</div> + <div + className={style['row']} + style={{ ...rowStyle, borderBottom: 'none' }} + > + <div className={style['label']} style={{ color: '#6b7280' }}> + Terjual + </div> <div className={style['value']}> {product.qty_sold > 0 ? formatToShortText(product.qty_sold) : '-'} </div> </div> {/* === DETAIL INFORMASI PRODUK === */} - <div className="mt-6 border-t pt-4"> - <h2 className="hidden md:block font-bold text-gray-800 text-sm mb-4"> + <div className='mt-6 border-t pt-4'> + <h2 className='hidden md:block font-bold text-gray-800 text-sm mb-4'> Detail Informasi Produk </h2> - + <SimpleGrid columns={{ base: 3, md: 3 }} spacing={{ base: 2, md: 10 }}> - <Flex - direction={{ base: 'column', md: 'row' }} - align="center" - textAlign={{ base: 'center', md: 'left' }} - gap={{ base: 2, md: 3 }} - > - <img src="/images/produk_asli.svg" alt="Distributor Resmi" className="w-8 h-8 md:w-10 md:h-10 shrink-0" /> - <Box> - <Text fontSize={{ base: "10px", md: "11px" }} color="gray.500" lineHeight="short" mb="1px">Distributor Resmi</Text> - <Text fontSize={{ base: "10px", md: "12px" }} fontWeight="bold" color="gray.800" lineHeight="1.2">Jaminan Produk Asli</Text> - </Box> - </Flex> - - <Flex - direction={{ base: 'column', md: 'row' }} - align="center" - textAlign={{ base: 'center', md: 'left' }} - gap={{ base: 2, md: 3 }} - > - <img src="/images/estimasi.svg" alt="Estimasi Penyiapan" className="w-8 h-8 md:w-9 md:h-9 shrink-0" /> - <Box> - <Text fontSize={{ base: "10px", md: "11px" }} color="gray.500" lineHeight="short" mb="1px">Estimasi Penyiapan</Text> - {isLoading ? ( - <Center><Skeleton height="10px" width="50px" mt="2px" /></Center> - ) : ( - <Text fontSize={{ base: "10px", md: "12px" }} fontWeight="bold" color="gray.800" lineHeight="1.2"> - {sla?.sla_date || '-'} - </Text> - )} - </Box> - </Flex> - - <Flex - direction={{ base: 'column', md: 'row' }} - align="center" - textAlign={{ base: 'center', md: 'left' }} - gap={{ base: 2, md: 3 }} - > - <img src="/images/garansi.svg" alt="Garansi Produk" className="w-8 h-8 md:w-10 md:h-10 shrink-0" /> - <Box> - <Text fontSize={{ base: "10px", md: "11px" }} color="gray.500" lineHeight="short" mb="1px">Garansi Produk</Text> - {loadingWarranty ? ( - <Center><Skeleton height="10px" width="50px" mt="2px" /></Center> - ) : ( - <Text fontSize={{ base: "10px", md: "12px" }} fontWeight="bold" color="gray.800" lineHeight="1.2"> - {selectedVariant && warranties[selectedVariant.id] ? warranties[selectedVariant.id] : '-'} - </Text> - )} - </Box> - </Flex> + <Flex + direction={{ base: 'column', md: 'row' }} + align='center' + textAlign={{ base: 'center', md: 'left' }} + gap={{ base: 2, md: 3 }} + > + <img + src='/images/produk_asli.svg' + alt='Distributor Resmi' + className='w-8 h-8 md:w-10 md:h-10 shrink-0' + /> + <Box> + <Text + fontSize={{ base: '10px', md: '11px' }} + color='gray.500' + lineHeight='short' + mb='1px' + > + Distributor Resmi + </Text> + <Text + fontSize={{ base: '10px', md: '12px' }} + fontWeight='bold' + color='gray.800' + lineHeight='1.2' + > + Jaminan Produk Asli + </Text> + </Box> + </Flex> + + <Flex + direction={{ base: 'column', md: 'row' }} + align='center' + textAlign={{ base: 'center', md: 'left' }} + gap={{ base: 2, md: 3 }} + > + <img + src='/images/estimasi.svg' + alt='Estimasi Penyiapan' + className='w-8 h-8 md:w-9 md:h-9 shrink-0' + /> + <Box> + <Text + fontSize={{ base: '10px', md: '11px' }} + color='gray.500' + lineHeight='short' + mb='1px' + > + Estimasi Penyiapan + </Text> + {isLoading ? ( + <Center> + <Skeleton height='10px' width='50px' mt='2px' /> + </Center> + ) : ( + <Text + fontSize={{ base: '10px', md: '12px' }} + fontWeight='bold' + color='gray.800' + lineHeight='1.2' + > + {sla?.sla_date || '-'} + </Text> + )} + </Box> + </Flex> + + <Flex + direction={{ base: 'column', md: 'row' }} + align='center' + textAlign={{ base: 'center', md: 'left' }} + gap={{ base: 2, md: 3 }} + > + <img + src='/images/garansi.svg' + alt='Garansi Produk' + className='w-8 h-8 md:w-10 md:h-10 shrink-0' + /> + <Box> + <Text + fontSize={{ base: '10px', md: '11px' }} + color='gray.500' + lineHeight='short' + mb='1px' + > + Garansi Produk + </Text> + {loadingWarranty ? ( + <Center> + <Skeleton height='10px' width='50px' mt='2px' /> + </Center> + ) : ( + <Text + fontSize={{ base: '10px', md: '12px' }} + fontWeight='bold' + color='gray.800' + lineHeight='1.2' + > + {selectedVariant && warranties[selectedVariant.id] + ? warranties[selectedVariant.id] + : '-'} + </Text> + )} + </Box> + </Flex> </SimpleGrid> </div> </div> ); }; -export default Information;
\ No newline at end of file +export default Information; |
