summaryrefslogtreecommitdiff
path: root/src/lib/transaction/components/Transactions.jsx
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2025-03-03 16:38:10 +0700
committerit-fixcomart <it@fixcomart.co.id>2025-03-03 16:38:10 +0700
commitfaf6403595602d78b502acfacc721923addbf4a8 (patch)
treebb0ce17c3a8d4fe36f9ebc547b33354156673ae7 /src/lib/transaction/components/Transactions.jsx
parentcd072c875c334b1140e4f797a37a9e991d53e2b5 (diff)
<iman> update code
Diffstat (limited to 'src/lib/transaction/components/Transactions.jsx')
-rw-r--r--src/lib/transaction/components/Transactions.jsx487
1 files changed, 337 insertions, 150 deletions
diff --git a/src/lib/transaction/components/Transactions.jsx b/src/lib/transaction/components/Transactions.jsx
index a8685105..64ae9393 100644
--- a/src/lib/transaction/components/Transactions.jsx
+++ b/src/lib/transaction/components/Transactions.jsx
@@ -31,11 +31,30 @@ import getSite from '../api/listSiteApi';
import transactionsApi from '../api/transactionsApi';
import { motion } from 'framer-motion';
import Image from '@/core/components/elements/Image/Image';
+import { upsertUserCart } from '~/services/cart';
+import { useProductCartContext } from '@/contexts/ProductCartContext';
+import { Swiper, SwiperSlide } from 'swiper/react';
+import 'swiper/css';
const Transactions = ({ context = '' }) => {
const auth = useAuth();
const router = useRouter();
- const { q = '', page = 1, site = null, limit = 15 } = router.query;
-
+ const {
+ q = '',
+ page = 1,
+ site = null,
+ limit = 15,
+ status = 'all',
+ } = router.query;
+ const {
+ productCart,
+ setRefreshCart,
+ setProductCart,
+ refreshCart,
+ isLoading,
+ setIsloading,
+ } = useProductCartContext();
+ console.log('context', context);
+ console.log('router.query', router.query);
const [inputQuery, setInputQuery] = useState(q);
const [toOthers, setToOthers] = useState(null);
const [toCancel, setToCancel] = useState(null);
@@ -44,16 +63,32 @@ const Transactions = ({ context = '' }) => {
const [siteFilter, setSiteFilter] = useState(site);
const [pageNew, setPageNew] = useState(page);
const [limitNew, setLimitNew] = useState(limit);
+ // const [status, setStatus] = useState('idle');
+ const [statusNew, setStatusNew] = useState(status);
+ const [contextNew, setcontextNew] = useState(router.query.context || context);
const query = {
name: q,
offset: (pageNew - 1) * limitNew,
- context,
+ context: contextNew,
limit: limitNew,
+ status: statusNew,
site:
siteFilter || (auth?.webRole === null && auth?.site ? auth.site : null),
};
+
+ const statuses = [
+ { id: 'all', label: 'Semua' },
+ { id: 'quotation', label: 'Pending Quotation' },
+ { id: 'diterima', label: 'Pesanan Diterima' },
+ { id: 'diproses', label: 'Pesanan Diproses' },
+ { id: 'dikirim', label: 'Pesanan Dikirim' },
+ { id: 'selesai', label: 'Pesanan Selesai' },
+ { id: 'cancel', label: 'Pesanan Dibatalkan' },
+ ];
+
+ console.log('query', query);
const { transactions } = useTransactions({ query });
- console.log('transactions', transactions);
+ // console.log('transactions', transactions);
const fetchSite = async () => {
const site = await getSite();
setListSites(site.sites);
@@ -229,6 +264,67 @@ const Transactions = ({ context = '' }) => {
useEffect(() => {
fetchSite();
}, []);
+
+ const handleBuyBack = async (products) => {
+ // if (status === 'success') return;
+
+ try {
+ // setStatus('loading');
+
+ const results = await Promise.all(
+ products.map((product) =>
+ upsertUserCart({
+ userId: auth.id,
+ type: 'product',
+ id: product.id,
+ qty: product.quantity,
+ selected: true,
+ source: 'buy', // Tetap gunakan 'buy' agar bisa masuk ke halaman pembelian
+ qtyAppend: false,
+ })
+ )
+ );
+
+ // console.log(`Produk berhasil dimasukkan ke dalam cart`, results);
+
+ // ✅ Panggil setRefreshCart(true) setiap kali satu produk berhasil ditambahkan
+
+ setRefreshCart(true);
+
+ // setStatus('idle');
+ toast.success('Semua produk berhasil ditambahkan ke keranjang belanja');
+ // Tampilkan notifikasi
+ // toast({
+ // title: 'Tambah ke keranjang',
+ // description: 'Semua produk berhasil ditambahkan ke keranjang belanja',
+ // status: 'success',
+ // duration: 3000,
+ // isClosable: true,
+ // position: 'top',
+ // });
+
+ // Redirect ke halaman checkout
+ router.push('/shop/checkout?source=buy');
+ } catch (error) {
+ console.error('Gagal menambahkan produk ke keranjang:', error);
+ // setStatus('error');
+ }
+ };
+
+ const handleStatusChange = (status) => {
+ setStatusNew(status);
+
+ if (['quotation', 'cancel', 'diterima', ''].includes(status)) {
+ setcontextNew('quotation');
+ } else {
+ setcontextNew('');
+ }
+
+ if (status === 'all') {
+ router.push('/my/transactions');
+ }
+ };
+
return (
<>
<MobileView>
@@ -445,66 +541,126 @@ const Transactions = ({ context = '' }) => {
)}
</div>
</div>
- <div className='flex flex-row items-center justify-between mb-2'>
- <div className='flex flex-col gap-2 pb-2'>
- {listSites?.length > 0 ? (
- <select
- value={siteFilter}
- onChange={handleSiteFilterChange}
- className='form-input'
+ <div className=''>
+ <div
+ class='flex items-center p-4 mb-4 text-sm border border-yellow-500 text-yellow-800 rounded-lg bg-yellow-50'
+ role='alert'
+ >
+ <svg
+ class='flex-shrink-0 inline w-5 h-5 mr-2'
+ aria-hidden='true'
+ fill='currentColor'
+ viewBox='0 0 20 20'
+ >
+ <path d='M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z' />
+ </svg>
+ <span class='sr-only'>Info</span>
+ <div className='text-justify flex flex-col gap-1'>
+ <p className='font-bold text-black'>Info Transaksi</p>
+ <span className='text-black'>
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
+ do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+ </span>
+ </div>
+ </div>
+ </div>
+ <div className='flex flex-col gap-y-2 border rounded mb-2'>
+ <div className='p-2'>
+ <div className='flex items-center space-x-3'>
+ <span className='text-sm font-medium text-gray-600'>
+ Status
+ </span>
+ <Swiper
+ spaceBetween={10}
+ slidesPerView={5.25}
+ className='w-full h-8'
>
- <option value=''>Pilih Site</option>
- {listSites.map((site) => (
- <option value={site} key={site}>
- {site}
- </option>
+ {statuses.map((status) => (
+ <SwiperSlide key={status.id} className='w-auto'>
+ <button
+ className={`px-4 py-1 text-sm font-medium border rounded-lg transition whitespace-nowrap min-w-40
+ ${
+ statusNew === status.id
+ ? 'border-red-500 text-red-500 bg-white'
+ : 'border-gray-300 text-gray-400 bg-gray-100 hover:bg-gray-200'
+ }`}
+ onClick={() => handleStatusChange(status.id)}
+ >
+ {status.label}
+ </button>
+ </SwiperSlide>
))}
- </select>
- ) : (
- <div></div>
- )}
+ </Swiper>
+ </div>
+ </div>
+ <div className='flex flex-row items-center justify-between mb-2 p-2'>
+ <div className='flex flex-col gap-2 pb-2'>
+ {listSites?.length > 0 ? (
+ <select
+ value={siteFilter}
+ onChange={handleSiteFilterChange}
+ className='form-input'
+ >
+ <option value=''>Pilih Site</option>
+ {listSites.map((site) => (
+ <option value={site} key={site}>
+ {site}
+ </option>
+ ))}
+ </select>
+ ) : (
+ <div></div>
+ )}
- <form className='flex gap-x-1' onSubmit={handleSubmit}>
- <input
- type='text'
- className='form-input'
- placeholder='Cari Transaksi...'
- value={inputQuery}
- onChange={(e) => setInputQuery(e.target.value)}
- />
- <button
- className='btn-light bg-transparent px-3'
- type='submit'
+ <form className='flex gap-x-1' onSubmit={handleSubmit}>
+ <input
+ type='text'
+ className='form-input'
+ placeholder='Cari Transaksi...'
+ value={inputQuery}
+ onChange={(e) => setInputQuery(e.target.value)}
+ />
+ <button
+ className='btn-light bg-transparent px-3'
+ type='submit'
+ >
+ <MagnifyingGlassIcon className='w-6' />
+ </button>
+ </form>
+ </div>
+ <div className='flex flex-row gap-4 items-center justify-center'>
+ <p>
+ Menampilkan {startItem}-
+ {endItem
+ ? endItem
+ : transactions?.data?.saleOrderTotal
+ ? transactions?.data?.saleOrderTotal
+ : limitNew}{' '}
+ dari{' '}
+ {transactions?.data?.saleOrderTotal
+ ? transactions?.data?.saleOrderTotal
+ : limitNew}
+ </p>
+ <select
+ id='limitSelect'
+ value={limitNew}
+ onChange={(e) => {
+ setLimitNew(Number(e.target.value));
+ setPageNew(1);
+ }}
+ className='border p-2'
>
- <MagnifyingGlassIcon className='w-6' />
- </button>
- </form>
- </div>
- <div className='flex flex-row gap-4 items-center justify-center'>
- <p>
- Menampilkan {startItem}-
- {endItem ? endItem : transactions?.data?.saleOrderTotal} dari{' '}
- {transactions?.data?.saleOrderTotal}
- </p>
- <select
- id='limitSelect'
- value={limitNew}
- onChange={(e) => {
- setLimitNew(Number(e.target.value));
- setPageNew(1);
- }}
- className='border p-2'
- >
- <option value={10}>10</option>
- <option value={15}>15</option>
- <option value={20}>20</option>
- </select>
+ <option value={10}>10</option>
+ <option value={15}>15</option>
+ <option value={20}>20</option>
+ </select>
+ </div>
</div>
</div>
- <div className='flex'>
+ <div className='flex justify-center items-center'>
{!transactions.isLoading &&
- (!transactions?.data?.saleOrders ||
- transactions?.data?.saleOrders?.length == 0) && (
+ transactions?.data?.saleOrders?.length == 0 && (
<div className='justify-center p-4'>
<p className='text-gray-500 text-center '>
Tidak Ada Transaksi
@@ -512,107 +668,138 @@ const Transactions = ({ context = '' }) => {
</div>
)}
- {transactions && transactions.data?.saleOrders?.length > 0 && (
- <div className='flex flex-col gap-4 w-full'>
- {transactions.data.saleOrders.map((saleOrder, index) => (
- <div
- key={index}
- className='border p-2 hover:border-red-500 w-full rounded-sm'
- >
- {/* <Link
- href={`/my/quotations/${saleOrder?.id}`}
- className='hover:border-red-500 block w-full'
- > */}
- <div className='flex flex-row justify-between items-center py-2'>
- <div className='flex justify-center gap-3'>
- <TransactionStatusBadge status={saleOrder.status} />
- <p className='text-red-500'>{saleOrder.name}</p>
- <p>
- Salesperson:{' '}
- {
+ {transactions.isLoading && (
+ <div className='flex justify-center items-center my-2'>
+ <Spinner className='w-6 text-gray_r-12/50 fill-gray_r-12' />
+ </div>
+ )}
+
+ {!transactions.isLoading &&
+ transactions &&
+ transactions.data?.saleOrders?.length > 0 && (
+ <div className='flex flex-col gap-4 w-full'>
+ {transactions.data.saleOrders.map((saleOrder, index) => (
+ <div
+ key={index}
+ className='border p-2 hover:border-red-500 w-full rounded-sm'
+ >
+ <Link
+ href={`/my/quotations/${saleOrder?.id}`}
+ className='hover:border-red-500 block w-full'
+ >
+ <div className='flex flex-row justify-between items-center py-2'>
+ <div className='flex justify-center gap-3'>
+ <TransactionStatusBadge
+ status={saleOrder.status}
+ />
+ <p className='text-red-500'>{saleOrder.name}</p>
+ <p className='text-black'>
+ Salesperson:{' '}
+ {
+ <span className='font-semibold'>
+ {saleOrder.sales}
+ </span>
+ }
+ </p>
+ </div>
+ <div className='text-black'>
+ Tanggal Pesanan:{' '}
<span className='font-semibold'>
- {saleOrder.sales}
+ {saleOrder.dateOrder.split(' ')[0] || '-'}
</span>
- }
- </p>
- </div>
- <div>
- Tanggal Pesanan:{' '}
- <span className='font-semibold'>
- {saleOrder.dateOrder.split(' ')[0] || '-'}
- </span>
- </div>
- </div>
- <hr className='mt-3 mb-3 border border-gray-100' />
- <div className='flex flex-row gap-2 justify-between items-center '>
- <div className='flex justify-start w-4/5 flex-col gap-2'>
- <div className='flex gap-2'>
- <div>
- <Image
- src={saleOrder.products[0]?.parent?.image}
- alt={saleOrder.products[0]?.name}
- className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md'
- />
</div>
- <div className='flex flex-col gap-3 justify-start'>
- <p className='flex flex-row gap-2'>
- <span className='text-sm'>Nomor PO:</span>
- <span className='text-sm text-red-500 font-semibold'>
- {saleOrder.purchaseOrderName || '-'}
- </span>
- </p>
- <p className='line-clamp-2 leading-6 tracking-wide opacity-90 !text-gray_r-12 font-semibold text-nowrap'>
- {saleOrder.products[0]?.parent?.name}
- </p>
- <p className='opacity-85 !text-gray_r-12'>
- {saleOrder.products[0]?.quantity} x{' '}
- {currencyFormat(
- saleOrder.products[0]?.price?.priceDiscount
- )}
- </p>
- <div className='flex flex-row justify-start items-center'>
- {saleOrder.products?.length > 1 && (
- <div className='flex flex-row gap-1 justify-start items-center'>
- {saleOrder.products
- .slice(1)
- .map((product, index) => (
- <Image
- key={index} // Tambahkan key untuk setiap elemen dalam map()
- src={product?.parent?.image}
- alt={product?.name}
- className='object-contain object-center border border-gray_r-6 h-8 w-8 rounded-md'
- />
- ))}
- <Link
- href={`/my/quotations/${saleOrder?.id}`}
- className='text-sm text-red-500 text-nowrap'
- >
- Lihat semua produk
- </Link>
+ </div>
+ <hr className='mt-3 mb-3 border border-gray-100' />
+ <div className='flex flex-row gap-2 justify-between items-center '>
+ <div className='flex justify-start w-3/4 flex-col gap-2'>
+ <div className='flex gap-2'>
+ <div>
+ <Image
+ src={saleOrder.products[0]?.parent?.image}
+ alt={saleOrder.products[0]?.name}
+ className='object-contain object-center border border-gray_r-6 h-32 w-full rounded-md'
+ />
+ </div>
+ <div className='flex flex-col gap-3 justify-start'>
+ <p className='flex flex-row gap-2'>
+ <span className='text-sm text-black'>
+ Nomor PO:
+ </span>
+ <span className='text-sm text-red-500 font-semibold'>
+ {saleOrder.purchaseOrderName || '-'}
+ </span>
+ </p>
+ <p className='line-clamp-2 leading-6 tracking-wide opacity-90 !text-gray_r-12 font-semibold text-nowrap'>
+ {saleOrder.products[0]?.parent?.name}
+ </p>
+ <p className='opacity-85 !text-gray_r-12'>
+ {saleOrder.products[0]?.quantity} x{' '}
+ {currencyFormat(
+ saleOrder.products[0]?.price
+ ?.priceDiscount
+ )}
+ </p>
+ <div className='flex flex-row justify-start items-center'>
+ {saleOrder.products?.length > 1 && (
+ <div className='flex flex-row gap-1 justify-start items-center'>
+ {saleOrder.products
+ .slice(1, 6)
+ .map((product, index) => (
+ <Image
+ key={index} // Tambahkan key untuk setiap elemen dalam map()
+ src={product?.parent?.image}
+ alt={product?.name}
+ className='object-contain object-center border border-gray_r-6 h-8 w-8 rounded-md'
+ />
+ ))}
+ <Link
+ href={`/my/quotations/${saleOrder?.id}`}
+ className='text-sm text-red-500 text-nowrap'
+ >
+ Lihat semua produk
+ </Link>
+ </div>
+ )}
</div>
- )}
+ </div>
+ </div>
+ <div className='flex flex-row w-full text-nowrap gap-2 text-black'>
+ <span className='text-sm'>
+ Pesanan dibuat oleh:
+ </span>
+ <p className='text-sm font-semibold'>
+ {saleOrder.address.customer?.name || '-'}
+ </p>
+ </div>
+ </div>
+ <div className='w-[1px] h-24 bg-gray-300'></div>
+ <div className='w-1/4 flex flex-row gap-3 justify-center items-center'>
+ <div className='flex flex-col text-black'>
+ <p>Total Harga</p>
+ <p className='font-bold'>
+ {currencyFormat(saleOrder.amountTotal)}
+ </p>
+ </div>
+ <div>
+ <button
+ type='button'
+ onClick={() =>
+ handleBuyBack(saleOrder.products)
+ }
+ className='flex-1 py-2 btn-solid-red text-nowrap'
+ >
+ Beli Lagi
+ </button>
</div>
</div>
</div>
- <div className='flex flex-row w-full text-nowrap gap-2'>
- <span className='text-sm'>
- pesanan dibuat oleh:
- </span>
- <p className='text-sm font-semibold'>
- {saleOrder.address.customer?.name || '-'}
- </p>
- </div>
- </div>
- <div className='w-[1px] h-24 bg-gray-300'></div>
- <div className='w-1/5'>Total harga</div>
+ </Link>
</div>
- {/* </Link> */}
- </div>
- ))}
- </div>
- )}
+ ))}
+ </div>
+ )}
</div>
- <table className='table-data'>
+ {/* <table className='table-data'>
<thead>
<tr>
<th>No. Transaksi</th>
@@ -670,7 +857,7 @@ const Transactions = ({ context = '' }) => {
</tr>
))}
</tbody>
- </table>
+ </table> */}
<Pagination
pageCount={pageCount}