diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2024-04-05 07:42:54 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2024-04-05 07:42:54 +0000 |
| commit | d551570b1a4c08d415e299f37eba86879ba96b57 (patch) | |
| tree | 9bce735e93158ea1aaa1a3be6ca013cc22507b35 | |
| parent | 8eb374869c950c3879d0b463729d1f078b38325a (diff) | |
| parent | 50425ea134852897bf125aae0f68a1642eb3b3b8 (diff) | |
Merged in feature/voucher-shipment (pull request #133)
Add voucher shipping feature
| -rw-r--r-- | src/lib/checkout/api/checkoutApi.js | 34 | ||||
| -rw-r--r-- | src/lib/checkout/api/getVoucher.js | 37 | ||||
| -rw-r--r-- | src/lib/checkout/components/Checkout.jsx | 224 |
3 files changed, 224 insertions, 71 deletions
diff --git a/src/lib/checkout/api/checkoutApi.js b/src/lib/checkout/api/checkoutApi.js index 24f1868a..fd982fff 100644 --- a/src/lib/checkout/api/checkoutApi.js +++ b/src/lib/checkout/api/checkoutApi.js @@ -1,28 +1,20 @@ -import odooApi from '@/core/api/odooApi' -import { getAuth } from '@/core/utils/auth' +import odooApi from '@/core/api/odooApi'; +import { getAuth } from '@/core/utils/auth'; export const checkoutApi = async ({ data }) => { - const auth = getAuth() + const auth = getAuth(); const dataCheckout = await odooApi( 'POST', `/api/v1/partner/${auth.partnerId}/sale_order/checkout`, data - ) - return dataCheckout -} + ); + return dataCheckout; +}; -export const getProductsCheckout = async (voucher, query) => { - const id = getAuth()?.id - let products - if(voucher && query){ - products = await odooApi('GET',`/api/v1/user/${id}/sale_order/checkout?voucher=${voucher}&source=buy`) - }else if (voucher){ - products = await odooApi('GET',`/api/v1/user/${id}/sale_order/checkout?voucher=${voucher}`) - }else if (query) { - products = await odooApi('GET',`/api/v1/user/${id}/sale_order/checkout?source=buy`) - }else{ - products = await odooApi('GET',`/api/v1/user/${id}/sale_order/checkout`) - } - - return products -} +export const getProductsCheckout = async (query) => { + const queryParam = new URLSearchParams(query); + const userId = getAuth()?.id; + const url = `/api/v1/user/${userId}/sale_order/checkout?${queryParam.toString()}`; + const result = await odooApi('GET', url); + return result; +}; diff --git a/src/lib/checkout/api/getVoucher.js b/src/lib/checkout/api/getVoucher.js index 07cf376e..54c8cce5 100644 --- a/src/lib/checkout/api/getVoucher.js +++ b/src/lib/checkout/api/getVoucher.js @@ -1,21 +1,24 @@ -import odooApi from '@/core/api/odooApi' +import odooApi from '@/core/api/odooApi'; -export const getVoucher = async (id, source) => { - let dataVoucher = null - if(source){ - dataVoucher = await odooApi('GET', `/api/v1/user/${id}/voucher?source=${source}`) - }else { - dataVoucher = await odooApi('GET', `/api/v1/user/${id}/voucher`) - } - return dataVoucher -} +export const getVoucher = async (id, query) => { + const queryParam = new URLSearchParams(query); + const url = `/api/v1/user/${id}/voucher?${queryParam.toString()}`; + const dataVoucher = await odooApi('GET', url); + return dataVoucher; +}; export const findVoucher = async (code, id, source) => { - let dataVoucher = null - if(source){ - dataVoucher = await odooApi('GET', `/api/v1/user/${id}/voucher?code=${code}&source=${source}`) - }else{ - dataVoucher = await odooApi('GET', `/api/v1/user/${id}/voucher?code=${code}`) + let dataVoucher = null; + if (source) { + dataVoucher = await odooApi( + 'GET', + `/api/v1/user/${id}/voucher?code=${code}&source=${source}` + ); + } else { + dataVoucher = await odooApi( + 'GET', + `/api/v1/user/${id}/voucher?code=${code}` + ); } - return dataVoucher -} + return dataVoucher; +}; diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index 52edbd05..042fc258 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -43,9 +43,16 @@ const Checkout = () => { const auth = useAuth(); const [activeVoucher, SetActiveVoucher] = useState(null); - - const { data: cartCheckout } = useQuery('cartCheckout-' + activeVoucher, () => - getProductsCheckout(activeVoucher, query) + const [activeVoucherShipping, setActiveVoucherShipping] = useState(null); + + const { data: cartCheckout } = useQuery( + ['cartCheckout', activeVoucher, activeVoucherShipping], + () => + getProductsCheckout({ + source: query, + voucher: activeVoucher, + voucher_shipping: activeVoucherShipping, + }) ); const [selectedAddress, setSelectedAddress] = useState({ @@ -103,6 +110,7 @@ const Checkout = () => { const [bottomPopupTnC, SetBottomPopupTnC] = useState(null); const [itemTnC, setItemTnC] = useState(null); const [listVouchers, SetListVoucher] = useState(null); + const [listVoucherShippings, SetListVoucherShipping] = useState(null); const [discountVoucher, SetDiscountVoucher] = useState(0); const [codeVoucher, SetCodeVoucher] = useState(null); const [findCodeVoucher, SetFindVoucher] = useState(null); @@ -117,13 +125,23 @@ const Checkout = () => { const voucher = async () => { if (!listVouchers) { try { - let dataVoucher = await getVoucher(auth?.id, query); + setLoadingVoucher(true); + let dataVoucher = await getVoucher(auth?.id, { + source: query, + }); SetListVoucher(dataVoucher); + + let dataVoucherShipping = await getVoucher(auth?.id, { + source: query, + type: 'shipping', + }); + SetListVoucherShipping(dataVoucherShipping); } finally { setLoadingVoucher(false); } } }; + const VoucherCode = async (code) => { let dataVoucher = await findVoucher(code, auth.id, query); if (dataVoucher.length <= 0) { @@ -333,6 +351,7 @@ const Checkout = () => { estimated_arrival_days: splitDuration(etd), delivery_service_type: selectedExpedisiService, voucher: activeVoucher, + voucher_shipping: activeVoucherShipping, type: 'sale_order', }; @@ -419,6 +438,11 @@ const Checkout = () => { return false; }, [products]); + const voucherShippingAmt = cartCheckout?.discountVoucherShipping || 0; + const discShippingAmt = Math.min(biayaKirim, voucherShippingAmt); + + const finalShippingAmt = biayaKirim - discShippingAmt; + return ( <> <BottomPopup @@ -528,8 +552,145 @@ const Checkout = () => { </div> )} - <hr className='mt-10 my-4 border-gray_r-10' /> - <div className=''> + <hr className='mt-8 mb-4 border-gray_r-8' /> + + {listVoucherShippings && listVoucherShippings?.length > 0 && ( + <div> + <h3 className='font-semibold mb-4'>Promo Gratis Ongkir</h3> + {listVoucherShippings?.map((item) => ( + <div key={item.id} className='relative'> + <div + className={`border border-solid mb-5 w-full hover:cursor-pointer p-2 pl-4 pr-4 `} + > + {item.canApply && ( + <div + class='p-2 mb-4 text-sm text-green-800 rounded-lg bg-green-50 dark:text-green-400' + role='alert' + > + <p> + Potensi potongan sebesar{' '} + <span className='text-green font-bold'> + {currencyFormat(item.discountVoucher)} + </span> + </p> + </div> + )} + {!item.canApply && ( + <div + class='p-2 mb-4 text-sm text-red-800 rounded-lg bg-red-50' + role='alert' + onClick={() => handlingTnC(item)} + > + <p> + Voucher tidak bisa di gunakan,{' '} + <span className='text-red font-bold'> + Baca Selengkapnya ! + </span> + </p> + </div> + )} + + <div className={`flex gap-x-3 relative`}> + {item.canApply === false && ( + <div className='absolute w-full h-full bg-gray_r-3/40 top-0 left-0 z-50' /> + )} + <div className='hidden md:w-[250px] md:block'> + <Image + src={item.image} + alt={item.name} + className={`object-cover`} + /> + </div> + <div className='w-full'> + <div className='flex justify-between gap-x-2 mb-1 items-center'> + <div className=''> + <h3 className='font-semibold'>{item.name}</h3> + <div className='mt-1'> + <span className='text-sm line-clamp-3'> + {item.description}{' '} + </span> + </div> + </div> + <div className='flex justify-end'> + <label class='relative inline-flex items-center cursor-pointer'> + <input + type='checkbox' + value='' + class='sr-only peer' + checked={activeVoucherShipping === item.code} + onChange={() => + setActiveVoucherShipping( + activeVoucherShipping === item.code + ? null + : item.code + ) + } + /> + <div class="w-11 h-6 bg-gray-200 rounded-full peer dark:bg-gray-700 peer-focus:ring-4 peer-focus:ring-green-300 dark:peer-focus:ring-green-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-green-600"></div> + </label> + </div> + </div> + <hr className='mt-2 my-2 border-gray_r-8' /> + <div className='flex justify-between items-center'> + <p className='text-justify text-sm md:text-xs'> + Kode Voucher :{' '} + <span className='text-red-500 font-semibold'> + {item.code} + </span> + </p> + <p className='text-sm md:text-xs'> + {activeVoucher === item.code && ( + <span className=' text-green-600'> + Voucher digunakan{' '} + </span> + )} + </p> + </div> + <div className='flex items-center mt-3'> + <svg + aria-hidden='true' + fill='none' + stroke='currentColor' + stroke-width='1.5' + viewBox='0 0 24 24' + className='w-5 text-black' + > + <path + d='M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z' + stroke-linecap='round' + stroke-linejoin='round' + ></path> + </svg> + <div className='flex justify-between items-center'> + <div className='text-left ml-3 text-sm '> + Berakhir dalam{' '} + <span className='text-red-600'> + {item.remainingTime} + </span>{' '} + lagi,{' '} + </div> + <div + className='text-sm ml-2 text-red-600' + onClick={() => handlingTnC(item)} + > + Baca S&K + </div> + </div> + </div> + </div> + </div> + <div className='mt-3'> + <p className='text-justify text-sm '></p> + </div> + </div> + </div> + ))} + </div> + )} + + <hr className='mt-8 mb-4 border-gray_r-8' /> + + <div> {!loadingVoucher && listVouchers?.length === 0 ? ( <div className='flex items-center justify-center mt-4 mb-4'> <div className='text-center'> @@ -714,14 +875,7 @@ const Checkout = () => { </div> </div> <div className='mt-3'> - <p className='text-justify text-sm '> - {/* {item.canApply === false - ? 'Tambah ' + - currencyFormat(item.differenceToApply) + - ' untuk pakai promo ini' - : 'Potensi potongan sebesar ' + - currencyFormat(hitungDiscountVoucher(item.code))} */} - </p> + <p className='text-justify text-sm '></p> </div> </div> </div> @@ -887,14 +1041,18 @@ const Checkout = () => { </div> <div className='flex gap-x-2 justify-between'> <div className='text-gray_r-11'> - Biaya Kirim <p className='text-xs mt-3'>{etdFix}</p> - </div> - <div> - {currencyFormat( - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 - )} + Biaya Kirim <p className='text-xs mt-1'>{etdFix}</p> </div> + <div>{currencyFormat(biayaKirim)}</div> </div> + {activeVoucherShipping && voucherShippingAmt && ( + <div className='flex gap-x-2 justify-between'> + <div className='text-gray_r-11'>Diskon Kirim</div> + <div className='text-danger-500'> + - {currencyFormat(discShippingAmt)} + </div> + </div> + )} </div> )} @@ -913,10 +1071,7 @@ const Checkout = () => { <div className='flex gap-x-2 justify-between mb-4'> <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> - {currencyFormat( - cartCheckout?.grandTotal + - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 - )} + {currencyFormat(cartCheckout?.grandTotal + finalShippingAmt)} </div> </div> )} @@ -926,7 +1081,7 @@ const Checkout = () => { <div className='mt-4 mb-4'> <button type='button' - onClick={() => { + onClick={async () => { SetBottomPopup(true); voucher(); }} @@ -1182,14 +1337,18 @@ const Checkout = () => { <div className='flex gap-x-2 justify-between'> <div className='text-gray_r-11'> Biaya Kirim - <p className='text-xs mt-3'>{etdFix}</p> - </div> - <div> - {currencyFormat( - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 - )} + <p className='text-xs mt-1'>{etdFix}</p> </div> + <div>{currencyFormat(biayaKirim)}</div> </div> + {activeVoucherShipping && voucherShippingAmt && ( + <div className='flex gap-x-2 justify-between'> + <div className='text-gray_r-11'>Diskon Kirim</div> + <div className='text-danger-500'> + - {currencyFormat(discShippingAmt)} + </div> + </div> + )} </div> )} @@ -1209,8 +1368,7 @@ const Checkout = () => { <div>Grand Total</div> <div className='font-semibold text-gray_r-12'> {currencyFormat( - cartCheckout?.grandTotal + - Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 + cartCheckout?.grandTotal + finalShippingAmt )} </div> </div> |
