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 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, Divider, 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'; const CreateMerchant = () => { 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 [subDistricts, setSubDistricts] = useState([]); const [zips, setZips] = useState([]); const [isExample, setIsExample] = useState(false); const [BannerMerchant, setBannerMerchant] = useState(); const recaptchaRef = useRef(null); const router = useRouter(); useEffect(() => { const getBanner = async () => { const get = await odooApi('GET', '/api/v1/banner?type=banner-form-tempo'); // setBannerMerchant(get[0].image); setBannerMerchant( 'http://192.168.23.244:8069/api/image/x_banner.banner/x_banner_image/485' ); }; getBanner(); }, []); const auth = useAuth(); if (auth == false) { router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`); } useEffect(() => { const loadProfile = async () => { try { const dataProfile = await addressApi({ id: auth.parentId ? auth.parentId : auth.partnerId, }); 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(); 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]); const onSubmitHandler = async (values) => { const dokumenKtpDirut = document.getElementById('dokumenKtpDirut').files[0]; const kartuNama = document.getElementById('kartuNama').files[0]; const sppkp = document.getElementById('sppkp').files[0]; const npwp = document.getElementById('npwp').files[0]; const suratPernyataan = document.getElementById('suratPernyataan').files[0]; const fotoKantor = document.getElementById('fotoKantor').files[0]; if (!npwp) { toast.error('NPWP wajib di tambahkan'); return; } if (!suratPernyataan) { toast.error('Surat Pernyataan Nomor Rekening wajib di tambahkan'); return; } if (!fotoKantor) { toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan'); return; } const toastId = toast.loading('Mengirimkan formulir merchant...'); const data = { ...values, name_merchant: 'Form Merchant - ' + values.company, partner_id: auth.partnerId, address: values.address, state: values.state, city: values.city, district: values.district, subDistrict: values.subDistrict, zip: values.zip, bank_name: values.bank, rekening_name: values.rekening, account_number: values.accountNumber, email_company: values.email, email_sales: values.emailSales, email_finance: values.emailFinance, phone: values.phone, mobile: values.mobile, description: 'Nama Perusahaan : ' + values.company + ' \r\n Alamat : ' + values.address + ' \r\n Kota : ' + values.city + ' \r\n Unit Perusahaan : ' + values.company_unit + ' \r\n Telepon: ' + values.phone + ' \r\n Email : ' + values.email + ' \r\n No Hp : ' + values.mobile, file_dokumenKtpDirut: dokumenKtpDirut ? await getFileBase64(dokumenKtpDirut) : '', file_kartuNama: kartuNama ? await getFileBase64(kartuNama) : '', file_npwp: npwp ? await getFileBase64(npwp) : '', file_sppkp: sppkp ? await getFileBase64(sppkp) : '', file_suratPernyataan: suratPernyataan ? await getFileBase64(suratPernyataan) : '', file_fotoKantor: fotoKantor ? await getFileBase64(fotoKantor) : '', }; // const formData = new FormData(); // formData.append('npwp', values.npwp[0]); const create_leads = await createMerchantApi({ data }); if (create_leads) { toast.dismiss(toastId); 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 = (event) => { const file = event.target.files[0]; if (file.size > 1000000) { toast.error('Maksimal ukuran file adalah 1MB'); event.target.value = ''; return; } const fieldName = event.target.name; // Nama input file setFileNames((prev) => ({ ...prev, [fieldName]: file ? file.name : '', // Tambahkan atau perbarui file di state })); }; return ( <> setIsExample(false)} >
Contoh SPPKP
{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

isi detail perusahaan sesuai dengan nama yang terdaftar{' '}
Format: PT. INDOTEKNIK DOTCOM GEMILANG
{errors.company?.message}
alamat sesuai dengan alamat perusahaan
{errors.address?.message}
( )} />
{errors.state?.message}
( )} />
{errors.city?.message}
( )} />
{errors.district?.message}
( )} />
{errors.subDistrict?.message}
( <> {/* Jika zips tidak kosong, tampilkan dropdown */} {zips.length > 0 ? ( ) : ( // Jika zips kosong, tampilkan input manual )} )} />
{errors.zip?.message}
Isi detail data bank perusahaan anda
Format: BCA, Mandiri, CIMB, BNI dll
{errors.bank?.message}
Format: John Doe
{errors.rekening?.message}
Format: 01234567896
{errors.accountNumber?.message}
{errors.email?.message}
{errors.emailSales?.message}
{errors.emailFinance?.message}
isi no telepon perusahaan yang sesuai
{errors.phone?.message}
isi no handphone perusahaan yang sesuai
{errors.mobile?.message}
Pastikan dokumen yang anda upload sudah benar
{fileNames.dokumenKtpDirut}
Format: pdf. max file size 1MB
{errors.dokumenKtpDirut?.message}
Pastikan dokumen yang anda upload sudah benar
{fileNames.kartuNama}
Format: pdf. max file size 1MB
{errors.kartuNama?.message}
Pastikan dokumen yang anda upload sudah benar
{ handleFileChange(e); // Untuk update UI (opsional) }} aria-invalid={errors.npwp?.message} /> {fileNames.npwp}
Format: pdf. max file size 1MB
{errors.npwp?.message}
Pastikan dokumen yang anda upload sudah benar
setIsExample(!isExample)} className='h-fit mr-8 rounded text-white p-2 flex flex-row items-center bg-red-500 hover:cursor-pointer hover:bg-red-400' >

Lihat Contoh

{fileNames.sppkp}
Format: pdf. max file size 1MB
{errors.sppkp?.message}
Pastikan dokumen yang anda upload sudah benar

Download Template

{fileNames.suratPernyataan}
Format: pdf. max file size 1MB
{errors.suratPernyataan?.message}
Pastikan dokumen yang anda upload sudah benar
{fileNames.fotoKantor}
Format: jpeg, jpg, png. max file size 1MB
{errors.fotoKantor?.message}
{/*
*/}
{/* */}
{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

{errors.company?.message}
isi detail perusahaan sesuai dengan nama yang terdaftar{' '}
{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
{errors.bank?.message}
{errors.rekening?.message}
{errors.accountNumber?.message}
Isi detail data bank perusahaan anda
{errors.email?.message}
isi detail perusahaan sesuai dengan data yang terdaftar
{errors.emailSales?.message}
isi detail perusahaan sesuai dengan data yang terdaftar
{errors.emailFinance?.message}
isi detail perusahaan sesuai dengan data yang terdaftar
{errors.phone?.message}
isi detail perusahaan sesuai dengan data yang terdaftar
{errors.mobile?.message}
isi detail perusahaan sesuai dengan data yang terdaftar
{fileNames.dokumenKtpDirut}
Format: pdf. max file size 1MB
{errors.dokumenKtpDirut?.message}
{fileNames.kartuNama}
Format: pdf. max file size 1MB
{errors.kartuNama?.message}
{ handleFileChange(e); // Untuk update UI (opsional) }} aria-invalid={errors.npwp?.message} /> {fileNames.npwp}
Format: pdf. max file size 1MB
{errors.npwp?.message}
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}
Format: pdf. max file size 1MB
{errors.sppkp?.message}

Download Template

{fileNames.suratPernyataan}
Format: pdf. max file size 1MB
{errors.suratPernyataan?.message}
{fileNames.fotoKantor}
Format: jpeg, jpg, png. max file size 1MB
{errors.fotoKantor?.message}
{/*
*/}
{/* */}
); }; const validationSchema = Yup.object().shape({ company: Yup.string().required('Harus di-isi'), email: Yup.string() .email('Format harus seperti contoh@email.com') .required('Harus di-isi'), emailSales: Yup.string() .email('Format harus seperti contoh@email.com') .required('Harus di-isi'), emailFinance: Yup.string() .email('Format harus seperti contoh@email.com') .required('Harus di-isi'), phone: Yup.string().required('Harus di-isi'), state: Yup.string().required('Harus dipilih'), city: Yup.string().required('Harus dipilih'), district: Yup.string().required('Harus dipilih'), subDistrict: Yup.string().required('Harus dipilih'), zip: Yup.string().required('Harus di-isi'), bank: Yup.string().required('Harus di-isi'), rekening: Yup.string().required('Harus di-isi'), accountNumber: Yup.string().required('Harus di-isi'), address: Yup.string().required('Harus di-isi'), mobile: Yup.string().required('Harus di-isi'), npwp: Yup.mixed().required('File is required'), suratPernyataan: Yup.mixed().required('File is required'), }); const defaultValues = { company: '', email: '', emailSales: '', emailFinance: '', phone: '', state: '', city: '', district: '', subDistrict: '', zip: '', bank: '', rekening: '', accountNumber: '', address: '', mobile: '', }; export default CreateMerchant;