diff options
Diffstat (limited to 'src/lib/merchant')
| -rw-r--r-- | src/lib/merchant/components/Dokumen.jsx | 2458 | ||||
| -rw-r--r-- | src/lib/merchant/components/InformasiPerusahaan.jsx | 2681 | ||||
| -rw-r--r-- | src/lib/merchant/components/InformasiVendor.jsx | 111 | ||||
| -rw-r--r-- | src/lib/merchant/components/Konfirmasi.jsx | 252 | ||||
| -rw-r--r-- | src/lib/merchant/components/Merchant.jsx | 54 | ||||
| -rw-r--r-- | src/lib/merchant/components/SyaratDagang.jsx | 144 |
6 files changed, 2989 insertions, 2711 deletions
diff --git a/src/lib/merchant/components/Dokumen.jsx b/src/lib/merchant/components/Dokumen.jsx index 19df56a5..87c5839c 100644 --- a/src/lib/merchant/components/Dokumen.jsx +++ b/src/lib/merchant/components/Dokumen.jsx @@ -4,12 +4,19 @@ 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 React, { + useEffect, + useRef, + useState, + forwardRef, + useImperativeHandle, +} from 'react'; import ReCAPTCHA from 'react-google-recaptcha'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; import * as Yup from 'yup'; import createMerchantApi from '../api/createMerchantApi'; +import getMerchantApi from '../api/getMerchantApi'; import addressApi from '@/lib/address/api/addressApi'; import PageContent from '@/lib/content/components/PageContent'; import { useRouter } from 'next/router'; @@ -24,406 +31,1327 @@ 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 Dokumen = ({ handleIsError }) => { - const isError = (value) => { - // Logika menentukan error - const result = value ? true : false; - handleIsError(result); // Panggil handleIsError dari Merchant - return result; - }; - const { - register, - handleSubmit, - formState: { errors }, - control, - reset, - watch, - setValue, - getValues, - } = useForm({ - resolver: yupResolver(validationSchema), - defaultValues, - }); - const list_unit = [ - { - value: 'Manufacturing', - label: 'Manufacturing', - }, - { - value: 'Hospitality', - label: 'Hospitality', - }, - { - value: 'Automotive', - label: 'Automotive', - }, - { - value: 'Retail', - label: 'Retail', - }, - { - value: 'Maining', - label: 'Maining', - }, - { - value: 'Lain - Lain', - label: 'Lain - Lain', - }, - ]; - const [state, setState] = useState([]); - const [cities, setCities] = useState([]); - const [districts, setDistricts] = useState([]); - const [fileNames, setFileNames] = useState({}); - const [DeatailFile, setDetailFile] = useState({}); - const [subDistricts, setSubDistricts] = useState([]); - const [zips, setZips] = useState([]); - const [isExample, setIsExample] = useState(false); - const [BannerMerchant, setBannerMerchant] = useState(); - const [isPkp, setIsPkp] = useState(false); - - const recaptchaRef = useRef(null); - const npwpRef = useRef(null); - const sppkpRef = useRef(null); - const ktpDirutRef = useRef(null); - const kartuNamaRef = useRef(null); - const suratPernyataanRef = useRef(null); - const fotoKantorRef = useRef(null); - const dataProdukRef = useRef(null); - const pricelistRef = 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(() => { - window.scrollTo({ - top: 0, - behavior: 'smooth', +const Dokumen = forwardRef( + ({ handleIsError, isKonfirmasi, buttonSubmitClick }, ref) => { + const isError = (value) => { + // Logika menentukan error + const result = value ? true : false; + handleIsError(result); // Panggil handleIsError dari Merchant + return result; + }; + const { + register, + handleSubmit, + formState: { errors }, + control, + reset, + watch, + setValue, + getValues, + } = useForm({ + resolver: yupResolver(validationSchema), + defaultValues, }); - }, []); - 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); - } - }; + 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); - loadProfile(); - }, [auth?.parentId]); + const recaptchaRef = useRef(null); + const npwpRef = useRef(null); + const sppkpRef = useRef(null); + const ktpDirutRef = useRef(null); + const kartuNamaRef = useRef(null); + const suratPernyataanRef = useRef(null); + const fotoKantorRef = useRef(null); + const dataProdukRef = useRef(null); + const pricelistRef = useRef(null); + const router = useRouter(); - 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(() => { + const auth = useAuth(); if (auth == false) { - return; + router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`); } - 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); + 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)' }, + ]; + console.log('fileNames', fileNames); + useEffect(() => { + const loadData = async () => { + try { + const data = await getMerchantApi(); + console.log('data', data); + if (data) { + setFileNames((prev) => ({ + ...prev, + ['npwp']: data.fileNpwp ? data.fileNpwp.name : '', + ['sppkp']: data.fileSppkp ? data.fileSppkp.name : '', + ['dokumenKtpDirut']: data.fileDokumenKtpDirut + ? data.fileDokumenKtpDirut.name + : '', + ['kartuNama']: data.fileKartuNama ? data.fileKartuNama.name : '', + ['suratPernyataan']: data.fileSuratPernyataan + ? data.fileSuratPernyataan.name + : '', + ['fotoKantor']: data.fileFotoKantor + ? data.fileFotoKantor.name + : '', + ['dataProduk']: data.fileDataProduk + ? data.fileDataProduk.name + : '', + ['pricelist']: data.filePricelist ? data.filePricelist.name : '', + })); + } + } catch (error) { + console.error('Error loading profile:', error); + handleIsError(true); // Jika ada error, panggil fungsi error handler + } }; - loadCities(); - } - }, [auth, watchState]); - const watchCity = watch('city'); + loadData(); + }, [reset, handleIsError]); - 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); + useEffect(() => { + window.scrollTo({ + top: 0, + behavior: 'smooth', + }); + }, []); + useImperativeHandle(ref, () => () => { + handleSubmit(onSubmitHandler)(); + }); + 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); + } }; - 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, + loadProfile(); + }, [auth?.parentId]); + + useEffect(() => { + const loadState = async () => { + let dataState = await stateApi({ tempo: false }); + dataState = dataState.map((state) => ({ + value: state.id, + label: state.name, })); - setSubDistricts(dataSubDistricts); + setState(dataState); }; - loadSubDistricts(); - } - }, [watchDistrict]); + loadState(); + }, []); - const watchsubDistrict = watch('subDistrict'); + 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]); - useEffect(() => { - let kelurahan = ''; - let kecamatan = ''; + const watchCity = watch('city'); - if (watchDistrict) { - setValue('zip', ''); - for (const data in districts) { - if (districts[data].value == watchDistrict) { - kecamatan = districts[data].label.toLowerCase(); - } + 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]); - if (watchsubDistrict) { - for (const data in subDistricts) { - if (subDistricts[data].value == watchsubDistrict) { - kelurahan = subDistricts[data].label.toLowerCase(); + 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(); + } } } - 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 + 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}` + ); - const result = await response.json(); + let dataMasuk = []; // Array untuk menyimpan kode pos yang sudah diproses - // 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, - })); + const result = await response.json(); - setZips(dataZips); // Set hasil ke state - }; + // 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, + })); - loadZip(); - } - }, [watchsubDistrict, subDistricts]); + setZips(dataZips); // Set hasil ke state + }; - const onSubmitHandler = async (values) => { - const options = { - behavior: 'smooth', - block: 'center', - }; - 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) { - if (npwpRef?.current) { - npwpRef.current.scrollIntoView(options); + loadZip(); } - toast.error('NPWP wajib di tambahkan'); - return; - } - if (!sppkp && isPkp) { - toast.error('SPPKP wajib di tambahkan'); - if (sppkpRef?.current) { - sppkpRef.current.scrollIntoView(options); + }, [watchsubDistrict, subDistricts]); + + const onSubmitHandler = async (values) => { + const options = { + behavior: 'smooth', + block: 'center', + }; + const npwp = { name: fileNames.npwp, format: DeatailFile.npwp }; + const sppkp = { name: fileNames.sppkp, format: DeatailFile.sppkp }; + const dokumenKtpDirut = { + name: fileNames.dokumenKtpDirut, + format: DeatailFile.dokumenKtpDirut, + }; + const kartuNama = { + name: fileNames.kartuNama, + format: DeatailFile.kartuNama, + }; + const suratPernyataan = { + name: fileNames.suratPernyataan, + format: DeatailFile.suratPernyataan, + }; + const fotoKantor = { + name: fileNames.fotoKantor, + format: DeatailFile.fotoKantor, + }; + const dataProduk = { + name: fileNames.dataProduk, + format: DeatailFile.dataProduk, + }; + const pricelist = { + name: fileNames.pricelist, + format: DeatailFile.pricelist, + }; + + if (!npwp.name && isPkp) { + if (npwpRef?.current) { + npwpRef.current.scrollIntoView(options); + } + toast.error('NPWP wajib di tambahkan'); + return; } - return; - } - if (!dokumenKtpDirut && !isPkp) { - toast.error('KTP Dirut/Direktur wajib di tambahkan'); - if (ktpDirutRef?.current) { - ktpDirutRef.current.scrollIntoView(options); + if (!sppkp.name && isPkp) { + toast.error('SPPKP wajib di tambahkan'); + if (sppkpRef?.current) { + sppkpRef.current.scrollIntoView(options); + } + return; } - return; - } - if (!fotoKantor) { - toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan'); - if (fotoKantorRef?.current) { - fotoKantorRef.current.scrollIntoView(options); + if (!dokumenKtpDirut.name && !isPkp) { + toast.error('KTP Dirut/Direktur wajib di tambahkan'); + if (ktpDirutRef?.current) { + ktpDirutRef.current.scrollIntoView(options); + } + return; } - return; - } - if (!pricelist) { - toast.error('Pricelist wajib di tambahkan'); - if (pricelistRef?.current) { - pricelistRef.current.scrollIntoView(options); + if (!fotoKantor.name) { + toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan'); + if (fotoKantorRef?.current) { + fotoKantorRef.current.scrollIntoView(options); + } + return; + } + if (!pricelist.name) { + toast.error('Pricelist wajib di tambahkan'); + if (pricelistRef?.current) { + pricelistRef.current.scrollIntoView(options); + } + return; } + const toastId = toast.loading('Mengirimkan formulir merchant...'); + const dokumen = { + file_npwp: { details: npwp.format ? npwp : '' }, + file_sppkp: { details: sppkp.format ? sppkp : '' }, + file_dokumenKtpDirut: { + details: dokumenKtpDirut.format ? dokumenKtpDirut : '', + }, + file_kartuNama: { details: kartuNama.format ? kartuNama : '' }, + file_suratPernyataan: { + details: suratPernyataan.format ? suratPernyataan : '', + }, + file_fotoKantor: { details: fotoKantor.format ? fotoKantor : '' }, + file_dataProduk: { details: dataProduk.format ? dataProduk : '' }, + file_pricelist: { details: pricelist.format ? pricelist : '' }, + }; + let data = { + file_dokumen: JSON.stringify(dokumen), + }; + const create_leads = await createMerchantApi({ data }); + if (create_leads) { + toast.dismiss(toastId); + toast.success('Berhasil menambahkan data'); + isError(false); + reset(); + } else { + toast.dismiss(toastId); + toast.error('Gagal menambahkan data'); + } + }; + + // const DownLoadSurat = () => { + // download surat dari /public/file/Surat Pernyataan Nomor Rekening.docx + // }; + + if (!auth) { return; } - const toastId = toast.loading('Mengirimkan formulir merchant...'); - const data = { - ...values, - 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 : '', + // 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 > 2000000) { + // try { + // const toastId = toast.loading('mencoba mengompresi file...'); + // // Compress image file + // const options = { + // maxSizeMB: 0.5, // Target size in MB + // maxWidthOrHeight: 1920, // Adjust as needed + // useWebWorker: true, + // }; + // const compressedFile = await imageCompression(file, options); + // toast.success('berhasil mengompresi file', { duration: 4000 }); + // // Convert compressed file to Base64 + // fileBase64 = await getFileBase64(compressedFile); + // } catch (error) { + // toast.error('Gagal mengompresi file', { duration: 4000 }); + // } + toast.error('Maks file size 2MB', { 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 + })); }; - isError(false); - toast.dismiss(toastId); - toast.success('Berhasil menambahkan data'); - // 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'); - // } - }; + return ( + <> + <BottomPopup + className='' + title='Contoh SPPKP' + active={isExample} + close={() => setIsExample(false)} + > + <div className='flex p-2'> + <Image + src='/images/NO-SPPKP-FORMAT-TEMPLATE.jpg' + alt='Contoh SPPKP' + className='w-full h-full ' + width={800} + height={800} + quality={85} + /> + </div> + </BottomPopup> + <DesktopView> + <div className='container flex flex-col items-star py-4 '> + <h2 className='text-xs md:text-title-sm font-semibold mb-6'> + Dokumen + </h2> - // const DownLoadSurat = () => { - // download surat dari /public/file/Surat Pernyataan Nomor Rekening.docx - // }; + <div className='w-full mt-4'> + <form + onSubmit={handleSubmit(onSubmitHandler)} + className='flex flex-col gap-4' + > + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + NPWP{' '} + {!isPkp && ( + <span className=' opacity-60'>(Opsional)</span> + )} + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Pastikan dokumen yang anda upload sudah benar + </span> + )} + </div> + <div + className={`w-3/5 flex flex-col justify-between ${ + isKonfirmasi ? 'items-end' : 'items-start' + }`} + ref={npwpRef} + > + <div + className={`flex flex-row items-start gap-2 w-full ${ + isKonfirmasi ? 'justify-end' : 'justify-start' + }`} + > + {isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.npwp} + </span> + )} + <label + htmlFor='npwp' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.npwp ? 'Ubah Dokumen' : 'Upload Dokumen'} + </label> + <input + {...register('npwp')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='npwp' + onChange={(e) => { + handleFileChange(e); // Untuk update UI (opsional) + }} + aria-invalid={errors.npwp?.message} + /> + {!isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.npwp} + </span> + )} + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + )} - if (!auth) { - return; - } - // Tetap di bagian atas, tidak boleh ada kondisi sebelum hook + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.npwp?.message} + </div> + </div> + </div> + <div + className={`w-full flex flex-row items-start ${ + isKonfirmasi && 'gap-2' + } `} + > + <div className='w-2/5 flex flex-row justify-between items-center '> + <div> + <label className='form-label text-nowrap' ref={sppkpRef}> + SPPKP{' '} + {!isPkp && ( + <span className=' opacity-60'>(Opsional)</span> + )} + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Pastikan dokumen yang anda upload sudah benar + </span> + )} + </div> + <div + onClick={() => setIsExample(!isExample)} + className={`h-fit ${ + !isKonfirmasi && 'mr-8' + } rounded text-white p-2 flex flex-row items-center bg-red-500 hover:cursor-pointer hover:bg-red-400`} + > + <EyeIcon + className={`${isKonfirmasi ? 'w-4' : 'w-4 mr-2'} `} + /> + {!isKonfirmasi && ( + <p className='font-light text-xs '>Lihat Contoh</p> + )} + </div> + </div> + <div + className={`w-3/5 flex flex-col justify-between ${ + isKonfirmasi ? 'items-end' : 'items-start' + }`} + > + <div className='flex flex-row items-start justify-start gap-2'> + {isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2 '> + {fileNames.sppkp} + </span> + )} + <label + htmlFor='sppkp' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.sppkp ? 'Ubah Dokumen' : 'Upload Dokumen'} + </label> + <input + {...register('sppkp')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='sppkp' + onChange={handleFileChange} + aria-invalid={errors.sppkp?.message} + /> + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + )} - const handleFileChange = async (event) => { - let fileBase64 = ''; - const file = event.target.files[0]; + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.sppkp?.message} + </div> + </div> + </div> - 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 ( - <> - <BottomPopup - className='' - title='Contoh SPPKP' - active={isExample} - close={() => setIsExample(false)} - > - <div className='flex p-2'> - <Image - src='/images/NO-SPPKP-FORMAT-TEMPLATE.jpg' - alt='Contoh SPPKP' - className='w-full h-full ' - width={800} - height={800} - quality={85} - /> - </div> - </BottomPopup> - <DesktopView> - <div className='container flex flex-col items-star py-4 '> - <h2 className='text-xs md:text-title-sm font-semibold mb-6'> - Dokumen - </h2> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + KTP Dirut/Direktur{' '} + {isPkp && <span className=' opacity-60'>(Opsional)</span>} + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Pastikan dokumen yang anda upload sudah benar + </span> + )} + </div> + <div + className={`w-3/5 flex flex-col justify-between ${ + isKonfirmasi ? 'items-end' : 'items-start' + }`} + ref={ktpDirutRef} + > + <div + className={`flex flex-row items-start ${ + isKonfirmasi ? 'justify-end' : 'justify-start' + } gap-2 w-full`} + > + {isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.dokumenKtpDirut} + </span> + )} + <label + htmlFor='dokumenKtpDirut' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.dokumenKtpDirut + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + {...register('dokumenKtpDirut')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='dokumenKtpDirut' + onChange={handleFileChange} + aria-invalid={errors.dokumenKtpDirut?.message} + /> + {!isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.dokumenKtpDirut} + </span> + )} + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + )} + + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.dokumenKtpDirut?.message} + </div> + </div> + </div> + + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label + className='form-label text-nowrap' + ref={kartuNamaRef} + > + Kartu Nama <span className=' opacity-60'>(Opsional)</span>{' '} + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Pastikan dokumen yang anda upload sudah benar + </span> + )} + </div> + <div + className={`w-3/5 flex flex-col justify-between ${ + isKonfirmasi ? 'items-end' : 'items-start' + }`} + > + <div className='flex flex-row items-start justify-start gap-2'> + {isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.kartuNama} + </span> + )} + <label + htmlFor='kartuNama' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.kartuNama + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + {...register('kartuNama')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='kartuNama' + onChange={handleFileChange} + aria-invalid={errors.kartuNama?.message} + /> + {!isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.kartuNama} + </span> + )} + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + )} + + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.kartuNama?.message} + </div> + </div> + </div> - <div className='w-full mt-4'> - <form - onSubmit={handleSubmit(onSubmitHandler)} - className='flex flex-col gap-4' - > - <div className='w-full flex flex-row'> - <div className='w-2/5'> + <div className='w-full flex flex-row items-start '> + <div className='w-2/5 flex flex-row justify-between items-center '> + <div> + <label + className={`form-label ${ + isKonfirmasi ? 'text-wrap' : ' text-nowrap' + }`} + ref={suratPernyataanRef} + > + Surat Pernyataan Nomor Rekening{' '} + <span className=' opacity-60'>(Opsional)</span> + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Wajib diisi jika nomor rekening berbeda dengan nama + perusahaan + </span> + )} + </div> + <a + href='/file/Surat Pernyataan Nomor Rekening.docx' + download='Surat Pernyataan Nomor Rekening.docx' + 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' + > + <p className='font-light text-xs'>Download Template</p> + </a> + </div> + <div + className={`w-3/5 flex flex-col justify-between ${ + isKonfirmasi ? 'items-end' : 'items-start' + }`} + > + <div className='flex flex-row items-start justify-start gap-2'> + {isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.suratPernyataan} + </span> + )} + <label + htmlFor='suratPernyataan' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.suratPernyataan + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + {...register('suratPernyataan')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='suratPernyataan' + onChange={handleFileChange} + aria-invalid={errors.suratPernyataan?.message} + /> + {!isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.suratPernyataan} + </span> + )} + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + )} + + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.suratPernyataan?.message} + </div> + </div> + </div> + <div className='w-full flex flex-row items-start '> + <div className='w-2/5 flex flex-col justify-start items-start '> + <label + className={`form-label ${ + isKonfirmasi ? 'text-wrap' : 'text-nowrap' + }`} + ref={fotoKantorRef} + > + Foto Gudang / Kantor Bagian Depan + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Pastikan dokumen yang anda upload sudah benar + </span> + )} + </div> + <div + className={`w-3/5 flex flex-col justify-between ${ + isKonfirmasi ? 'items-end' : 'items-start' + }`} + > + <div className='flex flex-row items-start justify-start gap-2'> + {isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.fotoKantor} + </span> + )} + <label + htmlFor='fotoKantor' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.fotoKantor + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + {...register('fotoKantor')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='fotoKantor' + onChange={handleFileChange} + aria-invalid={errors.fotoKantor?.message} + /> + {!isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.fotoKantor} + </span> + )} + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + )} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.fotoKantor?.message} + </div> + </div> + </div> + <div className='w-full flex flex-row items-start '> + <div className='w-2/5 flex flex-col justify-start items-start '> + <label + className={`form-label ${ + isKonfirmasi ? 'text-wrap' : 'text-nowrap' + }`} + ref={dataProdukRef} + > + Data Produk (Item Name, Gambar, Deskripsi){' '} + <span className=' opacity-60'>(Opsional)</span>{' '} + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Pastikan dokumen yang anda upload sudah benar + </span> + )} + </div> + <div + className={`w-3/5 flex flex-col justify-between ${ + isKonfirmasi ? 'items-end' : 'items-start' + }`} + > + <div className='flex flex-row items-start justify-start gap-2'> + {isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.dataProduk} + </span> + )} + <label + htmlFor='dataProduk' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.dataProduk + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + {...register('dataProduk')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='dataProduk' + onChange={handleFileChange} + aria-invalid={errors.dataProduk?.message} + /> + {!isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.dataProduk} + </span> + )} + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + )} + + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.dataProduk?.message} + </div> + </div> + </div> + <div className='w-full flex flex-row items-start '> + <div className='w-2/5 flex flex-col justify-start items-start '> + <label + className='form-label text-nowrap' + ref={pricelistRef} + > + Pricelist + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Pastikan dokumen yang anda upload sudah benar + </span> + )} + </div> + <div + className={`w-3/5 flex flex-col justify-between ${ + isKonfirmasi ? 'items-end' : 'items-start' + }`} + > + <div className='flex flex-row items-start justify-start gap-2'> + {isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.pricelist} + </span> + )} + <label + htmlFor='pricelist' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.pricelist + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + {...register('pricelist')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='pricelist' + onChange={handleFileChange} + aria-invalid={errors.pricelist?.message} + /> + {!isKonfirmasi && ( + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.pricelist} + </span> + )} + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB + </span> + )} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.pricelist?.message} + </div> + </div> + </div> + <div className=''> + {/* <div> + <ReCAPTCHA + ref={recaptchaRef} + sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} + /> + </div> */} + </div> + <div className='flex justify-end'> + {/* <Button + colorScheme='red' + className='w-full md:w-fit' + type='submit' + > + Daftar Merchant{' '} + {<ChevronRightIcon className='w-5' color='white' />} + </Button> */} + {!isKonfirmasi && ( + <div> + <span className='text-xs opacity-60'> + *Pastikan data yang anda masukan sudah benar dan sesuai + </span> + <button + type='submit' + className='btn-light bg-red-500 rounded-lg text-white w-fit py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-between hover:bg-red-400' + > + <span className={` `}>Langkah Selanjutnya</span> + {<ChevronRightIcon className='w-5' />} + </button> + </div> + )} + </div> + </form> + <PageContent path='/daftar-merchant' /> + </div> + </div> + </DesktopView> + <MobileView> + <div className='container flex flex-col items-star py-4'> + {BannerMerchant && ( + <ImageBanner + src={BannerMerchant} + alt='FORM MERCHANT' + width={1000} + height={160} + className='w-full mt-6' + /> + )} + <h1 className='text-h-sm md:text-title-sm font-semibold mb-6 text-center'> + Form Merchant + </h1> + <div className='text-center mb-6'> + 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. + </div> + <h2 className='font-semibold mb-6'>Informasi Perusahaan</h2> + + <div className='w-full mt-4'> + <form + onSubmit={handleSubmit(onSubmitHandler)} + className='flex flex-col gap-4' + > + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'> + Nama Perusahaan + </label> + <input + {...register('company')} + placeholder='Format: PT. INDOTEKNIK DOTCOM GEMILANG' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.company?.message} + </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan nama yang terdaftar{' '} + </span> + </div> + </div> + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'>Nama PIC</label> + <input + {...register('PICName')} + placeholder='Masukkan Nama PIC ' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.PICName?.message} + </div> + <span className='opacity-65 text-xs'> + Isi dengan nama sales / penanggung jawab + </span> + </div> + </div> + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'> + Alamat Perusahaan + </label> + <input + {...register('address')} + placeholder='Masukkan alamat lengkap perusahaan' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.address?.message} + </div> + <div className='flex flex-row w-full justify-between gap-2'> + <div className='provinsi w-full'> + <Controller + name='state' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={state} + placeholder='Provinsi' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.state?.message} + </div> + </div> + <div className='kab w-full'> + <Controller + name='city' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={cities} + disabled={!watchState} + placeholder='Kab/Kota' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.city?.message} + </div> + </div> + </div> + <div className='flex flex-row w-full justify-between gap-2'> + <div className='kec w-full'> + <Controller + name='district' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={districts} + disabled={!watchState || !watchCity} + placeholder='Kecamatan' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.district?.message} + </div> + </div> + <div className='kel w-full'> + <Controller + name='subDistrict' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={subDistricts} + disabled={!watchDistrict} + placeholder='Kelurahan' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.subDistrict?.message} + </div> + </div> + <div className='zip w-full'> + <Controller + name='zip' + control={control} + render={(props) => ( + <> + {zips.length > 0 ? ( + <HookFormSelect + {...props} + options={zips} + disabled={!watchsubDistrict} + placeholder='Zip' + /> + ) : ( + <input + {...register('zip')} + placeholder='Kode Pos' + type='number' + className='form-input' + disabled={!watchsubDistrict} + /> + )} + </> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.zip?.message} + </div> + </div> + </div> + </div> + <span className='opacity-65 text-xs'> + Alamat sesuai dengan alamat perusahaan + </span> + </div> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'>Data Bank</label> + <div className='w-full flex flex-row gap-2'> + <div> + <input + {...register('bank')} + placeholder='Nama bank' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.bank?.message} + </div> + </div> + <div> + <input + {...register('rekening')} + placeholder='Nama Rekening' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.rekening?.message} + </div> + </div> + <div> + <input + {...register('accountNumber')} + placeholder='Nomor Rekening Bank' + type='number' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountNumber?.message} + </div> + </div> + </div> + <span className='opacity-65 text-xs'> + Isi detail data bank perusahaan anda + </span> + </div> + <div className='w-full flex flex-col'> <label className='form-label text-nowrap'> - NPWP{' '} - {!isPkp && <span className=' opacity-60'>(Opsional)</span>} + Email Perusahaan </label> + <input + {...register('email')} + placeholder='contoh@email.com' + type='email' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.email?.message} + </div> <span className='opacity-65 text-xs'> - Pastikan dokumen yang anda upload sudah benar + Isi detail perusahaan sesuai dengan data yang terdaftar </span> </div> - <div - className='w-3/5 flex flex-col justify-start items-start' - ref={npwpRef} - > + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'>Email Sales</label> + <input + {...register('emailSales')} + placeholder='contoh@email.com' + type='email' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.emailSales?.message} + </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan data yang terdaftar + </span> + </div> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'> + Email Finance + </label> + <input + {...register('emailFinance')} + placeholder='contoh@email.com' + type='email' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.emailFinance?.message} + </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan data yang terdaftar + </span> + </div> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'> + No. Telepon Perusahaan + </label> + <input + {...register('phone')} + placeholder='Format: 08123456789 / (021) 123 4567' + type='tel' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.phone?.message} + </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan data yang terdaftar + </span> + </div> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'> + No. Handphone + </label> + <input + {...register('mobile')} + placeholder='Masukkan nomor handphone' + type='tel' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.mobile?.message} + </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan data yang terdaftar + </span> + </div> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'> + Harga Tayang (HET){' '} + <span className=' opacity-60'>(Opsional)</span> + </label> + <input + {...register('hargaTayang')} + placeholder='Masukkan Harga Tayang (HET)' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.hargaTayang?.message} + </div> + </div> + + <div className='w-full flex flex-col gap-2'> + <label className='form-label text-nowrap'> + NPWP{' '} + {!isPkp && <span className=' opacity-60'>(Opsional)</span>} + </label> <div className='flex flex-row items-start justify-start gap-2'> <label htmlFor='npwp' @@ -442,7 +1370,7 @@ const Dokumen = ({ handleIsError }) => { }} aria-invalid={errors.npwp?.message} /> - <span className='mt-2 text-gray-600 line-clamp-2'> + <span className=' text-gray-600 line-clamp-2'> {fileNames.npwp} </span> </div> @@ -454,30 +1382,23 @@ const Dokumen = ({ handleIsError }) => { {errors.npwp?.message} </div> </div> - </div> - <div className='w-full flex flex-row items-start'> - <div className='w-2/5 flex flex-row justify-between items-center'> - <div> - <label className='form-label text-nowrap' ref={sppkpRef}> + <div className='w-full flex flex-col gap-2 items-start '> + <div className='flex flex-row w-full justify-between items-center '> + <label className='form-label text-nowrap'> SPPKP{' '} {!isPkp && ( <span className=' opacity-60'>(Opsional)</span> )} </label> - <span className='opacity-65 text-xs'> - Pastikan dokumen yang anda upload sudah benar - </span> - </div> - <div - onClick={() => 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' - > - <EyeIcon className={`w-4 mr-2 `} /> + <div + onClick={() => 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' + > + <EyeIcon className={`w-4 mr-2 `} /> - <p className='font-light text-xs '>Lihat Contoh</p> + <p className='font-light text-xs '>Lihat Contoh</p> + </div> </div> - </div> - <div className='w-3/5 flex flex-col justify-between items-start'> <div className='flex flex-row items-start justify-start gap-2'> <label htmlFor='sppkp' @@ -494,7 +1415,7 @@ const Dokumen = ({ handleIsError }) => { onChange={handleFileChange} aria-invalid={errors.sppkp?.message} /> - <span className='mt-2 text-gray-600 line-clamp-2'> + <span className=' text-gray-600 line-clamp-2'> {fileNames.sppkp} </span> </div> @@ -506,23 +1427,13 @@ const Dokumen = ({ handleIsError }) => { {errors.sppkp?.message} </div> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> + <div className='w-full flex flex-col gap-2'> <label className='form-label text-nowrap'> KTP Dirut/Direktur{' '} {isPkp && <span className=' opacity-60'>(Opsional)</span>} </label> - <span className='opacity-65 text-xs'> - Pastikan dokumen yang anda upload sudah benar - </span> - </div> - <div - className='w-3/5 flex flex-col justify-start items-start' - ref={ktpDirutRef} - > - <div className='flex flex-row items-start justify-start gap-2'> + <div className='flex flex-row items-start justify-start gap-2 '> <label htmlFor='dokumenKtpDirut' className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' @@ -540,7 +1451,7 @@ const Dokumen = ({ handleIsError }) => { onChange={handleFileChange} aria-invalid={errors.dokumenKtpDirut?.message} /> - <span className='mt-2 text-gray-600 line-clamp-2'> + <span className=' text-gray-600 line-clamp-2'> {fileNames.dokumenKtpDirut} </span> </div> @@ -552,18 +1463,11 @@ const Dokumen = ({ handleIsError }) => { {errors.dokumenKtpDirut?.message} </div> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> - <label className='form-label text-nowrap' ref={kartuNamaRef}> + <div className='w-full flex flex-col gap-2'> + <label className='form-label text-nowrap'> Kartu Nama <span className=' opacity-60'>(Opsional)</span>{' '} </label> - <span className='opacity-65 text-xs'> - Pastikan dokumen yang anda upload sudah benar - </span> - </div> - <div className='w-3/5 flex flex-col justify-start items-start'> <div className='flex flex-row items-start justify-start gap-2'> <label htmlFor='kartuNama' @@ -580,7 +1484,7 @@ const Dokumen = ({ handleIsError }) => { onChange={handleFileChange} aria-invalid={errors.kartuNama?.message} /> - <span className='mt-2 text-gray-600 line-clamp-2'> + <span className=' text-gray-600 line-clamp-2'> {fileNames.kartuNama} </span> </div> @@ -592,32 +1496,23 @@ const Dokumen = ({ handleIsError }) => { {errors.kartuNama?.message} </div> </div> - </div> - <div className='w-full flex flex-row items-start '> - <div className='w-2/5 flex flex-row justify-between items-center '> - <div> - <label - className='form-label text-nowrap' - ref={suratPernyataanRef} - > + <div className='w-full flex flex-col gap-2 items-start '> + <div className='flex flex-row w-full justify-between items-center'> + <label className='form-label text-wrap'> Surat Pernyataan Nomor Rekening{' '} <span className=' opacity-60'>(Opsional)</span> </label> - <span className='opacity-65 text-xs'> - Wajib diisi jika nomor rekening berbeda dengan nama - perusahaan - </span> + <a + href='/file/Surat Pernyataan Nomor Rekening.docx' + download='Surat Pernyataan Nomor Rekening.docx' + className='h-fit rounded text-white p-2 flex flex-row items-center bg-red-500 hover:cursor-pointer hover:bg-red-400' + > + <p className='font-light text-xs text-nowrap'> + Download Template + </p> + </a> </div> - <a - href='/file/Surat Pernyataan Nomor Rekening.docx' - download='Surat Pernyataan Nomor Rekening.docx' - 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' - > - <p className='font-light text-xs'>Download Template</p> - </a> - </div> - <div className='w-3/5 flex flex-col justify-between items-start'> <div className='flex flex-row items-start justify-start gap-2'> <label htmlFor='suratPernyataan' @@ -636,7 +1531,7 @@ const Dokumen = ({ handleIsError }) => { onChange={handleFileChange} aria-invalid={errors.suratPernyataan?.message} /> - <span className='mt-2 text-gray-600 line-clamp-2'> + <span className=' text-gray-600 line-clamp-2'> {fileNames.suratPernyataan} </span> </div> @@ -648,20 +1543,10 @@ const Dokumen = ({ handleIsError }) => { {errors.suratPernyataan?.message} </div> </div> - </div> - <div className='w-full flex flex-row items-start '> - <div className='w-2/5 flex flex-col justify-start items-start '> - <label - className='form-label text-nowrap' - ref={fotoKantorRef} - > + <div className='w-full flex flex-col gap-2 items-start '> + <label className='form-label text-nowrap'> Foto Gudang / Kantor Bagian Depan </label> - <span className='opacity-65 text-xs'> - Pastikan dokumen yang anda upload sudah benar - </span> - </div> - <div className='w-3/5 flex flex-col justify-between items-start'> <div className='flex flex-row items-start justify-start gap-2'> <label htmlFor='fotoKantor' @@ -690,21 +1575,11 @@ const Dokumen = ({ handleIsError }) => { {errors.fotoKantor?.message} </div> </div> - </div> - <div className='w-full flex flex-row items-start '> - <div className='w-2/5 flex flex-col justify-start items-start '> - <label - className='form-label text-nowrap' - ref={dataProdukRef} - > + <div className='w-full flex flex-col gap-2 items-start '> + <label className='form-label text-nowrap'> Data Produk (Item Name, Gambar, Deskripsi){' '} <span className=' opacity-60'>(Opsional)</span>{' '} </label> - <span className='opacity-65 text-xs'> - Pastikan dokumen yang anda upload sudah benar - </span> - </div> - <div className='w-3/5 flex flex-col justify-between items-start'> <div className='flex flex-row items-start justify-start gap-2'> <label htmlFor='dataProduk' @@ -730,20 +1605,11 @@ const Dokumen = ({ handleIsError }) => { </span> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.dataProduk?.message} + {errors.fotoKantor?.message} </div> </div> - </div> - <div className='w-full flex flex-row items-start '> - <div className='w-2/5 flex flex-col justify-start items-start '> - <label className='form-label text-nowrap' ref={pricelistRef}> - Pricelist - </label> - <span className='opacity-65 text-xs'> - Pastikan dokumen yang anda upload sudah benar - </span> - </div> - <div className='w-3/5 flex flex-col justify-between items-start'> + <div className='w-full flex flex-col gap-2 items-start '> + <label className='form-label text-nowrap'>Pricelist</label> <div className='flex flex-row items-start justify-start gap-2'> <label htmlFor='pricelist' @@ -772,679 +1638,41 @@ const Dokumen = ({ handleIsError }) => { {errors.pricelist?.message} </div> </div> - </div> - <div className=''> - {/* <div> + <div className=''> + {/* <div> <ReCAPTCHA ref={recaptchaRef} sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} /> </div> */} - </div> - <div className='flex justify-start'> - {/* <Button - colorScheme='red' - className='w-full md:w-fit' - type='submit' - > - Daftar Merchant{' '} - {<ChevronRightIcon className='w-5' color='white' />} - </Button> */} - <div> - <button + </div> + <div className='flex justify-end mb-4'> + <Button + colorScheme='red' + className='w-full md:w-fit' type='submit' - className='btn-light bg-red-500 rounded-lg text-white w-full md:w-fit mt-6 ml-0 md:ml-auto flex justify-between hover:bg-red-400' > - <span>Daftar Merchant </span> - </button> - </div> - </div> - </form> - <PageContent path='/daftar-merchant' /> - </div> - </div> - </DesktopView> - <MobileView> - <div className='container flex flex-col items-star py-4'> - {BannerMerchant && ( - <ImageBanner - src={BannerMerchant} - alt='FORM MERCHANT' - width={1000} - height={160} - className='w-full mt-6' - /> - )} - <h1 className='text-h-sm md:text-title-sm font-semibold mb-6 text-center'> - Form Merchant - </h1> - <div className='text-center mb-6'> - 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. - </div> - <h2 className='font-semibold mb-6'>Informasi Perusahaan</h2> - - <div className='w-full mt-4'> - <form - onSubmit={handleSubmit(onSubmitHandler)} - className='flex flex-col gap-4' - > - <div className='w-full flex flex-col'> - <div className='w-full'> - <label className='form-label text-nowrap'> - Nama Perusahaan - </label> - <input - {...register('company')} - placeholder='Format: PT. INDOTEKNIK DOTCOM GEMILANG' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.company?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan nama yang terdaftar{' '} - </span> - </div> - </div> - <div className='w-full flex flex-col'> - <div className='w-full'> - <label className='form-label text-nowrap'>Nama PIC</label> - <input - {...register('PICName')} - placeholder='Masukkan Nama PIC ' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.PICName?.message} - </div> - <span className='opacity-65 text-xs'> - Isi dengan nama sales / penanggung jawab - </span> - </div> - </div> - <div className='w-full flex flex-col'> - <div className='w-full'> - <label className='form-label text-nowrap'> - Alamat Perusahaan - </label> - <input - {...register('address')} - placeholder='Masukkan alamat lengkap perusahaan' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.address?.message} - </div> - <div className='flex flex-row w-full justify-between gap-2'> - <div className='provinsi w-full'> - <Controller - name='state' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={state} - placeholder='Provinsi' - /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.state?.message} - </div> - </div> - <div className='kab w-full'> - <Controller - name='city' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={cities} - disabled={!watchState} - placeholder='Kab/Kota' - /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.city?.message} - </div> - </div> - </div> - <div className='flex flex-row w-full justify-between gap-2'> - <div className='kec w-full'> - <Controller - name='district' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={districts} - disabled={!watchState || !watchCity} - placeholder='Kecamatan' - /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.district?.message} - </div> - </div> - <div className='kel w-full'> - <Controller - name='subDistrict' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={subDistricts} - disabled={!watchDistrict} - placeholder='Kelurahan' - /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.subDistrict?.message} - </div> - </div> - <div className='zip w-full'> - <Controller - name='zip' - control={control} - render={(props) => ( - <> - {zips.length > 0 ? ( - <HookFormSelect - {...props} - options={zips} - disabled={!watchsubDistrict} - placeholder='Zip' - /> - ) : ( - <input - {...register('zip')} - placeholder='Kode Pos' - type='number' - className='form-input' - disabled={!watchsubDistrict} - /> - )} - </> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.zip?.message} - </div> - </div> - </div> - </div> - <span className='opacity-65 text-xs'> - Alamat sesuai dengan alamat perusahaan - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'>Data Bank</label> - <div className='w-full flex flex-row gap-2'> - <div> - <input - {...register('bank')} - placeholder='Nama bank' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.bank?.message} - </div> - </div> - <div> - <input - {...register('rekening')} - placeholder='Nama Rekening' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.rekening?.message} - </div> - </div> + Daftar Merchant{' '} + {/* {<ChevronRightIcon className='w-5' color='white' />} */} + </Button> <div> - <input - {...register('accountNumber')} - placeholder='Nomor Rekening Bank' - type='number' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.accountNumber?.message} - </div> - </div> - </div> - <span className='opacity-65 text-xs'> - Isi detail data bank perusahaan anda - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'> - Email Perusahaan - </label> - <input - {...register('email')} - placeholder='contoh@email.com' - type='email' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.email?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'>Email Sales</label> - <input - {...register('emailSales')} - placeholder='contoh@email.com' - type='email' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.emailSales?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'>Email Finance</label> - <input - {...register('emailFinance')} - placeholder='contoh@email.com' - type='email' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.emailFinance?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'> - No. Telepon Perusahaan - </label> - <input - {...register('phone')} - placeholder='Format: 08123456789 / (021) 123 4567' - type='tel' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.phone?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'>No. Handphone</label> - <input - {...register('mobile')} - placeholder='Masukkan nomor handphone' - type='tel' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.mobile?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'> - Harga Tayang (HET){' '} - <span className=' opacity-60'>(Opsional)</span> - </label> - <input - {...register('hargaTayang')} - placeholder='Masukkan Harga Tayang (HET)' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.hargaTayang?.message} - </div> - </div> - - <div className='w-full flex flex-col gap-2'> - <label className='form-label text-nowrap'> - NPWP{' '} - {!isPkp && <span className=' opacity-60'>(Opsional)</span>} - </label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='npwp' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.npwp ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('npwp')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='npwp' - onChange={(e) => { - handleFileChange(e); // Untuk update UI (opsional) - }} - aria-invalid={errors.npwp?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.npwp} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.npwp?.message} - </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <div className='flex flex-row w-full justify-between items-center '> - <label className='form-label text-nowrap'> - SPPKP{' '} - {!isPkp && <span className=' opacity-60'>(Opsional)</span>} - </label> - <div - onClick={() => 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' - > - <EyeIcon className={`w-4 mr-2 `} /> - - <p className='font-light text-xs '>Lihat Contoh</p> - </div> - </div> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='sppkp' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.sppkp ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('sppkp')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='sppkp' - onChange={handleFileChange} - aria-invalid={errors.sppkp?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.sppkp} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.sppkp?.message} - </div> - </div> - - <div className='w-full flex flex-col gap-2'> - <label className='form-label text-nowrap'> - KTP Dirut/Direktur{' '} - {isPkp && <span className=' opacity-60'>(Opsional)</span>} - </label> - <div className='flex flex-row items-start justify-start gap-2 '> - <label - htmlFor='dokumenKtpDirut' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.dokumenKtpDirut - ? 'Ubah Dokumen' - : 'Upload Dokumen'} - </label> - <input - {...register('dokumenKtpDirut')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='dokumenKtpDirut' - onChange={handleFileChange} - aria-invalid={errors.dokumenKtpDirut?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.dokumenKtpDirut} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.dokumenKtpDirut?.message} - </div> - </div> - - <div className='w-full flex flex-col gap-2'> - <label className='form-label text-nowrap'> - Kartu Nama <span className=' opacity-60'>(Opsional)</span>{' '} - </label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='kartuNama' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.kartuNama ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('kartuNama')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='kartuNama' - onChange={handleFileChange} - aria-invalid={errors.kartuNama?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.kartuNama} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.kartuNama?.message} - </div> - </div> - - <div className='w-full flex flex-col gap-2 items-start '> - <div className='flex flex-row w-full justify-between items-center'> - <label className='form-label text-wrap'> - Surat Pernyataan Nomor Rekening{' '} - <span className=' opacity-60'>(Opsional)</span> - </label> - <a - href='/file/Surat Pernyataan Nomor Rekening.docx' - download='Surat Pernyataan Nomor Rekening.docx' - className='h-fit rounded text-white p-2 flex flex-row items-center bg-red-500 hover:cursor-pointer hover:bg-red-400' - > - <p className='font-light text-xs text-nowrap'> - Download Template - </p> - </a> - </div> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='suratPernyataan' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.suratPernyataan - ? 'Ubah Dokumen' - : 'Upload Dokumen'} - </label> - <input - {...register('suratPernyataan')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='suratPernyataan' - onChange={handleFileChange} - aria-invalid={errors.suratPernyataan?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.suratPernyataan} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.suratPernyataan?.message} - </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <label className='form-label text-nowrap'> - Foto Gudang / Kantor Bagian Depan - </label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='fotoKantor' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.fotoKantor ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('fotoKantor')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='fotoKantor' - onChange={handleFileChange} - aria-invalid={errors.fotoKantor?.message} - /> - <span className='mt-2 text-gray-600 line-clamp-2'> - {fileNames.fotoKantor} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.fotoKantor?.message} - </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <label className='form-label text-nowrap'> - Data Produk (Item Name, Gambar, Deskripsi){' '} - <span className=' opacity-60'>(Opsional)</span>{' '} - </label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='dataProduk' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.dataProduk ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('dataProduk')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='dataProduk' - onChange={handleFileChange} - aria-invalid={errors.dataProduk?.message} - /> - <span className='mt-2 text-gray-600 line-clamp-2'> - {fileNames.dataProduk} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.fotoKantor?.message} - </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <label className='form-label text-nowrap'>Pricelist</label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='pricelist' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.pricelist ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('pricelist')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='pricelist' - onChange={handleFileChange} - aria-invalid={errors.pricelist?.message} - /> - <span className='mt-2 text-gray-600 line-clamp-2'> - {fileNames.pricelist} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.pricelist?.message} - </div> - </div> - <div className=''> - {/* <div> - <ReCAPTCHA - ref={recaptchaRef} - sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} - /> - </div> */} - </div> - <div className='flex justify-end mb-4'> - <Button - colorScheme='red' - className='w-full md:w-fit' - type='submit' - > - Daftar Merchant{' '} - {/* {<ChevronRightIcon className='w-5' color='white' />} */} - </Button> - <div> - {/* <button + {/* <button type='submit' className='btn-yellow w-full md:w-fit mt-6 ml-0 md:ml-auto' > Simpan </button> */} + </div> </div> - </div> - </form> - <PageContent path='/daftar-merchant' /> + </form> + <PageContent path='/daftar-merchant' /> + </div> </div> - </div> - </MobileView> - </> - ); -}; + </MobileView> + </> + ); + } +); const validationSchema = Yup.object().shape({ npwp: Yup.mixed().required('File is required'), pricelist: Yup.mixed().required('File is required'), diff --git a/src/lib/merchant/components/InformasiPerusahaan.jsx b/src/lib/merchant/components/InformasiPerusahaan.jsx index a5456378..88bad0c4 100644 --- a/src/lib/merchant/components/InformasiPerusahaan.jsx +++ b/src/lib/merchant/components/InformasiPerusahaan.jsx @@ -4,7 +4,13 @@ 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 React, { + useEffect, + useRef, + useState, + forwardRef, + useImperativeHandle, +} from 'react'; import ReCAPTCHA from 'react-google-recaptcha'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; @@ -26,665 +32,1179 @@ import DesktopView from '@/core/components/views/DesktopView'; import getFileBase64 from '@/core/utils/getFileBase64'; import odooApi from '~/libs/odooApi'; -const CreateMerchant = ({ handleIsError }) => { - const isError = (value) => { - // Logika menentukan error - const result = value ? true : false; - handleIsError(result); // Panggil handleIsError dari Merchant - return result; - }; - // React.useEffect(() => { - // handleIsError(isError()); - // }, [handleIsError]); - const { - register, - handleSubmit, - formState: { errors }, - control, - reset, - watch, - setValue, - getValues, - } = useForm({ - resolver: yupResolver(validationSchema), - defaultValues, - }); - console.log('errors', errors); - console.log('errors length', errors.length); - 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); - - useEffect(() => { - window.scrollTo({ - top: 0, - behavior: 'smooth', - }); - }, []); - - 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 loadData = async () => { - try { - const data = await getMerchantApi(); - console.log('data', data); - reset({ - pejabatName: data.pejabatName ? data.pejabatName : '', - PICName: data.picMerchant || '', - PICPosition: data.picPosition || '', - address: data.address || '', - state: data.state || '', - city: data.city || '', - district: data.district || '', - subDistrict: data.subDistrict || '', - zip: parseInt(data.zip) || '', - email: data.emailCompany || '', - emailSales: data.emailSales || '', - emailFinance: data.emailFinance || '', - bank: data.bankName || '', - rekening: data.rekeningName || '', - accountNumber: data.accountNumber || '', - phone: data.phone || '', - mobile: data.mobile || '', - bisnisType: data.bisnisType ? parseInt(data.bisnisType) : null, - categoryPerusahaan: data.categoryPerusahaan - ? parseInt(data.categoryPerusahaan) - : null, - website: data.website || '', - }); - } catch (error) { - console.error('Error loading profile:', error); - handleIsError(true); // Jika ada error, panggil fungsi error handler - } +const CreateMerchant = forwardRef( + ({ handleIsError, isKonfirmasi, buttonSubmitClick }, ref) => { + const isError = (value) => { + // Logika menentukan error + const result = value ? true : false; + handleIsError(result); // Panggil handleIsError dari Merchant + return result; }; + // React.useEffect(() => { + // handleIsError(isError()); + // }, [handleIsError]); + const { + register, + handleSubmit, + formState: { errors }, + control, + reset, + watch, + setValue, + getValues, + } = useForm({ + resolver: yupResolver(validationSchema), + defaultValues, + }); + console.log('errors', errors); + console.log('errors length', errors.length); + 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); - loadData(); - }, [reset, handleIsError]); + useEffect(() => { + window.scrollTo({ + top: 0, + behavior: 'smooth', + }); + }, []); - 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); - } - }; + // useEffect(() => { + // console.log('MASUK SINI IMANUEL'); + // handleSubmit(onSubmitHandler); // Jalankan handler saat buttonSubmitClick berubah + // }, [buttonSubmitClick]); - loadProfile(); - }, [auth?.parentId]); + useImperativeHandle(ref, () => () => { + handleSubmit(onSubmitHandler)(); + }); - useEffect(() => { - const loadState = async () => { - let dataState = await stateApi({ tempo: false }); - dataState = dataState.map((state) => ({ - value: state.id, - label: state.name, - })); - setState(dataState); - }; - loadState(); - }, []); + const recaptchaRef = useRef(null); + const router = useRouter(); - const watchState = watch('state'); - useEffect(() => { + const auth = useAuth(); if (auth == false) { - return; + router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`); } - 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); + 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 loadData = async () => { + try { + const data = await getMerchantApi(); + console.log('data', data); + if (data) { + reset({ + pejabatName: data.pejabatName ? data.pejabatName : '', + PICName: data.picMerchant || '', + PICPosition: data.picPosition || '', + address: data.address ? data.address : '', + state: data.state ? data.state : '', + city: data.city || '', + district: data.district || '', + subDistrict: data.subDistrict || '', + zip: parseInt(data.zip) || '', + email: data.emailCompany || '', + emailSales: data.emailSales || '', + emailFinance: data.emailFinance || '', + bank: data.bankName || '', + rekening: data.rekeningName || '', + accountNumber: data.accountNumber || '', + phone: data.phone || '', + mobile: data.mobile || '', + bisnisType: data.bisnisType ? parseInt(data.bisnisType) : null, + categoryPerusahaan: data.categoryPerusahaan + ? parseInt(data.categoryPerusahaan) + : null, + website: data.website || '', + }); + } + } catch (error) { + console.error('Error loading profile:', error); + handleIsError(true); // Jika ada error, panggil fungsi error handler + } }; - loadCities(); - } - }, [auth, watchState]); - const watchCity = watch('city'); - console.log('watchCity', watchCity); - 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); + loadData(); + }, [reset, handleIsError]); + + 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); + } }; - 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, + loadProfile(); + }, [auth?.parentId]); + + useEffect(() => { + const loadState = async () => { + let dataState = await stateApi({ tempo: false }); + dataState = dataState.map((state) => ({ + value: state.id, + label: state.name, })); - setSubDistricts(dataSubDistricts); + setState(dataState); }; - loadSubDistricts(); - } - }, [watchDistrict]); + loadState(); + }, []); - const watchsubDistrict = watch('subDistrict'); + 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]); - useEffect(() => { - let kelurahan = ''; - let kecamatan = ''; + const watchCity = watch('city'); + console.log('watchCity', watchCity); + 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]); - if (watchDistrict) { - // setValue('zip', ''); - for (const data in districts) { - if (districts[data].value == watchDistrict) { - kecamatan = districts[data].label.toLowerCase(); - } + 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]); - if (watchsubDistrict) { - for (const data in subDistricts) { - if (subDistricts[data].value == watchsubDistrict) { - kelurahan = subDistricts[data].label.toLowerCase(); + 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(); + } } } - 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 + 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}` + ); - const result = await response.json(); + let dataMasuk = []; // Array untuk menyimpan kode pos yang sudah diproses - // 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, - })); + const result = await response.json(); - setZips(dataZips); // Set hasil ke state - }; + // 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, + })); - loadZip(); - } - }, [watchsubDistrict, subDistricts]); - const onSubmitHandler = async (values) => { - console.log('data yang mau dikirim', values); - const toastId = toast.loading('Mengirimkan formulir merchant...'); - const data = { - ...values, - name_merchant: 'Form Merchant - ' + values.company, - pejabat_name: values.pejabatName, - pic_merchant: values.PICName, - pic_position: values.PICPosition, - 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, - bisnis_type: values.bisnisType, - category_perusahaan: values.categoryPerusahaan, - website: values.website, - 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, + setZips(dataZips); // Set hasil ke state + }; + + loadZip(); + } + }, [watchsubDistrict, subDistricts]); + const onSubmitHandler = async (values) => { + console.log('apakah ada error', errors); + console.log('data yang mau dikirim IMANUEL', values); + const toastId = toast.loading('Mengirimkan formulir merchant...'); + const data = { + name_merchant: 'Form Merchant - ' + values.company, + pejabat_name: values.pejabatName, + pic_merchant: values.PICName, + pic_position: values.PICPosition, + 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, + bisnis_type: values.bisnisType, + category_perusahaan: values.categoryPerusahaan, + website: values.website, + 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, + }; + const create_leads = await createMerchantApi({ data }); + if (create_leads) { + toast.dismiss(toastId); + toast.success('Berhasil menambahkan data'); + isError(false); + reset(); + // router.push('/'); + } else { + toast.dismiss(toastId); + toast.error('Gagal menambahkan data'); + } }; - const create_leads = await createMerchantApi({ data }); - if (create_leads) { - toast.dismiss(toastId); - toast.success('Berhasil menambahkan data'); - isError(false); - reset(); - // router.push('/'); - } else { - toast.dismiss(toastId); - toast.error('Gagal menambahkan data'); - } - }; - // const DownLoadSurat = () => { - // download surat dari /public/file/Surat Pernyataan Nomor Rekening.docx - // }; + // 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 + 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]; + 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 }); + 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); } - } 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 ( - <> - <BottomPopup - className='' - title='Contoh SPPKP' - active={isExample} - close={() => setIsExample(false)} - > - <div className='flex p-2'> - <Image - src='/images/NO-SPPKP-FORMAT-TEMPLATE.jpg' - alt='Contoh SPPKP' - className='w-full h-full ' - width={800} - height={800} - quality={85} - /> - </div> - </BottomPopup> - <DesktopView> - <div className='container flex flex-col items-star py-4 '> - <h2 className='text-xs md:text-title-sm font-semibold mb-6'> - Informasi Perusahaan - </h2> + 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 + })); + }; - <div className='w-full mt-4'> - <form - onSubmit={handleSubmit(onSubmitHandler)} - className='flex flex-col gap-4' - > - <div className='w-full flex flex-row'> - <div className='w-2/5'> - <label className='form-label text-nowrap'> - Nama Perusahaan - </label> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan nama yang terdaftar{' '} - </span> - </div> - <div className='w-3/5'> - <input - {...register('company')} - placeholder='Masukkan nama perusahaan' - type='text' - className='form-input' - /> - <span className='opacity-65 text-xs'> - Format: PT. INDOTEKNIK DOTCOM GEMILANG - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.company?.message} + return ( + <> + <BottomPopup + className='' + title='Contoh SPPKP' + active={isExample} + close={() => setIsExample(false)} + > + <div className='flex p-2'> + <Image + src='/images/NO-SPPKP-FORMAT-TEMPLATE.jpg' + alt='Contoh SPPKP' + className='w-full h-full ' + width={800} + height={800} + quality={85} + /> + </div> + </BottomPopup> + <DesktopView> + <div className='container flex flex-col items-star py-4 '> + <h2 className='text-xs md:text-title-sm font-semibold mb-6'> + Informasi Perusahaan + </h2> + + <div className='w-full mt-4'> + <form + onSubmit={handleSubmit(onSubmitHandler)} + className='flex flex-col gap-4' + > + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Nama Perusahaan + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan nama yang terdaftar{' '} + </span> + )} </div> - </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> - <label className='form-label text-nowrap'> - Pejabat Berwenang - </label> - <span className='opacity-65 text-xs'> - isi dengan nama pejabat yang berwewenang di perusahaan anda - </span> - </div> - <div className='w-3/5'> - <input - {...register('pejabatName')} - placeholder='Masukkan nama pejabat berwenang' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.pejabatName?.message} + <div className='w-3/5'> + <input + {...register('company')} + placeholder='Masukkan nama perusahaan' + type='text' + className='form-input' + /> + <span className='opacity-65 text-xs'> + Format: PT. INDOTEKNIK DOTCOM GEMILANG + </span> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.company?.message} + </div> </div> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> - <label className='form-label text-nowrap'>Nama PIC</label> - <span className='opacity-65 text-xs'> - isi dengan nama sales / penanggung jawab - </span> - </div> - <div className='w-3/5'> - <input - {...register('PICName')} - placeholder='Masukkan nama PIC' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.PICName?.message} + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Pejabat Berwenang + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + isi dengan nama pejabat yang berwewenang di perusahaan + anda + </span> + )} </div> - </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> - <label className='form-label text-nowrap'>Jabatan PIC</label> - <span className='opacity-65 text-xs'> - isi dengan jabatan sales / penanggung jawab - </span> - </div> - <div className='w-3/5'> - <input - {...register('PICPosition')} - placeholder='Masukkan jabatan PIC' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.PICPosition?.message} + <div className='w-3/5'> + <input + {...register('pejabatName')} + placeholder='Masukkan nama pejabat berwenang' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.pejabatName?.message} + </div> </div> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> - <label className='form-label text-nowrap'> - Alamat Perusahaan - </label> - <span className='opacity-65 text-xs'> - Alamat sesuai dengan alamat perusahaan - </span> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'>Nama PIC</label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + isi dengan nama sales / penanggung jawab + </span> + )} + </div> + <div className='w-3/5'> + <input + {...register('PICName')} + placeholder='Masukkan nama PIC' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.PICName?.message} + </div> + </div> </div> - <div className='w-3/5 flex flex-col'> - <div> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Jabatan PIC + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + isi dengan jabatan sales / penanggung jawab + </span> + )} + </div> + <div className='w-3/5'> <input - {...register('address')} - placeholder='Masukkan alamat lengkap perusahaan' + {...register('PICPosition')} + placeholder='Masukkan jabatan PIC' type='text' className='form-input' /> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.address?.message} + {errors.PICPosition?.message} </div> </div> - <div className='flex flex-row w-full justify-between gap-2'> - <div className='provinsi w-full'> - <Controller - name='state' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={state} - placeholder='Provinsi' - /> - )} + </div> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Alamat Perusahaan + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Alamat sesuai dengan alamat perusahaan + </span> + )} + </div> + <div className='w-3/5 flex flex-col'> + <div> + <input + {...register('address')} + placeholder='Masukkan alamat lengkap perusahaan' + type='text' + className='form-input' /> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.state?.message} + {errors.address?.message} </div> </div> - <div className='kab w-full'> - <Controller - name='city' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={cities} - disabled={!watchState} - placeholder='Kab/Kota' + <div + className={` sub-alamat flex ${ + isKonfirmasi ? 'flex-col' : 'flex-row' + } w-full gap-3`} + > + <div + className={`flex ${ + isKonfirmasi + ? ' flex-row gap-3 w-full' + : 'flex-row gap-3 w-2/5' + }`} + > + <div className='provinsi w-full'> + <Controller + name='state' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={state} + placeholder='Provinsi' + /> + )} /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.city?.message} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.state?.message} + </div> + </div> + <div className='kab w-full'> + <Controller + name='city' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={cities} + disabled={!watchState} + placeholder='Kab/Kota' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.city?.message} + </div> + </div> </div> - </div> - <div className='kec w-full'> - <Controller - name='district' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={districts} - disabled={!watchState || !watchCity} - placeholder='Kecamatan' + <div + className={`flex-row flex gap-2 justify-between ${ + isKonfirmasi ? 'w-full' : 'w-3/5' + }`} + > + <div className='kec w-full'> + <Controller + name='district' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={districts} + disabled={!watchState || !watchCity} + placeholder='Kecamatan' + /> + )} /> - )} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.district?.message} + </div> + </div> + <div className='kel w-full'> + <Controller + name='subDistrict' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={subDistricts} + disabled={!watchDistrict} + placeholder='Kelurahan' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.subDistrict?.message} + </div> + </div> + <div className='zip w-full'> + <Controller + name='zip' + control={control} + render={(props) => ( + <> + {/* Jika zips tidak kosong, tampilkan dropdown */} + {zips.length < 0 ? ( + // Jika zips kosong, tampilkan input manual + <input + {...register('zip')} + placeholder='Kode Pos' + type='number' + className='form-input' + disabled={!watchsubDistrict} + /> + ) : ( + <HookFormSelect + {...props} + options={zips} + disabled={!watchsubDistrict} + placeholder='Zip' + /> + )} + </> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.zip?.message} + </div> + </div> + </div> + </div> + </div> + </div> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'>Data Bank</label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Isi detail data bank perusahaan anda + </span> + )} + </div> + <div className='w-3/5 flex flex-row gap-2'> + <div> + <input + {...register('bank')} + placeholder='Nama bank' + type='text' + className='form-input' /> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Format: BCA, Mandiri, CIMB, BNI dll + </span> + )} <div className='text-caption-2 text-danger-500 mt-1'> - {errors.district?.message} + {errors.bank?.message} </div> </div> - <div className='kel w-full'> - <Controller - name='subDistrict' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={subDistricts} - disabled={!watchDistrict} - placeholder='Kelurahan' - /> - )} + <div> + <input + {...register('rekening')} + placeholder='Nama Rekening' + type='text' + className='form-input' /> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Format: John Doe + </span> + )} <div className='text-caption-2 text-danger-500 mt-1'> - {errors.subDistrict?.message} + {errors.rekening?.message} </div> </div> - <div className='zip w-full'> - <Controller - name='zip' - control={control} - render={(props) => ( - <> - {/* Jika zips tidak kosong, tampilkan dropdown */} - {zips.length < 0 ? ( - // Jika zips kosong, tampilkan input manual - <input - {...register('zip')} - placeholder='Kode Pos' - type='number' - className='form-input' - disabled={!watchsubDistrict} - /> - ) : ( - <HookFormSelect - {...props} - options={zips} - disabled={!watchsubDistrict} - placeholder='Zip' - /> - )} - </> - )} + <div> + <input + {...register('accountNumber')} + placeholder='Nomor Rekening Bank' + type='number' + className='form-input' /> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Format: 01234567896 + </span> + )} <div className='text-caption-2 text-danger-500 mt-1'> - {errors.zip?.message} + {errors.accountNumber?.message} </div> </div> </div> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> - <label className='form-label text-nowrap'>Data Bank</label> - <span className='opacity-65 text-xs'> - Isi detail data bank perusahaan anda - </span> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Email Perusahaan + </label> + </div> + <div className='w-3/5'> + <input + {...register('email')} + placeholder='contoh@email.com' + type='email' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.email?.message} + </div> + </div> </div> - <div className='w-3/5 flex flex-row gap-2'> - <div> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Email Sales + </label> + </div> + <div className='w-3/5'> + <input + {...register('emailSales')} + placeholder='contoh@email.com' + type='email' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.emailSales?.message} + </div> + </div> + </div> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Email Finance + </label> + </div> + <div className='w-3/5'> + <input + {...register('emailFinance')} + placeholder='contoh@email.com' + type='email' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.emailFinance?.message} + </div> + </div> + </div> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + No. Telepon Perusahaan + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Isi no telepon perusahaan yang sesuai + </span> + )} + </div> + <div className='w-3/5'> + <input + {...register('phone', { + required: 'Nomor telepon wajib diisi.', + pattern: { + value: /^\+?[0-9]{10,15}$/, + message: 'Nomor telepon tidak valid.', + }, + })} + placeholder='Masukkan nomor telepon perusahaan' + type='tel' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.phone?.message} + </div> + </div> + </div> + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + No. Handphone + </label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + Isi no handphone perusahaan yang sesuai + </span> + )} + </div> + <div className='w-3/5'> + <input + {...register('mobile')} + placeholder='Masukkan nomor handphone' + type='tel' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.mobile?.message} + </div> + </div> + </div> + + <div className='flex flex-row justify-between items-center'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Tipe Bisnis + </label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih tipe bisnis yang sesuai + </span> + )} + </div> + <div className='w-3/5 flex flex-col '> + <div className='flex flex-row items-center gap-3'> + <div + // className={`${isKonfirmasi ? 'w-[75%]' : 'w-[25%]'}`} + // ref={tempoDurationRef} + > + <Controller + name='bisnisType' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={dataBisnisType} + placeholder={'Pilih tipe bisnis'} + /> + )} + /> + + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.bisnisType?.message} + </div> + </div> + </div> + </div> + </div> + <div className='flex flex-row justify-between items-center'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Kategori Perusahaan + </label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih kategori perusahaan yang sesuai + </span> + )} + </div> + <div className='w-3/5 flex flex-col '> + <div className='flex flex-row items-center gap-3'> + <div + // className={`${isKonfirmasi ? 'w-[75%]' : 'w-[25%]'}`} + className='w-[55%]' + // ref={tempoDurationRef} + > + <Controller + name='categoryPerusahaan' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={dataCategoryPerusahaan} + placeholder={'Pilih category perusahaan'} + /> + )} + /> + + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.categoryPerusahaan?.message} + </div> + </div> + </div> + </div> + </div> + + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'>Website</label> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + isi dengan website perusahaan anda + </span> + )} + </div> + <div className='w-3/5'> <input - {...register('bank')} - placeholder='Nama bank' + {...register('website')} + placeholder='Masukkan website' type='text' className='form-input' /> - <span className='opacity-65 text-xs'> - Format: BCA, Mandiri, CIMB, BNI dll - </span> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.bank?.message} + {errors.website?.message} </div> </div> - <div> + </div> + + <div className=''> + {/* <div> + <ReCAPTCHA + ref={recaptchaRef} + sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} + /> + </div> */} + </div> + <div className='flex justify-end'> + {/* <Button + colorScheme='red' + className='w-full md:w-fit' + type='submit' + > + Daftar Merchant{' '} + {<ChevronRightIcon className='w-5' color='white' />} + </Button> */} + {!isKonfirmasi && ( + <div> + <span className='text-xs opacity-60'> + *Pastikan data yang anda masukan sudah benar dan sesuai + </span> + <button + type='submit' + className='btn-light bg-red-500 rounded-lg text-white w-fit py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-between hover:bg-red-400' + > + <span className={` `}>Langkah Selanjutnya</span> + {<ChevronRightIcon className='w-5' />} + </button> + </div> + )} + </div> + </form> + <PageContent path='/daftar-merchant' /> + </div> + </div> + </DesktopView> + <MobileView> + <div className='container flex flex-col items-star py-4'> + {BannerMerchant && ( + <ImageBanner + src={BannerMerchant} + alt='FORM MERCHANT' + width={1000} + height={160} + className='w-full mt-6' + /> + )} + <h1 className='text-h-sm md:text-title-sm font-semibold mb-6 text-center'> + Form Merchant + </h1> + <div className='text-center mb-6'> + 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. + </div> + <h2 className='font-semibold mb-6'>Informasi Perusahaan</h2> + + <div className='w-full mt-4'> + <form + onSubmit={handleSubmit(onSubmitHandler)} + className='flex flex-col gap-4' + > + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'> + Nama Perusahaan + </label> <input - {...register('rekening')} - placeholder='Nama Rekening' + {...register('company')} + placeholder='Format: PT. INDOTEKNIK DOTCOM GEMILANG' type='text' className='form-input' /> - <span className='opacity-65 text-xs'>Format: John Doe</span> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.rekening?.message} + {errors.company?.message} </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan nama yang terdaftar{' '} + </span> </div> - <div> + </div> + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'>Nama PIC</label> <input - {...register('accountNumber')} - placeholder='Nomor Rekening Bank' - type='number' + {...register('PICName')} + placeholder='Masukkan Nama PIC ' + type='text' className='form-input' /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.PICName?.message} + </div> <span className='opacity-65 text-xs'> - Format: 01234567896 + Isi dengan nama sales / penanggung jawab </span> + </div> + </div> + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'> + Alamat Perusahaan + </label> + <input + {...register('address')} + placeholder='Masukkan alamat lengkap perusahaan' + type='text' + className='form-input' + /> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.accountNumber?.message} + {errors.address?.message} + </div> + <div className='flex flex-row w-full justify-between gap-2'> + <div className='provinsi w-full'> + <Controller + name='state' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={state} + placeholder='Provinsi' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.state?.message} + </div> + </div> + <div className='kab w-full'> + <Controller + name='city' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={cities} + disabled={!watchState} + placeholder='Kab/Kota' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.city?.message} + </div> + </div> + </div> + <div className='flex flex-row w-full justify-between gap-2'> + <div className='kec w-full'> + <Controller + name='district' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={districts} + disabled={!watchState || !watchCity} + placeholder='Kecamatan' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.district?.message} + </div> + </div> + <div className='kel w-full'> + <Controller + name='subDistrict' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={subDistricts} + disabled={!watchDistrict} + placeholder='Kelurahan' + /> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.subDistrict?.message} + </div> + </div> + <div className='zip w-full'> + <Controller + name='zip' + control={control} + render={(props) => ( + <> + {zips.length > 0 ? ( + <HookFormSelect + {...props} + options={zips} + disabled={!watchsubDistrict} + placeholder='Zip' + /> + ) : ( + <input + {...register('zip')} + placeholder='Kode Pos' + type='number' + className='form-input' + disabled={!watchsubDistrict} + /> + )} + </> + )} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.zip?.message} + </div> + </div> + </div> + </div> + <span className='opacity-65 text-xs'> + Alamat sesuai dengan alamat perusahaan + </span> + </div> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'>Data Bank</label> + <div className='w-full flex flex-row gap-2'> + <div> + <input + {...register('bank')} + placeholder='Nama bank' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.bank?.message} + </div> + </div> + <div> + <input + {...register('rekening')} + placeholder='Nama Rekening' + type='text' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.rekening?.message} + </div> + </div> + <div> + <input + {...register('accountNumber')} + placeholder='Nomor Rekening Bank' + type='number' + className='form-input' + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountNumber?.message} + </div> </div> </div> + <span className='opacity-65 text-xs'> + Isi detail data bank perusahaan anda + </span> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> + <div className='w-full flex flex-col'> <label className='form-label text-nowrap'> Email Perusahaan </label> - </div> - <div className='w-3/5'> <input {...register('email')} placeholder='contoh@email.com' @@ -694,13 +1214,12 @@ const CreateMerchant = ({ handleIsError }) => { <div className='text-caption-2 text-danger-500 mt-1'> {errors.email?.message} </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan data yang terdaftar + </span> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> + <div className='w-full flex flex-col'> <label className='form-label text-nowrap'>Email Sales</label> - </div> - <div className='w-3/5'> <input {...register('emailSales')} placeholder='contoh@email.com' @@ -710,15 +1229,14 @@ const CreateMerchant = ({ handleIsError }) => { <div className='text-caption-2 text-danger-500 mt-1'> {errors.emailSales?.message} </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan data yang terdaftar + </span> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> + <div className='w-full flex flex-col'> <label className='form-label text-nowrap'> Email Finance </label> - </div> - <div className='w-3/5'> <input {...register('emailFinance')} placeholder='contoh@email.com' @@ -728,39 +1246,31 @@ const CreateMerchant = ({ handleIsError }) => { <div className='text-caption-2 text-danger-500 mt-1'> {errors.emailFinance?.message} </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan data yang terdaftar + </span> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> + <div className='w-full flex flex-col'> <label className='form-label text-nowrap'> No. Telepon Perusahaan </label> - <span className='opacity-65 text-xs'> - Isi no telepon perusahaan yang sesuai - </span> - </div> - <div className='w-3/5'> <input {...register('phone')} - placeholder='Masukkan nomor telepon perusahaan' + placeholder='Format: 08123456789 / (021) 123 4567' type='tel' className='form-input' /> <div className='text-caption-2 text-danger-500 mt-1'> {errors.phone?.message} </div> + <span className='opacity-65 text-xs'> + Isi detail perusahaan sesuai dengan data yang terdaftar + </span> </div> - </div> - <div className='w-full flex flex-row'> - <div className='w-2/5'> + <div className='w-full flex flex-col'> <label className='form-label text-nowrap'> No. Handphone </label> - <span className='opacity-65 text-xs'> - Isi no handphone perusahaan yang sesuai - </span> - </div> - <div className='w-3/5'> <input {...register('mobile')} placeholder='Masukkan nomor handphone' @@ -770,774 +1280,353 @@ const CreateMerchant = ({ handleIsError }) => { <div className='text-caption-2 text-danger-500 mt-1'> {errors.mobile?.message} </div> - </div> - </div> - - <div className='flex flex-row justify-between items-center'> - <div className='w-2/5'> - <label className='form-label text-nowrap'>Tipe Bisnis</label> - <span className='text-xs opacity-60'> - Pilih tipe bisnis yang sesuai - </span> - </div> - <div className='w-3/5 flex flex-col '> - <div className='flex flex-row items-center gap-3'> - <div - // className={`${isKonfirmasi ? 'w-[75%]' : 'w-[25%]'}`} - // ref={tempoDurationRef} - > - <Controller - name='bisnisType' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={dataBisnisType} - placeholder={'Pilih tipe bisnis'} - /> - )} - /> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.bisnisType?.message} - </div> - </div> - </div> - </div> - </div> - <div className='flex flex-row justify-between items-center'> - <div className='w-2/5'> - <label className='form-label text-nowrap'> - Kategori Perusahaan - </label> - <span className='text-xs opacity-60'> - Pilih kategori perusahaan yang sesuai - </span> - </div> - <div className='w-3/5 flex flex-col '> - <div className='flex flex-row items-center gap-3'> - <div - // className={`${isKonfirmasi ? 'w-[75%]' : 'w-[25%]'}`} - className='w-[55%]' - // ref={tempoDurationRef} - > - <Controller - name='categoryPerusahaan' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={dataCategoryPerusahaan} - placeholder={'Pilih category perusahaan'} - /> - )} - /> - - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.categoryPerusahaan?.message} - </div> - </div> - </div> - </div> - </div> - - <div className='w-full flex flex-row'> - <div className='w-2/5'> - <label className='form-label text-nowrap'>Website</label> <span className='opacity-65 text-xs'> - isi dengan website perusahaan anda + Isi detail perusahaan sesuai dengan data yang terdaftar </span> </div> - <div className='w-3/5'> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'> + Harga Tayang (HET){' '} + <span className=' opacity-60'>(Opsional)</span> + </label> <input - {...register('website')} - placeholder='Masukkan website' + {...register('hargaTayang')} + placeholder='Masukkan Harga Tayang (HET)' type='text' className='form-input' /> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.website?.message} + {errors.hargaTayang?.message} </div> </div> - </div> - - <div className=''> - {/* <div> - <ReCAPTCHA - ref={recaptchaRef} - sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} - /> - </div> */} - </div> - <div className='flex justify-end'> - {/* <Button - colorScheme='red' - className='w-full md:w-fit' - type='submit' - > - Daftar Merchant{' '} - {<ChevronRightIcon className='w-5' color='white' />} - </Button> */} - - <div> - <span className='text-xs opacity-60'> - *Pastikan data yang anda masukan sudah benar dan sesuai - </span> - <button - type='submit' - className='btn-light bg-red-500 rounded-lg text-white w-fit py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-between hover:bg-red-400' - > - <span className={` `}>Langkah Selanjutnya</span> - {<ChevronRightIcon className='w-5' />} - </button> - </div> - </div> - </form> - <PageContent path='/daftar-merchant' /> - </div> - </div> - </DesktopView> - <MobileView> - <div className='container flex flex-col items-star py-4'> - {BannerMerchant && ( - <ImageBanner - src={BannerMerchant} - alt='FORM MERCHANT' - width={1000} - height={160} - className='w-full mt-6' - /> - )} - <h1 className='text-h-sm md:text-title-sm font-semibold mb-6 text-center'> - Form Merchant - </h1> - <div className='text-center mb-6'> - 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. - </div> - <h2 className='font-semibold mb-6'>Informasi Perusahaan</h2> - <div className='w-full mt-4'> - <form - onSubmit={handleSubmit(onSubmitHandler)} - className='flex flex-col gap-4' - > - <div className='w-full flex flex-col'> - <div className='w-full'> + <div className='w-full flex flex-col gap-2'> <label className='form-label text-nowrap'> - Nama Perusahaan + NPWP{' '} + {!isPkp && <span className=' opacity-60'>(Opsional)</span>} </label> - <input - {...register('company')} - placeholder='Format: PT. INDOTEKNIK DOTCOM GEMILANG' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.company?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan nama yang terdaftar{' '} - </span> - </div> - </div> - <div className='w-full flex flex-col'> - <div className='w-full'> - <label className='form-label text-nowrap'>Nama PIC</label> - <input - {...register('PICName')} - placeholder='Masukkan Nama PIC ' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.PICName?.message} + <div className='flex flex-row items-start justify-start gap-2'> + <label + htmlFor='npwp' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.npwp ? 'Ubah Dokumen' : 'Upload Dokumen'} + </label> + <input + {...register('npwp')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='npwp' + onChange={(e) => { + handleFileChange(e); // Untuk update UI (opsional) + }} + aria-invalid={errors.npwp?.message} + /> + <span className=' text-gray-600 line-clamp-2'> + {fileNames.npwp} + </span> </div> - <span className='opacity-65 text-xs'> - Isi dengan nama sales / penanggung jawab + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB </span> - </div> - </div> - <div className='w-full flex flex-col'> - <div className='w-full'> - <label className='form-label text-nowrap'> - Alamat Perusahaan - </label> - <input - {...register('address')} - placeholder='Masukkan alamat lengkap perusahaan' - type='text' - className='form-input' - /> + <div className='text-caption-2 text-danger-500 mt-1'> - {errors.address?.message} - </div> - <div className='flex flex-row w-full justify-between gap-2'> - <div className='provinsi w-full'> - <Controller - name='state' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={state} - placeholder='Provinsi' - /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.state?.message} - </div> - </div> - <div className='kab w-full'> - <Controller - name='city' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={cities} - disabled={!watchState} - placeholder='Kab/Kota' - /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.city?.message} - </div> - </div> - </div> - <div className='flex flex-row w-full justify-between gap-2'> - <div className='kec w-full'> - <Controller - name='district' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={districts} - disabled={!watchState || !watchCity} - placeholder='Kecamatan' - /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.district?.message} - </div> - </div> - <div className='kel w-full'> - <Controller - name='subDistrict' - control={control} - render={(props) => ( - <HookFormSelect - {...props} - options={subDistricts} - disabled={!watchDistrict} - placeholder='Kelurahan' - /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.subDistrict?.message} - </div> - </div> - <div className='zip w-full'> - <Controller - name='zip' - control={control} - render={(props) => ( - <> - {zips.length > 0 ? ( - <HookFormSelect - {...props} - options={zips} - disabled={!watchsubDistrict} - placeholder='Zip' - /> - ) : ( - <input - {...register('zip')} - placeholder='Kode Pos' - type='number' - className='form-input' - disabled={!watchsubDistrict} - /> - )} - </> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.zip?.message} - </div> - </div> + {errors.npwp?.message} </div> </div> - <span className='opacity-65 text-xs'> - Alamat sesuai dengan alamat perusahaan - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'>Data Bank</label> - <div className='w-full flex flex-row gap-2'> - <div> - <input - {...register('bank')} - placeholder='Nama bank' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.bank?.message} - </div> - </div> - <div> - <input - {...register('rekening')} - placeholder='Nama Rekening' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.rekening?.message} + <div className='w-full flex flex-col gap-2 items-start '> + <div className='flex flex-row w-full justify-between items-center '> + <label className='form-label text-nowrap'> + SPPKP{' '} + {!isPkp && ( + <span className=' opacity-60'>(Opsional)</span> + )} + </label> + <div + onClick={() => 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' + > + <EyeIcon className={`w-4 mr-2 `} /> + + <p className='font-light text-xs '>Lihat Contoh</p> </div> </div> - <div> + <div className='flex flex-row items-start justify-start gap-2'> + <label + htmlFor='sppkp' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.sppkp ? 'Ubah Dokumen' : 'Upload Dokumen'} + </label> <input - {...register('accountNumber')} - placeholder='Nomor Rekening Bank' - type='number' - className='form-input' + {...register('sppkp')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='sppkp' + onChange={handleFileChange} + aria-invalid={errors.sppkp?.message} /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.accountNumber?.message} - </div> + <span className=' text-gray-600 line-clamp-2'> + {fileNames.sppkp} + </span> </div> - </div> - <span className='opacity-65 text-xs'> - Isi detail data bank perusahaan anda - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'> - Email Perusahaan - </label> - <input - {...register('email')} - placeholder='contoh@email.com' - type='email' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.email?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'>Email Sales</label> - <input - {...register('emailSales')} - placeholder='contoh@email.com' - type='email' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.emailSales?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'>Email Finance</label> - <input - {...register('emailFinance')} - placeholder='contoh@email.com' - type='email' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.emailFinance?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'> - No. Telepon Perusahaan - </label> - <input - {...register('phone')} - placeholder='Format: 08123456789 / (021) 123 4567' - type='tel' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.phone?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'>No. Handphone</label> - <input - {...register('mobile')} - placeholder='Masukkan nomor handphone' - type='tel' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.mobile?.message} - </div> - <span className='opacity-65 text-xs'> - Isi detail perusahaan sesuai dengan data yang terdaftar - </span> - </div> - <div className='w-full flex flex-col'> - <label className='form-label text-nowrap'> - Harga Tayang (HET){' '} - <span className=' opacity-60'>(Opsional)</span> - </label> - <input - {...register('hargaTayang')} - placeholder='Masukkan Harga Tayang (HET)' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.hargaTayang?.message} - </div> - </div> - - <div className='w-full flex flex-col gap-2'> - <label className='form-label text-nowrap'> - NPWP{' '} - {!isPkp && <span className=' opacity-60'>(Opsional)</span>} - </label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='npwp' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.npwp ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('npwp')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='npwp' - onChange={(e) => { - handleFileChange(e); // Untuk update UI (opsional) - }} - aria-invalid={errors.npwp?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.npwp} + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.npwp?.message} - </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <div className='flex flex-row w-full justify-between items-center '> - <label className='form-label text-nowrap'> - SPPKP{' '} - {!isPkp && <span className=' opacity-60'>(Opsional)</span>} - </label> - <div - onClick={() => 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' - > - <EyeIcon className={`w-4 mr-2 `} /> - - <p className='font-light text-xs '>Lihat Contoh</p> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.sppkp?.message} </div> </div> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='sppkp' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.sppkp ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('sppkp')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='sppkp' - onChange={handleFileChange} - aria-invalid={errors.sppkp?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.sppkp} - </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.sppkp?.message} - </div> - </div> - - <div className='w-full flex flex-col gap-2'> - <label className='form-label text-nowrap'> - KTP Dirut/Direktur{' '} - {isPkp && <span className=' opacity-60'>(Opsional)</span>} - </label> - <div className='flex flex-row items-start justify-start gap-2 '> - <label - htmlFor='dokumenKtpDirut' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.dokumenKtpDirut - ? 'Ubah Dokumen' - : 'Upload Dokumen'} + <div className='w-full flex flex-col gap-2'> + <label className='form-label text-nowrap'> + KTP Dirut/Direktur{' '} + {isPkp && <span className=' opacity-60'>(Opsional)</span>} </label> - <input - {...register('dokumenKtpDirut')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='dokumenKtpDirut' - onChange={handleFileChange} - aria-invalid={errors.dokumenKtpDirut?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.dokumenKtpDirut} + <div className='flex flex-row items-start justify-start gap-2 '> + <label + htmlFor='dokumenKtpDirut' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.dokumenKtpDirut + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + {...register('dokumenKtpDirut')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='dokumenKtpDirut' + onChange={handleFileChange} + aria-invalid={errors.dokumenKtpDirut?.message} + /> + <span className=' text-gray-600 line-clamp-2'> + {fileNames.dokumenKtpDirut} + </span> + </div> + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.dokumenKtpDirut?.message} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.dokumenKtpDirut?.message} + </div> </div> - </div> - <div className='w-full flex flex-col gap-2'> - <label className='form-label text-nowrap'> - Kartu Nama <span className=' opacity-60'>(Opsional)</span>{' '} - </label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='kartuNama' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.kartuNama ? 'Ubah Dokumen' : 'Upload Dokumen'} + <div className='w-full flex flex-col gap-2'> + <label className='form-label text-nowrap'> + Kartu Nama <span className=' opacity-60'>(Opsional)</span>{' '} </label> - <input - {...register('kartuNama')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='kartuNama' - onChange={handleFileChange} - aria-invalid={errors.kartuNama?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.kartuNama} + <div className='flex flex-row items-start justify-start gap-2'> + <label + htmlFor='kartuNama' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.kartuNama ? 'Ubah Dokumen' : 'Upload Dokumen'} + </label> + <input + {...register('kartuNama')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='kartuNama' + onChange={handleFileChange} + aria-invalid={errors.kartuNama?.message} + /> + <span className=' text-gray-600 line-clamp-2'> + {fileNames.kartuNama} + </span> + </div> + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.kartuNama?.message} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.kartuNama?.message} + </div> </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <div className='flex flex-row w-full justify-between items-center'> - <label className='form-label text-wrap'> - Surat Pernyataan Nomor Rekening{' '} - <span className=' opacity-60'>(Opsional)</span> - </label> - <a - href='/file/Surat Pernyataan Nomor Rekening.docx' - download='Surat Pernyataan Nomor Rekening.docx' - className='h-fit rounded text-white p-2 flex flex-row items-center bg-red-500 hover:cursor-pointer hover:bg-red-400' - > - <p className='font-light text-xs text-nowrap'> - Download Template - </p> - </a> - </div> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='suratPernyataan' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.suratPernyataan - ? 'Ubah Dokumen' - : 'Upload Dokumen'} - </label> - <input - {...register('suratPernyataan')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='suratPernyataan' - onChange={handleFileChange} - aria-invalid={errors.suratPernyataan?.message} - /> - <span className=' text-gray-600 line-clamp-2'> - {fileNames.suratPernyataan} + <div className='w-full flex flex-col gap-2 items-start '> + <div className='flex flex-row w-full justify-between items-center'> + <label className='form-label text-wrap'> + Surat Pernyataan Nomor Rekening{' '} + <span className=' opacity-60'>(Opsional)</span> + </label> + <a + href='/file/Surat Pernyataan Nomor Rekening.docx' + download='Surat Pernyataan Nomor Rekening.docx' + className='h-fit rounded text-white p-2 flex flex-row items-center bg-red-500 hover:cursor-pointer hover:bg-red-400' + > + <p className='font-light text-xs text-nowrap'> + Download Template + </p> + </a> + </div> + <div className='flex flex-row items-start justify-start gap-2'> + <label + htmlFor='suratPernyataan' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.suratPernyataan + ? 'Ubah Dokumen' + : 'Upload Dokumen'} + </label> + <input + {...register('suratPernyataan')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='suratPernyataan' + onChange={handleFileChange} + aria-invalid={errors.suratPernyataan?.message} + /> + <span className=' text-gray-600 line-clamp-2'> + {fileNames.suratPernyataan} + </span> + </div> + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.suratPernyataan?.message} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.suratPernyataan?.message} + </div> </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <label className='form-label text-nowrap'> - Foto Gudang / Kantor Bagian Depan - </label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='fotoKantor' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.fotoKantor ? 'Ubah Dokumen' : 'Upload Dokumen'} + <div className='w-full flex flex-col gap-2 items-start '> + <label className='form-label text-nowrap'> + Foto Gudang / Kantor Bagian Depan </label> - <input - {...register('fotoKantor')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='fotoKantor' - onChange={handleFileChange} - aria-invalid={errors.fotoKantor?.message} - /> - <span className='mt-2 text-gray-600 line-clamp-2'> - {fileNames.fotoKantor} + <div className='flex flex-row items-start justify-start gap-2'> + <label + htmlFor='fotoKantor' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.fotoKantor ? 'Ubah Dokumen' : 'Upload Dokumen'} + </label> + <input + {...register('fotoKantor')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='fotoKantor' + onChange={handleFileChange} + aria-invalid={errors.fotoKantor?.message} + /> + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.fotoKantor} + </span> + </div> + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.fotoKantor?.message} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.fotoKantor?.message} + </div> </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <label className='form-label text-nowrap'> - Data Produk (Item Name, Gambar, Deskripsi){' '} - <span className=' opacity-60'>(Opsional)</span>{' '} - </label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='dataProduk' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.dataProduk ? 'Ubah Dokumen' : 'Upload Dokumen'} + <div className='w-full flex flex-col gap-2 items-start '> + <label className='form-label text-nowrap'> + Data Produk (Item Name, Gambar, Deskripsi){' '} + <span className=' opacity-60'>(Opsional)</span>{' '} </label> - <input - {...register('dataProduk')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='dataProduk' - onChange={handleFileChange} - aria-invalid={errors.dataProduk?.message} - /> - <span className='mt-2 text-gray-600 line-clamp-2'> - {fileNames.dataProduk} + <div className='flex flex-row items-start justify-start gap-2'> + <label + htmlFor='dataProduk' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.dataProduk ? 'Ubah Dokumen' : 'Upload Dokumen'} + </label> + <input + {...register('dataProduk')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='dataProduk' + onChange={handleFileChange} + aria-invalid={errors.dataProduk?.message} + /> + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.dataProduk} + </span> + </div> + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.fotoKantor?.message} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.fotoKantor?.message} + </div> </div> - </div> - <div className='w-full flex flex-col gap-2 items-start '> - <label className='form-label text-nowrap'>Pricelist</label> - <div className='flex flex-row items-start justify-start gap-2'> - <label - htmlFor='pricelist' - className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' - > - {fileNames.pricelist ? 'Ubah Dokumen' : 'Upload Dokumen'} - </label> - <input - {...register('pricelist')} - type='file' - className='form-input hidden' - accept='.pdf,.png,.jpg,.jpeg' - id='pricelist' - onChange={handleFileChange} - aria-invalid={errors.pricelist?.message} - /> - <span className='mt-2 text-gray-600 line-clamp-2'> - {fileNames.pricelist} + <div className='w-full flex flex-col gap-2 items-start '> + <label className='form-label text-nowrap'>Pricelist</label> + <div className='flex flex-row items-start justify-start gap-2'> + <label + htmlFor='pricelist' + className='cursor-pointer min-w-40 text-center bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded' + > + {fileNames.pricelist ? 'Ubah Dokumen' : 'Upload Dokumen'} + </label> + <input + {...register('pricelist')} + type='file' + className='form-input hidden' + accept='.pdf,.png,.jpg,.jpeg' + id='pricelist' + onChange={handleFileChange} + aria-invalid={errors.pricelist?.message} + /> + <span className='mt-2 text-gray-600 line-clamp-2'> + {fileNames.pricelist} + </span> + </div> + <span className='text-xs opacity-60 text-red-500'> + Format: pdf, jpeg, jpg, png. max file size 2MB </span> - </div> - <span className='text-xs opacity-60 text-red-500'> - Format: pdf, jpeg, jpg, png. max file size 2MB - </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.pricelist?.message} + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.pricelist?.message} + </div> </div> - </div> - <div className=''> - {/* <div> + <div className=''> + {/* <div> <ReCAPTCHA ref={recaptchaRef} sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} /> </div> */} - </div> - <div className='flex justify-end mb-4'> - <Button - colorScheme='red' - className='w-full md:w-fit' - type='submit' - > - Daftar Merchant{' '} - {/* {<ChevronRightIcon className='w-5' color='white' />} */} - </Button> - <div> - {/* <button + </div> + <div className='flex justify-end mb-4'> + <Button + colorScheme='red' + className='w-full md:w-fit' + type='submit' + > + Daftar Merchant{' '} + {/* {<ChevronRightIcon className='w-5' color='white' />} */} + </Button> + <div> + {/* <button type='submit' className='btn-yellow w-full md:w-fit mt-6 ml-0 md:ml-auto' > Simpan </button> */} + </div> </div> - </div> - </form> - <PageContent path='/daftar-merchant' /> + </form> + <PageContent path='/daftar-merchant' /> + </div> </div> - </div> - </MobileView> - </> - ); -}; + </MobileView> + </> + ); + } +); + const validationSchema = Yup.object().shape({ company: Yup.string().required('Harus di-isi'), pejabatName: Yup.string().required('Harus di-isi'), diff --git a/src/lib/merchant/components/InformasiVendor.jsx b/src/lib/merchant/components/InformasiVendor.jsx index d47d22ee..f86cf3c9 100644 --- a/src/lib/merchant/components/InformasiVendor.jsx +++ b/src/lib/merchant/components/InformasiVendor.jsx @@ -4,7 +4,13 @@ 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 React, { + useEffect, + useRef, + useState, + forwardRef, + useImperativeHandle, +} from 'react'; import ReCAPTCHA from 'react-google-recaptcha'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; @@ -26,7 +32,7 @@ import DesktopView from '@/core/components/views/DesktopView'; import getFileBase64 from '@/core/utils/getFileBase64'; import odooApi from '~/libs/odooApi'; import { formatValue } from 'react-currency-input-field'; -const InformasiVendor = ({ handleIsError }) => { +const InformasiVendor = forwardRef(({ handleIsError, isKonfirmasi }, ref) => { const isError = (value) => { // Logika menentukan error const result = value ? true : false; @@ -139,24 +145,30 @@ const InformasiVendor = ({ handleIsError }) => { useEffect(() => { const loadData = async () => { const data = await getMerchantApi(); - console.log('data vendor', data); - reset({ - hargaTayang: data.hargaTayang || '', - categoryProduk: data.categoryProduk || '', - merkDagang: data.merkDagang || '', - isPengajuanTempo: data.isPengajuanTempo || '', - tempoDuration: parseInt(data.tempoDuration) || '', - // kreditLimit: parseInt(data.kreditLimit) || '', - waktuPengiriman: data.waktuPengiriman || '', - terhitungSejak: parseInt(data.terhitungSejak) || '', - }); - handleKreditLimitChange(data.kreditLimit); - setSelectedIds(watch('categoryProduk').split(',').map(Number)); + if (data) { + console.log('data vendor', data); + reset({ + hargaTayang: data.hargaTayang || '', + categoryProduk: data.categoryProduk || '', + merkDagang: data.merkDagang || '', + isPengajuanTempo: data.isPengajuanTempo || '', + tempoDuration: parseInt(data.tempoDuration) || '', + // kreditLimit: parseInt(data.kreditLimit) || '', + waktuPengiriman: data.waktuPengiriman || '', + terhitungSejak: parseInt(data.terhitungSejak) || '', + }); + handleKreditLimitChange(data.kreditLimit || ''); + setSelectedIds(watch('categoryProduk').split(',').map(Number)); + } }; loadData(); }, []); + useImperativeHandle(ref, () => () => { + handleSubmit(onSubmitHandler)(); + }); + const handleKreditLimitChange = (e) => { console.log('e', e); let value = e.target?.value ? e.target.value : e; @@ -375,7 +387,6 @@ const InformasiVendor = ({ handleIsError }) => { const onSubmitHandler = async (values) => { const toastId = toast.loading('Mengirimkan formulir merchant...'); const data = { - ...values, harga_tayang: values.hargaTayang, categoryProduk: values.categoryProduk, merk_dagang: values.merkDagang, @@ -495,15 +506,19 @@ const InformasiVendor = ({ handleIsError }) => { <div className={`flex flex-row justify-between items-start`}> <div className='w-2/5 text-nowrap'> - <label className='form-label '> + <label + className={`form-label ${isKonfirmasi && 'text-wrap'}`} + > Tipe Kategori Produk yang Digunakan </label> - <span className='text-xs opacity-60'> - Pilih kategori produk bisa lebih dari 1 - </span> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih kategori produk bisa lebih dari 1 + </span> + )} </div> <div className='w-3/5 flex flex-col'> - <div className='flex flex-row justify-between'> + <div className='flex flex-row justify-between gap-2'> <div className='flex flex-col gap-2' // ref={categoryProdukRef} @@ -519,7 +534,7 @@ const InformasiVendor = ({ handleIsError }) => { </Checkbox> ))} </div> - <div className='flex flex-col gap-2'> + <div className='flex flex-col gap-2 '> {secondColumn.map((item) => ( <Checkbox colorScheme='red' @@ -587,13 +602,15 @@ const InformasiVendor = ({ handleIsError }) => { <div className='flex flex-row justify-between items-center'> <div className='w-2/5'> <label className='form-label text-nowrap'>Durasi Tempo</label> - <span className='text-xs opacity-60'> - Pilih durasi tempo yang anda inginkan - </span> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih durasi tempo yang anda inginkan + </span> + )} </div> <div className='w-3/5 flex flex-col '> <div className='flex flex-row items-center gap-3'> - <div className={`w-[25%]`}> + <div className={`${!isKonfirmasi && 'w-[25%]'}`}> <Controller name='tempoDuration' control={control} @@ -619,9 +636,11 @@ const InformasiVendor = ({ handleIsError }) => { <label className='form-label text-nowrap'> Jumlah Kredit Limit </label> - <span className='opacity-65 text-xs'> - isi dengan kredit limit perusahaan anda - </span> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + isi dengan kredit limit perusahaan anda + </span> + )} </div> <div className='w-3/5'> <input @@ -642,9 +661,11 @@ const InformasiVendor = ({ handleIsError }) => { <label className='form-label text-nowrap'> Waktu Pengiriman </label> - <span className='opacity-65 text-xs'> - isi dengan waktu pengiriman anda - </span> + {!isKonfirmasi && ( + <span className='opacity-65 text-xs'> + isi dengan waktu pengiriman anda + </span> + )} </div> <div className='w-3/5 flex flex-row gap-2'> <div className='w-1/3'> @@ -691,7 +712,7 @@ const InformasiVendor = ({ handleIsError }) => { /> </div> */} </div> - <div className='flex justify-start'> + <div className='flex justify-end'> {/* <Button colorScheme='red' className='w-full md:w-fit' @@ -700,14 +721,20 @@ const InformasiVendor = ({ handleIsError }) => { Daftar Merchant{' '} {<ChevronRightIcon className='w-5' color='white' />} </Button> */} - <div> - <button - type='submit' - className='btn-light bg-red-500 rounded-lg text-white w-full md:w-fit mt-6 ml-0 md:ml-auto flex justify-between hover:bg-red-400' - > - <span>Daftar Merchant </span> - </button> - </div> + {!isKonfirmasi && ( + <div> + <span className='text-xs opacity-60'> + *Pastikan data yang anda masukan sudah benar dan sesuai + </span> + <button + type='submit' + className='btn-light bg-red-500 rounded-lg text-white w-fit py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-between hover:bg-red-400' + > + <span className={` `}>Langkah Selanjutnya</span> + {<ChevronRightIcon className='w-5' />} + </button> + </div> + )} </div> </form> <PageContent path='/daftar-merchant' /> @@ -1354,7 +1381,7 @@ const InformasiVendor = ({ handleIsError }) => { </MobileView> </> ); -}; +}); const validationSchema = Yup.object().shape({ categoryProduk: Yup.string().required('Harus di-pilih'), merkDagang: Yup.string().required('Harus di-isi'), diff --git a/src/lib/merchant/components/Konfirmasi.jsx b/src/lib/merchant/components/Konfirmasi.jsx index 6372f156..45db7388 100644 --- a/src/lib/merchant/components/Konfirmasi.jsx +++ b/src/lib/merchant/components/Konfirmasi.jsx @@ -1,207 +1,109 @@ import React, { useState, useEffect, useMemo, useRef } from 'react'; import { Controller, set, useForm } from 'react-hook-form'; import HookFormSelect from '@/core/components/elements/Select/HookFormSelect'; +// import ProgressBar from '@ramonak/react-progress-bar'; import { - usePengajuanTempoStoreDokumen, - usePengajuanTempoStore, -} from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; -import KontakPerusahaan from './KontakPerusahaan'; -import ProgressBar from '@ramonak/react-progress-bar'; -import { UseToastOptions } from '@chakra-ui/react'; + Button, + Checkbox, + Spinner, + Tooltip, + UseToastOptions, +} from '@chakra-ui/react'; import odooApi from '~/libs/odooApi'; import { toast } from 'react-hot-toast'; import getFileBase64 from '@/core/utils/getFileBase64'; import { CheckCircleIcon } from '@heroicons/react/24/outline'; import InformasiPerusahaan from './InformasiPerusahaan'; -import Pengiriman from './Pengiriman'; -import KonfirmasiDokumen from './KonfirmasiDokumen'; +import InformasiVendor from './InformasiVendor'; +import SyaratDagang from './SyaratDagang'; +import Dokumen from './Dokumen'; import useDevice from '@/core/hooks/useDevice'; import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline'; +import { useRouter } from 'next/router'; const Konfirmasi = ({ chekValid, buttonSubmitClick }) => { - const { control, watch, setValue, getValues } = useForm(); + const { control, watch, setValue, getValues, reset } = useForm(); const { isDesktop, isMobile } = useDevice(); const [isOpenInformasi, setIsOpenInformasi] = useState(true); const [isOpenKontak, setIsOpenKontak] = useState(false); const [isOpenPengiriman, setIsOpenPengiriman] = useState(false); const [isOpenKonfirmasi, setIsOpenKonfirmasi] = useState(false); - const [industries, setIndustries] = useState([]); - const { - formDokumen, - errorsDokumen, - validateDokumen, - updateFormDokumen, - getJumlahDokumenDiisi, - } = usePengajuanTempoStoreDokumen(); - const { form, errors, validate, updateForm } = usePengajuanTempoStore(); - const handleInputChange = async (event) => { - let fileBase64 = ''; - const { name } = event.target; - const file = event.target.files?.[0]; - // Allowed file extensions - const allowedExtensions = ['pdf', 'png', 'jpg', 'jpeg']; - let fileExtension = ''; - if (file) { - fileExtension = file.name.split('.').pop()?.toLowerCase(); - - if (!fileExtension || !allowedExtensions.includes(fileExtension)) { - toast.error( - 'Format file yang diijinkan adalah .pdf, .png, .jpg, atau .jpeg', - { duration: 4000 } - ); - - event.target.value = ''; - return; - } - if (file.size > 2000000) { - toast.error('Maksimal ukuran file adalah 2MB', { duration: 4000 }); - - event.target.value = ''; - return; - } - - fileBase64 = await getFileBase64(file); - updateFormDokumen(name, file.name, fileExtension, fileBase64); - validateDokumen(); + const formRef = useRef(null); + const router = useRouter(); + const handleDaftarMerchant = () => { + if (formRef.current) { + formRef.current(); // Memicu submit form di InformasiPerusahaan } }; - - const isFormValid = useMemo( - () => Object.keys(errorsDokumen).length === 0, - [errorsDokumen] - ); - const dokumenNibRef = useRef(null); - const dokumenNpwpRef = useRef(null); - const dokumenSppkpRef = useRef(null); - const dokumenAktaPerubahanRef = useRef(null); - const dokumenKtpDirutRef = useRef(null); - const dokumenAktaPendirianRef = useRef(null); - const dokumenLaporanKeuanganRef = useRef(null); - const dokumenFotoKantorRef = useRef(null); - const dokumenTempatBekerjaRef = useRef(null); - - useEffect(() => { - const loadIndustries = async () => { - if (!isFormValid) { - const options = { - behavior: 'smooth', - block: 'center', - }; - if (errorsDokumen.dokumenNib && dokumenNibRef.current) { - dokumenNibRef.current.scrollIntoView(options); - return; - } - if (errorsDokumen.dokumenNpwp && dokumenNpwpRef.current) { - dokumenNpwpRef.current.scrollIntoView(options); - return; - } - if (errorsDokumen.dokumenSppkp && dokumenSppkpRef.current) { - dokumenSppkpRef.current.scrollIntoView(options); - return; - } - if ( - errorsDokumen.dokumenAktaPerubahan && - dokumenAktaPerubahanRef.current - ) { - dokumenAktaPerubahanRef.current.scrollIntoView(options); - return; - } - if (errorsDokumen.dokumenKtpDirut && dokumenKtpDirutRef.current) { - dokumenKtpDirutRef.current.scrollIntoView(options); - return; - } - if ( - errorsDokumen.dokumenAktaPendirian && - dokumenAktaPendirianRef.current - ) { - dokumenAktaPendirianRef.current.scrollIntoView(options); - return; - } - if ( - errorsDokumen.dokumenLaporanKeuangan && - dokumenLaporanKeuanganRef.current - ) { - dokumenLaporanKeuanganRef.current.scrollIntoView(options); - return; - } - if (errorsDokumen.dokumenFotoKantor && dokumenFotoKantorRef.current) { - dokumenFotoKantorRef.current.scrollIntoView(options); - return; - } - if ( - errorsDokumen.dokumenTempatBekerja && - dokumenTempatBekerjaRef.current - ) { - dokumenTempatBekerjaRef.current.scrollIntoView(options); - return; - } - } - }; - loadIndustries(); - }, [buttonSubmitClick, chekValid]); - - useEffect(() => { - validateDokumen(); - }, [buttonSubmitClick]); - - useEffect(() => { - const loadIndustries = async () => { - const dataIndustries = await odooApi('GET', '/api/v1/partner/industry'); - setIndustries( - dataIndustries?.map((o) => ({ - value: o.id, - label: o.name, - category: o.category, - })) - ); - }; - loadIndustries(); - }, []); - - useEffect(() => { - const selectedIndustryType = industries.find( - (industry) => industry.value === watch('industry_id') - ); - if (selectedIndustryType) { - updateForm('industry_id', `${selectedIndustryType?.value}`); - validate(); + const handleIsError = (value) => { + console.log('LAHKAH SELANJUTNYA', value); + if (!value) { + // goToNextStep(); + toast.success('Berhasil medaftarkan merchant'); } - }, [watch('industry_id'), industries]); + reset(); + router.push('/'); + }; - useEffect(() => { - if (form.industry_id) { - setValue('industry_id', parseInt(form.industry_id)); - } - }, [form]); - return ( <> {isDesktop && ( - <form className='flex mt-4 flex-col w-full '> - <div className='w-full grid grid-cols-[1fr_auto_1fr] gap-5'> - <div className='w-full flex flex-col gap-5 '> - <div className=''> - <InformasiPerusahaan isKonfirmasi={true} /> - </div> - <div className='h-px bg-gray-300'></div> - <div className=''> - <KontakPerusahaan isKonfirmasi={true} /> + <> + <form className='flex mt-4 flex-col w-full '> + <div className='w-full grid grid-cols-[1fr_auto_1fr] gap-5'> + <div className='w-full flex flex-col gap-5 '> + <div className=''> + <InformasiPerusahaan + isKonfirmasi={true} + ref={formRef} + handleIsError={handleIsError} + /> + </div> + <div className='h-px bg-gray-300'></div> + <div className=''> + <SyaratDagang + isKonfirmasi={true} + ref={formRef} + handleIsError={handleIsError} + /> + </div> </div> - </div> - <div className='w-px bg-gray-300'></div> - <div className='w-full grid grid-rows-[1fc_auto_1fc] gap-5'> - <div> - <Pengiriman isKonfirmasi={true} /> - </div> - <div className='h-px bg-gray-300'></div> - <div> - <KonfirmasiDokumen isKonfirmasi={true} /> + <div className='w-px bg-gray-300'></div> + <div className='w-full grid grid-rows-[1fc_auto_1fc] gap-5'> + <div className=''> + <InformasiVendor + isKonfirmasi={true} + ref={formRef} + handleIsError={handleIsError} + /> + </div> + <div className='h-px bg-gray-300'></div> + <div> + <Dokumen + isKonfirmasi={true} + ref={formRef} + handleIsError={handleIsError} + /> + </div> </div> </div> + </form> + + <div className='flex flex-col items-end justify-end gap-2'> + <span className='text-xs opacity-60'> + *Pastikan data yang anda masukan sudah benar dan sesuai + </span> + <Button + colorScheme='red' + w='36' + onClick={handleDaftarMerchant} // Memicu form submit + > + Daftar Merchant + </Button> </div> - </form> + </> )} - {isMobile && ( + {/* {isMobile && ( <form className='flex mt-8 py-4 flex-col w-full gap-4'> <div className='flex flex-col gap-4'> <div className='flex flex-row justify-between items-center'> @@ -289,7 +191,7 @@ const Konfirmasi = ({ chekValid, buttonSubmitClick }) => { {isOpenKonfirmasi && <KonfirmasiDokumen isKonfirmasi={true} />} </div> </form> - )} + )} */} </> ); }; diff --git a/src/lib/merchant/components/Merchant.jsx b/src/lib/merchant/components/Merchant.jsx index a995cb19..28244be6 100644 --- a/src/lib/merchant/components/Merchant.jsx +++ b/src/lib/merchant/components/Merchant.jsx @@ -5,6 +5,7 @@ import InformasiPerusahaan from './InformasiPerusahaan'; import InformasiVendor from './InformasiVendor'; import SyaratDagang from './SyaratDagang'; import Dokumen from './Dokumen'; +import Konfirmasi from './Konfirmasi'; import { getAuth } from '~/libs/auth'; import { setAuth } from '@/core/utils/auth'; import useAuth from '@/core/hooks/useAuth'; @@ -35,17 +36,30 @@ const Merchant = () => { const [error, setError] = useState(false); const handleIsError = (value) => { - console.log('value yang dihasilkan', value); + console.log('LAHKAH SELANJUTNYA', value); if (!value) { goToNextStep(); } setError(value); // Memperbarui state berdasarkan isError }; const stepDivs = [ - <InformasiPerusahaan handleIsError={handleIsError} />, - <InformasiVendor handleIsError={handleIsError} />, - <SyaratDagang handleIsError={handleIsError} />, - <Dokumen handleIsError={handleIsError} />, + <InformasiPerusahaan + handleIsError={handleIsError} + buttonSubmitClick={buttonSubmitClick} + />, + <InformasiVendor + handleIsError={handleIsError} + buttonSubmitClick={buttonSubmitClick} + />, + <SyaratDagang + handleIsError={handleIsError} + buttonSubmitClick={buttonSubmitClick} + />, + <Dokumen + handleIsError={handleIsError} + buttonSubmitClick={buttonSubmitClick} + />, + <Konfirmasi handleIsError={handleIsError} />, ]; const stepLabels = [ @@ -64,6 +78,11 @@ const Merchant = () => { }); }, [currentStep]); + useEffect(() => { + <InformasiPerusahaan buttonSubmitClick={buttonSubmitClick} />; + console.log('MASUK SINI'); + }, [buttonSubmitClick]); + // useEffect(() => { // const loadBigData = async () => { // const toCamelCase = (str) => @@ -166,6 +185,9 @@ const Merchant = () => { const goPrevStep = () => { setCurrentStep((prev) => (prev === NUMBER_OF_STEPS - 1 ? prev : prev - 1)); }; + const handleDaftarMerchant = () => { + setButtonSubmitClick((prev) => !prev); + }; useEffect(() => { const getBanner = async () => { @@ -210,17 +232,17 @@ const Merchant = () => { {isMobile && ( <div className='h-[2px] bg-gray-300 w-[120%] inset-0 mt-4 mb-4 relative transform -translate-x-5'></div> )} - {/* <div + <div className={`flex ${ isMobile ? 'flex-col justify-start items-start' : 'flex-col justify-end items-end' } mb-8 gap-2`} > - <span className='text-xs opacity-60'> + {/* <span className='text-xs opacity-60'> *Pastikan data yang anda masukan sudah benar dan sesuai - </span> - <div + </span> */} + {/* <div className={` flex flex-row ${ currentStep > 0 && currentStep < 5 ? 'justify-between' @@ -254,8 +276,8 @@ const Merchant = () => { </Button> </> )} - </div> - {currentStep == 5 && ( + </div> */} + {/* {currentStep == 0 && ( <div className={`flex flex-col ${ isMobile ? 'items-start' : 'items-end' @@ -264,14 +286,14 @@ const Merchant = () => { <Button colorScheme='red' w={`${isMobile ? 'full' : '36'}`} - isDisabled={!isCheckedTNC} - onClick={handleDaftarTempo} + // isDisabled={!isCheckedTNC} + onClick={handleDaftarMerchant} > - Daftar Tempo {<ChevronRightIcon className='w-5' />} + Daftar Merchant {<ChevronRightIcon className='w-5' />} </Button> </div> - )} - </div> */} + )} */} + </div> </div> </> ); diff --git a/src/lib/merchant/components/SyaratDagang.jsx b/src/lib/merchant/components/SyaratDagang.jsx index 83faf520..362302fd 100644 --- a/src/lib/merchant/components/SyaratDagang.jsx +++ b/src/lib/merchant/components/SyaratDagang.jsx @@ -4,7 +4,13 @@ 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 React, { + useEffect, + useRef, + useState, + forwardRef, + useImperativeHandle, +} from 'react'; import ReCAPTCHA from 'react-google-recaptcha'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; @@ -25,7 +31,7 @@ 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 = ({ handleIsError }) => { +const SyaratDagang = forwardRef(({ handleIsError, isKonfirmasi }, ref) => { const isError = (value) => { // Logika menentukan error const result = value ? true : false; @@ -91,32 +97,36 @@ const SyaratDagang = ({ handleIsError }) => { const data = await getMerchantApi(); setbigData(data); console.log('data vendor', data); - reset({ - isKembaliBarang: data.isKembaliBarang || '', - textReturn: data.textReturn || '', - tenggatWaktu: (() => { - const waktu = data.tenggatWaktu - ? data.tenggatWaktu.split(' ')[0] - : ''; - if (waktu === '14') return '14'; - if (waktu === '30') return '30'; - return 'custom'; - })(), - customTenggatWaktu: (() => { - if (watch('tenggatWaktu') === 'custom') return data.tenggatWaktu; - return ''; - })(), - sertifikatProduk: data.sertifikatProduk || '', - customSertifikatProduk: data.customSertifikatProduk || '', - tempoGaransi: parseInt(data.tempoGaransi) || '', - explainGaransi: data.explainGaransi || '', - minimumPembelian: data.minimumPembelian || '', - isOrderQuantity: data.isOrderQuantity || '', - }); - // handleKreditLimitChange(data.kreditLimit); - setSelectedIds(watch('sertifikatProduk').split(',').map(Number)); - if (watch('customSertifikatProduk')) { - // setSelectedIds([...selectedIds, 4]); + if (data) { + reset({ + isKembaliBarang: data.isKembaliBarang || '', + textReturn: data.textReturn || '', + tenggatWaktu: (() => { + const waktu = data.tenggatWaktu + ? data.tenggatWaktu.split(' ')[0] + : ''; + if (waktu === '14') return '14'; + if (waktu === '30') return '30'; + return 'custom'; + })(), + customTenggatWaktu: (() => { + if (watch('tenggatWaktu') === 'custom') + return data.tenggatWaktu ? data.tenggatWaktu : ''; + return ''; + })(), + sertifikatProduk: data.sertifikatProduk || '', + customSertifikatProduk: data.customSertifikatProduk || '', + tempoGaransi: parseInt(data.tempoGaransi) || '', + explainGaransi: data.explainGaransi || '', + minimumPembelian: + data.isOrderQuantity == 'tidak' ? '' : data.minimumPembelian || '', + isOrderQuantity: data.isOrderQuantity || '', + }); + // handleKreditLimitChange(data.kreditLimit); + setSelectedIds(watch('sertifikatProduk').split(',').map(Number)); + if (watch('customSertifikatProduk')) { + // setSelectedIds([...selectedIds, 4]); + } } }; @@ -129,7 +139,9 @@ const SyaratDagang = ({ handleIsError }) => { behavior: 'smooth', }); }, []); - + useImperativeHandle(ref, () => () => { + handleSubmit(onSubmitHandler)(); + }); const auth = useAuth(); if (auth == false) { router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`); @@ -357,7 +369,6 @@ const SyaratDagang = ({ handleIsError }) => { const onSubmitHandler = async (values) => { const toastId = toast.loading('Mengirimkan formulir merchant...'); const data = { - ...values, is_kembali_barang: values.isKembaliBarang, text_return: values.textReturn, tenggat_waktu: values.tenggatWaktu, @@ -448,12 +459,16 @@ const SyaratDagang = ({ handleIsError }) => { </div> </BottomPopup> <DesktopView> - <div className='container flex flex-col items-star py-4 '> + <div + className={`container flex flex-col h-fit items-start ${ + !isKonfirmasi && 'py-4' + }`} + > <h2 className='text-xs md:text-title-sm font-semibold mb-6'> Syarat Perdagangan </h2> - <div className='w-full mt-4'> + <div className='w-full mt-4 '> <form onSubmit={handleSubmit(onSubmitHandler)} className='flex flex-col gap-4' @@ -544,12 +559,16 @@ const SyaratDagang = ({ handleIsError }) => { <div className={`flex flex-row justify-between items-start`}> <div className='w-2/5 text-nowrap'> - <label className='form-label '> + <label + className={`form-label ${isKonfirmasi && 'text-wrap'}`} + > Dokumen/Sertifikat yang Dimiliki Oleh Brand </label> - <span className='text-xs opacity-60'> - Pilih dokumen/sertifikat bisa lebih dari 1 - </span> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih dokumen/sertifikat bisa lebih dari 1 + </span> + )} </div> <div className='w-3/5 flex flex-col'> <div className='flex flex-row justify-between w-full'> @@ -610,13 +629,15 @@ const SyaratDagang = ({ handleIsError }) => { <div className='flex flex-row justify-between items-center'> <div className='w-2/5'> <label className='form-label text-nowrap'>Garansi</label> - <span className='text-xs opacity-60'> - Pilih waktu garansi yang diberikan - </span> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih waktu garansi yang diberikan + </span> + )} </div> <div className='w-3/5 flex flex-col '> <div className='flex flex-row items-center gap-3'> - <div className={`w-[25%]`}> + <div className={`${!isKonfirmasi && 'w-[25%]'}`}> <Controller name='tempoGaransi' control={control} @@ -717,34 +738,23 @@ const SyaratDagang = ({ handleIsError }) => { </div> </div> - <div className=''> - {/* <div> - <ReCAPTCHA - ref={recaptchaRef} - sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} - /> - </div> */} - </div> - <div className='flex justify-start'> - {/* <Button - colorScheme='red' - className='w-full md:w-fit' - type='submit' - > - Daftar Merchant{' '} - {<ChevronRightIcon className='w-5' color='white' />} - </Button> */} - <div> - <button - type='submit' - className='btn-light bg-red-500 rounded-lg text-white w-full md:w-fit mt-6 ml-0 md:ml-auto flex justify-between hover:bg-red-400' - > - <span>Daftar Merchant </span> - </button> + {!isKonfirmasi && ( + <div className='flex justify-end'> + <div> + <span className='text-xs opacity-60'> + *Pastikan data yang anda masukan sudah benar dan sesuai + </span> + <button + type='submit' + className='btn-light bg-red-500 rounded-lg text-white w-fit py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-between hover:bg-red-400' + > + <span className={` `}>Langkah Selanjutnya</span> + {<ChevronRightIcon className='w-5' />} + </button> + </div> </div> - </div> + )} </form> - <PageContent path='/daftar-merchant' /> </div> </div> </DesktopView> @@ -1388,7 +1398,7 @@ const SyaratDagang = ({ handleIsError }) => { </MobileView> </> ); -}; +}); const validationSchema = Yup.object().shape({ isKembaliBarang: Yup.string().required('Harus di-pilih'), tenggatWaktu: Yup.string().required('Harus di-pilih'), |
