From 4b9cb6312d313cb76d1d9db03f29b59d2279b2c1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 27 Dec 2024 11:44:54 +0700 Subject: update merchant --- src/lib/form/api/createMerchantApi.js | 8 + src/lib/form/components/Merchant.jsx | 1478 +++++++++++++++++++++++++++++---- 2 files changed, 1335 insertions(+), 151 deletions(-) create mode 100644 src/lib/form/api/createMerchantApi.js (limited to 'src') diff --git a/src/lib/form/api/createMerchantApi.js b/src/lib/form/api/createMerchantApi.js new file mode 100644 index 00000000..8fd79857 --- /dev/null +++ b/src/lib/form/api/createMerchantApi.js @@ -0,0 +1,8 @@ +import odooApi from '@/core/api/odooApi'; + +const createMerchantApi = async ({ data }) => { + const lead = await odooApi('POST', '/api/v1/merchant', data); + return lead; +}; + +export default createMerchantApi; diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index ee7d177d..db5f5ddd 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -1,6 +1,8 @@ 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'; @@ -8,10 +10,17 @@ import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; import * as Yup from 'yup'; import createLeadApi from '../api/createLeadApi'; +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 { ChevronRightIcon } from '@heroicons/react/24/outline'; +import MobileView from '@/core/components/views/MobileView'; +import DesktopView from '@/core/components/views/DesktopView'; const CreateMerchant = () => { const { register, @@ -21,6 +30,7 @@ const CreateMerchant = () => { reset, watch, setValue, + getValues, } = useForm({ resolver: yupResolver(validationSchema), defaultValues, @@ -51,8 +61,13 @@ const CreateMerchant = () => { label: 'Lain - Lain', }, ]; - const [cities, setCities] = useState([]); 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 [company_unit, setCompany_unit] = useState(list_unit); const recaptchaRef = useRef(null); @@ -63,6 +78,28 @@ const CreateMerchant = () => { router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`); } + useEffect(() => { + const loadProfile = async () => { + try { + const dataProfile = await addressApi({ id: auth.parentId }); + console.log('dataProfile', dataProfile); + 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); + } + }; + + if (auth?.parentId) { + loadProfile(); + } + }, [auth?.parentId, setValue]); + useEffect(() => { const loadState = async () => { let dataState = await stateApi(); @@ -92,18 +129,134 @@ const CreateMerchant = () => { loadCities(); }, [auth, watchState, setValue]); + const watchCity = watch('city'); + + useEffect(() => { + setValue('district', ''); + if (watchCity) { + const loadDistricts = async () => { + let dataDistricts = await districtApi({ cityId: watchCity }); + dataDistricts = dataDistricts.map((district) => ({ + value: district.id, + label: district.name, + })); + setDistricts(dataDistricts); + }; + loadDistricts(); + } + }, [watchCity, setValue]); + + const watchDistrict = watch('district'); + useEffect(() => { + setValue('subDistrict', ''); + if (watchDistrict) { + const loadSubDistricts = async () => { + let dataSubDistricts = await subDistrictApi({ + districtId: watchDistrict, + }); + dataSubDistricts = dataSubDistricts.map((district) => ({ + value: district.id, + label: district.name, + })); + setSubDistricts(dataSubDistricts); + }; + loadSubDistricts(); + } + }, [watchDistrict, setValue]); + + const watchsubDistrict = watch('subDistrict'); + + useEffect(() => { + setValue('zip', ''); + let kelurahan = ''; + let kecamatan = ''; + + if (watchDistrict) { + 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, setValue, subDistricts]); + const onSubmitHandler = async (values) => { - const recaptchaValue = recaptchaRef.current.getValue(); - if (!recaptchaValue) { - toast.error('Catcha harus diisi'); + 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; + } + console.log('Submitted Values:', values); + console.log('values.npwp[0]:', values.npwp[0]); + console.log('npwp:', npwp); const data = { ...values, name: 'Form Merchant - ' + values.company, - contact_name: values.cp, - email_from: values.email, + 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_finnance: values.emailFinance, phone: values.phone, + mobile: values.mobile, description: 'Nama Perusahaan : ' + values.company + @@ -123,200 +276,1201 @@ const CreateMerchant = () => { values.mobile + 'Keterangan : ' + values.description, + 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 create_leads = await createLeadApi({ data }); - if (create_leads) { - toast.success('Berhasil menambahkan data'); - reset(); - recaptchaRef.current.reset(); - } + // const formData = new FormData(); + // formData.append('npwp', values.npwp[0]); + // const create_leads = await createLeadApi({ formData }); + // if (create_leads) { + // toast.success('Berhasil menambahkan data'); + // reset(); + // } }; + + // 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 > 2000000) { + toast.error('Maksimal ukuran file adalah 2MB'); + 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 + })); + }; + + console.log('errors', errors); return ( -
-

- Form Merchant -

-
-
-

- Penjualan online adalah hal yang HARUS dilakukan mulai sekarang. - Perubahan dalam banyak industri dan pola pembelian. Gabung dengan - platform kami dan mulai penjualan lansung di ribuan perusahaan d - seluruh Indonesia.{' '} -

