diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-05-14 09:27:26 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-05-14 09:27:26 +0700 |
| commit | 29ecab270822500ead372d8d3e05c9281a514715 (patch) | |
| tree | a32735f4b7fab774de6a2bbee9380f363c51bec2 /src/lib | |
| parent | dd66804b05166ad6bb71bf54fe3374d9897fee86 (diff) | |
| parent | 746a11b810ae9e8a974a76d0548297cd0faff9b5 (diff) | |
Merge branch 'new-release' into CR/form-merchant
Diffstat (limited to 'src/lib')
21 files changed, 547 insertions, 88 deletions
diff --git a/src/lib/address/components/EditAddress.jsx b/src/lib/address/components/EditAddress.jsx index 62858465..ba6bd25b 100644 --- a/src/lib/address/components/EditAddress.jsx +++ b/src/lib/address/components/EditAddress.jsx @@ -38,7 +38,7 @@ const EditAddress = ({ id, defaultValues }) => { useEffect(() => { const loadProfile = async () => { - const dataProfile = await addressApi({ id: auth.parentId }); + const dataProfile = await addressApi({ id: auth.partnerId }); setValue('industry', dataProfile.industryId); setValue('companyType', dataProfile.companyTypeId); setValue('taxName', dataProfile.taxName); @@ -161,7 +161,7 @@ const EditAddress = ({ id, defaultValues }) => { } // if (isUpdated?.id) { - if (address?.id && auth.company ? isUpdated?.id : true) { + if (address?.id && (auth.company && auth?.partnerId == id ? isUpdated?.id : true)) { toast.success('Berhasil mengubah alamat'); router.back(); } else { diff --git a/src/lib/auth/components/CompanyProfile.jsx b/src/lib/auth/components/CompanyProfile.jsx index 410d6a23..d404ebe7 100644 --- a/src/lib/auth/components/CompanyProfile.jsx +++ b/src/lib/auth/components/CompanyProfile.jsx @@ -59,7 +59,11 @@ const CompanyProfile = () => { useEffect(() => { const loadProfile = async () => { const dataProfile = await addressApi({ - id: auth.parentId ? auth.parentId : auth.parent_id, + id: auth?.company + ? auth.parentId + ? auth.parentId + : auth.partnerId + : auth.partnerId, }); setCompany_type(dataProfile?.companyType); setValue('name', dataProfile?.name); @@ -311,9 +315,19 @@ const CompanyProfile = () => { <input {...register('npwp')} type='text' + disabled className='form-input mt-3' maxLength={16} /> + <span className='text-xs opacity-60 text-red-500'> + *Untuk mengganti NPWP bisa menghubungi kami{' '} + <a + href='https://wa.me/6281717181922' target='_blank' rel='noreferrer' + style={{ textDecoration: 'underline' }} + > + disini. + </a> + </span> <div className='text-caption-2 text-danger-500 mt-1'> {errors.npwp?.message} </div> diff --git a/src/lib/auth/components/Menu.jsx b/src/lib/auth/components/Menu.jsx index 4682dbab..df33314c 100644 --- a/src/lib/auth/components/Menu.jsx +++ b/src/lib/auth/components/Menu.jsx @@ -197,6 +197,7 @@ const Menu = () => { <button type='button' className='text-gray_r-12/80 p-2 text-left hover:bg-gray_r-5 ' + onClick={() => logout()} > <div className='flex gap-x-3 items-center'> <ImageNext diff --git a/src/lib/category/components/Category.jsx b/src/lib/category/components/Category.jsx index 91553295..15bfabc9 100644 --- a/src/lib/category/components/Category.jsx +++ b/src/lib/category/components/Category.jsx @@ -14,7 +14,7 @@ const Category = () => { const [openCategories, setOpenCategory] = useState([]); const [banner, setBanner] = useState([]); - const promotionProgram = useQuery('banner-promo-category-card', bannerApi({ type: 'banner-promo-category-card' })); + // const promotionProgram = useQuery('banner-promo-category-card', bannerApi({ type: 'banner-promo-category-card' })); useEffect(() => { const loadCategories = async () => { diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx index e3b586f1..5256a328 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -39,18 +39,20 @@ const { getProductsCheckout } = require('../api/checkoutApi'); function convertToInternational(number) { if (typeof number !== 'string') { - throw new Error("Input harus berupa string"); + throw new Error('Input harus berupa string'); } if (number.startsWith('08')) { - return '+62' + number.slice(2); + return '+62' + number.slice(2); } return number; } const Checkout = () => { - const PPN = process.env.NEXT_PUBLIC_PPN ? parseFloat(process.env.NEXT_PUBLIC_PPN) : 0; + const PPN = process.env.NEXT_PUBLIC_PPN + ? parseFloat(process.env.NEXT_PUBLIC_PPN) + : 0; const router = useRouter(); const query = router.query.source ?? null; const qVoucher = router.query.voucher ?? null; @@ -145,15 +147,31 @@ const Checkout = () => { if (!listVouchers) { try { setLoadingVoucher(true); + const productCategories = products + ?.reduce((categories, product) => { + if (product.categories && Array.isArray(product.categories)) { + product.categories.forEach((category) => { + if (category.id && !categories.includes(category.id)) { + categories.push(category.id); + } + }); + } + return categories; + }, []) + .join(','); + let dataVoucher = await getVoucher(auth?.id, { source: query, type: 'all,brand', + partner_id: auth?.partnerId, + voucher_category: productCategories, // Add the product categories }); SetListVoucher(dataVoucher); let dataVoucherShipping = await getVoucher(auth?.id, { source: query, type: 'shipping', + voucher_category: productCategories, // Add the product categories }); SetListVoucherShipping(dataVoucherShipping); } finally { @@ -163,10 +181,23 @@ const Checkout = () => { }; const VoucherCode = async (code) => { - // let dataVoucher = await findVoucher(code, auth.id, query); + const productCategories = products + ?.reduce((categories, product) => { + if (product.categories && Array.isArray(product.categories)) { + product.categories.forEach((category) => { + if (category.id && !categories.includes(category.id)) { + categories.push(category.id); + } + }); + } + return categories; + }, []) + .join(','); + let dataVoucher = await getVoucher(auth?.id, { source: query, code: code, + voucher_category: productCategories, // Add the product categories }); if (dataVoucher.length <= 0) { SetFindVoucher(1); @@ -482,13 +513,25 @@ const Checkout = () => { if (query) { data.source = 'buy'; } - if (poNumber.current.value) data.po_number = poNumber.current.value; + if (poNumber.current.value) { + if (typeof file == 'undefined') { + toast.error( + 'Nomor PO ' + + poNumber.current.value + + ' telah dimasukkan, Harap upload file PO yang dimaksud' + ); + setIsLoading(false); + return; + } + data.po_number = poNumber.current.value; + } if (typeof file !== 'undefined') data.po_file = await getFileBase64(file); const isCheckouted = await checkoutApi({ data }); if (!isCheckouted?.id) { toast.error('Gagal melakukan transaksi, terjadi kesalahan internal'); + setIsLoading(false); return; } else { gtagPurchase(products, biayaKirim, isCheckouted.name); @@ -504,10 +547,12 @@ const Checkout = () => { gtag('set', 'user_data', { email: auth.email, - phone_number: convertToInternational(auth.mobile) ?? convertToInternational(auth.phone), + phone_number: + convertToInternational(auth.mobile) ?? + convertToInternational(auth.phone), }); - gtag('config', 'AW-954540379', { ' allow_enhanced_conversions':true } ) ; + gtag('config', 'AW-954540379', { ' allow_enhanced_conversions': true }); for (const product of products) deleteItemCart({ productId: product.id }); if (grandTotal > 0) { @@ -1114,7 +1159,7 @@ const Checkout = () => { </Skeleton> )} <Divider /> - <SectionValidation address={selectedAddress.invoicing} /> + <SectionValidation address={selectedAddress.shipping} /> <SectionExpedisi address={selectedAddress.shipping} listExpedisi={listExpedisi} @@ -1210,7 +1255,9 @@ const Checkout = () => { <div>{currencyFormat(cartCheckout?.subtotal)}</div> </div> <div className='flex gap-x-2 justify-between'> - <div className='text-gray_r-11'>PPN {((PPN - 1) * 100).toFixed(0)}%</div> + <div className='text-gray_r-11'> + PPN {((PPN - 1) * 100).toFixed(0)}% + </div> <div>{currencyFormat(cartCheckout?.tax)}</div> </div> <div className='flex gap-x-2 justify-between'> @@ -1412,7 +1459,7 @@ const Checkout = () => { </Skeleton> )} <Divider /> - <SectionValidation address={selectedAddress.invoicing} /> + <SectionValidation address={selectedAddress.shipping} /> <SectionExpedisi address={selectedAddress.shipping} listExpedisi={listExpedisi} @@ -1514,7 +1561,9 @@ const Checkout = () => { <div>{currencyFormat(cartCheckout?.subtotal)}</div> </div> <div className='flex gap-x-2 justify-between'> - <div className='text-gray_r-11'>PPN {((PPN - 1) * 100).toFixed(0)}%</div> + <div className='text-gray_r-11'> + PPN {((PPN - 1) * 100).toFixed(0)}% + </div> <div>{currencyFormat(cartCheckout?.tax)}</div> </div> <div className='flex gap-x-2 justify-between'> @@ -1697,7 +1746,8 @@ const SectionAddress = ({ address, label, url }) => ( ); const SectionValidation = ({ address }) => - address?.stateId == 0 && ( + address?.stateId == 0 || + (address?.rajaongkirCityId == 0 && ( <BottomPopup active={true} title='Update Alamat'> <div className='leading-7 text-gray_r-12/80'> Mohon untuk memperbarui alamat Anda dengan mengklik tombol di bawah ini.{' '} @@ -1711,7 +1761,7 @@ const SectionValidation = ({ address }) => </Link> </div> </BottomPopup> - ); + )); const SectionExpedisi = ({ address, diff --git a/src/lib/checkout/components/CheckoutSection.jsx b/src/lib/checkout/components/CheckoutSection.jsx index 623152c6..c6be9056 100644 --- a/src/lib/checkout/components/CheckoutSection.jsx +++ b/src/lib/checkout/components/CheckoutSection.jsx @@ -33,7 +33,7 @@ export const SectionAddress = ({ address, label, url }) => { }; export const SectionValidation = ({ address }) => - address?.rajaongkirCityId == 0 && ( + address?.stateId == 0 || address?.rajaongkirCityId == 0 && ( <BottomPopup active={true} title='Update Alamat'> <div className='leading-7 text-gray_r-12/80'> Mohon untuk memperbarui alamat Anda dengan mengklik tombol di bawah ini.{' '} diff --git a/src/lib/flashSale/api/flashSaleApi.js b/src/lib/flashSale/api/flashSaleApi.js index 115b07dc..410b720c 100644 --- a/src/lib/flashSale/api/flashSaleApi.js +++ b/src/lib/flashSale/api/flashSaleApi.js @@ -1,8 +1,9 @@ import odooApi from '@/core/api/odooApi' -const flashSaleApi = async () => { - const flashSale = await odooApi('GET', '/api/v1/flashsale/header') +const flashSaleApi = async ({isShow = true}) => { + const flashSale = await odooApi('GET', '/api/v1/flashsale/header?is_show_program='+isShow) return flashSale } export default flashSaleApi +
\ No newline at end of file diff --git a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx index 4b420fac..adcc7ba0 100644 --- a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx +++ b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx @@ -13,14 +13,14 @@ const FlashSaleNonDisplay = () => { const router = useRouter(); useEffect(() => { const loadFlashSales = async () => { - const dataFlashSales = await flashSaleApi(); + const dataFlashSales = await flashSaleApi({isShow: false}); setFlashSales(dataFlashSales); setIsLoading(false); }; loadFlashSales(); }, []); - const handleSubmit = () => { - router.push(`/shop/search?penawaran=${flashSales[0]?.pricelistId}`); + const handleSubmit = (flashSale) => { + router.push(`/shop/search?penawaran=${flashSale?.pricelistId}`); }; if (isLoading) { return <FlashSaleSkeleton />; @@ -33,10 +33,10 @@ const FlashSaleNonDisplay = () => { <div key={index}> <div className='flex items-center mb-4 justify-between '> <div className='font-medium sm:text-h-lg mt-1.5'> - Penawaran Terbatas + {flashSale.name} </div> <div - onClick={handleSubmit} + onClick={() => handleSubmit(flashSale)} className='!text-red-500 font-semibold cursor-pointer' > Lihat Semua @@ -56,7 +56,7 @@ const FlashSaleProduct = ({ flashSaleId }) => { useEffect(() => { const loadProducts = async () => { const dataProducts = await productSearchApi({ - query: `fq=-flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=25&orderBy=flashsale-discount-desc&source=similar`, + query: `fq=flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=25&orderBy=flashsale-discount-desc&source=similar`, operation: 'AND', }); setProducts(dataProducts.response); diff --git a/src/lib/home/components/ServiceList.jsx b/src/lib/home/components/ServiceList.jsx index e32e8747..8fa1cf22 100644 --- a/src/lib/home/components/ServiceList.jsx +++ b/src/lib/home/components/ServiceList.jsx @@ -59,7 +59,7 @@ const ServiceList = () => { </div> <div className='w-full '> <Link - href='/pembayaran-tempo-detail' + href='/pengajuan-tempo' className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg' > <div className=''> diff --git a/src/lib/pengajuan-tempo/component/Dokumen.jsx b/src/lib/pengajuan-tempo/component/Dokumen.jsx index f986d47a..aedb9016 100644 --- a/src/lib/pengajuan-tempo/component/Dokumen.jsx +++ b/src/lib/pengajuan-tempo/component/Dokumen.jsx @@ -566,7 +566,7 @@ const Dokumen = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { > <div> <label className='form-label text-nowrap'> - Foto tempat kerja + Foto Ruangan Tempat Kerja </label> <span className='text-xs opacity-60 text-red-500'> Format: pdf, jpeg, jpg, png. max file size 2MB @@ -1144,7 +1144,7 @@ const Dokumen = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { ref={dokumenTempatBekerjaRef} > <label className='form-label text-nowrap'> - Foto tempat kerja + Foto Ruangan Tempat Kerja </label> <div className='flex flex-row gap-2'> <label diff --git a/src/lib/pengajuan-tempo/component/KonfirmasiDokumen.jsx b/src/lib/pengajuan-tempo/component/KonfirmasiDokumen.jsx index 66d33b43..7c10f80c 100644 --- a/src/lib/pengajuan-tempo/component/KonfirmasiDokumen.jsx +++ b/src/lib/pengajuan-tempo/component/KonfirmasiDokumen.jsx @@ -646,7 +646,7 @@ const KonfirmasiDokumen = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { <div className='w-full flex flex-row items-center '> <div className='w-2/5'> <label className='form-label text-nowrap'> - Foto tempat kerja + Foto Ruangan Tempat Kerja </label> </div> <div className='w-3/5'> @@ -1492,7 +1492,7 @@ const KonfirmasiDokumen = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { <div className='w-full flex flex-row items-center '> <div className='w-2/5'> <label className='form-label text-wrap'> - Foto tempat kerja + Foto Ruangan Tempat Kerja </label> </div> <div className='w-3/5'> diff --git a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx index 5bef5134..7cf201b7 100644 --- a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx +++ b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx @@ -173,11 +173,11 @@ const PengajuanTempo = () => { } return data; // Jika bukan object atau array, kembalikan nilai aslinya }; - + const payment = auth?.parentId ? auth?.parentId : auth?.partnerId; try { const dataPaymentTerm = await odooApi( 'GET', - `/api/v1/partner/detail-tempo/${auth.parentId}` + `/api/v1/partner/detail-tempo/${payment}` ); const transformedData = transformKeysToCamelCase(dataPaymentTerm); setBigData(transformedData); @@ -191,7 +191,6 @@ const PengajuanTempo = () => { useEffect(() => { const cachedData = bigData; - const loadBigData = async () => { if (cachedData) { // Ambil kunci-kunci yang relevan berdasarkan currentStep dari stepDivsForm @@ -218,6 +217,10 @@ const PengajuanTempo = () => { : String(bigData[key]); // Untuk tipe primitif // Kirim data yang sudah diubah ke string ke stepDivsUpdateForm stepDivsUpdateForm[currentStep](key, stringData); + if (key == 'dokumenProsedur') { + const stringData = bigData[key]; + stepDivsUpdateForm[currentStep](key, stringData); + } } }); } @@ -293,11 +296,14 @@ const PengajuanTempo = () => { try { const address = await createPengajuanTempoApi({ id: idTempo, - user_id: auth.parentId, + user_id: auth.parentId ? auth.parentId : auth.partnerId, partner_id: auth.partnerId, section: label, tempo_request: tempoRequest, ...formData, + formDokumenProsedur: formData.dokumenProsedur + ? JSON.stringify(formData.dokumenProsedur) + : false, }); if (address.id) { setIdTempo(address.id); @@ -341,7 +347,7 @@ const PengajuanTempo = () => { try { const address = await createPengajuanTempoApi({ id: idTempo, - user_id: auth.parentId, + user_id: auth.parentId ? auth.parentId : auth.partnerId, partner_id: auth.partnerId, formDocs: JSON.stringify(formattedDokumen), }); @@ -402,7 +408,7 @@ const PengajuanTempo = () => { try { const address = await createPengajuanTempoApi({ id: idTempo, - user_id: auth.parentId, + user_id: auth.parentId ? auth.parentId : auth.partnerId, partner_id: auth.partnerId, formSupplier: JSON.stringify(productOrder), }); @@ -447,7 +453,7 @@ const PengajuanTempo = () => { const address = await createPengajuanTempoApi({ id: 0, partner_id: auth.partnerId, - user_id: auth.parentId, + user_id: auth.parentId ? auth.parentId : auth.partnerId, tempo_request: false, ...form, }); @@ -466,6 +472,9 @@ const PengajuanTempo = () => { user_id: address2.userId, tempo_request: false, ...formPengiriman, + formDokumenProsedur: formPengiriman.dokumenProsedur + ? JSON.stringify(formPengiriman.dokumenProsedur) + : false, }); if (address3.id && formattedDokumen.length > 0) { // Kirim dokumen yang sudah difilter @@ -518,7 +527,7 @@ const PengajuanTempo = () => { toast.dismiss(toastId); setIsLoading(false); - toast.error('Terjadi kesalahan dalam pengiriman formulir'); + toast.error('Terjadi kesalahan dalam pengiriman formulir hehehehe'); console.error(error); } }; @@ -647,11 +656,14 @@ const PengajuanTempo = () => { <TempoTermCondition onCheckChange={handleCheckChange} /> <Button colorScheme='red' - w={`${isMobile ? 'full' : '36'}`} - isDisabled={!isCheckedTNC} + w={`${isMobile ? 'full' : '48'}`} + isDisabled={!isCheckedTNC || isLoading} onClick={handleDaftarTempo} > - Daftar Tempo {<ChevronRightIcon className='w-5' />} + {isLoading + ? 'Loading...' + : 'Daftar Tempo'} + {!isLoading && <ChevronRightIcon className='w-5' />} </Button> </div> )} diff --git a/src/lib/pengajuan-tempo/component/Pengiriman.jsx b/src/lib/pengajuan-tempo/component/Pengiriman.jsx index 755cf45d..a8e7fd22 100644 --- a/src/lib/pengajuan-tempo/component/Pengiriman.jsx +++ b/src/lib/pengajuan-tempo/component/Pengiriman.jsx @@ -13,6 +13,7 @@ import { } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; import { toast } from 'react-hot-toast'; import useDevice from '@/core/hooks/useDevice'; +import getFileBase64 from '@/core/utils/getFileBase64'; const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { const { control, watch, setValue } = useForm(); const { isDesktop, isMobile } = useDevice(); @@ -21,6 +22,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { errorsPengiriman, validatePengiriman, updateFormPengiriman, + updateDokumenProsedur, } = usePengajuanTempoStorePengiriman(); const { form } = usePengajuanTempoStore(); const [states, setState] = useState([]); @@ -34,6 +36,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { const [zipsInvoice, setZipsInvoice] = useState([]); const [sameAddress, setSameAddress] = useState(false); const [sameAddressStreet, setSameAddressStreet] = useState(false); + const [nameFile, setNameFile] = useState(); const [selectedIds, setSelectedIds] = useState( formPengiriman.dokumenPengiriman @@ -299,11 +302,66 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { validatePengiriman(); }; + const handleInputChangeFile = async (event) => { + let fileBase64 = ''; + const { name } = event.target; + const file = event.target.files?.[0]; + // Allowed file extensions + const allowedExtensions = ['pdf', 'png', 'jpg', 'jpeg']; + let fileExtension = ''; + if (file) { + fileExtension = file.name.split('.').pop()?.toLowerCase(); // Extract file extension + + // Check if the file extension is allowed + if (!fileExtension || !allowedExtensions.includes(fileExtension)) { + toast.error( + 'Format file yang diijinkan adalah .pdf, .png, .jpg, atau .jpeg', + { duration: 4000 } + ); + + event.target.value = ''; + return; + } + + // Check for file size + if (file.size > 2000000) { + // try { + // const toastId = toast.loading('mencoba mengompresi file...'); + // // Compress image file + // const options = { + // maxSizeMB: 0.5, // Target size in MB + // maxWidthOrHeight: 1920, // Adjust as needed + // useWebWorker: true, + // }; + // const compressedFile = await imageCompression(file, options); + // toast.success('berhasil mengompresi file', { duration: 4000 }); + // // Convert compressed file to Base64 + // fileBase64 = await getFileBase64(compressedFile); + // updateFormDokumen( + // name, + // compressedFile.name, + // fileExtension, + // fileBase64 + // ); + // } catch (error) { + // toast.error('Gagal mengompresi file', { duration: 4000 }); + // } + toast.error('Max File Upload 2MB', { duration: 4000 }); + } else { + // Convert file to Base64 + fileBase64 = await getFileBase64(file); + updateDokumenProsedur(file.name, fileExtension, fileBase64); + } + validatePengiriman(); + } + }; const isFormValid = useMemo( () => Object.keys(errorsPengiriman).length === 0, [errorsPengiriman] ); + const tukarInvoiceInputRef = useRef(null); + const tukarInvoiceInputPembayaranRef = useRef(null); const PICNameRef = useRef(null); const streetPengirimanRef = useRef(null); const statePengirimanRef = useRef(null); @@ -311,7 +369,9 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { const districtPengirimanRef = useRef(null); const subDistrictPengirimanRef = useRef(null); const zipRef = useRef(null); + const PICBarangMobileRef = useRef(null); const invoicePicRef = useRef(null); + const invoicePicMobileRef = useRef(null); const streetInvoiceRef = useRef(null); const stateInvoiceRef = useRef(null); const cityInvoiceRef = useRef(null); @@ -332,6 +392,14 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { behavior: 'smooth', block: 'center', }; + if (errorsPengiriman.tukarInvoiceInput && tukarInvoiceInputRef.current) { + tukarInvoiceInputRef.current.scrollIntoView(options); + return; + } + if (errorsPengiriman.tukarInvoiceInputPembayaran && tukarInvoiceInputPembayaranRef.current) { + tukarInvoiceInputPembayaranRef.current.scrollIntoView(options); + return; + } if (errorsPengiriman.PICName && PICNameRef.current) { PICNameRef.current.scrollIntoView(options); return; @@ -366,10 +434,18 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { zipRef.current.scrollIntoView(options); return; } + if (errorsPengiriman.PICBarangMobile && PICBarangMobileRef.current) { + PICBarangMobileRef.current.scrollIntoView(options); + return; + } if (errorsPengiriman.invoicePic && invoicePicRef.current) { invoicePicRef.current.scrollIntoView(options); return; } + if (errorsPengiriman.invoicePicMobile && invoicePicMobileRef.current) { + invoicePicMobileRef.current.scrollIntoView(options); + return; + } if (errorsPengiriman.streetInvoice && streetInvoiceRef.current) { streetInvoiceRef.current.scrollIntoView(options); return; @@ -803,6 +879,38 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { <div className='flex flex-row justify-between items-start'> <div className='w-2/5'> <label className='form-label text-nowrap'> + No. HP PIC Penerimaan Barang + </label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + isi nomor PIC penerimaan barang yang bertanggung jawab di + perusahaan anda + </span> + )} + </div> + <div className='w-3/5'> + <input + id='PICBarangMobile' + name='PICBarangMobile' + ref={PICBarangMobileRef} + placeholder='Masukkan nomor PIC penerimaan barang' + value={formPengiriman.PICBarangMobile} + type='tel' + className='form-input' + aria-invalid={errorsPengiriman.PICBarangMobile} + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errorsPengiriman.PICBarangMobile} + </div> + )} + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> Alamat Pengiriman Barang </label> {!isKonfirmasi && ( @@ -954,9 +1062,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { <HookFormSelect {...props} options={zips} - disabled={ - !watchsubDistrict || sameAddressStreet - } + disabled={sameAddressStreet} placeholder='Zip' /> ) : ( @@ -967,9 +1073,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { ref={zipRef} placeholder='Kode Pos' type='number' - disabled={ - !watchsubDistrict || sameAddressStreet - } + disabled={sameAddressStreet} value={formPengiriman.zipPengiriman} className='form-input' onChange={handleInputChange} @@ -1035,6 +1139,38 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { <div className='flex flex-row justify-between items-start'> <div className='w-2/5'> + <label className='form-label text-nowrap'> + No. HP PIC Penerimaan Invoice + </label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + isi nomor PIC penerimaan invoice yang bertanggung jawab di + perusahaan anda + </span> + )} + </div> + <div className='w-3/5'> + <input + id='invoicePicMobile' + name='invoicePicMobile' + ref={invoicePicMobileRef} + placeholder='Masukkan nomor PIC Penerimaan Invoice' + value={formPengiriman.invoicePicMobile} + type='tel' + className='form-input' + aria-invalid={errorsPengiriman.invoicePicMobile} + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errorsPengiriman.invoicePicMobile} + </div> + )} + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5'> <label className='form-label text-nowrap'> Alamat Pengiriman Invoice </label> @@ -1192,9 +1328,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { <HookFormSelect {...props} options={zipsInvoice} - disabled={ - !watchsubDistrictInvoice || sameAddress - } + disabled={sameAddress} placeholder='Zip' /> ) : ( @@ -1204,9 +1338,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { ref={zipInvoiceRef} placeholder='Kode Pos' type='number' - disabled={ - !watchsubDistrictInvoice || sameAddress - } + disabled={sameAddress} value={formPengiriman.zipInvoice} className='form-input' onChange={handleInputChange} @@ -1231,11 +1363,10 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { <div className='w-2/5'> <label className='form-label text-wrap'> Jadwal Penukaran Invoice{' '} - <span className=' opacity-60'>(Opsional)</span> </label> {!isKonfirmasi && ( <span className='text-xs opacity-60'> - isi jika perusahaan anda memiliki jadwal penukaran invoice + isi jadwal penukaran invoice </span> )} </div> @@ -1248,9 +1379,17 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { value={formPengiriman.tukarInvoiceInput} className='form-input' rows={4} + aria-invalid={errorsPengiriman.tukarInvoiceInput} + ref={tukarInvoiceInputRef} cols={40} onChange={handleInputChange} + required /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errorsPengiriman.tukarInvoiceInput} + </div> + )} </div> </div> @@ -1258,11 +1397,10 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { <div className='w-2/5'> <label className='form-label text-nowrap'> Jadwal Pembayaran{' '} - <span className=' opacity-60'>(Opsional)</span> </label> {!isKonfirmasi && ( <span className='text-xs opacity-60'> - isi jika perusahaan anda memiliki jadwal pembayaran + isi jadwal pembayaran </span> )} </div> @@ -1273,10 +1411,60 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { placeholder='Masukkan jadwal pembayaran' value={formPengiriman.tukarInvoiceInputPembayaran} className='form-input' + aria-invalid={errorsPengiriman.tukarInvoiceInputPembayaran} + ref={tukarInvoiceInputPembayaranRef} rows={4} cols={40} onChange={handleInputChange} + required /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errorsPengiriman.tukarInvoiceInputPembayaran} + </div> + )} + </div> + </div> + + <div className='w-full flex flex-row justify-between items-start'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Prosedur Pengiriman{' '} + <span className=' opacity-60'>(Opsional)</span> + </label> + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + </div> + <div className='w-3/5'> + <div className='flex flex-row items-start gap-2'> + <label + htmlFor='dokumenProsedur' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {formPengiriman?.dokumenProsedur?.name + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + id='dokumenProsedur' + name='dokumenProsedur' + type='file' + title=' ' + className='hidden' + aria-invalid={formPengiriman.dokumenProsedur} + onChange={handleInputChangeFile} + accept='.pdf,.png,.jpg,.jpeg' + /> + <span className='text-gray-600 line-clamp-2'> + {formPengiriman?.dokumenProsedur?.name} + </span> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errorsPengiriman.dokumenProsedur} + </div> + )} </div> </div> @@ -1483,6 +1671,30 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { </div> <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label text-nowrap'> + No. HP PIC Penerimaan Barang + </label> + <div className='flex items-center border border-gray-300 rounded-md w-full'> + <input + id='PICBarangMobile' + name='PICBarangMobile' + ref={PICBarangMobileRef} + value={formPengiriman.PICBarangMobile} + placeholder='Masukkan nomor PIC penerimaan barang' + type='tel' + className='form-input' + aria-invalid={errorsPengiriman.PICBarangMobile} + onChange={handleInputChange} + /> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errorsPengiriman.PICBarangMobile} + </div> + )} + </div> + + <div className='flex flex-col gap-2 justify-between items-start'> <label className='form-label text-nowrap'> Alamat Pengiriman Barang </label> @@ -1701,6 +1913,30 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { </div> <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label text-nowrap'> + No. HP PIC Penerimaan Invoice + </label> + <div className='flex items-center border border-gray-300 rounded-md w-full'> + <input + id='invoicePicMobile' + name='invoicePicMobile' + ref={invoicePicMobileRef} + value={formPengiriman.invoicePicMobile} + placeholder='Masukkan nomor PIC Penerimaan Invoice' + type='tel' + className='form-input' + aria-invalid={errorsPengiriman.invoicePicMobile} + onChange={handleInputChange} + /> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errorsPengiriman.PICBarangMobile} + </div> + )} + </div> + + <div className='flex flex-col gap-2 justify-between items-start'> <label className='form-label text-nowrap'> Alamat Pengiriman Invoice </label> @@ -1920,6 +2156,48 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { </div> </div> + <div className='w-full flex flex-col justify-between items-start gap-2'> + <div className=''> + <label className='form-label text-nowrap'> + Prosedur Pengiriman{' '} + <span className=' opacity-60'>(Opsional)</span> + </label> + </div> + <div className='flex flex-col gap-2'> + <div className='flex flex-row items-start gap-2'> + <label + htmlFor='dokumenProsedur' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {formPengiriman?.dokumenProsedur?.name + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + id='dokumenProsedur' + name='dokumenProsedur' + type='file' + title=' ' + className='hidden' + aria-invalid={errorsPengiriman.dokumenProsedur} + onChange={handleInputChangeFile} + accept='.pdf,.png,.jpg,.jpeg' + /> + <span className='mt-2 text-gray-600 line-clamp-2'> + {formPengiriman?.dokumenProsedur?.name} + </span> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errorsPengiriman.dokumenProsedur} + </div> + )} + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + </div> + </div> + <div className='flex flex-col gap-2 justify-between items-start'> <label className='form-label text-wrap'> Apakah ada dokumen tanda terima yang diberikan pada saat diff --git a/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx index 25a3a7ee..4898a3f8 100644 --- a/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx +++ b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx @@ -470,7 +470,7 @@ const InformasiPerusahaan = ({ useEffect(() => { const loadProfile = async () => { try { - const dataProfile = await addressApi({ id: auth.parentId }); + const dataProfile = await addressApi({ id: auth.parentId ? auth.parentId : auth.partnerId }); if (dataProfile.name) { updateForm('name', dataProfile.name); } @@ -507,7 +507,7 @@ const InformasiPerusahaan = ({ } }; - if (auth?.parentId) { + if (auth?.parentId || auth?.partnerId) { loadProfile(); } }, [auth?.parentId]); @@ -782,7 +782,7 @@ const InformasiPerusahaan = ({ <HookFormSelect {...props} options={zips} - disabled={!watchsubDistrict} + // disabled={!watchsubDistrict} placeholder='Zip' /> ) : ( @@ -793,7 +793,7 @@ const InformasiPerusahaan = ({ ref={zipRef} placeholder='Kode Pos' type='number' - disabled={!watchsubDistrict} + // disabled={!watchsubDistrict} value={form.zip} className='form-input' onChange={handleInputChange} @@ -1333,7 +1333,7 @@ const InformasiPerusahaan = ({ <HookFormSelect {...props} options={zips} - disabled={!watchsubDistrict} + // disabled={!watchsubDistrict} placeholder='Zip' /> ) : ( @@ -1344,7 +1344,7 @@ const InformasiPerusahaan = ({ ref={zipRef} placeholder='Kode Pos' type='number' - disabled={!watchsubDistrict} + // disabled={!watchsubDistrict} value={form.zip} className='form-input' onChange={handleInputChange} diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx index 5dfd452b..de88e5bb 100644 --- a/src/lib/product/components/Product/ProductDesktopVariant.jsx +++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx @@ -26,7 +26,7 @@ import ProductCard from '../ProductCard'; import ProductSimilar from '../ProductSimilar'; import ProductPromoSection from '~/modules/product-promo/components/Section'; import SimilarBottom from '~/modules/product-detail/components/SimilarBottom'; - +import { gtagAddToCart } from '@/core/utils/googleTag'; const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST; const ProductDesktopVariant = ({ @@ -41,14 +41,38 @@ const ProductDesktopVariant = ({ const { srsltid } = router.query; const [askAdminUrl, setAskAdminUrl, isApproval] = useState(); const [lowestPrice, setLowestPrice] = useState(null); - + const [qtyPickUp, setQtyPickUp] = useState(0); const [addCartAlert, setAddCartAlert] = useState(false); const [isLoadingSLA, setIsLoadingSLA] = useState(true); - + const [selectedVariant, setSelectedVariant] = useState(product.id); const { setRefreshCart } = useProductCartContext(); const [quantityInput, setQuantityInput] = useState(1); + const [activeVariant, setActiveVariant] = useState({ + id: null, + code: product.code, + name: product.name, + price: lowestPrice, + stock: product.stockTotal, + weight: product.weight, + isFlashSale: product.isFlashSale, + }); + + useEffect(() => { + if (selectedVariant) { + setActiveVariant({ + id: product.id, + code: product.code, + name: product.name, + price: product.price, + stock: product.stockTotal, + weight: product.weight, + isFlashSale: product.isFlashSale, + }); + } + }, [selectedVariant, product]); + const createdAskUrl = whatsappUrl({ template: 'product', payload: { @@ -95,6 +119,7 @@ const ProductDesktopVariant = ({ } const quantity = quantityInput; if (!validQuantity(quantity)) return; + gtagAddToCart(activeVariant, quantity); updateItemCart({ productId: product.id, quantity, @@ -232,6 +257,17 @@ const ProductDesktopVariant = ({ fetchData(); }, [product]); + useEffect(() => { + const fetchData = async () => { + const qty_available = await odooApi( + 'GET', + `/api/v1/product_variant/${product.id}/qty_available` + ); + setQtyPickUp(qty_available?.qty); + }; + fetchData(); + }, [product]); + return ( <DesktopView> <div className='container mx-auto pt-10'> @@ -451,7 +487,7 @@ const ProductDesktopVariant = ({ </Skeleton> </div> <div> - {product?.sla?.qty > 0 && ( + {qtyPickUp > 0 && ( <Link href='/panduan-pick-up-service' className='group'> <Image src='/images/PICKUP-NOW.png' @@ -462,6 +498,14 @@ const ProductDesktopVariant = ({ )} </div> </div> + {qtyPickUp > 0 && ( + <> + <div className='text-[12px] mt-1 text-red-500 italic'> + * {qtyPickUp} barang bisa di pickup + </div> + <div className='h-4' /> + </> + )} <div className='flex gap-x-3'> <Button onClick={() => handleAddToCart(product.id)} diff --git a/src/lib/product/components/Product/ProductMobile.jsx b/src/lib/product/components/Product/ProductMobile.jsx index 4cfd3755..16182271 100644 --- a/src/lib/product/components/Product/ProductMobile.jsx +++ b/src/lib/product/components/Product/ProductMobile.jsx @@ -95,7 +95,11 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => { useEffect(() => { if (!selectedVariant && variantOptions.length == 1) { - setSelectedVariant(variantOptions[0]); + const selectedVariant = + variantOptions?.find((variant) => variant.is_in_bu) || + variantOptions?.[0]; + setSelectedVariant(selectedVariant); + // setSelectedVariant(variantOptions[0]); } }, [selectedVariant, variantOptions]); diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx index f7b044aa..eb86485d 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -84,10 +84,7 @@ const ProductSearch = ({ if (router.asPath.includes('penawaran')) { query = { ...query, - fq: [ - `-flashsale_id_i:${router.query.penawaran}`, - `flashsale_price_f:[1 TO *]`, - ], + fq:`flashsale_id_i:${router.query.penawaran} AND flashsale_price_f:[1 TO *]`, orderBy: 'flashsale-discount-desc', }; setFinalQuery(query); @@ -152,7 +149,7 @@ const ProductSearch = ({ }, [dataCategoriesProduct, dataLob]); useEffect(() => { - if (prefixUrl.includes('category') || prefixUrl.includes('lob')) { + if (prefixUrl.includes('category') || prefixUrl.includes('lob') || router.asPath.includes('penawaran')) { setQueryFinal({ ...finalQuery, q, limit, orderBy }); } else { setQueryFinal({ ...query, q, limit, orderBy }); @@ -549,7 +546,7 @@ const ProductSearch = ({ <div className='h-6' /> - <SideBanner /> + <SideBanner query={search} /> </div> <div className='w-9/12 pl-6'> diff --git a/src/lib/tempo/components/Tempo.jsx b/src/lib/tempo/components/Tempo.jsx index c246f3d8..19cd673b 100644 --- a/src/lib/tempo/components/Tempo.jsx +++ b/src/lib/tempo/components/Tempo.jsx @@ -153,14 +153,18 @@ const Tempo = () => { </Skeleton> </p> </div> - <div className='grid grid-flow-col gap-4'> + <div className='grid grid-flow-col gap-2'> <div className='border w-full p-4'> <p>Sisa Kredit Limit</p> <Skeleton isLoaded={!isLoading} - h='36px' + h='fit' w='full' - className='text-3xl font-semibold text-green-600' + className={`text-3xl font-semibold ${ + limitTempo - amountDue < 0 + ? 'text-red-500' + : 'text-green-600' + } `} > {limitTempo && amountDue ? currencyFormat( @@ -468,7 +472,11 @@ const Tempo = () => { isLoaded={!isLoading} // h='36px' // w={16} - className='font-semibold text-sm text-nowrap text-green-700 ' + className={`font-semibold text-sm text-nowrap ${ + limitTempo - amountDue < 0 + ? 'text-red-500' + : 'text-green-700' + }`} > {limitTempo && amountDue ? currencyFormat( diff --git a/src/lib/tracking-order/component/TrackingOrder.jsx b/src/lib/tracking-order/component/TrackingOrder.jsx index 8a7b2579..31ebd012 100644 --- a/src/lib/tracking-order/component/TrackingOrder.jsx +++ b/src/lib/tracking-order/component/TrackingOrder.jsx @@ -8,12 +8,17 @@ import { useQuery } from 'react-query'; import { Spinner } from '@chakra-ui/react'; import { Search } from 'lucide-react'; import Link from 'next/link'; +import odooApi from '~/libs/odooApi'; +import Image from '~/components/ui/image'; +import useDevice from '@/core/hooks/useDevice'; const TrackingOrder = () => { const [idAWB, setIdAWB] = useState(null); + const { isDesktop, isMobile } = useDevice(); const [inputQuery, setInputQuery] = useState(null); const [buttonClick, setButtonClick] = useState(false); const [apiError, setApiError] = useState(null); // State to store API error message + const [BannerTracking, setBannerTracking] = useState(); const closePopup = () => { setIdAWB(null); @@ -65,13 +70,35 @@ const TrackingOrder = () => { setButtonClick(true); }; + useEffect(() => { + const getBanner = async () => { + const get = await odooApi( + 'GET', + '/api/v1/banner?type=tracking-order-banner' + ); + setBannerTracking(get[0].image); + }; + getBanner(); + }, []); + return ( <div className='container mx-auto flex py-10 flex-col'> + <div className={`${isDesktop && 'min-h-96'} min-w-full`}> + {BannerTracking && ( + <Image + src={BannerTracking} + alt='Tracking Order' + width={500} + height={160} + className='w-full mt-6' + /> + )} + </div> <h1 className='text-h-sm md:text-title-sm font-semibold mb-6'> Tracking Order </h1> <div className='flex justify-start items-start'> - <p className='text-base w-full'> + <p className={`${isMobile ? 'text-sm' : 'text-base'} w-full text-pretty `}> {`Untuk melacak pesanan Anda, masukkan Nomor Transaksi di kotak bawah ini dan masukkan Email login anda lalu tekan tombol "Lacak". Nomor Transaksi ini dapat Anda lihat dalam menu `} <Link href='/my/transactions' className='text-red-500'> Daftar Transaksi @@ -93,7 +120,11 @@ const TrackingOrder = () => { onSubmit={handleSubmit(onSubmitHandler)} className='flex mt-4 flex-row w-full ' > - <div className='w-[90%] grid grid-cols-2 gap-4'> + <div + className={`w-[90%] grid ${ + isMobile ? 'grid-rows-3' : 'grid-cols-2' + } gap-4`} + > <div className='flex flex-col '> <label className='form-label mb-2'>ID Pesanan*</label> <input diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index b2fb2c17..2ca7d386 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -885,7 +885,7 @@ const Transaction = ({ id }) => { ? `| ${product?.attributes.join(', ')}` : ''} </div> - {product.soQty && product.reservedStockQty && ( + {product.soQty && ( <div className='text-[10px] text-red-500 italic mt-2'> {product.soQty !== product.reservedStockQty ? 'Barang sedang disiapkan' diff --git a/src/lib/variant/components/VariantCard.jsx b/src/lib/variant/components/VariantCard.jsx index 08b7a97e..79746995 100644 --- a/src/lib/variant/components/VariantCard.jsx +++ b/src/lib/variant/components/VariantCard.jsx @@ -7,12 +7,12 @@ import { createSlug } from '@/core/utils/slug' import currencyFormat from '@/core/utils/currencyFormat' import { updateItemCart } from '@/core/utils/cart' import whatsappUrl from '@/core/utils/whatsappUrl' -import {useState } from 'react'; +import { useEffect, useState } from 'react'; import rejectProductApi from '../../../lib/transaction/api/rejectProductApi' // import {useTransaction} from 'C:\Users\Indoteknik\next-indoteknik\src\lib\transaction\hooks\useTransaction.js' import useTransaction from '../../../lib/transaction/hooks/useTransaction'; import ImageNext from 'next/image'; - +import odooApi from '~/libs/odooApi'; const VariantCard = ({ product, openOnClick = true, buyMore = false }) => { const router = useRouter() const id = router.query.id @@ -21,7 +21,7 @@ const VariantCard = ({ product, openOnClick = true, buyMore = false }) => { const [isModalOpen, setIsModalOpen] = useState(false); const [selectedProduct, setSelectedProduct] = useState(null); const [reason, setReason] = useState(''); - + const [qtyPickUp, setQtyPickUp] = useState(0); const addItemToCart = () => { @@ -67,6 +67,17 @@ const VariantCard = ({ product, openOnClick = true, buyMore = false }) => { toast.error('Gagal reject produk. Silakan coba lagi.'); } }; + + useEffect(() => { + const fetchData = async () => { + const qty_available = await odooApi( + 'GET', + `/api/v1/product_variant/${product.id}/qty_available` + ); + setQtyPickUp(qty_available?.qty); + }; + fetchData(); + }, [product]); const Card = () => ( <div className='flex gap-x-3'> @@ -117,10 +128,18 @@ const VariantCard = ({ product, openOnClick = true, buyMore = false }) => { <p className='text-caption-2 text-gray_r-11 mt-1'> Berat Item : {product?.weight} Kg x {product?.quantity} Barang </p> - <p className='text-[10px] text-red-500 italic mt-2'> - {product.availableQuantity} barang ini bisa di pickup maksimal pukul + {product.soQty && ( + <div className='text-[10px] text-red-500 italic mt-2'> + {product.soQty !== product.reservedStockQty + ? 'Barang sedang disiapkan' + : `${product.reservedStockQty} barang bisa di + kirim/pickup`} + </div> + )} + {/* <p className='text-[10px] text-red-500 italic mt-2'> + {qtyPickUp} barang ini bisa di pickup maksimal pukul 16.00 - </p> + </p> */} <div className='flex flex-wrap gap-x-1 items-center mt-auto'> {product.hasFlashsale && ( <> |
