diff options
| author | trisusilo48 <tri.susilo@altama.co.id> | 2025-03-27 14:44:54 +0700 |
|---|---|---|
| committer | trisusilo48 <tri.susilo@altama.co.id> | 2025-03-27 14:44:54 +0700 |
| commit | 969e193708e01ffb88c0d81d72d63dad200e0ef8 (patch) | |
| tree | 59c44292727bdfecb2970cb1d8130c53c0075653 /src/lib | |
| parent | f88f457fd1b91298ea8a7f9f396e49660a81e276 (diff) | |
| parent | d64f70fbc89e2cea6cbd95f5c3e3af437a3c2810 (diff) | |
Merge branch 'new-release' into feature/integrasi_biteship
# Conflicts:
# src/lib/address/components/EditAddress.jsx
Diffstat (limited to 'src/lib')
19 files changed, 452 insertions, 51 deletions
diff --git a/src/lib/address/components/EditAddress.jsx b/src/lib/address/components/EditAddress.jsx index 60ca20b7..9f038b74 100644 --- a/src/lib/address/components/EditAddress.jsx +++ b/src/lib/address/components/EditAddress.jsx @@ -71,7 +71,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); @@ -246,7 +246,8 @@ const EditAddress = ({ id, defaultValues }) => { ); } } - if (address?.id) { + // if (isUpdated?.id) { + if (address?.id && (auth.company && auth?.partnerId == id ? isUpdated?.id : true)) { toast.success('Berhasil mengubah alamat'); router.back(); } else { @@ -254,10 +255,13 @@ const EditAddress = ({ id, defaultValues }) => { router.back(); } } catch (error) { + console.log(error); toast.error('Terjadi kesalahan internal'); router.back(); } + + // if (isUpdated?.id) { // if (address?.id && auth.company ? isUpdated?.id : true) { // toast.success('Berhasil mengubah alamat'); diff --git a/src/lib/auth/components/CompanyProfile.jsx b/src/lib/auth/components/CompanyProfile.jsx index 410d6a23..6d4da1d1 100644 --- a/src/lib/auth/components/CompanyProfile.jsx +++ b/src/lib/auth/components/CompanyProfile.jsx @@ -59,7 +59,7 @@ 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); 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 fa8d8aea..637706a2 100644 --- a/src/lib/checkout/components/Checkout.jsx +++ b/src/lib/checkout/components/Checkout.jsx @@ -184,6 +184,7 @@ const Checkout = () => { let dataVoucher = await getVoucher(auth?.id, { source: query, type: 'all,brand', + partner_id : auth?.partnerId, }); SetListVoucher(dataVoucher); @@ -411,13 +412,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); diff --git a/src/lib/checkout/components/CheckoutSection.jsx b/src/lib/checkout/components/CheckoutSection.jsx index 623152c6..c82e15c7 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 && ( <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/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..fcfa7e1e 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,6 +302,59 @@ 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] @@ -311,7 +367,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); @@ -366,10 +424,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 +869,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 && ( @@ -955,7 +1053,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { {...props} options={zips} disabled={ - !watchsubDistrict || sameAddressStreet + sameAddressStreet } placeholder='Zip' /> @@ -968,7 +1066,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { placeholder='Kode Pos' type='number' disabled={ - !watchsubDistrict || sameAddressStreet + sameAddressStreet } value={formPengiriman.zipPengiriman} className='form-input' @@ -1035,6 +1133,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> @@ -1193,7 +1323,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { {...props} options={zipsInvoice} disabled={ - !watchsubDistrictInvoice || sameAddress + sameAddress } placeholder='Zip' /> @@ -1205,7 +1335,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { placeholder='Kode Pos' type='number' disabled={ - !watchsubDistrictInvoice || sameAddress + sameAddress } value={formPengiriman.zipInvoice} className='form-input' @@ -1280,6 +1410,48 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { </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> + <div className='flex flex-row justify-between items-start'> <div className='w-2/5'> <label className='form-label text-wrap'> @@ -1429,6 +1601,7 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { )} </div> </div> + </div> </form> </div> @@ -1483,6 +1656,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 +1898,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 +2141,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 @@ -2067,6 +2330,8 @@ const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => { </div> <div className='w-2/5'></div> </div> + + </div> </form> </div> 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 3e342bf0..486d1a4b 100644 --- a/src/lib/product/components/ProductSearch.jsx +++ b/src/lib/product/components/ProductSearch.jsx @@ -549,7 +549,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 && ( <> |
