summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/category/api/popularProduct.js31
-rw-r--r--src/lib/category/components/Category.jsx35
-rw-r--r--src/lib/category/components/PopularBrand.jsx83
-rw-r--r--src/lib/flashSale/components/FlashSaleNonDisplay.jsx66
-rw-r--r--src/lib/home/components/CategoryDynamic.jsx3
-rw-r--r--src/lib/product/components/ProductCard.jsx4
-rw-r--r--src/lib/product/components/ProductSearch.jsx5
-rw-r--r--src/lib/transaction/components/Transaction.jsx400
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>