diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/category/api/popularProduct.js | 31 | ||||
| -rw-r--r-- | src/lib/category/components/Category.jsx | 35 | ||||
| -rw-r--r-- | src/lib/category/components/PopularBrand.jsx | 83 | ||||
| -rw-r--r-- | src/lib/flashSale/components/FlashSaleNonDisplay.jsx | 66 | ||||
| -rw-r--r-- | src/lib/home/components/CategoryDynamic.jsx | 3 | ||||
| -rw-r--r-- | src/lib/product/components/ProductCard.jsx | 4 | ||||
| -rw-r--r-- | src/lib/product/components/ProductSearch.jsx | 5 | ||||
| -rw-r--r-- | src/lib/transaction/components/Transaction.jsx | 400 |
8 files changed, 406 insertions, 221 deletions
diff --git a/src/lib/category/api/popularProduct.js b/src/lib/category/api/popularProduct.js new file mode 100644 index 00000000..e17e0ae5 --- /dev/null +++ b/src/lib/category/api/popularProduct.js @@ -0,0 +1,31 @@ + +export const fetchPromoItemsSolr = async (category_id_ids) => { + let sort ='sort=qty_sold_f desc'; + try { + const queryParams = new URLSearchParams({ q: category_id_ids }); + const response = await fetch(`/solr/product/select?${queryParams.toString()}&rows=2000&fl=manufacture_name_s,manufacture_id_i,id,display_name_s&${sort}`); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + const promotions = await map(data.response.docs); + return promotions; + } catch (error) { + console.error("Error fetching promotion data:", error); + return []; + } + }; + + const map = async (promotions) => { + const result = []; + for (const promotion of promotions) { + const data = { + id: promotion.id, + name: promotion.display_name_s, + manufacture_name: promotion.manufacture_name_s, + manufacture_id: promotion.manufacture_id_i, + }; + result.push(data); + } + return result; + };
\ No newline at end of file diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index c147a3b3..ff958378 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -5,6 +5,7 @@ import { createSlug } from '@/core/utils/slug' import { ChevronRightIcon } from '@heroicons/react/24/outline' import Image from 'next/image' import { useEffect, useState } from 'react' +import PopularBrand from './PopularBrand' const Category = () => { const [categories, setCategories] = useState([]) @@ -30,6 +31,7 @@ const Category = () => { } loadCategories() }, []) + // console.log("categories",categories) return ( <DesktopView> @@ -38,8 +40,11 @@ const Category = () => { <div key={category.id} className='flex'> <Link href={createSlug('/shop/category/', category.name, category.id)} - className='category-mega-box__parent' + className='category-mega-box__parent flex items-center' > + <div className='w-6 h-6 border mr-2 rounded-full flex justify-center items-center'> + <Image src={category.image} alt='' width={16} height={16} /> + </div> {category.name} </Link> <div className='category-mega-box__child-wrapper'> @@ -80,33 +85,7 @@ const Category = () => { ))} </div> <div className='category-mega-box__child-wrapper !w-[260px] !flex !flex-col !gap-4'> - <div className='flex flex-col'> - <div className='grid grid-cols-2 max-h-full w-full gap-2'> - {category.childs.map((brand, index) => ( - (index < 8 ) && ( - <div key={brand.id} className='w-full flex items-center justify-center pb-2'> - <Link - href={createSlug('/shop/category/', brand.name, brand.id)} - className='category-mega-box__child-one w-fit h-full flex items-center justify-center ' - > - <Image src='https://erp.indoteknik.com/api/image/x_manufactures/x_logo_manufacture/661' alt='' width={104} height={44} objectFit='cover' /> - </Link> - </div> - ) - ))} - </div> - {category.childs.length > 8 && ( - <div className='flex hover:bg-gray_r-8/35 rounded-10'> - <Link - href={createSlug('/shop/category/', category.name, category.id)} - className='category-mega-box__child-one flex items-center gap-4 font-bold hover:ml-4' - > - <p className='mt-2 mb-0 text-danger-500 font-semibold'>Lihat Semua Brand</p> - <ChevronRightIcon className='w-4 text-danger-500 font-bold' /> - </Link> - </div> - )} - </div> + <PopularBrand category={category} /> <div className='flex w-60 h-20 object-cover'> <Image src='https://erp.indoteknik.com/api/image/x_banner.banner/x_banner_image/397' alt='' width={275} height={4} /> </div> diff --git a/src/lib/category/components/PopularBrand.jsx b/src/lib/category/components/PopularBrand.jsx new file mode 100644 index 00000000..dca731e8 --- /dev/null +++ b/src/lib/category/components/PopularBrand.jsx @@ -0,0 +1,83 @@ +import odooApi from '@/core/api/odooApi' +import React, { useEffect, useState } from 'react' +import axios from 'axios'; +import { useQuery } from 'react-query' +import Link from '@/core/components/elements/Link/Link' +import { createSlug } from '@/core/utils/slug' +import Image from 'next/image' +import { ChevronRightIcon } from '@heroicons/react/24/outline' +import useProductSearch from '../../../lib/product/hooks/useProductSearch'; +import { SolrResponse } from "~/types/solr"; +import { fetchPromoItemsSolr } from '../api/popularProduct' + +const SOLR_HOST = process.env.SOLR_HOST + +const PopularBrand = ({ category }) => { + const [topBrands, setTopBrands] = useState([]); + + const fetchTopBrands = async () => { + try { + const items = await fetchPromoItemsSolr(`category_id_ids:(${category.categoryDataIds.join(' OR ')})`); + // console.log("id",items) + // Fungsi untuk deduplikasi dan mengambil 12 nama brand teratas + const getTop12UniqueBrands = (prod) => { + const brandSet = new Set(); + const topBrands = []; + + for (const product of prod) { + if (!brandSet.has(product.manufacture_name)) { + brandSet.add(product.manufacture_name); + topBrands.push({ name: product.manufacture_name, id: product.manufacture_id }); + }else{ + } + if (topBrands.length === 18) break; + } + return topBrands; + } + + // Menggunakan hasil pencarian produk + const products = items; + const top12UniqueBrands = getTop12UniqueBrands(products); + + // console.log('top12UniqueBrands', top12UniqueBrands); + setTopBrands(top12UniqueBrands); + } catch (error) { + console.error("Error fetching data from Solr", error); + throw error; + } + } + + useEffect(() => { + fetchTopBrands(); + }, [category]); + + return ( + <div className='flex flex-col'> + <div className='grid grid-cols-3 max-h-full w-full gap-2'> + {topBrands.map((brand, index) => ( + <div key={index} className='w-full flex items-center justify-center pb-2'> + <Link + href={createSlug('/shop/brands/', brand.name, brand.id)} + className='category-mega-box__child-one w-8 h-full flex items-center justify-center ' + > + <Image src={`https://erp.indoteknik.com/api/image/x_manufactures/x_logo_manufacture/${brand.id}` } alt={`${brand.name}`} width={104} height={44} objectFit='cover' /> + </Link> + </div> + ))} + </div> + {/* {topBrands.length > 8 && ( + <div className='flex hover:bg-gray_r-8/35 rounded-10'> + <Link + href={createSlug('/shop/category/', category.name, category.id)} + className='category-mega-box__child-one flex items-center gap-4 font-bold hover:ml-4' + > + <p className='mt-2 mb-0 text-danger-500 font-semibold'>Lihat Semua Brand</p> + <ChevronRightIcon className='w-4 text-danger-500 font-bold' /> + </Link> + </div> + )} */} + </div> + ) +} + +export default PopularBrand; diff --git a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx new file mode 100644 index 00000000..8dc15b05 --- /dev/null +++ b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx @@ -0,0 +1,66 @@ +import Image from 'next/image'; +import { useEffect, useState } from 'react'; + +import CountDown from '@/core/components/elements/CountDown/CountDown'; +import productSearchApi from '@/lib/product/api/productSearchApi'; +import ProductSlider from '@/lib/product/components/ProductSlider'; + +import flashSaleApi from '../api/flashSaleApi'; +import { FlashSaleSkeleton } from '../skeleton/FlashSaleSkeleton'; + +const FlashSaleNonDisplay = () => { + const [flashSales, setFlashSales] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const loadFlashSales = async () => { + const dataFlashSales = await flashSaleApi(); + setFlashSales(dataFlashSales); + setIsLoading(false); + }; + loadFlashSales(); + }, []); + + if (isLoading) { + return <FlashSaleSkeleton />; + } + + return ( + flashSales?.length > 0 && ( + <div className='px-4 sm:px-0 grid grid-cols-1 gap-y-8'> + {flashSales.map((flashSale, index) => ( + <div key={index}> + <div className='flex gap-x-3 mb-4 justify-between sm:justify-start'> + <div className='font-medium sm:text-h-lg mt-1.5'> + Penawaran Terbatas + </div> + </div> + + <div className='relative'> + <FlashSaleProduct flashSaleId={flashSale.pricelistId} /> + </div> + </div> + ))} + </div> + ) + ); +}; + +const FlashSaleProduct = ({ flashSaleId }) => { + const [products, setProducts] = useState(null); + + useEffect(() => { + const loadProducts = async () => { + const dataProducts = await productSearchApi({ + query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500&orderBy=flashsale-discount-desc`, + operation: 'AND', + }); + setProducts(dataProducts.response); + }; + loadProducts(); + }, [flashSaleId]); + + return <ProductSlider products={products} />; +}; + +export default FlashSaleNonDisplay; diff --git a/src/lib/home/components/CategoryDynamic.jsx b/src/lib/home/components/CategoryDynamic.jsx index f2d1a16f..0cc43d91 100644 --- a/src/lib/home/components/CategoryDynamic.jsx +++ b/src/lib/home/components/CategoryDynamic.jsx @@ -33,9 +33,8 @@ const CategoryDynamic = () => { }; fetchCategoryData(); - }, [categoryManagement, categoryData]); + }, [categoryManagement.isLoading]); - return ( <div> {categoryManagement && categoryManagement.data?.map((category) => { diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 94db144d..35e2a665 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -17,8 +17,8 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { const [discount, setDiscount] = useState(0); let voucherPastiHemat = 0; - - if (product?.voucherPastiHemat?.length > 0) { + + if (product?.voucherPastiHemat ? product?.voucherPastiHemat.length : voucherPastiHemat > 0) { const stringVoucher = product?.voucherPastiHemat[0]; const validJsonString = stringVoucher.replace(/'/g, '"'); voucherPastiHemat = JSON.parse(validJsonString); diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index 09534a5d..a83e5e1e 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -41,8 +41,6 @@ const ProductSearch = ({ const { page = 1 } = query; const [q, setQ] = useState(query?.q || '*'); const [search, setSearch] = useState(query?.q || '*'); - const [limit, setLimit] = useState(router.query?.limit || 30); - const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular'); const [finalQuery, setFinalQuery] = useState({}); const [queryFinal, setQueryFinal] = useState({}); const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) @@ -50,6 +48,8 @@ const ProductSearch = ({ const categoryId = getIdFromSlug(prefixUrl) const [data, setData] = useState([]) const [dataLob, setDataLob] = useState([]); + const [limit, setLimit] = useState(query?.limit || 30); + const [orderBy, setOrderBy] = useState(router.query?.orderBy); if (defaultBrand) query.brand = defaultBrand.toLowerCase(); const dataIdCategories = [] useEffect(() => { @@ -267,6 +267,7 @@ const ProductSearch = ({ const orderOptions = [ + { value: '', label: 'Pilih Filter' }, { value: 'price-asc', label: 'Harga Terendah' }, { value: 'price-desc', label: 'Harga Tertinggi' }, { value: 'popular', label: 'Populer' }, diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index 9bef895a..85f6163b 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -1,6 +1,6 @@ import Spinner from '@/core/components/elements/Spinner/Spinner'; import NextImage from 'next/image'; -import rejectImage from "../../../../public/images/reject.png" +import rejectImage from '../../../../public/images/reject.png'; import useTransaction from '../hooks/useTransaction'; import TransactionStatusBadge from './TransactionStatusBadge'; import Divider from '@/core/components/elements/Divider/Divider'; @@ -40,7 +40,7 @@ import rejectProductApi from '../api/rejectProductApi'; import { useRouter } from 'next/router'; const Transaction = ({ id }) => { - const router = useRouter() + const router = useRouter(); const [isModalOpen, setIsModalOpen] = useState(false); const [selectedProduct, setSelectedProduct] = useState(null); const [reason, setReason] = useState(''); @@ -152,7 +152,10 @@ const Transaction = ({ id }) => { const memoizeVariantGroupCardReject = useMemo( () => ( <div className='p-4 pt-0 flex flex-col gap-y-3'> - <VariantGroupCard variants={transaction.data?.productsRejectLine} buyMore /> + <VariantGroupCard + variants={transaction.data?.productsRejectLine} + buyMore + /> </div> ), [transaction.data] @@ -182,26 +185,25 @@ const Transaction = ({ id }) => { }; const handleRejectProduct = async () => { - try{ + try { if (!reason.trim()) { toast.error('Masukkan alasan terlebih dahulu'); return; - }else{ - let idSo = transaction?.data.id - let idProduct = selectedProduct?.id - await rejectProductApi({ idSo, idProduct, reason}); + } else { + let idSo = transaction?.data.id; + let idProduct = selectedProduct?.id; + await rejectProductApi({ idSo, idProduct, reason }); closeModal(); - toast.success("Produk berhasil di reject") + toast.success('Produk berhasil di reject'); setTimeout(() => { window.location.reload(); - }, 1500); + }, 1500); } - }catch(error){ + } catch (error) { toast.error('Gagal reject produk. Silakan coba lagi.'); } }; - return ( transaction.data?.name && ( <> @@ -390,14 +392,20 @@ const Transaction = ({ id }) => { <p className='text-gray_r-11 leading-none'>Dokumen PO</p> <button type='button' - className='btn-light py-1.5 px-3 ml-auto' + className='inline-block text-danger-500' onClick={ transaction.data?.purchaseOrderFile ? () => downloadPurchaseOrder(transaction.data) - : openUploadPo + : transaction?.data.invoices.length < 1 + ? openUploadPo + : '' } > - {transaction.data?.purchaseOrderFile ? 'Download' : 'Upload'} + {transaction?.data?.purchaseOrderFile + ? 'Download' + : transaction?.data.invoices.length < 1 + ? 'Upload' + : '-'} </button> </div> </div> @@ -406,13 +414,13 @@ const Transaction = ({ id }) => { <Divider /> <div className='font-medium p-4'>Detail Produk</div> - {transaction?.data?.products.length > 0? ( - <div> - {memoizeVariantGroupCard} - </div> + {transaction?.data?.products.length > 0 ? ( + <div>{memoizeVariantGroupCard}</div> ) : ( - <div className='badge-red text-sm px-2 ml-4'>Semua produk telah di reject</div> - )} + <div className='badge-red text-sm px-2 ml-4'> + Semua produk telah di reject + </div> + )} {transaction?.data?.productsRejectLine.length > 0 && ( <div> @@ -594,12 +602,16 @@ const Transaction = ({ id }) => { onClick={ transaction.data?.purchaseOrderFile ? () => downloadPurchaseOrder(transaction.data) - : openUploadPo + : transaction?.data.invoices.length < 1 + ? openUploadPo + : '' } > {transaction?.data?.purchaseOrderFile ? 'Download' - : 'Upload'} + : transaction?.data.invoices.length < 1 + ? 'Upload' + : '-'} </button> </div> </> @@ -628,9 +640,11 @@ const Transaction = ({ id }) => { <div className='text-h-sm font-semibold mt-10 mb-4'> Pengiriman </div> - {transaction?.data?.pickings.length == 0 && ( - <div className='badge-red text-sm'>Belum ada pengiriman</div> - )} + {transaction?.data?.pickings.length == 0 && ( + <div className='badge-red text-sm'> + Belum ada pengiriman + </div> + )} <div className='grid grid-cols-1 gap-1 w-2/3'> {transaction?.data?.pickings?.map((airway) => ( <button @@ -646,7 +660,9 @@ const Transaction = ({ id }) => { </div> <div className='flex gap-x-2'> <div className='text-sm text-gray-600 badge-green leading-[1.5] mt-1'> - {airway?.delivered ? 'Pesanan Tiba' : 'Sedang Dikirim'} + {airway?.delivered + ? 'Pesanan Tiba' + : 'Sedang Dikirim'} </div> <ChevronRightIcon className='w-5 stroke-2' /> </div> @@ -655,51 +671,53 @@ const Transaction = ({ id }) => { </div> </div> <div className='invoice w-1/2 '> - <div className='text-h-sm font-semibold mt-10 mb-4 '>Invoice</div> - {transaction.data?.invoices?.length === 0 && ( - <div className='badge-red text-sm'>Belum ada invoice</div> - )} - <div className='grid grid-cols-1 gap-1 w-2/3 '> - {transaction.data?.invoices?.map((invoice, index) => ( - <Link href={`/my/invoices/${invoice.id}`} key={index}> - <div className='shadow rounded-md p-4 text-gray_r-12 font-normal flex justify-between'> - <div> - <p className='mb-1'>{invoice?.name}</p> - <div className='flex items-center gap-x-1'> - {invoice.amountResidual > 0 ? ( - <div className='badge-red'>Belum Lunas</div> - ) : ( - <div className='badge-green'>Lunas</div> - )} - <p className='text-caption-2 text-gray_r-11'> - {currencyFormat(invoice.amountTotal)} - </p> - </div> + <div className='text-h-sm font-semibold mt-10 mb-4 '> + Invoice + </div> + {transaction.data?.invoices?.length === 0 && ( + <div className='badge-red text-sm'>Belum ada invoice</div> + )} + <div className='grid grid-cols-1 gap-1 w-2/3 '> + {transaction.data?.invoices?.map((invoice, index) => ( + <Link href={`/my/invoices/${invoice.id}`} key={index}> + <div className='shadow rounded-md p-4 text-gray_r-12 font-normal flex justify-between'> + <div> + <p className='mb-1'>{invoice?.name}</p> + <div className='flex items-center gap-x-1'> + {invoice.amountResidual > 0 ? ( + <div className='badge-red'>Belum Lunas</div> + ) : ( + <div className='badge-green'>Lunas</div> + )} + <p className='text-caption-2 text-gray_r-11'> + {currencyFormat(invoice.amountTotal)} + </p> </div> - <ChevronRightIcon className='w-5 stroke-2' /> </div> - </Link> - ))} - </div> + <ChevronRightIcon className='w-5 stroke-2' /> + </div> + </Link> + ))} + </div> </div> </div> <div className='text-h-sm font-semibold mt-4 mb-4'> Rincian Pembelian </div> - {transaction?.data?.products?.length > 0? ( - <table className='table-data'> - <thead> - <tr> - <th>Nama Produk</th> - {/* <th>Diskon</th> */} - <th>Jumlah</th> - <th>Harga</th> - <th>Subtotal</th> - <th></th> - </tr> - </thead> - <tbody> + {transaction?.data?.products?.length > 0 ? ( + <table className='table-data'> + <thead> + <tr> + <th>Nama Produk</th> + {/* <th>Diskon</th> */} + <th>Jumlah</th> + <th>Harga</th> + <th>Subtotal</th> + <th></th> + </tr> + </thead> + <tbody> {transaction?.data?.products?.map((product) => ( <tr key={product.id}> <td className='flex'> @@ -711,37 +729,37 @@ const Transaction = ({ id }) => { )} className='w-[20%] flex-shrink-0' > - <div className='relative'> + <div className='relative'> <Image src={product?.parent?.image} alt={product?.name} className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md' /> - <div className='absolute top-0 right-4 flex mt-3'> - <div className='gambarB '> - {product.isSni && ( - <ImageNext - src='/images/sni-logo.png' - alt='SNI Logo' - className='w-2 h-4 object-contain object-top sm:h-4' - width={50} - height={50} - /> - )} - </div> - <div className='gambarC '> - {product.isTkdn && ( - <ImageNext - src='/images/TKDN.png' - alt='TKDN' - className='w-5 h-4 object-contain object-top ml-1 sm:h-4' - width={50} - height={50} - /> - )} + <div className='absolute top-0 right-4 flex mt-3'> + <div className='gambarB '> + {product.isSni && ( + <ImageNext + src='/images/sni-logo.png' + alt='SNI Logo' + className='w-2 h-4 object-contain object-top sm:h-4' + width={50} + height={50} + /> + )} + </div> + <div className='gambarC '> + {product.isTkdn && ( + <ImageNext + src='/images/TKDN.png' + alt='TKDN' + className='w-5 h-4 object-contain object-top ml-1 sm:h-4' + width={50} + height={50} + /> + )} + </div> </div> </div> - </div> </Link> <div className='px-2 text-left'> <Link @@ -774,33 +792,42 @@ const Transaction = ({ id }) => { {currencyFormat(product.price.price)} </div> )} */} - <div>{currencyFormat(product.price.priceDiscount)}</div> + <div> + {currencyFormat(product.price.priceDiscount)} + </div> </td> <td>{currencyFormat(product.price.subtotal)}</td> {/* {auth?.feature.soApproval && (auth.webRole == 2 || auth.webRole == 3) && (transaction.data.isReaject == false) && ( */} - {auth?.feature.soApproval && (auth.webRole == 2 || auth.webRole == 3) && (router.asPath.includes("/my/quotations/")) && transaction.data?.status == 'draft' && ( - <td> - <button - className="bg-red-500 text-white py-1 px-3 rounded" - onClick={() => openModal(product)} - > - Reject - </button> - </td> - )} + {auth?.feature.soApproval && + (auth.webRole == 2 || auth.webRole == 3) && + router.asPath.includes('/my/quotations/') && + transaction.data?.status == 'draft' && ( + <td> + <button + className='bg-red-500 text-white py-1 px-3 rounded' + onClick={() => openModal(product)} + > + Reject + </button> + </td> + )} </tr> ))} </tbody> </table> ) : ( - <div className='badge-red text-sm'>Semua produk telah di reject</div> + <div className='badge-red text-sm'> + Semua produk telah di reject + </div> )} - + {isModalOpen && ( <div className='fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center'> - <div className='bg-white p-4 rounded w-96 + <div + className='bg-white p-4 rounded w-96 ease-in-out opacity-100 - transform transition-transform duration-300 scale-100'> + transform transition-transform duration-300 scale-100' + > <h2 className='text-lg mb-2'>Berikan Alasan</h2> <textarea value={reason} @@ -826,117 +853,116 @@ const Transaction = ({ id }) => { </div> )} - {transaction?.data?.products?.map((product) => ( - <div className='flex justify-end mt-4' key={product.id}> - <div className='w-1/4 grid grid-cols-2 gap-y-3 text-gray_r-12/80'> - <div className='text-right'>Subtotal</div> - <div className='text-right font-medium'> - {currencyFormat(transaction.data?.amountUntaxed)} - </div> + {transaction?.data?.products?.map((product) => ( + <div className='flex justify-end mt-4' key={product.id}> + <div className='w-1/4 grid grid-cols-2 gap-y-3 text-gray_r-12/80'> + <div className='text-right'>Subtotal</div> + <div className='text-right font-medium'> + {currencyFormat(transaction.data?.amountUntaxed)} + </div> - <div className='text-right'>PPN 11%</div> - <div className='text-right font-medium'> - {currencyFormat(transaction.data?.amountTax)} - </div> + <div className='text-right'>PPN 11%</div> + <div className='text-right font-medium'> + {currencyFormat(transaction.data?.amountTax)} + </div> - <div className='text-right whitespace-nowrap'> - Biaya Pengiriman - </div> - <div className='text-right font-medium'> - {currencyFormat(transaction.data?.deliveryAmount)} - </div> + <div className='text-right whitespace-nowrap'> + Biaya Pengiriman + </div> + <div className='text-right font-medium'> + {currencyFormat(transaction.data?.deliveryAmount)} + </div> - <div className='text-right'>Grand Total</div> - <div className='text-right font-medium text-gray_r-12'> - {currencyFormat(transaction.data?.amountTotal)} + <div className='text-right'>Grand Total</div> + <div className='text-right font-medium text-gray_r-12'> + {currencyFormat(transaction.data?.amountTotal)} + </div> </div> </div> - </div> - ))} - - + ))} {transaction?.data?.productsRejectLine.length > 0 && ( - <div className='text-h-sm font-semibold mt-10 mb-4'> - Rincian Produk Reject - </div> + <div className='text-h-sm font-semibold mt-10 mb-4'> + Rincian Produk Reject + </div> )} {transaction?.data?.productsRejectLine.length > 0 && ( - <table className='table-data'> - <thead> - <tr> - <th>Nama Produk</th> - {/* <th>Diskon</th> */} - <th>Jumlah</th> - <th>Harga</th> - <th>Subtotal</th> - </tr> - </thead> - <tbody> - {transaction?.data?.productsRejectLine?.map((product) => ( - <tr key={product.id}> - <td className='flex'> + <table className='table-data'> + <thead> + <tr> + <th>Nama Produk</th> + {/* <th>Diskon</th> */} + <th>Jumlah</th> + <th>Harga</th> + <th>Subtotal</th> + </tr> + </thead> + <tbody> + {transaction?.data?.productsRejectLine?.map((product) => ( + <tr key={product.id}> + <td className='flex'> + <Link + href={createSlug( + '/shop/product/', + product?.parent.name, + product?.parent.id + )} + className='w-[20%] flex-shrink-0' + > + <Image + src={product?.parent?.image} + alt={product?.name} + className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md' + /> + </Link> + <div className='px-2 text-left'> <Link href={createSlug( '/shop/product/', product?.parent.name, product?.parent.id )} - className='w-[20%] flex-shrink-0' + className='line-clamp-2 leading-6 !text-gray_r-12 font-normal' > - <Image - src={product?.parent?.image} - alt={product?.name} - className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md' - /> + {product?.parent?.name} </Link> - <div className='px-2 text-left'> - <Link - href={createSlug( - '/shop/product/', - product?.parent.name, - product?.parent.id - )} - className='line-clamp-2 leading-6 !text-gray_r-12 font-normal' - > - {product?.parent?.name} - </Link> - <div className='text-gray_r-11 mt-2'> - {product?.code}{' '} - {product?.attributes.length > 0 - ? `| ${product?.attributes.join(', ')}` - : ''} - </div> + <div className='text-gray_r-11 mt-2'> + {product?.code}{' '} + {product?.attributes.length > 0 + ? `| ${product?.attributes.join(', ')}` + : ''} </div> - </td> - {/* <td> + </div> + </td> + {/* <td> {product.price.discountPercentage > 0 ? `${product.price.discountPercentage}%` : ''} </td> */} - <td>{product.quantity}</td> - <td> - {/* {product.price.discountPercentage > 0 && ( + <td>{product.quantity}</td> + <td> + {/* {product.price.discountPercentage > 0 && ( <div className='line-through mb-1 text-caption-1 text-gray_r-12/70'> {currencyFormat(product.price.price)} </div> )} */} - <div>{currencyFormat(product.price.priceDiscount)}</div> - </td> - <td className='flex justify-center'> - <NextImage - src={rejectImage} - alt='Reject' - width={90} - height={30} - /> - </td> - </tr> - ))} - </tbody> - </table> + <div> + {currencyFormat(product.price.priceDiscount)} + </div> + </td> + <td className='flex justify-center'> + <NextImage + src={rejectImage} + alt='Reject' + width={90} + height={30} + /> + </td> + </tr> + ))} + </tbody> + </table> )} - </div> </div> </DesktopView> |
