import HookFormSelect from '@/core/components/elements/Select/HookFormSelect'; import cityApi from '@/lib/address/api/cityApi'; import stateApi from '@/lib/address/api/stateApi.js'; import districtApi from '@/lib/address/api/districtApi'; import subDistrictApi from '@/lib/address/api/subDistrictApi'; import { yupResolver } from '@hookform/resolvers/yup'; import React, { useEffect, useRef, useState } from 'react'; import ReCAPTCHA from 'react-google-recaptcha'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; import * as Yup from 'yup'; import createMerchantApi from '../api/createMerchantApi'; import getMerchantApi from '../api/getMerchantApi'; import addressApi from '@/lib/address/api/addressApi'; import PageContent from '@/lib/content/components/PageContent'; import { useRouter } from 'next/router'; import useAuth from '@/core/hooks/useAuth'; import { Radio, RadioGroup, Stack, Checkbox, Button } from '@chakra-ui/react'; import { EyeIcon } from '@heroicons/react/24/outline'; import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; import Image from 'next/image'; import ImageBanner from '~/components/ui/image'; import { ChevronRightIcon } from '@heroicons/react/24/outline'; import MobileView from '@/core/components/views/MobileView'; import DesktopView from '@/core/components/views/DesktopView'; import getFileBase64 from '@/core/utils/getFileBase64'; import odooApi from '~/libs/odooApi'; import { formatValue } from 'react-currency-input-field'; const InformasiVendor = ({ handleIsError }) => { const isError = (value) => { // Logika menentukan error const result = value ? true : false; handleIsError(result); // Panggil handleIsError dari Merchant return result; }; const { register, handleSubmit, formState: { errors }, control, reset, watch, setValue, getValues, } = useForm({ resolver: yupResolver(validationSchema), defaultValues, }); const list_unit = [ { value: 'Manufacturing', label: 'Manufacturing', }, { value: 'Hospitality', label: 'Hospitality', }, { value: 'Automotive', label: 'Automotive', }, { value: 'Retail', label: 'Retail', }, { value: 'Maining', label: 'Maining', }, { value: 'Lain - Lain', label: 'Lain - Lain', }, ]; const [state, setState] = useState([]); const [cities, setCities] = useState([]); const [districts, setDistricts] = useState([]); const [fileNames, setFileNames] = useState({}); const [DeatailFile, setDetailFile] = useState({}); const [subDistricts, setSubDistricts] = useState([]); const [categoryProduk, setCategoryProduk] = useState([]); const [zips, setZips] = useState([]); const [isExample, setIsExample] = useState(false); const [BannerMerchant, setBannerMerchant] = useState(); const [isPkp, setIsPkp] = useState(false); const recaptchaRef = useRef(null); const router = useRouter(); const auth = useAuth(); if (auth == false) { router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`); } const dataTerhitungSejak = [ { value: 1, label: 'Terima PO' }, { value: 2, label: 'Barang Dikirimkan' }, { value: 3, label: 'Tukar Faktur' }, ]; const dataBisnisType = [ { value: 1, label: 'PT' }, { value: 2, label: 'CV' }, { value: 3, label: 'Perorangan' }, ]; const dataTempo = [ { value: 24, label: 'Tempo 14 Hari' }, { value: 25, label: 'Tempo 30 Hari' }, { value: 28, label: 'Tempo 60 Hari' }, { value: 31, label: 'Tempo 90 Hari' }, ]; const dataCategoryPerusahaan = [ { value: 1, label: 'Principal (Pemegang merk/Produsen)' }, { value: 2, label: 'Sole Distributor (Distributor Tunggal)' }, { value: 3, label: 'Authorized Distributor (Distributor Resmi)' }, { value: 4, label: 'Importer (Pengimpor Barang)' }, { value: 5, label: 'Wholesaler (Pedagang Besar)' }, ]; const category_produk = [ { id: 2040, name: 'Pengaman, Kesehatan & Keamanan' }, { id: 2097, name: 'Perkakas Tangan, Listrik & Pneumatic' }, { id: 2161, name: 'Mesin Industrial' }, { id: 2222, name: 'Mesin Pertanian & Perkebunan' }, { id: 2246, name: 'Mesin Pembersih & Janitorial' }, { id: 2273, name: 'Cairan Berbahan Kimia' }, { id: 2315, name: 'Perlengkapan Pengukuran & Pengujian' }, { id: 2354, name: 'Peralatan Listrik & Elektronik' }, { id: 2394, name: 'Perlengkapan Logistik & Gudang' }, { id: 2420, name: 'Peralatan Kantor & Stationery' }, { id: 2445, name: 'Komponen & Aksesoris' }, { id: 2477, name: 'Peralatan Horeca & Food Service' }, ]; const midIndex = Math.ceil(categoryProduk.length / 2); const firstColumn = categoryProduk.slice(0, midIndex); const secondColumn = categoryProduk.slice(midIndex); const [kreditLimitFormat, setKreditLimitFormat] = useState(); useEffect(() => { const loadData = async () => { const data = await getMerchantApi(); console.log('data vendor', data); reset({ hargaTayang: data.hargaTayang || '', categoryProduk: data.categoryProduk || '', merkDagang: data.merkDagang || '', isPengajuanTempo: data.isPengajuanTempo || '', tempoDuration: parseInt(data.tempoDuration) || '', // kreditLimit: parseInt(data.kreditLimit) || '', waktuPengiriman: data.waktuPengiriman || '', terhitungSejak: parseInt(data.terhitungSejak) || '', }); handleKreditLimitChange(data.kreditLimit); setSelectedIds(watch('categoryProduk').split(',').map(Number)); }; loadData(); }, []); const handleKreditLimitChange = (e) => { console.log('e', e); let value = e.target?.value ? e.target.value : e; // Hapus semua karakter non-numeric value = value.replace(/[^\d]/g, ''); // Format angka sebagai Rupiah tanpa mengubah nilai sebenarnya const formattedValue1 = formatValue({ value: value, groupSeparator: '.', decimalSeparator: ',', prefix: 'Rp ', }); setKreditLimitFormat(formattedValue1); setValue('kreditLimit', formattedValue1); }; const [selectedIds, setSelectedIds] = useState( watch('categoryProduk') ? watch('categoryProduk').split(',').map(Number) : [] // form.categoryProduk ? form.categoryProduk.split(',').map(Number) : [] // Parse string menjadi array angka // [] // Parse string menjadi array angka ); console.log( 'kategori produk', watch('categoryProduk').split(',').map(Number) ); console.log('selectedIds', selectedIds); const handleCheckboxChange = (id) => { const updatedSelected = selectedIds.includes(id) ? selectedIds.filter((selectedId) => selectedId !== id) : [...selectedIds, id]; console.log('updatedSelected', updatedSelected); setSelectedIds(updatedSelected); // Mengubah array kembali menjadi string yang dipisahkan oleh koma setValue('categoryProduk', updatedSelected.join(',')); }; const isChecked = (id) => selectedIds.includes(id); const handleCheckboxPortalChange = (value) => { setValue('isPengajuanTempo', `${value}`); }; useEffect(() => { window.scrollTo({ top: 0, behavior: 'smooth', }); }, []); console.log('categoryProduk', categoryProduk); useEffect(() => { const loadCategories = async () => { let dataCategories = await odooApi('GET', '/api/v1/category/tree'); const formattedCategories = dataCategories.map((category) => ({ id: category.id, name: category.name, })); console.log('formattedCategories', formattedCategories); // Simpan hasil ke state setCategoryProduk(formattedCategories); }; loadCategories(); }, []); useEffect(() => { const loadProfile = async () => { try { const dataProfile = await addressApi({ id: auth.parentId ? auth.parentId : auth.partnerId, }); if (dataProfile.companyType == 'pkp') { setIsPkp(true); } setValue('company', dataProfile?.name); setValue('address', dataProfile?.alamatBisnis); setValue('state', parseInt(dataProfile.stateId.id)); setValue('city', parseInt(dataProfile.city.id)); setValue('district', parseInt(dataProfile.district.id)); setValue('subDistrict', parseInt(dataProfile.subDistrict.id)); setValue('zip', parseInt(dataProfile.zip)); } catch (error) { console.error('Error loading profile:', error); } }; loadProfile(); }, [auth?.parentId]); useEffect(() => { const loadState = async () => { let dataState = await stateApi({ tempo: false }); dataState = dataState.map((state) => ({ value: state.id, label: state.name, })); setState(dataState); }; loadState(); }, []); const watchState = watch('state'); useEffect(() => { if (auth == false) { return; } if (watchState) { // setValue('city', ''); const loadCities = async () => { let dataCities = await cityApi({ stateId: watchState }); dataCities = dataCities?.map((city) => ({ value: city.id, label: city.name, })); setCities(dataCities); }; loadCities(); } }, [auth, watchState]); const watchCity = watch('city'); useEffect(() => { if (watchCity) { setValue('district', ''); const loadDistricts = async () => { let dataDistricts = await districtApi({ cityId: watchCity }); dataDistricts = dataDistricts.map((district) => ({ value: district.id, label: district.name, })); setDistricts(dataDistricts); }; loadDistricts(); } }, [watchCity]); const watchDistrict = watch('district'); useEffect(() => { if (watchDistrict) { setValue('subDistrict', ''); const loadSubDistricts = async () => { let dataSubDistricts = await subDistrictApi({ districtId: watchDistrict, }); dataSubDistricts = dataSubDistricts.map((district) => ({ value: district.id, label: district.name, })); setSubDistricts(dataSubDistricts); }; loadSubDistricts(); } }, [watchDistrict]); const watchsubDistrict = watch('subDistrict'); useEffect(() => { let kelurahan = ''; let kecamatan = ''; if (watchDistrict) { setValue('zip', ''); for (const data in districts) { if (districts[data].value == watchDistrict) { kecamatan = districts[data].label.toLowerCase(); } } } if (watchsubDistrict) { for (const data in subDistricts) { if (subDistricts[data].value == watchsubDistrict) { kelurahan = subDistricts[data].label.toLowerCase(); } } const loadZip = async () => { const response = await fetch( `https://alamat.thecloudalert.com/api/cari/index/?keyword=${kelurahan}` ); let dataMasuk = []; // Array untuk menyimpan kode pos yang sudah diproses const result = await response.json(); // Filter dan map data const dataZips = result.result .filter((zip) => zip.kecamatan.toLowerCase() === kecamatan) // Filter berdasarkan kecamatan .filter((zip) => { // Pastikan zip.kodepos belum ada di dataMasuk if (dataMasuk.includes(zip.kodepos)) { return false; // Jika sudah ada, maka skip (tidak akan ditambahkan) } else { dataMasuk.push(zip.kodepos); // Tambahkan ke dataMasuk return true; // Tambahkan zip ke hasil } }) .map((zip) => ({ value: parseInt(zip.kodepos), label: zip.kodepos, })); setZips(dataZips); // Set hasil ke state }; loadZip(); } }, [watchsubDistrict, subDistricts]); console.log('errors', errors); const onSubmitHandler = async (values) => { const toastId = toast.loading('Mengirimkan formulir merchant...'); const data = { ...values, harga_tayang: values.hargaTayang, categoryProduk: values.categoryProduk, merk_dagang: values.merkDagang, is_pengajuan_tempo: values.isPengajuanTempo, tempo_duration: values.tempoDuration, kredit_limit: values.kreditLimit, waktu_pengiriman: values.waktuPengiriman, terhitung_sejak: values.terhitungSejak, }; const create_leads = await createMerchantApi({ data }); if (create_leads) { toast.dismiss(toastId); isError(false); toast.success('Berhasil menambahkan data'); reset(); // router.push('/+'); } else { toast.dismiss(toastId); toast.error('Gagal menambahkan data'); } }; // const DownLoadSurat = () => { // download surat dari /public/file/Surat Pernyataan Nomor Rekening.docx // }; if (!auth) { return; } // Tetap di bagian atas, tidak boleh ada kondisi sebelum hook const handleFileChange = async (event) => { let fileBase64 = ''; const file = event.target.files[0]; if (file.size > 500000) { 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); } catch (error) { toast.error('Gagal mengompresi file', { duration: 4000 }); } } else { // Convert file to Base64 fileBase64 = await getFileBase64(file); } const fieldName = event.target.name; // Nama input file setDetailFile((prev) => ({ ...prev, [fieldName]: file ? fileBase64 : '', // Tambahkan atau perbarui file di state })); setFileNames((prev) => ({ ...prev, [fieldName]: file ? file.name : '', // Tambahkan atau perbarui file di state })); }; console.log("watch('isPengajuanTempo')", watch('kreditLimit')); return ( <> setIsExample(false)} > Informasi Vendor Harga Tayang (HET){' '} (Opsional) {errors.hargaTayang?.message} Tipe Kategori Produk yang Digunakan Pilih kategori produk bisa lebih dari 1 {firstColumn.map((item) => ( handleCheckboxChange(item.id)} isChecked={isChecked(item.id)} > {item.name} ))} {secondColumn.map((item) => ( handleCheckboxChange(item.id)} > {item.name} ))} {errors.categoryProduk?.message} Merk Dagang {errors.merkDagang?.message} Apakah anda memiliki Form Pengajuan Tempo? Ya, ada Tidak ada {errors.isPengajuanTempo?.message} Durasi Tempo Pilih durasi tempo yang anda inginkan ( )} /> {errors.tempoDuration?.message} Jumlah Kredit Limit isi dengan kredit limit perusahaan anda {errors.kreditLimit?.message} Waktu Pengiriman isi dengan waktu pengiriman anda {errors.waktuPengiriman?.message} terhitung sejak ( )} /> {errors.terhitungSejak?.message} {/* */} {/* Daftar Merchant{' '} {} */} Daftar Merchant {BannerMerchant && ( )} Form Merchant Lorem ipsum dolor sit amet consectetur. Commodo suspendisse at enim magnis ut quisque rhoncus. Felis volutpat fringilla sollicitudin ultricies. Enim non eget in lorem netus. Nisl pharetra accumsan diam suspendisse. Informasi Perusahaan Nama Perusahaan {errors.company?.message} Isi detail perusahaan sesuai dengan nama yang terdaftar{' '} Nama PIC {errors.PICName?.message} Isi dengan nama sales / penanggung jawab Alamat Perusahaan {errors.address?.message} ( )} /> {errors.state?.message} ( )} /> {errors.city?.message} ( )} /> {errors.district?.message} ( )} /> {errors.subDistrict?.message} ( <> {zips.length > 0 ? ( ) : ( )} > )} /> {errors.zip?.message} Alamat sesuai dengan alamat perusahaan Data Bank {errors.bank?.message} {errors.rekening?.message} {errors.accountNumber?.message} Isi detail data bank perusahaan anda Email Perusahaan {errors.email?.message} Isi detail perusahaan sesuai dengan data yang terdaftar Email Sales {errors.emailSales?.message} Isi detail perusahaan sesuai dengan data yang terdaftar Email Finance {errors.emailFinance?.message} Isi detail perusahaan sesuai dengan data yang terdaftar No. Telepon Perusahaan {errors.phone?.message} Isi detail perusahaan sesuai dengan data yang terdaftar No. Handphone {errors.mobile?.message} Isi detail perusahaan sesuai dengan data yang terdaftar Harga Tayang (HET){' '} (Opsional) {errors.hargaTayang?.message} NPWP{' '} {!isPkp && (Opsional)} {fileNames.npwp ? 'Ubah Dokumen' : 'Upload Dokumen'} { handleFileChange(e); // Untuk update UI (opsional) }} aria-invalid={errors.npwp?.message} /> {fileNames.npwp} Format: pdf, jpeg, jpg, png. max file size 2MB {errors.npwp?.message} SPPKP{' '} {!isPkp && (Opsional)} setIsExample(!isExample)} className='h-fit rounded text-white p-2 flex flex-row items-center bg-red-500 hover:cursor-pointer hover:bg-red-400' > Lihat Contoh {fileNames.sppkp ? 'Ubah Dokumen' : 'Upload Dokumen'} {fileNames.sppkp} Format: pdf, jpeg, jpg, png. max file size 2MB {errors.sppkp?.message} KTP Dirut/Direktur{' '} {isPkp && (Opsional)} {fileNames.dokumenKtpDirut ? 'Ubah Dokumen' : 'Upload Dokumen'} {fileNames.dokumenKtpDirut} Format: pdf, jpeg, jpg, png. max file size 2MB {errors.dokumenKtpDirut?.message} Kartu Nama (Opsional){' '} {fileNames.kartuNama ? 'Ubah Dokumen' : 'Upload Dokumen'} {fileNames.kartuNama} Format: pdf, jpeg, jpg, png. max file size 2MB {errors.kartuNama?.message} Surat Pernyataan Nomor Rekening{' '} (Opsional) Download Template {fileNames.suratPernyataan ? 'Ubah Dokumen' : 'Upload Dokumen'} {fileNames.suratPernyataan} Format: pdf, jpeg, jpg, png. max file size 2MB {errors.suratPernyataan?.message} Foto Gudang / Kantor Bagian Depan {fileNames.fotoKantor ? 'Ubah Dokumen' : 'Upload Dokumen'} {fileNames.fotoKantor} Format: pdf, jpeg, jpg, png. max file size 2MB {errors.fotoKantor?.message} Data Produk (Item Name, Gambar, Deskripsi){' '} (Opsional){' '} {fileNames.dataProduk ? 'Ubah Dokumen' : 'Upload Dokumen'} {fileNames.dataProduk} Format: pdf, jpeg, jpg, png. max file size 2MB {errors.fotoKantor?.message} Pricelist {fileNames.pricelist ? 'Ubah Dokumen' : 'Upload Dokumen'} {fileNames.pricelist} Format: pdf, jpeg, jpg, png. max file size 2MB {errors.pricelist?.message} {/* */} Daftar Merchant{' '} {/* {} */} {/* Simpan */} > ); }; const validationSchema = Yup.object().shape({ categoryProduk: Yup.string().required('Harus di-pilih'), merkDagang: Yup.string().required('Harus di-isi'), isPengajuanTempo: Yup.string().required('Harus di-pilih'), tempoDuration: Yup.string().required('Harus di-pilih'), kreditLimit: Yup.string().required('Harus di-isi'), waktuPengiriman: Yup.string().required('Harus di-isi'), terhitungSejak: Yup.string().required('Harus di-pilih'), }); const defaultValues = { categoryProduk: '', merkDagang: '', isPengajuanTempo: '', tempoDuration: '', kreditLimit: '', waktuPengiriman: '', terhitungSejak: '', }; export default InformasiVendor;
Lihat Contoh
Download Template