diff options
Diffstat (limited to 'src/lib/form/components/Merchant.jsx')
| -rw-r--r-- | src/lib/form/components/Merchant.jsx | 1478 |
1 files changed, 1327 insertions, 151 deletions
diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx index ee7d177d..db5f5ddd 100644 --- a/src/lib/form/components/Merchant.jsx +++ b/src/lib/form/components/Merchant.jsx @@ -1,6 +1,8 @@ import HookFormSelect from '@/core/components/elements/Select/HookFormSelect'; import cityApi from '@/lib/address/api/cityApi'; import stateApi from '@/lib/address/api/stateApi.js'; +import districtApi from '@/lib/address/api/districtApi'; +import subDistrictApi from '@/lib/address/api/subDistrictApi'; import { yupResolver } from '@hookform/resolvers/yup'; import React, { useEffect, useRef, useState } from 'react'; import ReCAPTCHA from 'react-google-recaptcha'; @@ -8,10 +10,17 @@ import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; import * as Yup from 'yup'; import createLeadApi from '../api/createLeadApi'; +import addressApi from '@/lib/address/api/addressApi'; import PageContent from '@/lib/content/components/PageContent'; import { useRouter } from 'next/router'; import useAuth from '@/core/hooks/useAuth'; - +import { Radio, RadioGroup, Stack, Divider, Button } from '@chakra-ui/react'; +import { EyeIcon } from '@heroicons/react/24/outline'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import Image from 'next/image'; +import { ChevronRightIcon } from '@heroicons/react/24/outline'; +import MobileView from '@/core/components/views/MobileView'; +import DesktopView from '@/core/components/views/DesktopView'; const CreateMerchant = () => { const { register, @@ -21,6 +30,7 @@ const CreateMerchant = () => { reset, watch, setValue, + getValues, } = useForm({ resolver: yupResolver(validationSchema), defaultValues, @@ -51,8 +61,13 @@ const CreateMerchant = () => { label: 'Lain - Lain', }, ]; - const [cities, setCities] = useState([]); const [state, setState] = useState([]); + const [cities, setCities] = useState([]); + const [districts, setDistricts] = useState([]); + const [fileNames, setFileNames] = useState({}); + const [subDistricts, setSubDistricts] = useState([]); + const [zips, setZips] = useState([]); + const [isExample, setIsExample] = useState(false); const [company_unit, setCompany_unit] = useState(list_unit); const recaptchaRef = useRef(null); @@ -64,6 +79,28 @@ const CreateMerchant = () => { } useEffect(() => { + const loadProfile = async () => { + try { + const dataProfile = await addressApi({ id: auth.parentId }); + console.log('dataProfile', dataProfile); + setValue('company', dataProfile?.name); + setValue('address', dataProfile?.alamatBisnis); + setValue('state', parseInt(dataProfile.stateId.id)); + setValue('city', parseInt(dataProfile.city.id)); + setValue('district', parseInt(dataProfile.district.id)); + setValue('subDistrict', parseInt(dataProfile.subDistrict.id)); + setValue('zip', parseInt(dataProfile.zip)); + } catch (error) { + console.error('Error loading profile:', error); + } + }; + + if (auth?.parentId) { + loadProfile(); + } + }, [auth?.parentId, setValue]); + + useEffect(() => { const loadState = async () => { let dataState = await stateApi(); dataState = dataState.map((state) => ({ @@ -92,18 +129,134 @@ const CreateMerchant = () => { loadCities(); }, [auth, watchState, setValue]); + const watchCity = watch('city'); + + useEffect(() => { + setValue('district', ''); + if (watchCity) { + const loadDistricts = async () => { + let dataDistricts = await districtApi({ cityId: watchCity }); + dataDistricts = dataDistricts.map((district) => ({ + value: district.id, + label: district.name, + })); + setDistricts(dataDistricts); + }; + loadDistricts(); + } + }, [watchCity, setValue]); + + const watchDistrict = watch('district'); + useEffect(() => { + setValue('subDistrict', ''); + if (watchDistrict) { + const loadSubDistricts = async () => { + let dataSubDistricts = await subDistrictApi({ + districtId: watchDistrict, + }); + dataSubDistricts = dataSubDistricts.map((district) => ({ + value: district.id, + label: district.name, + })); + setSubDistricts(dataSubDistricts); + }; + loadSubDistricts(); + } + }, [watchDistrict, setValue]); + + const watchsubDistrict = watch('subDistrict'); + + useEffect(() => { + setValue('zip', ''); + let kelurahan = ''; + let kecamatan = ''; + + if (watchDistrict) { + for (const data in districts) { + if (districts[data].value == watchDistrict) { + kecamatan = districts[data].label.toLowerCase(); + } + } + } + + if (watchsubDistrict) { + for (const data in subDistricts) { + if (subDistricts[data].value == watchsubDistrict) { + kelurahan = subDistricts[data].label.toLowerCase(); + } + } + const loadZip = async () => { + const response = await fetch( + `https://alamat.thecloudalert.com/api/cari/index/?keyword=${kelurahan}` + ); + + let dataMasuk = []; // Array untuk menyimpan kode pos yang sudah diproses + + const result = await response.json(); + + // Filter dan map data + const dataZips = result.result + .filter((zip) => zip.kecamatan.toLowerCase() === kecamatan) // Filter berdasarkan kecamatan + .filter((zip) => { + // Pastikan zip.kodepos belum ada di dataMasuk + if (dataMasuk.includes(zip.kodepos)) { + return false; // Jika sudah ada, maka skip (tidak akan ditambahkan) + } else { + dataMasuk.push(zip.kodepos); // Tambahkan ke dataMasuk + return true; // Tambahkan zip ke hasil + } + }) + .map((zip) => ({ + value: parseInt(zip.kodepos), + label: zip.kodepos, + })); + + setZips(dataZips); // Set hasil ke state + }; + + loadZip(); + } + }, [watchsubDistrict, setValue, subDistricts]); + const onSubmitHandler = async (values) => { - const recaptchaValue = recaptchaRef.current.getValue(); - if (!recaptchaValue) { - toast.error('Catcha harus diisi'); + const dokumenKtpDirut = document.getElementById('dokumenKtpDirut').files[0]; + const kartuNama = document.getElementById('kartuNama').files[0]; + const sppkp = document.getElementById('sppkp').files[0]; + const npwp = document.getElementById('npwp').files[0]; + const suratPernyataan = document.getElementById('suratPernyataan').files[0]; + const fotoKantor = document.getElementById('fotoKantor').files[0]; + if (!npwp) { + toast.error('NPWP wajib di tambahkan'); + return; + } + if (!suratPernyataan) { + toast.error('Surat Pernyataan Nomor Rekening wajib di tambahkan'); return; } + if (!fotoKantor) { + toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan'); + return; + } + console.log('Submitted Values:', values); + console.log('values.npwp[0]:', values.npwp[0]); + console.log('npwp:', npwp); const data = { ...values, name: 'Form Merchant - ' + values.company, - contact_name: values.cp, - email_from: values.email, + address: values.address, + state: values.state, + city: values.city, + district: values.district, + SubDistrict: values.SubDistrict, + zip: values.zip, + bank_name: values.bank, + rekening_name: values.rekening, + account_number: values.accountNumber, + email_company: values.email, + email_sales: values.emailSales, + email_finnance: values.emailFinance, phone: values.phone, + mobile: values.mobile, description: 'Nama Perusahaan : ' + values.company + @@ -123,200 +276,1201 @@ const CreateMerchant = () => { values.mobile + 'Keterangan : ' + values.description, + file_dokumenKtpDirut: dokumenKtpDirut + ? await getFileBase64(dokumenKtpDirut) + : '', + file_kartuNama: kartuNama ? await getFileBase64(kartuNama) : '', + file_npwp: npwp ? await getFileBase64(npwp) : '', + file_sppkp: sppkp ? await getFileBase64(sppkp) : '', + file_suratPernyataan: suratPernyataan + ? await getFileBase64(suratPernyataan) + : '', + file_fotoKantor: fotoKantor ? await getFileBase64(fotoKantor) : '', }; - const create_leads = await createLeadApi({ data }); - if (create_leads) { - toast.success('Berhasil menambahkan data'); - reset(); - recaptchaRef.current.reset(); - } + // const formData = new FormData(); + // formData.append('npwp', values.npwp[0]); + // const create_leads = await createLeadApi({ formData }); + // if (create_leads) { + // toast.success('Berhasil menambahkan data'); + // reset(); + // } }; + + // const DownLoadSurat = () => { + // download surat dari /public/file/Surat Pernyataan Nomor Rekening.docx + // }; + if (!auth) { return; } + // Tetap di bagian atas, tidak boleh ada kondisi sebelum hook + + const handleFileChange = (event) => { + const file = event.target.files[0]; + if (file.size > 2000000) { + toast.error('Maksimal ukuran file adalah 2MB'); + event.target.value = ''; + return; + } + const fieldName = event.target.name; // Nama input file + setFileNames((prev) => ({ + ...prev, + [fieldName]: file ? file.name : '', // Tambahkan atau perbarui file di state + })); + }; + + console.log('errors', errors); return ( - <div className='container mx-auto p-4 md:p-0 my-0 md:my-10'> - <h1 className='text-h-sm md:text-title-sm font-semibold mb-6'> - Form Merchant - </h1> - <div className='w-full p-4 bg-white border border-gray_r-6 rounded'> - <div - className='flex items-center bg-blue-100 border border-blue-400 text-blue-500 font-bold px-4 py-3 mb-4' - role='alert' - > - <p> - Penjualan online adalah hal yang HARUS dilakukan mulai sekarang. - Perubahan dalam banyak industri dan pola pembelian. Gabung dengan - platform kami dan mulai penjualan lansung di ribuan perusahaan d - seluruh Indonesia.{' '} - </p> + <> + <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> - <div className='w-full grid grid-cols-2 gap-x-2'> - <form onSubmit={handleSubmit(onSubmitHandler)}> - <div className=''> - <div> - <label className='form-label mb-2'>Nama Perusahan *</label> - <input - {...register('company')} - placeholder='PT.Indoteknik' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.company?.message} + </BottomPopup> + <DesktopView> + <div className='container flex flex-col items-star py-4'> + <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='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> + <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} + </div> </div> </div> - </div> - <div className=''> - <div> - <label className='form-label mb-2'>Alamat*</label> - <input - {...register('address')} - placeholder='jl. Bandengan no.31 ' - type='text' - className='form-input' - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.address?.message} + <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> + <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.address?.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 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 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 ? ( + <HookFormSelect + {...props} + options={zips} + disabled={!watchsubDistrict} + placeholder='Zip' + /> + ) : ( + // Jika zips kosong, tampilkan input manual + <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> + </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> + <div className='w-3/5 flex flex-row gap-2'> + <div> + <input + {...register('bank')} + placeholder='Nama bank' + 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} + </div> + </div> + <div> + <input + {...register('rekening')} + placeholder='Nama Rekening' + 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} + </div> + </div> + <div> + <input + {...register('accountNumber')} + placeholder='Nomor Rekening Bank' + type='number' + className='form-input' + /> + <span className='opacity-65 text-xs'> + Format: 01234567896 + </span> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountNumber?.message} + </div> + </div> + </div> + </div> + <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-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> + <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' + 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> + <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> - <div className=''> - <div> - <label className='form-label mb-2'>No. Telp *</label> + + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + KTP Dirut/Direktur{' '} + <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='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' + id='dokumenKtpDirut' + onChange={handleFileChange} + aria-invalid={errors.dokumenKtpDirut?.message} + /> + <span className='mt-2 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> + + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <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' + 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' + id='kartuNama' + onChange={handleFileChange} + aria-invalid={errors.kartuNama?.message} + /> + <span className='mt-2 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> + + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'>NPWP</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='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' + id='npwp' + onChange={(e) => { + handleFileChange(e); // Untuk update UI (opsional) + }} + aria-invalid={errors.npwp?.message} + /> + <span className='mt-2 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> + <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'> + SPPKP<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 `} /> + + <p className='font-light text-xs '>Lihat Contoh</p> + </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' + 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' + id='sppkp' + onChange={handleFileChange} + aria-invalid={errors.sppkp?.message} + /> + <span className='mt-2 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> + <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'> + Surat Pernyataan Nomor Rekening + </label> + <span className='opacity-65 text-xs'> + Pastikan dokumen yang anda upload sudah benar + </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 items-start'> + <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' + id='suratPernyataan' + onChange={handleFileChange} + aria-invalid={errors.suratPernyataan?.message} + /> + <span className='mt-2 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> + <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'> + 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' + 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> + <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> + {/* <button + type='submit' + className='btn-yellow w-full md:w-fit mt-6 ml-0 md:ml-auto' + > + Simpan + </button> */} + </div> + </div> + </form> + <PageContent path='/daftar-merchant' /> + </div> + </div> + </DesktopView> + <MobileView> + <div className='container flex flex-col items-star py-4'> + <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'> + 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'> + Email Perusahaan + </label> <input - {...register('phone')} - placeholder='021-XXXX' - type='text' + {...register('email')} + placeholder='contoh@email.com' + type='email' className='form-input' /> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.phone?.message} + {errors.email?.message} </div> + <span className='opacity-65 text-xs'> + isi detail perusahaan sesuai dengan data yang terdaftar + </span> </div> - </div> - <div> - <label className='form-label mb-2'>Provinsi*</label> - <Controller - name='state' - control={control} - render={(props) => ( - <HookFormSelect {...props} options={state} /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.state?.message} - </div> - </div> - <div className=''> - <div> - <label className='form-label mb-2'>Kota*</label> - <Controller - name='city' - control={control} - render={(props) => ( - <HookFormSelect {...props} options={cities} /> - )} - /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.city?.message} - </div> - </div> - </div> - <div className=''> - <div> - <label className='form-label mb-2'>Unit Perusahaan*</label> - <Controller - name='company_unit' - control={control} - render={(props) => ( - <HookFormSelect {...props} options={company_unit} /> - )} + <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.company_unit?.message} + {errors.emailSales?.message} </div> + <span className='opacity-65 text-xs'> + isi detail perusahaan sesuai dengan data yang terdaftar + </span> </div> - </div> - <div className=''> - <div> - <label className='form-label mb-2'>Website *</label> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'>Email Finance</label> <input - {...register('website')} - placeholder='https://indoteknik.com' - type='text' + {...register('emailFinance')} + placeholder='contoh@email.com' + type='email' className='form-input' /> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.website?.message} + {errors.emailFinance?.message} </div> + <span className='opacity-65 text-xs'> + isi detail perusahaan sesuai dengan data yang terdaftar + </span> </div> - </div> - <div className=''> - <div> - <label className='form-label mb-2'>Contact Person*</label> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'> + No. Telepon Perusahaan + </label> <input - {...register('cp')} - placeholder='Jhone doe' - type='text' + {...register('phone')} + placeholder='Format: 08123456789 / (021) 123 4567' + type='tel' className='form-input' /> <div className='text-caption-2 text-danger-500 mt-1'> - {errors.cp?.message} + {errors.phone?.message} </div> + <span className='opacity-65 text-xs'> + isi detail perusahaan sesuai dengan data yang terdaftar + </span> </div> - </div> - <div className=''> - <div> - <label className='form-label mb-2'>No HP *</label> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'>No. Handphone</label> <input {...register('mobile')} - placeholder='628XXXXXXX' - type='text' + 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> - <div className=''> - <div> - <label className='form-label mb-2'>Alamat Email *</label> - <input - {...register('email')} - placeholder='contoh@email.com' - type='email' - className='form-input' - /> + + <div className='w-full flex flex-col gap-2'> + <label className='form-label text-nowrap'> + KTP Dirut/Direktur{' '} + <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' + 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.email?.message} + {errors.dokumenKtpDirut?.message} </div> </div> - </div> - <div className=''> - <div> - <ReCAPTCHA - ref={recaptchaRef} - sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} - /> + + <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' + 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'> + <label className='form-label text-nowrap'>NPWP</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' + 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<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' + 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 items-start '> + <div className='flex flex-row w-full justify-between items-center'> + <label className='form-label text-wrap'> + Surat Pernyataan Nomor Rekening + </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' + 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=''> + <div> + <ReCAPTCHA + ref={recaptchaRef} + sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} + /> + </div> </div> - </div> - <div className=''> - <div> - <button + <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> + {/* <button type='submit' className='btn-yellow w-full md:w-fit mt-6 ml-0 md:ml-auto' > Simpan - </button> + </button> */} + </div> </div> - </div> - </form> - <PageContent path='/daftar-merchant' /> + </form> + <PageContent path='/daftar-merchant' /> + </div> </div> - </div> - </div> + </MobileView> + </> ); }; const validationSchema = Yup.object().shape({ @@ -324,21 +1478,43 @@ const validationSchema = Yup.object().shape({ email: Yup.string() .email('Format harus seperti contoh@email.com') .required('Harus di-isi'), + emailSales: Yup.string() + .email('Format harus seperti contoh@email.com') + .required('Harus di-isi'), + emailFinance: Yup.string() + .email('Format harus seperti contoh@email.com') + .required('Harus di-isi'), phone: Yup.string().required('Harus di-isi'), cp: Yup.string().required('Harus di-isi'), state: Yup.string().required('Harus dipilih'), - city: Yup.string().required('Harus di-isi'), + city: Yup.string().required('Harus dipilih'), + district: Yup.string().required('Harus dipilih'), + subDistrict: Yup.string().required('Harus dipilih'), + zip: Yup.string().required('Harus di-isi'), + bank: Yup.string().required('Harus di-isi'), + rekening: Yup.string().required('Harus di-isi'), + accountNumber: Yup.string().required('Harus di-isi'), company_unit: Yup.string().required('Harus di-isi'), address: Yup.string().required('Harus di-isi'), website: Yup.string().required('Harus di-isi'), mobile: Yup.string().required('Harus di-isi'), + npwp: Yup.mixed().required('File is required'), + suratPernyataan: Yup.mixed().required('File is required'), }); const defaultValues = { company: '', email: '', + emailSales: '', + emailFinance: '', phone: '', state: '', city: '', + district: '', + subDistrict: '', + zip: '', + bank: '', + rekening: '', + accountNumber: '', company_unit: '', cp: '', address: '', |