+ <> + setIsExample(false)} + > +
+ Contoh SPPKP
-
-
-
-
- - -
- {errors.company?.message} + + +
+

+ 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} +
-
-
-
- - -
- {errors.address?.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, jpeg, jpg, png. max file size 2MB + + +
+ {errors.dokumenKtpDirut?.message} +
+
+
+ +
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+
+
+ + + + {fileNames.kartuNama} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {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, jpeg, jpg, png. max file size 2MB + + +
+ {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, jpeg, jpg, png. max file size 2MB + + +
+ {errors.sppkp?.message} +
+
+
+
+
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+ +

Download Template

+
+
+
+
+ + + + {fileNames.suratPernyataan} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.suratPernyataan?.message} +
+
+
+
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+
+
+ + + + {fileNames.fotoKantor} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.fotoKantor?.message} +
+
+
+
+
+ +
+
+
+ +
+ {/* */} +
+
+ + +
+
+ + +
+

+ 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.phone?.message} + {errors.email?.message}
+ + isi detail perusahaan sesuai dengan data yang terdaftar +
-
-
- - ( - - )} - /> -
- {errors.state?.message} -
-
-
-
- - ( - - )} - /> -
- {errors.city?.message} -
-
-
-
-
- - ( - - )} +
+ +
- {errors.company_unit?.message} + {errors.emailSales?.message}
+ + isi detail perusahaan sesuai dengan data yang terdaftar +
-
-
-
- +
+
- {errors.website?.message} + {errors.emailFinance?.message}
+ + isi detail perusahaan sesuai dengan data yang terdaftar +
-
-
-
- +
+
- {errors.cp?.message} + {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, jpeg, jpg, png. max file size 2MB + +
- {errors.email?.message} + {errors.dokumenKtpDirut?.message}
-
-
-
- + +
+ +
+ + + + {fileNames.kartuNama} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.kartuNama?.message} +
+
+ +
+ +
+ + { + 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} +
+
+
+
+ +
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, jpeg, jpg, png. max file size 2MB + + +
+ {errors.sppkp?.message} +
+
+
+
+ + +

+ Download Template +

