import React from 'react'; import { useMemo, useState, useEffect, useRef } from 'react'; import Image from '~/components/ui/image'; import Stepper from './Stepper'; import InformasiPerusahaan from './informasiPerusahaan'; import KontakPerusahaan from './KontakPerusahaan'; import Pengiriman from './Pengiriman'; import Referensi from './Referensi'; import Dokumen from './Dokumen'; import Konfirmasi from './Konfirmasi'; import { getAuth } from '~/libs/auth'; import { setAuth } from '@/core/utils/auth'; import useAuth from '@/core/hooks/useAuth'; import { useRouter } from 'next/router'; import { Controller, useForm } from 'react-hook-form'; import { usePengajuanTempoStore, usePengajuanTempoStoreKontakPerson, usePengajuanTempoStorePengiriman, usePengajuanTempoStoreSupplier, usePengajuanTempoStoreDokumen, } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline'; import createPengajuanTempoApi from '../api/createPengajuanTempoApi'; import { Button, Checkbox, Spinner, Tooltip } from '@chakra-ui/react'; import clsxm from '~/libs/clsxm'; import { toast } from 'react-hot-toast'; import useDevice from '@/core/hooks/useDevice'; import odooApi from '~/libs/odooApi'; import editAuthTempo from '../api/editAuthTempo'; import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; import PageContent from '@/lib/content/components/PageContent'; const PengajuanTempo = () => { const { isDesktop, isMobile } = useDevice(); const [currentStep, setCurrentStep] = React.useState(0); const NUMBER_OF_STEPS = 6; const [isLoading, setIsLoading] = useState(false); const [bigData, setBigData] = useState(); const [idTempo, setIdTempo] = useState(0); const { form, errors, validate, updateForm } = usePengajuanTempoStore(); const { control, watch, setValue, setError } = useForm(); const auth = useAuth(); console.log('auth', auth); const router = useRouter(); const [BannerTempo, setBannerTempo] = useState(); const { formDokumen, errorsDokumen, validateDokumen, updateFormDokumen } = usePengajuanTempoStoreDokumen(); const { formKontakPerson, errorsKontakPerson, validateKontakPerson, updateFormKontakPerson, } = usePengajuanTempoStoreKontakPerson(); const { formSupplier, errorsSupplier, validateSupplier, updateFormSupplier, hasSavedata, updateHasSave, } = usePengajuanTempoStoreSupplier(); const { formPengiriman, errorsPengiriman, validatePengiriman, updateFormPengiriman, } = usePengajuanTempoStorePengiriman(); const [notValid, setNotValid] = useState(false); const [buttonSubmitClick, setButtonSubmitClick] = useState(false); const stepDivs = [ , , , , , , ]; const stepDivsError = [ errors, errorsKontakPerson, errorsPengiriman, errorsSupplier, errorsDokumen,
Konfirmasi
, ]; const stepDivsForm = [ form, formKontakPerson, formPengiriman, formSupplier, formDokumen, '', ]; const stepDivsUpdateForm = [ updateForm, updateFormKontakPerson, updateFormPengiriman, updateFormSupplier, updateFormDokumen,
Konfirmasi
, ]; const stepLabels = [ 'informasi_perusahaan', 'kontak_person', 'Pengiriman', 'Referensi', 'Dokumen', 'Konfirmasi', ]; const isFormValid = useMemo( () => Object.keys(stepDivsError[currentStep]).length === 0, [stepDivsError[currentStep]] ); useEffect(() => { validate(); validateKontakPerson(); validatePengiriman(); validateDokumen(); updateHasSave(true); if (isFormValid) { window.scrollTo({ top: 0, behavior: 'smooth', }); } }, [currentStep, buttonSubmitClick]); useEffect(() => { window.scrollTo({ top: 0, behavior: 'smooth', }); }, [currentStep]); useEffect(() => { const loadBigData = async () => { const toCamelCase = (str) => str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()); const transformKeysToCamelCase = (data) => { if (Array.isArray(data)) { return data.map((item) => transformKeysToCamelCase(item)); } else if (data && typeof data === 'object') { return Object.keys(data).reduce((acc, key) => { const camelKey = toCamelCase(key); // Ubah kunci menjadi camelCase acc[camelKey] = transformKeysToCamelCase(data[key]); // Rekursif untuk nested object atau array return acc; }, {}); } 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/${payment}` ); const transformedData = transformKeysToCamelCase(dataPaymentTerm); setBigData(transformedData); } catch (error) { console.error('Error loading dataPaymentTerm:', error); } }; loadBigData(); }, [auth]); useEffect(() => { const cachedData = bigData; const loadBigData = async () => { if (cachedData) { // Ambil kunci-kunci yang relevan berdasarkan currentStep dari stepDivsForm const formKeys = stepDivsForm[currentStep] ? Object.keys(stepDivsForm[currentStep]) : []; if (currentStep === 3) { stepDivsUpdateForm[currentStep](cachedData.supplierIds); } else if (currentStep === 4) { formKeys.forEach((key) => { if (cachedData[key]) { // Proses hanya kunci yang ada di cachedData const { name, format, base64 } = cachedData[key]; stepDivsUpdateForm[currentStep](key, name, format, base64); } }); } else { formKeys.forEach((key) => { if (bigData[key]) { // Ubah data menjadi string const stringData = typeof bigData[key] === 'object' ? JSON.stringify(bigData[key]) // Untuk objek atau array : 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); } } }); } } }; loadBigData(); validate(); validateKontakPerson(); validatePengiriman(); validateDokumen(); validateSupplier(); updateHasSave(true); }, [currentStep, bigData, auth]); const goToNextStep = () => { if (!isFormValid) { setNotValid(true); setButtonSubmitClick(!buttonSubmitClick); return; } else { // saveToLocalStorage(stepLabels[currentStep], stepDivsForm[currentStep]); if (currentStep == 3) { handleDaftarTempoSupplier(); } else if (currentStep == 4) { handleDaftarTempoDokumen(); } else { handleDaftarTempoPerPage( stepLabels[currentStep], stepDivsForm[currentStep] ); } setButtonSubmitClick(!buttonSubmitClick); setNotValid(false); } setCurrentStep((prev) => (prev === NUMBER_OF_STEPS - 1 ? prev : prev + 1)); }; const goPrevStep = () => { // if (!isFormValid) { // setNotValid(true); // setButtonSubmitClick(!buttonSubmitClick); // return; // } else { // // saveToLocalStorage(stepLabels[currentStep], stepDivsForm[currentStep]); // if (currentStep == 3) { // handleDaftarTempoSupplier(); // } else if (currentStep == 4) { // handleDaftarTempoDokumen(); // } else { // handleDaftarTempoPerPage( // stepLabels[currentStep], // stepDivsForm[currentStep] // ); // } // setButtonSubmitClick(!buttonSubmitClick); // setNotValid(false); // } setCurrentStep((prev) => (prev === NUMBER_OF_STEPS - 1 ? prev : prev - 1)); }; const handleDaftarTempoPerPage = async ( label, formData, tempoRequest = false ) => { for (const error of stepDivsError) { if (error.length > 0) { return; } } const toastId = toast.loading('Mengirimkan formulir pengajuan tempo...'); setIsLoading(true); try { const address = await createPengajuanTempoApi({ id: idTempo, 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); } toast.dismiss(toastId); setIsLoading(false); } catch (error) { toast.dismiss(toastId); setIsLoading(false); toast.error('Terjadi kesalahan dalam pengiriman formulir'); console.error(error); } }; const handleDaftarTempoDokumen = async () => { for (const error of stepDivsError) { if (error.length > 0) { return; } } // Filter hanya dokumen dengan `format` yang tidak undefined const formattedDokumen = Object.entries(formDokumen) .filter(([_, doc]) => doc.format !== undefined) // Hanya dokumen dengan `format` tidak undefined .map(([key, doc]) => ({ documentName: key, details: { name: doc.name, format: doc.format, base64: doc.base64, }, })); const toastId = toast.loading('Mengirimkan formulir pengajuan tempo...'); if (formattedDokumen.length === 0) { // toast.error('Tidak ada dokumen valid untuk dikirim.'); return; } setIsLoading(true); try { const address = await createPengajuanTempoApi({ id: idTempo, user_id: auth.parentId ? auth.parentId : auth.partnerId, partner_id: auth.partnerId, formDocs: JSON.stringify(formattedDokumen), }); if (address.id) { setIdTempo(address.id); } toast.dismiss(toastId); setIsLoading(false); } catch (error) { toast.dismiss(toastId); setIsLoading(false); toast.error('Terjadi kesalahan dalam pengiriman formulir'); console.error(error); } }; const isSupplierDataChanged = (formSupplier, supplierIds) => { if (formSupplier.length !== supplierIds.length) { return true; } return formSupplier.some((supplier, index) => { const original = supplierIds[index]; return ( supplier.supplier !== original.supplier || supplier.pic !== original.pic || supplier.telepon !== original.telepon || supplier.durasiTempo !== original.durasiTempo || supplier.creditLimit !== original.creditLimit ); }); }; const handleDaftarTempoSupplier = async () => { for (const error of stepDivsError) { if (error.length > 0) { return; } } const productOrder = formSupplier.map((product) => ({ supplier: product.supplier, pic: product.pic, telepon: product.telepon, durasiTempo: product.durasiTempo, creditLimit: product.creditLimit, })); // Periksa perubahan const toastId = toast.loading('Mengirimkan formulir pengajuan tempo...'); if (bigData?.supplierIds) { if (!isSupplierDataChanged(productOrder, bigData.supplierIds)) { return; } } setIsLoading(true); try { const address = await createPengajuanTempoApi({ id: idTempo, user_id: auth.parentId ? auth.parentId : auth.partnerId, partner_id: auth.partnerId, formSupplier: JSON.stringify(productOrder), }); if (address.id) { setIdTempo(address.id); } toast.dismiss(toastId); setIsLoading(false); } catch (error) { toast.dismiss(toastId); setIsLoading(false); toast.error('Terjadi kesalahan dalam pengiriman formulir'); console.error(error); } }; const handleDaftarTempo = async () => { const phones = [ { key: 'mobile', label: 'No. HP Perusahaan', value: form.mobile?.trim() }, { key: 'direkturMobile', label: 'No. HP Direktur', value: formKontakPerson.direkturMobile?.trim(), }, { key: 'purchasingMobile', label: 'No. HP Purchasing', value: formKontakPerson.purchasingMobile?.trim(), }, { key: 'financeMobile', label: 'No. HP Finance', value: formKontakPerson.financeMobile?.trim(), }, { key: 'PICBarangMobile', label: 'No. HP PIC Barang', value: formPengiriman.PICBarangMobile?.trim(), }, { key: 'invoicePicMobile', label: 'No. HP PIC Invoice', value: formPengiriman.invoicePicMobile?.trim(), }, ].filter((p) => p.value); const seen = new Map(); let firstErrorField = null; // Reset error manual phones.forEach((p) => setError(p.key, { type: 'manual', message: '' })); for (const phone of phones) { if (!seen.has(phone.value)) { seen.set(phone.value, phone); } else { const first = seen.get(phone.value); // Tampilkan toast toast.error(`${phone.label} tidak boleh sama dengan ${first.label}`); // Error merah di bawah input setError(phone.key, { type: 'manual', message: `${phone.label} tidak boleh sama dengan ${first.label}`, }); // Pasangan pertama yang duplikat setError(first.key, { type: 'manual', message: `${first.label} tidak boleh sama dengan ${phone.label}`, }); if (!firstErrorField) { firstErrorField = phone.key; } } } if (firstErrorField) { setTimeout(() => { const el = document.querySelector(`[name="${firstErrorField}"]`); if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); el.focus(); } }, 100); return; } for (const error of stepDivsError) { if (error.length > 0) { return; } } const formattedDokumen = Object.entries(formDokumen) .filter(([_, doc]) => doc.format !== undefined) .map(([key, doc]) => ({ documentName: key, details: { name: doc.name, format: doc.format, base64: doc.base64, }, })); const toastId = toast.loading('Mengirimkan formulir pengajuan tempo...'); setIsLoading(true); try { let address4; let address3; const address = await createPengajuanTempoApi({ id: 0, partner_id: auth.partnerId, user_id: auth.parentId ? auth.parentId : auth.partnerId, tempo_request: false, ...form, }); if (address.id) { const address2 = await createPengajuanTempoApi({ id: address.id, partner_id: auth.partnerId, user_id: address.userId, tempo_request: false, ...formKontakPerson, }); if (address2.id) { address3 = await createPengajuanTempoApi({ id: address2.id, partner_id: auth.partnerId, user_id: address2.userId, tempo_request: false, ...formPengiriman, formDokumenProsedur: formPengiriman.dokumenProsedur ? JSON.stringify(formPengiriman.dokumenProsedur) : false, }); if (address3.id && formattedDokumen.length > 0) { address4 = await createPengajuanTempoApi({ id: address3.id, partner_id: auth.partnerId, user_id: address3.userId, tempo_request: true, formDocs: JSON.stringify(formattedDokumen), }); } else { address4 = await createPengajuanTempoApi({ id: address3.id, partner_id: auth.partnerId, user_id: address3.userId, tempo_request: true, }); } } } if (address4?.id) { toast.success('Pengajuan tempo berhasil dilakukan'); const toastId2 = toast.loading('Mengubah status akun...'); const isUpdated = await editAuthTempo(); if (isUpdated?.user) { const update = await setAuth(isUpdated.user); if (update) { toast.dismiss(toastId2); setIsLoading(false); toast.success('Berhasil mengubah status akun', { duration: 1000 }); router.push('/pengajuan-tempo/finish'); } else { toast.dismiss(toastId2); setIsLoading(false); toast.success('Pengajuan tempo berhasil dilakukan'); toast.error('Gagal mengubah status akun', { duration: 1000 }); router.push('/pengajuan-tempo'); } removeFromLocalStorage(); return; } } else { toast.dismiss(toastId); setIsLoading(false); toast.error('Terjadi kesalahan dalam pengiriman formulir'); } } catch (error) { toast.dismiss(toastId); setIsLoading(false); toast.error('Terjadi kesalahan dalam pengiriman formulir'); console.error(error); } }; const removeFromLocalStorage = () => { for (const key of stepLabels) { localStorage.removeItem(key); } }; const [isCheckedTNC, setIsCheckedTNC] = useState(false); const handleCheckChange = (checked) => { setIsCheckedTNC(checked); }; useEffect(() => { const getBanner = async () => { const get = await odooApi('GET', '/api/v1/banner?type=banner-form-tempo'); setBannerTempo(get[0].image); // setBannerTempo( // 'https://erp.indoteknik.com/api/image/x_banner.banner/x_banner_image/431' // ); }; getBanner(); }, []); return ( <>
{BannerTempo && ( FORM Tempo )}

Form Pengajuan Tempo

Pembayaran tempo adalah layanan pembayaran berjangka yang difasilitasi indoteknik.com untuk konsumen akun bisnis yang terdaftar dengan waktu pembayaran mulai dari 7, 14, 21 hingga 30 Hari.

{stepDivs[currentStep]}
{isDesktop &&
} {isMobile && (
)}
*Pastikan data yang anda masukan sudah benar dan sesuai
0 && currentStep < 5 ? 'justify-between' : 'justify-end' } items-center w-full ${isMobile ? 'gap-x-4 ' : ''}`} > {currentStep < 5 && currentStep > 0 && ( )} {currentStep < 5 && ( <> )}
{currentStep == 5 && (
)}
); }; const TempoTermCondition = ({ onCheckChange }) => { const [isCheckedTNC, SetIsCheckedTNC] = useState(false); const [openTNC, SetOpenTNC] = useState(false); const { isDesktop, isMobile } = useDevice(); const openTNCHandle = () => { SetOpenTNC(!openTNC); }; const toggleCheckTNC = () => { const newValue = !isCheckedTNC; SetIsCheckedTNC(newValue); if (onCheckChange) { onCheckChange(newValue); } }; return ( <>
{' '} syarat dan ketentuan
SetOpenTNC(false)} title='Syarat & Ketentuan Pendaftaran Tempo' > ); }; export default PengajuanTempo;