+
+
+
+ + + + {fileNames.suratPernyataan} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.suratPernyataan?.message} +
+
+
+ +
+ + + + {fileNames.fotoKantor} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.fotoKantor?.message} +
+
+
+
+ +
-
-
-
- +
+ {/* + */} +
-
- - + + +
-
-
+ + ); }; const validationSchema = Yup.object().shape({ @@ -324,21 +1478,43 @@ const validationSchema = Yup.object().shape({ 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'), cp: Yup.string().required('Harus di-isi'), state: Yup.string().required('Harus dipilih'), - city: Yup.string().required('Harus di-isi'), + 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'), company_unit: Yup.string().required('Harus di-isi'), address: Yup.string().required('Harus di-isi'), website: 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: '', company_unit: '', cp: '', address: '', -- cgit v1.2.3 From 7fe286e1436fc66b31912e08a3e79bcc430a89b9 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 27 Dec 2024 14:58:04 +0700 Subject: update merchant --- src/lib/form/components/Merchant.jsx | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index db5f5ddd..4dd50983 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -9,7 +9,7 @@ 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 createLeadApi from '../api/createLeadApi'; +import createMerchantApi from '../api/createMerchantApi'; import addressApi from '@/lib/address/api/addressApi'; import PageContent from '@/lib/content/components/PageContent'; import { useRouter } from 'next/router'; @@ -21,6 +21,7 @@ import Image from 'next/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'; const CreateMerchant = () => { const { register, @@ -247,7 +248,7 @@ const CreateMerchant = () => { state: values.state, city: values.city, district: values.district, - SubDistrict: values.SubDistrict, + subDistrict: values.subDistrict, zip: values.zip, bank_name: values.bank, rekening_name: values.rekening, @@ -289,7 +290,7 @@ const CreateMerchant = () => { }; // const formData = new FormData(); // formData.append('npwp', values.npwp[0]); - // const create_leads = await createLeadApi({ formData }); + const create_leads = await createMerchantApi({ data }); // if (create_leads) { // toast.success('Berhasil menambahkan data'); // reset(); @@ -920,21 +921,21 @@ const CreateMerchant = () => {
- + */}
- {/* */} +
@@ -1485,7 +1486,6 @@ const validationSchema = Yup.object().shape({ .email('Format harus seperti contoh@email.com') .required('Harus di-isi'), phone: Yup.string().required('Harus di-isi'), - cp: Yup.string().required('Harus di-isi'), state: Yup.string().required('Harus dipilih'), city: Yup.string().required('Harus dipilih'), district: Yup.string().required('Harus dipilih'), @@ -1494,9 +1494,7 @@ const validationSchema = Yup.object().shape({ bank: Yup.string().required('Harus di-isi'), rekening: Yup.string().required('Harus di-isi'), accountNumber: Yup.string().required('Harus di-isi'), - company_unit: Yup.string().required('Harus di-isi'), address: Yup.string().required('Harus di-isi'), - website: 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'), @@ -1515,10 +1513,7 @@ const defaultValues = { bank: '', rekening: '', accountNumber: '', - company_unit: '', - cp: '', address: '', - website: '', mobile: '', }; -- cgit v1.2.3 From 7eb1cec305b015a6e4bffbd19a0ac8946ec41797 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 30 Dec 2024 14:08:31 +0700 Subject: update merchant --- src/lib/form/components/Merchant.jsx | 99 +++++++++++++++++------------------- 1 file changed, 48 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index 4dd50983..ce0b5430 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -82,8 +82,9 @@ const CreateMerchant = () => { useEffect(() => { const loadProfile = async () => { try { - const dataProfile = await addressApi({ id: auth.parentId }); - console.log('dataProfile', dataProfile); + 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)); @@ -96,9 +97,7 @@ const CreateMerchant = () => { } }; - if (auth?.parentId) { - loadProfile(); - } + loadProfile(); }, [auth?.parentId, setValue]); useEffect(() => { @@ -218,7 +217,6 @@ const CreateMerchant = () => { loadZip(); } }, [watchsubDistrict, setValue, subDistricts]); - const onSubmitHandler = async (values) => { const dokumenKtpDirut = document.getElementById('dokumenKtpDirut').files[0]; const kartuNama = document.getElementById('kartuNama').files[0]; @@ -238,12 +236,11 @@ const CreateMerchant = () => { toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan'); return; } - console.log('Submitted Values:', values); - console.log('values.npwp[0]:', values.npwp[0]); - console.log('npwp:', npwp); + const toastId = toast.loading('Mengirimkan formulir merchant...'); const data = { ...values, - name: 'Form Merchant - ' + values.company, + name_merchant: 'Form Merchant - ' + values.company, + partner_id: auth.partnerId, address: values.address, state: values.state, city: values.city, @@ -255,7 +252,7 @@ const CreateMerchant = () => { account_number: values.accountNumber, email_company: values.email, email_sales: values.emailSales, - email_finnance: values.emailFinance, + email_finance: values.emailFinance, phone: values.phone, mobile: values.mobile, description: @@ -271,12 +268,8 @@ const CreateMerchant = () => { values.phone + ' \r\n Email : ' + values.email + - ' \r\n Website : ' + - values.website + ' \r\n No Hp : ' + - values.mobile + - 'Keterangan : ' + - values.description, + values.mobile, file_dokumenKtpDirut: dokumenKtpDirut ? await getFileBase64(dokumenKtpDirut) : '', @@ -291,10 +284,15 @@ const CreateMerchant = () => { // const formData = new FormData(); // formData.append('npwp', values.npwp[0]); const create_leads = await createMerchantApi({ data }); - // if (create_leads) { - // toast.success('Berhasil menambahkan data'); - // reset(); - // } + 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 = () => { @@ -308,8 +306,8 @@ const CreateMerchant = () => { const handleFileChange = (event) => { const file = event.target.files[0]; - if (file.size > 2000000) { - toast.error('Maksimal ukuran file adalah 2MB'); + if (file.size > 1000000) { + toast.error('Maksimal ukuran file adalah 1MB'); event.target.value = ''; return; } @@ -320,7 +318,6 @@ const CreateMerchant = () => { })); }; - console.log('errors', errors); return ( <> { {...register('dokumenKtpDirut')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='dokumenKtpDirut' onChange={handleFileChange} aria-invalid={errors.dokumenKtpDirut?.message} @@ -686,7 +683,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -716,7 +713,7 @@ const CreateMerchant = () => { {...register('kartuNama')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='kartuNama' onChange={handleFileChange} aria-invalid={errors.kartuNama?.message} @@ -726,7 +723,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -754,7 +751,7 @@ const CreateMerchant = () => { {...register('npwp')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='npwp' onChange={(e) => { handleFileChange(e); // Untuk update UI (opsional) @@ -766,7 +763,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -805,7 +802,7 @@ const CreateMerchant = () => { {...register('sppkp')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='sppkp' onChange={handleFileChange} aria-invalid={errors.sppkp?.message} @@ -815,7 +812,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -855,7 +852,7 @@ const CreateMerchant = () => { {...register('suratPernyataan')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='suratPernyataan' onChange={handleFileChange} aria-invalid={errors.suratPernyataan?.message} @@ -865,7 +862,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -894,7 +891,7 @@ const CreateMerchant = () => { {...register('fotoKantor')} type='file' className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' + accept='.png,.jpg,.jpeg' id='fotoKantor' onChange={handleFileChange} aria-invalid={errors.fotoKantor?.message} @@ -904,7 +901,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: jpeg, jpg, png. max file size 1MB
@@ -913,12 +910,12 @@ const CreateMerchant = () => {
-
+ {/*
-
+
*/}
{/*
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -1271,7 +1268,7 @@ const CreateMerchant = () => { {...register('kartuNama')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='kartuNama' onChange={handleFileChange} aria-invalid={errors.kartuNama?.message} @@ -1281,7 +1278,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -1302,7 +1299,7 @@ const CreateMerchant = () => { {...register('npwp')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='npwp' onChange={(e) => { handleFileChange(e); // Untuk update UI (opsional) @@ -1314,7 +1311,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -1346,7 +1343,7 @@ const CreateMerchant = () => { {...register('sppkp')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='sppkp' onChange={handleFileChange} aria-invalid={errors.sppkp?.message} @@ -1356,7 +1353,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -1391,7 +1388,7 @@ const CreateMerchant = () => { {...register('suratPernyataan')} type='file' className='form-input hidden' - accept='.pdf' + accept='application/pdf' id='suratPernyataan' onChange={handleFileChange} aria-invalid={errors.suratPernyataan?.message} @@ -1401,7 +1398,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: pdf. max file size 1MB
@@ -1423,7 +1420,7 @@ const CreateMerchant = () => { {...register('fotoKantor')} type='file' className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' + accept='.png,.jpg,.jpeg' id='fotoKantor' onChange={handleFileChange} aria-invalid={errors.fotoKantor?.message} @@ -1433,7 +1430,7 @@ const CreateMerchant = () => {
- Format: pdf, jpeg, jpg, png. max file size 2MB + Format: jpeg, jpg, png. max file size 1MB
@@ -1441,12 +1438,12 @@ const CreateMerchant = () => {
-
+ {/*
-
+
*/}
+
+
+ + + isi detail perusahaan sesuai dengan nama yang terdaftar{' '} + +
+
+ +
+ {errors.PICName?.message} +
+
+
-
+
- isi no telepon perusahaan yang sesuai + Isi no telepon perusahaan yang sesuai
@@ -712,7 +712,7 @@ const CreateMerchant = () => { No. Handphone - isi no handphone perusahaan yang sesuai + Isi no handphone perusahaan yang sesuai
@@ -1187,7 +1187,7 @@ const CreateMerchant = () => { {errors.PICName?.message}
- isi dengan nama sales / penanggung jawab + Isi dengan nama sales / penanggung jawab
@@ -1307,7 +1307,7 @@ const CreateMerchant = () => {
- alamat sesuai dengan alamat perusahaan + Alamat sesuai dengan alamat perusahaan
-- cgit v1.2.3 From 10f1426c6325d46d531abeb63ff340375e3d8559 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 2 Jan 2025 11:24:24 +0700 Subject: update merchant --- src/lib/form/components/Merchant.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index a7df740c..9c82de22 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -466,7 +466,7 @@ const CreateMerchant = () => { Alamat Perusahaan - alamat sesuai dengan alamat perusahaan + Alamat sesuai dengan alamat perusahaan
-- cgit v1.2.3 From f4af8b3972d373aa8c8627ac787c3415d2d3f129 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 2 Jan 2025 11:28:18 +0700 Subject: update merchant --- src/lib/form/components/Merchant.jsx | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index 9c82de22..b2e308be 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -734,9 +734,6 @@ const CreateMerchant = () => { Harga Tayang (HET){' '} (Opsional) - - Isi detail perusahaan sesuai dengan data yang terdaftar{' '} -
{
{errors.hargaTayang?.message}
- - Isi detail perusahaan sesuai dengan data yang terdaftar -
-- cgit v1.2.3 From aa6d766e6dc3d033cbcb864762d77377121d446a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 7 Jan 2025 15:29:17 +0700 Subject: update merchant --- src/lib/form/components/Merchant.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index b2e308be..95317dfb 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -1102,7 +1102,7 @@ const CreateMerchant = () => { />
*/}
-
+
{/*
@@ -1740,14 +1740,14 @@ const CreateMerchant = () => { />
*/}
-
+
{/* */} -
- -
-
- - -
-
- - -
- {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.PICName?.message} -
- - Isi dengan nama sales / penanggung jawab - -
-
-
-
- - -
- {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 - -
-
- - -
- {errors.hargaTayang?.message} -
-
- -
- -
- - { - 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} -
-
-
-
- -
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, jpeg, jpg, png. max file size 2MB - - -
- {errors.sppkp?.message} -
-
- -
- -
- - - - {fileNames.dokumenKtpDirut} - -
- - Format: pdf, jpeg, jpg, png. max file size 2MB - - -
- {errors.dokumenKtpDirut?.message} -
-
- -
- -
- - - - {fileNames.kartuNama} - -
- - Format: pdf, jpeg, jpg, png. max file size 2MB - - -
- {errors.kartuNama?.message} -
-
- -
- -
- - - - {fileNames.suratPernyataan} - -
- - Format: pdf, jpeg, jpg, png. max file size 2MB - - -
- {errors.suratPernyataan?.message} -
-
-
- -
- - - - {fileNames.fotoKantor} - -
- - Format: pdf, jpeg, jpg, png. max file size 2MB - - -
- {errors.fotoKantor?.message} -
-
-
- -
- - - - {fileNames.dataProduk} - -
- - Format: pdf, jpeg, jpg, png. max file size 2MB - - -
- {errors.fotoKantor?.message} -
-
-
- -
- - - - {fileNames.pricelist} - -
- - Format: pdf, jpeg, jpg, png. max file size 2MB - - -
- {errors.pricelist?.message} -
-
-
- {/*
- -
*/} -
-
- -
- {/* */} -
-
-
- -
-
- - - ); -}; -const validationSchema = Yup.object().shape({ - company: Yup.string().required('Harus di-isi'), - PICName: 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'), - pricelist: Yup.mixed().required('File is required'), -}); -const defaultValues = { - company: '', - PICName: '', - email: '', - emailSales: '', - emailFinance: '', - phone: '', - state: '', - city: '', - district: '', - subDistrict: '', - zip: '', - bank: '', - rekening: '', - accountNumber: '', - address: '', - mobile: '', -}; - -export default CreateMerchant; diff --git a/src/lib/merchant/components/AccountSwitch.jsx b/src/lib/merchant/components/AccountSwitch.jsx new file mode 100644 index 00000000..b9bf34b1 --- /dev/null +++ b/src/lib/merchant/components/AccountSwitch.jsx @@ -0,0 +1,60 @@ +import Link from 'next/link'; +import Image from '~/components/ui/image'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import { useEffect, useState } from 'react'; +import odooApi from '@/core/api/odooApi'; +import useDevice from '@/core/hooks/useDevice'; +import useAuth from '@/core/hooks/useAuth'; +import axios from 'axios'; +import { toast } from 'react-hot-toast'; +import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline'; + +const FinishTempo = ({ query }) => { + const [data, setData] = useState(); + const [transactionData, setTransactionData] = useState(); + const { isDesktop, isMobile } = useDevice(); + const auth = useAuth(); + + return ( +
+
+

+ Form Merchant Kamu Gagal Dilakukan +

+
+ Registrasi Tempo + +
+ Terima kasih atas minat anda untuk mendaftar merchant, namun sayangnya + akun anda bukan merupakan akun bisnis. Segera ubah akun anda menjadi + Bisnis untuk menggunakan fitur ini +
+ + Ubah Akun + + +
+ ); +}; + +export default FinishTempo; diff --git a/src/lib/merchant/components/InformasiPerusahaan.jsx b/src/lib/merchant/components/InformasiPerusahaan.jsx new file mode 100644 index 00000000..87d8ff9b --- /dev/null +++ b/src/lib/merchant/components/InformasiPerusahaan.jsx @@ -0,0 +1,1928 @@ +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 '../../form/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 [DeatailFile, setDetailFile] = useState({}); + const [subDistricts, setSubDistricts] = 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 dataBisnisType = [ + { value: 1, label: 'PT' }, + { value: 2, label: 'CV' }, + { value: 3, label: 'Perorangan' }, + ]; + 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)' }, + ]; + + 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]); + const onSubmitHandler = async (values) => { + const npwp = DeatailFile.npwp; + const sppkp = DeatailFile.sppkp; + const dokumenKtpDirut = DeatailFile.dokumenKtpDirut; + const kartuNama = DeatailFile.kartuNama; + const suratPernyataan = DeatailFile.suratPernyataan; + const fotoKantor = DeatailFile.fotoKantor; + const dataProduk = DeatailFile.dataProduk; + const pricelist = DeatailFile.pricelist; + if (!npwp && isPkp) { + toast.error('NPWP wajib di tambahkan'); + return; + } + if (!sppkp && isPkp) { + toast.error('SPPKP wajib di tambahkan'); + return; + } + if (!dokumenKtpDirut && !isPkp) { + toast.error('KTP Dirut/Direktur wajib di tambahkan'); + return; + } + if (!fotoKantor) { + toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan'); + return; + } + if (!pricelist) { + toast.error('Pricelist wajib di tambahkan'); + return; + } + const toastId = toast.loading('Mengirimkan formulir merchant...'); + const data = { + ...values, + name_merchant: 'Form Merchant - ' + values.company, + pic_merchant: values.PICName, + 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, + harga_tayang: values.hargaTayang, + description: + 'Nama Perusahaan : ' + + values.company + + ' \r\n Alamat : ' + + values.address + + ' \r\n Kota : ' + + values.city + + ' \r\n Telepon: ' + + values.phone + + ' \r\n Email : ' + + values.email + + ' \r\n No Hp : ' + + values.mobile, + file_dokumenKtpDirut: dokumenKtpDirut ? dokumenKtpDirut : '', + file_kartuNama: kartuNama ? kartuNama : '', + file_npwp: npwp ? npwp : '', + file_sppkp: sppkp ? sppkp : '', + file_suratPernyataan: suratPernyataan ? suratPernyataan : '', + file_fotoKantor: fotoKantor ? fotoKantor : '', + file_dataProduk: dataProduk ? dataProduk : '', + file_pricelist: pricelist ? pricelist : '', + }; + // 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 = 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 + })); + }; + return ( + <> + setIsExample(false)} + > +
+ Contoh SPPKP +
+
+ +
+

+ Informasi Perusahaan +

+ +
+
+
+
+ + + Isi detail perusahaan sesuai dengan nama yang terdaftar{' '} + +
+
+ + + Format: PT. INDOTEKNIK DOTCOM GEMILANG + +
+ {errors.company?.message} +
+
+
+
+
+ + + isi dengan nama pejabat yang berwewenang di perusahaan anda + +
+
+ +
+ {errors.pejabatName?.message} +
+
+
+
+
+ + + isi dengan nama sales / penanggung jawab + +
+
+ +
+ {errors.PICName?.message} +
+
+
+
+
+ + + isi dengan jabatan sales / penanggung jawab + +
+
+ +
+ {errors.PICPosition?.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} +
+
+
+ +
+
+ +
+
+ +
+ {errors.hargaTayang?.message} +
+
+
+ +
+
+ + + Pilih tipe bisnis yang sesuai + +
+
+
+
+ ( + + )} + /> + +
+ {errors.bisnisType?.message} +
+
+
+
+
+
+
+ + + Pilih kategori perusahaan yang sesuai + +
+
+
+
+ ( + + )} + /> + +
+ {errors.categoryPerusahaan?.message} +
+
+
+
+
+ +
+
+ + + isi dengan website perusahaan anda + +
+
+ +
+ {errors.website?.message} +
+
+
+ +
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+
+
+ + { + 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} +
+
+
+
+
+
+ + + 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, jpeg, jpg, png. max file size 2MB + + +
+ {errors.sppkp?.message} +
+
+
+ +
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+
+
+ + + + {fileNames.dokumenKtpDirut} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.dokumenKtpDirut?.message} +
+
+
+ +
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+
+
+ + + + {fileNames.kartuNama} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.kartuNama?.message} +
+
+
+ +
+
+
+ + + Wajib diisi jika nomor rekening berbeda dengan nama + perusahaan + +
+ +

Download Template

+
+
+
+
+ + + + {fileNames.suratPernyataan} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.suratPernyataan?.message} +
+
+
+
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+
+
+ + + + {fileNames.fotoKantor} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.fotoKantor?.message} +
+
+
+
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+
+
+ + + + {fileNames.dataProduk} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.fotoKantor?.message} +
+
+
+
+
+ + + Pastikan dokumen yang anda upload sudah benar + +
+
+
+ + + + {fileNames.pricelist} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.pricelist?.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.PICName?.message} +
+ + Isi dengan nama sales / penanggung jawab + +
+
+
+
+ + +
+ {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 + +
+
+ + +
+ {errors.hargaTayang?.message} +
+
+ +
+ +
+ + { + 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} +
+
+
+
+ +
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, jpeg, jpg, png. max file size 2MB + + +
+ {errors.sppkp?.message} +
+
+ +
+ +
+ + + + {fileNames.dokumenKtpDirut} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.dokumenKtpDirut?.message} +
+
+ +
+ +
+ + + + {fileNames.kartuNama} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.kartuNama?.message} +
+
+ +
+
+ + +

+ Download Template +

+
+
+
+ + + + {fileNames.suratPernyataan} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.suratPernyataan?.message} +
+
+
+ +
+ + + + {fileNames.fotoKantor} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.fotoKantor?.message} +
+
+
+ +
+ + + + {fileNames.dataProduk} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.fotoKantor?.message} +
+
+
+ +
+ + + + {fileNames.pricelist} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.pricelist?.message} +
+
+
+ {/*
+ +
*/} +
+
+ +
+ {/* */} +
+
+
+ +
+
+
+ + ); +}; +const validationSchema = Yup.object().shape({ + company: Yup.string().required('Harus di-isi'), + pejabatName: Yup.string().required('Harus di-isi'), + PICName: Yup.string().required('Harus di-isi'), + PICPosition: 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'), + bisnisType: Yup.string().required('Harus dipilih'), + categoryPerusahaan: 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'), + pricelist: Yup.mixed().required('File is required'), +}); +const defaultValues = { + company: '', + pejabatName: '', + PICName: '', + PICPosition: '', + email: '', + emailSales: '', + emailFinance: '', + phone: '', + state: '', + city: '', + district: '', + subDistrict: '', + zip: '', + bank: '', + rekening: '', + accountNumber: '', + address: '', + mobile: '', +}; + +export default CreateMerchant; diff --git a/src/lib/merchant/components/InformasiVendor.jsx b/src/lib/merchant/components/InformasiVendor.jsx new file mode 100644 index 00000000..b53bd52f --- /dev/null +++ b/src/lib/merchant/components/InformasiVendor.jsx @@ -0,0 +1,1393 @@ +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 '../../form/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, 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'; +const InformasiVendor = () => { + 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 [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(category_produk.length / 2); + const firstColumn = category_produk.slice(0, midIndex); + const secondColumn = category_produk.slice(midIndex); + + 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 + ); + + const handleCheckboxChange = (id) => { + const updatedSelected = selectedIds.includes(id) + ? selectedIds.filter((selectedId) => selectedId !== id) + : [...selectedIds, id]; + + 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(() => { + 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]); + const onSubmitHandler = async (values) => { + const npwp = DeatailFile.npwp; + const sppkp = DeatailFile.sppkp; + const dokumenKtpDirut = DeatailFile.dokumenKtpDirut; + const kartuNama = DeatailFile.kartuNama; + const suratPernyataan = DeatailFile.suratPernyataan; + const fotoKantor = DeatailFile.fotoKantor; + const dataProduk = DeatailFile.dataProduk; + const pricelist = DeatailFile.pricelist; + if (!npwp && isPkp) { + toast.error('NPWP wajib di tambahkan'); + return; + } + if (!sppkp && isPkp) { + toast.error('SPPKP wajib di tambahkan'); + return; + } + if (!dokumenKtpDirut && !isPkp) { + toast.error('KTP Dirut/Direktur wajib di tambahkan'); + return; + } + if (!fotoKantor) { + toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan'); + return; + } + if (!pricelist) { + toast.error('Pricelist wajib di tambahkan'); + return; + } + const toastId = toast.loading('Mengirimkan formulir merchant...'); + const data = { + ...values, + name_merchant: 'Form Merchant - ' + values.company, + pic_merchant: values.PICName, + 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, + harga_tayang: values.hargaTayang, + description: + 'Nama Perusahaan : ' + + values.company + + ' \r\n Alamat : ' + + values.address + + ' \r\n Kota : ' + + values.city + + ' \r\n Telepon: ' + + values.phone + + ' \r\n Email : ' + + values.email + + ' \r\n No Hp : ' + + values.mobile, + file_dokumenKtpDirut: dokumenKtpDirut ? dokumenKtpDirut : '', + file_kartuNama: kartuNama ? kartuNama : '', + file_npwp: npwp ? npwp : '', + file_sppkp: sppkp ? sppkp : '', + file_suratPernyataan: suratPernyataan ? suratPernyataan : '', + file_fotoKantor: fotoKantor ? fotoKantor : '', + file_dataProduk: dataProduk ? dataProduk : '', + file_pricelist: pricelist ? pricelist : '', + }; + // 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 = 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 + })); + }; + return ( + <> + setIsExample(false)} + > +
+ Contoh SPPKP +
+
+ +
+

+ Informasi Vendor +

+ +
+
+
+
+ +
+
+ +
+ {errors.hargaTayang?.message} +
+
+
+ +
+
+ + + 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} +
+
+
+ +
+
+ +
+
+ +
+ {errors.merkDagang?.message} +
+
+
+ +
+
+ +
+
+
+ + + + Ya, ada + + + Tidak ada + + + +
+ +
+ {errors.isPengajuanTempo?.message} +
+
+
+ +
+
+ + + Pilih durasi tempo yang anda inginkan + +
+
+
+
+ ( + + )} + /> + +
+ {errors.tempoDuration?.message} +
+
+
+
+
+ +
+
+ + + isi dengan kredit limit perusahaan anda + +
+
+ +
+ {errors.kreditLimit?.message} +
+
+
+ +
+
+ + + isi dengan waktu pengiriman anda + +
+
+
+ +
+ {errors.waktuPengiriman?.message} +
+
+
+
+ + + ( + + )} + /> +
+
+ {errors.terhitungSejak?.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.PICName?.message} +
+ + Isi dengan nama sales / penanggung jawab + +
+
+
+
+ + +
+ {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 + +
+
+ + +
+ {errors.hargaTayang?.message} +
+
+ +
+ +
+ + { + 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} +
+
+
+
+ +
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, jpeg, jpg, png. max file size 2MB + + +
+ {errors.sppkp?.message} +
+
+ +
+ +
+ + + + {fileNames.dokumenKtpDirut} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.dokumenKtpDirut?.message} +
+
+ +
+ +
+ + + + {fileNames.kartuNama} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.kartuNama?.message} +
+
+ +
+
+ + +

+ Download Template +

+
+
+
+ + + + {fileNames.suratPernyataan} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.suratPernyataan?.message} +
+
+
+ +
+ + + + {fileNames.fotoKantor} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.fotoKantor?.message} +
+
+
+ +
+ + + + {fileNames.dataProduk} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.fotoKantor?.message} +
+
+
+ +
+ + + + {fileNames.pricelist} + +
+ + Format: pdf, jpeg, jpg, png. max file size 2MB + + +
+ {errors.pricelist?.message} +
+
+
+ {/*
+ +
*/} +
+
+ +
+ {/* */} +
+
+
+ +
+
+
+ + ); +}; +const validationSchema = Yup.object().shape({ + categoryProduk: Yup.string().required('Harus di-isi'), + merkDagang: Yup.string().required('Harus di-isi'), + tempoDuration: Yup.string().required('Harus di-isi'), + kreditLimit: Yup.string().required('Harus di-isi'), + waktuPengiriman: Yup.string().required('Harus di-isi'), + terhitungSejak: Yup.string().required('Harus di-isi'), + pejabatName: Yup.string().required('Harus di-isi'), + PICName: Yup.string().required('Harus di-isi'), + PICPosition: 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'), + bisnisType: Yup.string().required('Harus dipilih'), + categoryPerusahaan: 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'), + pricelist: Yup.mixed().required('File is required'), +}); +const defaultValues = { + company: '', + pejabatName: '', + PICName: '', + PICPosition: '', + email: '', + emailSales: '', + emailFinance: '', + phone: '', + state: '', + city: '', + district: '', + subDistrict: '', + zip: '', + bank: '', + rekening: '', + accountNumber: '', + address: '', + mobile: '', +}; + +export default InformasiVendor; diff --git a/src/lib/merchant/components/Merchant.jsx b/src/lib/merchant/components/Merchant.jsx new file mode 100644 index 00000000..30ad0130 --- /dev/null +++ b/src/lib/merchant/components/Merchant.jsx @@ -0,0 +1,273 @@ +import React from 'react'; +import { useMemo, useState, useEffect, useRef } from 'react'; +import Image from '~/components/ui/image'; +import InformasiPerusahaan from './InformasiPerusahaan'; +import InformasiVendor from './InformasiVendor'; +import SyaratDagang from './SyaratDagang'; +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 { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline'; +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 BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import PageContent from '@/lib/content/components/PageContent'; +const Merchant = () => { + 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 { control, watch, setValue } = useForm(); + const auth = useAuth(); + const router = useRouter(); + const [BannerTempo, setBannerTempo] = useState(); + const [notValid, setNotValid] = useState(false); + const [buttonSubmitClick, setButtonSubmitClick] = useState(false); + const stepDivs = [ + , + , + , + ]; + + const stepLabels = [ + 'informasi_perusahaan', + 'kontak_person', + 'Pengiriman', + 'Referensi', + 'Dokumen', + 'Konfirmasi', + ]; + + // 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 + // }; + + // try { + // const dataPaymentTerm = await odooApi( + // 'GET', + // `/api/v1/partner/detail-tempo/${auth.parentId}` + // ); + // 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); + // } + // }); + // } + // } + // }; + // 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 = () => { + setCurrentStep((prev) => (prev === NUMBER_OF_STEPS - 1 ? prev : prev - 1)); + }; + + 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 && ( +
+ +
+ )} +
+
+ + ); +}; + +export default Merchant; diff --git a/src/lib/merchant/components/SyaratDagang.jsx b/src/lib/merchant/components/SyaratDagang.jsx new file mode 100644 index 00000000..0e34c5cf --- /dev/null +++ b/src/lib/merchant/components/SyaratDagang.jsx @@ -0,0 +1,1290 @@ +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 '../../form/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, 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'; +const SyaratDagang = () => { + 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 [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: 1, name: 'TKDN' }, + { id: 2, name: 'SNI' }, + { id: 3, name: 'K3L' }, + { id: 4, name: '' }, + ]; + + const firstColumn = category_produk; + + 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 + ); + + const handleCheckboxChange = (id) => { + const updatedSelected = selectedIds.includes(id) + ? selectedIds.filter((selectedId) => selectedId !== id) + : [...selectedIds, id]; + + setSelectedIds(updatedSelected); + + // Mengubah array kembali menjadi string yang dipisahkan oleh koma + setValue('categoryProduk', updatedSelected.join(',')); + }; + + const isChecked = (id) => selectedIds.includes(id); + + const handleCheckboxReturChange = (value) => { + setValue('isKembaliBarang', `${value}`); + }; + + const handleCheckboxTenggatWaktuChange = (value) => { + setValue('tenggatWaktu', `${value}`); + }; + 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]); + const onSubmitHandler = async (values) => { + const npwp = DeatailFile.npwp; + const sppkp = DeatailFile.sppkp; + const dokumenKtpDirut = DeatailFile.dokumenKtpDirut; + const kartuNama = DeatailFile.kartuNama; + const suratPernyataan = DeatailFile.suratPernyataan; + const fotoKantor = DeatailFile.fotoKantor; + const dataProduk = DeatailFile.dataProduk; + const pricelist = DeatailFile.pricelist; + if (!npwp && isPkp) { + toast.error('NPWP wajib di tambahkan'); + return; + } + if (!sppkp && isPkp) { + toast.error('SPPKP wajib di tambahkan'); + return; + } + if (!dokumenKtpDirut && !isPkp) { + toast.error('KTP Dirut/Direktur wajib di tambahkan'); + return; + } + if (!fotoKantor) { + toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan'); + return; + } + if (!pricelist) { + toast.error('Pricelist wajib di tambahkan'); + return; + } + const toastId = toast.loading('Mengirimkan formulir merchant...'); + const data = { + ...values, + name_merchant: 'Form Merchant - ' + values.company, + pic_merchant: values.PICName, + 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, + harga_tayang: values.hargaTayang, + description: + 'Nama Perusahaan : ' + + values.company + + ' \r\n Alamat : ' + + values.address + + ' \r\n Kota : ' + + values.city + + ' \r\n Telepon: ' + + values.phone + + ' \r\n Email : ' + + values.email + + ' \r\n No Hp : ' + + values.mobile, + file_dokumenKtpDirut: dokumenKtpDirut ? dokumenKtpDirut : '', + file_kartuNama: kartuNama ? kartuNama : '', + file_npwp: npwp ? npwp : '', + file_sppkp: sppkp ? sppkp : '', + file_suratPernyataan: suratPernyataan ? suratPernyataan : '', + file_fotoKantor: fotoKantor ? fotoKantor : '', + file_dataProduk: dataProduk ? dataProduk : '', + file_pricelist: pricelist ? pricelist : '', + }; + // 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 = 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 + })); + }; + return ( + <> + setIsExample(false)} + > +
+ Contoh SPPKP +
+
+ +
+

+ Syarat Perdagangan +

+ +
+
+
+
+ +
+
+
+ + +
+ + Ya, dapat diretur + + {watch('isKembaliBarang') == 'ya' && ( +