summaryrefslogtreecommitdiff
path: root/src/lib/merchant/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/merchant/components')
-rw-r--r--src/lib/merchant/components/AccountSwitch.jsx60
-rw-r--r--src/lib/merchant/components/Dokumen.jsx1252
-rw-r--r--src/lib/merchant/components/InformasiPerusahaan.jsx2285
-rw-r--r--src/lib/merchant/components/InformasiVendor.jsx748
-rw-r--r--src/lib/merchant/components/Konfirmasi.jsx198
-rw-r--r--src/lib/merchant/components/Merchant.jsx142
-rw-r--r--src/lib/merchant/components/SyaratDagang.jsx822
7 files changed, 5507 insertions, 0 deletions
diff --git a/src/lib/merchant/components/AccountSwitch.jsx b/src/lib/merchant/components/AccountSwitch.jsx
new file mode 100644
index 00000000..b9bf34b1
--- /dev/null
+++ b/src/lib/merchant/components/AccountSwitch.jsx
@@ -0,0 +1,60 @@
+import Link from 'next/link';
+import Image from '~/components/ui/image';
+import whatsappUrl from '@/core/utils/whatsappUrl';
+import { useEffect, useState } from 'react';
+import odooApi from '@/core/api/odooApi';
+import useDevice from '@/core/hooks/useDevice';
+import useAuth from '@/core/hooks/useAuth';
+import axios from 'axios';
+import { toast } from 'react-hot-toast';
+import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline';
+
+const FinishTempo = ({ query }) => {
+ const [data, setData] = useState();
+ const [transactionData, setTransactionData] = useState();
+ const { isDesktop, isMobile } = useDevice();
+ const auth = useAuth();
+
+ return (
+ <div className='container flex flex-col items-center gap-4'>
+ <div
+ className={`flex ${
+ isMobile ? 'w-full' : 'w-2/3'
+ } justify-center items-center`}
+ >
+ <h1
+ className={`text-red-500 text-center py-4 font-semibold ${
+ isMobile ? 'text-lg' : 'text-3xl'
+ }`}
+ >
+ Form Merchant Kamu Gagal Dilakukan
+ </h1>
+ </div>
+ <Image
+ src='/images/ICON_TEMPO.png'
+ alt='Registrasi Tempo'
+ width={isMobile ? 300 : 550}
+ height={isMobile ? 300 : 550}
+ />
+
+ <div
+ className={`mt-2 text-center opacity-75 leading-6 p-4 md:p-0 ${
+ isMobile ? 'w-full text-sm' : 'w-4/5 text-base'
+ }`}
+ >
+ Terima kasih atas minat anda untuk mendaftar merchant, namun sayangnya
+ akun anda bukan merupakan akun bisnis. Segera ubah akun anda menjadi
+ Bisnis untuk menggunakan fitur ini
+ </div>
+ <Link
+ href={'/my/profile'}
+ className='btn-solid-red rounded-md text-base flex flex-row items-center justify-center'
+ >
+ Ubah Akun
+ <ChevronRightIcon className='w-5' />
+ </Link>
+ </div>
+ );
+};
+
+export default FinishTempo;
diff --git a/src/lib/merchant/components/Dokumen.jsx b/src/lib/merchant/components/Dokumen.jsx
new file mode 100644
index 00000000..c13353e5
--- /dev/null
+++ b/src/lib/merchant/components/Dokumen.jsx
@@ -0,0 +1,1252 @@
+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,
+ 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';
+import useAuth from '@/core/hooks/useAuth';
+import { Radio, RadioGroup, Stack, Divider, Button } from '@chakra-ui/react';
+import { EyeIcon } from '@heroicons/react/24/outline';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import Image from 'next/image';
+import ImageBanner from '~/components/ui/image';
+import { ChevronRightIcon } from '@heroicons/react/24/outline';
+import MobileView from '@/core/components/views/MobileView';
+import DesktopView from '@/core/components/views/DesktopView';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import odooApi from '~/libs/odooApi';
+const 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,
+ });
+
+ 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 [fileNames, setFileNames] = useState({});
+ const [DeatailFile, setDetailFile] = useState({});
+ const [isExample, setIsExample] = useState(false);
+ const [isPkp, setIsPkp] = useState(false);
+
+ 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')}`);
+ }
+ useEffect(() => {
+ const loadData = async () => {
+ try {
+ const data = await getMerchantApi();
+ 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
+ }
+ };
+
+ loadData();
+ }, [reset, handleIsError]);
+
+ useEffect(() => {
+ if (!isKonfirmasi) {
+ 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);
+ }
+ };
+
+ loadProfile();
+ }, [auth?.parentId]);
+
+ 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;
+ }
+ if (!sppkp.name && isPkp) {
+ toast.error('SPPKP wajib di tambahkan');
+ if (sppkpRef?.current) {
+ sppkpRef.current.scrollIntoView(options);
+ }
+ return;
+ }
+ if (!dokumenKtpDirut.name && !isPkp) {
+ toast.error('KTP Dirut/Direktur wajib di tambahkan');
+ if (ktpDirutRef?.current) {
+ ktpDirutRef.current.scrollIntoView(options);
+ }
+ return;
+ }
+ 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');
+ }
+ };
+
+ if (!auth) {
+ return;
+ }
+
+ 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
+ }));
+ };
+ 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 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>
+ )}
+
+ <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>
+ )}
+
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.sppkp?.message}
+ </div>
+ </div>
+ </div>
+
+ <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 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'>
+ {!isKonfirmasi && (
+ <h2 className='font-semibold mb-6 text-xl'>Dokumen</h2>
+ )}
+
+ <div className='w-full mt-4'>
+ <form
+ onSubmit={handleSubmit(onSubmitHandler)}
+ className='flex flex-col gap-4'
+ >
+ <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-center 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-center 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-center 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-center 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-center 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-center 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=' 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-wrap'>
+ Data Produk (Item Name, Gambar, Deskripsi){' '}
+ <span className=' opacity-60'>(Opsional)</span>{' '}
+ </label>
+ <div className='flex flex-row items-center 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=' 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-center 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=' 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-center w-full '>
+ {/* <Button
+ colorScheme='red'
+ className='w-full md:w-fit'
+ type='submit'
+ >
+ Daftar Merchant{' '}
+ {<ChevronRightIcon className='w-5' color='white' />}
+ </Button> */}
+ {!isKonfirmasi && (
+ <div className='w-full'>
+ <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-full py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-center hover:bg-red-400'
+ >
+ <span className={` `}>Langkah Selanjutnya</span>
+ {<ChevronRightIcon className='w-5' />}
+ </button>
+ </div>
+ )}
+ </div>
+ </form>
+ <PageContent path='/daftar-merchant' />
+ </div>
+ </div>
+ </MobileView>
+ </>
+ );
+ }
+);
+const validationSchema = Yup.object().shape({
+ npwp: Yup.mixed().required('File is required'),
+ pricelist: Yup.mixed().required('File is required'),
+});
+const defaultValues = {
+ company: '',
+ pejabatName: '',
+ PICName: '',
+ PICPosition: '',
+ email: '',
+ emailSales: '',
+ emailFinance: '',
+ phone: '',
+ state: '',
+ city: '',
+ district: '',
+ subDistrict: '',
+ zip: '',
+ bank: '',
+ rekening: '',
+ accountNumber: '',
+ address: '',
+ mobile: '',
+};
+
+export default Dokumen;
diff --git a/src/lib/merchant/components/InformasiPerusahaan.jsx b/src/lib/merchant/components/InformasiPerusahaan.jsx
new file mode 100644
index 00000000..8e4f9c56
--- /dev/null
+++ b/src/lib/merchant/components/InformasiPerusahaan.jsx
@@ -0,0 +1,2285 @@
+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,
+ 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';
+import useAuth from '@/core/hooks/useAuth';
+import { Radio, RadioGroup, Stack, Divider, Button } from '@chakra-ui/react';
+import { EyeIcon } from '@heroicons/react/24/outline';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import Image from 'next/image';
+import ImageBanner from '~/components/ui/image';
+import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline';
+import MobileView from '@/core/components/views/MobileView';
+import DesktopView from '@/core/components/views/DesktopView';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import odooApi from '~/libs/odooApi';
+
+const CreateMerchant = 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,
+ });
+ const [bisnisType, setBisnisType] = useState([]);
+ const [state, setState] = useState([]);
+ const [cities, setCities] = useState([]);
+ const [districts, setDistricts] = useState([]);
+ const [subDistricts, setSubDistricts] = useState([]);
+ const [zips, setZips] = useState([]);
+ const [isExample, setIsExample] = useState(false);
+ const [isPkp, setIsPkp] = useState(false);
+ const [fileNames, setFileNames] = useState({});
+ const [DeatailFile, setDetailFile] = useState({});
+ 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 bisnisTypeRef = useRef(null);
+
+ const handleConfirmSubmit = (format, base64) => {
+ if (format == 'pdf') {
+ setFormat(`application/${format}`);
+ } else if (format == 'png' || format == 'jpg' || format == 'jpeg') {
+ setFormat(`image/${format}`);
+ } else {
+ setFormat(format);
+ }
+ setBase64(
+ base64.trim().replace(/^"+/, '').replace(/"+$/, '').replaceAll('\\', '')
+ );
+ setIsExample(!isExample);
+ };
+ 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(); // Extract file extension
+
+ // Check if the file extension is allowed
+ if (!fileExtension || !allowedExtensions.includes(fileExtension)) {
+ toast.error(
+ 'Format file yang diijinkan adalah .pdf, .png, .jpg, atau .jpeg',
+ { duration: 4000 }
+ );
+
+ event.target.value = '';
+ return;
+ }
+
+ // Check for file size
+ 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);
+ updateFormDokumen(
+ name,
+ compressedFile.name,
+ fileExtension,
+ fileBase64
+ );
+ } catch (error) {
+ toast.error('Gagal mengompresi file', { duration: 4000 });
+ }
+ } else {
+ // Convert file to Base64
+ fileBase64 = await getFileBase64(file);
+ updateFormDokumen(name, file.name, fileExtension, fileBase64);
+ }
+ validateDokumen();
+ }
+ };
+
+
+ useEffect(() => {
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth',
+ });
+ }, []);
+
+
+ useImperativeHandle(ref, () => () => {
+ handleSubmit(onSubmitHandler)();
+ });
+
+ 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)' },
+ ];
+
+ 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
+ }));
+ };
+
+ useEffect(() => {
+ const loadData = async () => {
+ try {
+ const data = await getMerchantApi();
+ if (data) {
+ reset({
+ name: data.name ? data.name : '',
+ 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 || '',
+ categoryPerusahaan: data.categoryPerusahaan
+ ? parseInt(data.categoryPerusahaan)
+ : null,
+ website: data.website || '',
+ });
+ 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
+ : '',
+ }));
+ }
+ } catch (error) {
+ console.error('Error loading profile:', error);
+ handleIsError(true); // Jika ada error, panggil fungsi error handler
+ }
+ };
+
+ loadData();
+ }, [reset, handleIsError]);
+
+ useEffect(() => {
+ if (errors.bisnisType && bisnisTypeRef.current) {
+ bisnisTypeRef.current.scrollIntoView({ behavior: "smooth", block: "center" });
+ }
+ }, [errors.bisnisType]);
+
+ useEffect(() => {
+ const loadProfile = async () => {
+ try {
+ const dataProfile = await addressApi({
+ id: auth.parentId ? auth.parentId : auth.partnerId,
+ });
+ if (dataProfile.companyType == 'pkp') {
+ setIsPkp(true);
+ }
+ setValue('name', 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 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,
+ };
+ 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 : '' },
+ };
+
+ let data = {
+ file_dokumen: JSON.stringify(dokumen),
+ };
+
+ loadProfile();
+ }, [auth?.parentId]);
+
+ useEffect(() => {
+ const loadState = async () => {
+ let dataState = await stateApi({ tempo: false });
+ dataState = dataState.map((state) => ({
+ value: state.id,
+ label: state.name,
+ }));
+ setState(dataState);
+ };
+ loadState();
+ }, []);
+
+ const watchState = watch('state');
+ useEffect(() => {
+ if (auth == false) {
+ return;
+ }
+ if (watchState) {
+ // setValue('city', '');
+ const loadCities = async () => {
+ let dataCities = await cityApi({ stateId: watchState });
+ dataCities = dataCities?.map((city) => ({
+ value: city.id,
+ label: city.name,
+ }));
+ setCities(dataCities);
+ };
+ loadCities();
+ }
+ }, [auth, watchState]);
+
+ const watchCity = watch('city');
+ useEffect(() => {
+ if (watchCity) {
+ // setValue('district', '');
+ const loadDistricts = async () => {
+ let dataDistricts = await districtApi({ cityId: watchCity });
+ dataDistricts = dataDistricts.map((district) => ({
+ value: district.id,
+ label: district.name,
+ }));
+ setDistricts(dataDistricts);
+ };
+ loadDistricts();
+ }
+ }, [watchCity]);
+
+ const watchDistrict = watch('district');
+ useEffect(() => {
+ if (watchDistrict) {
+ // setValue('subDistrict', '');
+ const loadSubDistricts = async () => {
+ let dataSubDistricts = await subDistrictApi({
+ districtId: watchDistrict,
+ });
+ dataSubDistricts = dataSubDistricts.map((district) => ({
+ value: district.id,
+ label: district.name,
+ }));
+ setSubDistricts(dataSubDistricts);
+ };
+ loadSubDistricts();
+ }
+ }, [watchDistrict]);
+
+ const watchsubDistrict = watch('subDistrict');
+
+ useEffect(() => {
+ let kelurahan = '';
+ let kecamatan = '';
+
+ if (watchDistrict) {
+ // setValue('zip', '');
+ for (const data in districts) {
+ if (districts[data].value == watchDistrict) {
+ kecamatan = districts[data].label.toLowerCase();
+ }
+ }
+ }
+
+ if (watchsubDistrict) {
+ for (const data in subDistricts) {
+ if (subDistricts[data].value == watchsubDistrict) {
+ kelurahan = subDistricts[data].label.toLowerCase();
+ }
+ }
+ const loadZip = async () => {
+ const response = await fetch(
+ `https://alamat.thecloudalert.com/api/cari/index/?keyword=${kelurahan}`
+ );
+
+ let dataMasuk = []; // Array untuk menyimpan kode pos yang sudah diproses
+
+ const result = await response.json();
+
+ // Filter dan map data
+ const dataZips = result.result
+ .filter((zip) => zip.kecamatan.toLowerCase() === kecamatan) // Filter berdasarkan kecamatan
+ .filter((zip) => {
+ // Pastikan zip.kodepos belum ada di dataMasuk
+ if (dataMasuk.includes(zip.kodepos)) {
+ return false; // Jika sudah ada, maka skip (tidak akan ditambahkan)
+ } else {
+ dataMasuk.push(zip.kodepos); // Tambahkan ke dataMasuk
+ return true; // Tambahkan zip ke hasil
+ }
+ })
+ .map((zip) => ({
+ value: parseInt(zip.kodepos),
+ label: zip.kodepos,
+ }));
+
+ setZips(dataZips); // Set hasil ke state
+ };
+
+ loadZip();
+ }
+ }, [watchsubDistrict, subDistricts]);
+ const [selected, setSelected] = useState('PKP');
+ const onSubmitHandler = async (values) => {
+ 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 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 : '' },
+ };
+ const data = {
+ name_merchant: 'Form Merchant - ' + values.name,
+ address: values.address,
+ state: parseInt(values.state),
+ city: parseInt(values.city),
+ district: parseInt(values.district),
+ subDistrict: parseInt(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,
+ description:
+ 'Nama Perusahaan : ' +
+ values.name +
+ ' \r\n Alamat : ' +
+ values.address +
+ ' \r\n Kota : ' +
+ values.city +
+ ' \r\n Telepon: ' +
+ values.phone +
+ ' \r\n Email : ' +
+ values.email +
+ ' \r\n No Hp : ' +
+ values.mobile,
+ file_dokumen: JSON.stringify(dokumen),
+ };
+ const options = {
+ behavior: 'smooth',
+ block: 'center',
+ };
+ if (!dokumenKtpDirut.name && !isPkp) {
+ toast.error('KTP Dirut/Direktur wajib di tambahkan');
+ if (ktpDirutRef?.current) {
+ ktpDirutRef.current.scrollIntoView(options);
+ }
+ return;
+ }
+ if (!fotoKantor.name) {
+ toast.error('Foto Gudang / Kantor Bagian Depan wajib di tambahkan');
+ if (fotoKantorRef?.current) {
+ fotoKantorRef.current.scrollIntoView(options);
+ }
+ return;
+ }
+ 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
+ // };
+
+ if (!auth) {
+ return;
+ }
+ // Tetap di bagian atas, tidak boleh ada kondisi sebelum hook
+ const onInvalid = (errors) => {
+ console.error('Form validation errors:', errors);
+ };
+
+
+
+ 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 Bisnis
+ </h2>
+
+ <div className='w-full mt-4'>
+ <form
+
+ onSubmit={handleSubmit(onSubmitHandler, onInvalid)}
+ className='flex flex-col gap-4'
+ >
+ <Controller
+ name="bisnisType"
+ control={control}
+ render={({ field }) => (
+ <div ref={bisnisTypeRef} className="space-y-2 w-full flex flex-row">
+ <div className="w-2/5">
+ <label className="font-semibold text-gray-800">Tipe Bisnis</label>
+ </div>
+ <div className="flex items-center space-x-6 .w-3/5">
+ {dataBisnisType.map((option) => (
+ <label key={option.value} className="flex items-center space-x-2 cursor-pointer">
+ <input
+ type="radio"
+ value={option.label}
+ checked={field.value === option.value}
+ onChange={() => field.onChange(option.value)}
+ className="sr-only peer"
+ />
+ <div className="w-4 h-4 rounded-full border-2 border-red-100 flex items-center justify-center
+ peer-checked:border-[5px] peer-checked:border-red-500
+ peer-focus:outline peer-focus:outline-red-100">
+ <div className="absolute top-1/2 left-1/2 w-2.5 h-2.5 bg-red-500 rounded-full -translate-x-1/2 -translate-y-1/2 opacity-0 peer-checked:opacity-200" />
+ </div>
+ <span className=" text-gray-800">{option.label}</span>
+ </label>
+
+ ))}
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.bisnisType?.message}
+ </div>
+ </div>
+ </div>
+ )}
+ />
+ <div className='w-full flex flex-row'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama BIsnis
+ </label>
+ {!isKonfirmasi && (
+ <span className='opacity-65 text-xs'>
+ Isi detail perusahaan sesuai dengan nama yang terdaftar{' '}
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ {...register('name')}
+ 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.name?.message}
+ </div>
+ </div>
+ </div>
+ {/* <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 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 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-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('PICPosition')}
+ placeholder='Masukkan jabatan PIC'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.PICPosition?.message}
+ </div>
+ </div>
+ </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.address?.message}
+ </div>
+ </div>
+ <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.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-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={({ field }) => (
+ <input
+ {...field}
+ 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>
+ <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.bank?.message}
+ </div>
+ </div>
+ <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.rekening?.message}
+ </div>
+ </div>
+ <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.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 Bisnis
+ </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 Bisnis
+ </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='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 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>
+ )}
+
+ <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}
+ />
+ {!isKonfirmasi && (
+ <span className='mt-2 text-gray-600 line-clamp-2'>
+ {fileNames.sppkp}
+ </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.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 ${
+ 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='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('website')}
+ placeholder='Masukkan website'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.website?.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={` `}>Daftar Merchant</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'>
+ {!isKonfirmasi && (
+ <h2 className='font-semibold mb-6 text-xl'>
+ Informasi Perusahaan
+ </h2>
+ )}
+ <Controller
+ name="bisnisType"
+ control={control}
+ render={({ field }) => (
+ <div ref={bisnisTypeRef} className="space-y-2">
+ <label className="font-semibold text-gray-800">Tipe Bisnis</label>
+ <div className="flex items-center space-x-6">
+ {dataBisnisType.map((option) => (
+ <label key={option.value} className="flex items-center space-x-2 cursor-pointer">
+ <input
+ type="radio"
+ value={option.value}
+ checked={field.bisnisType === option.label}
+ onChange={() => field.onChange(option.label)}
+ className="sr-only peer"
+ />
+ <div className="w-4 h-4 rounded-full border-2 border-red-100 flex items-center justify-center
+ peer-checked:border-[5px] peer-checked:border-red-500
+ peer-focus:outline peer-focus:outline-red-100">
+ <div className="absolute top-1/2 left-1/2 w-2.5 h-2.5 bg-red-500 rounded-full -translate-x-1/2 -translate-y-1/2 opacity-0 peer-checked:opacity-200" />
+ </div>
+ <span className="text-sm text-gray-800">{option.label}</span>
+ </label>
+
+ ))}
+ </div>
+ </div>
+ )}
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.bisnisType?.message}
+ </div>
+ <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 Bisnis
+ </label>
+ <input
+ {...register('name')}
+ placeholder='Format: PT. INDOTEKNIK DOTCOM GEMILANG'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.name?.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'>
+ Pejabat Berwenang
+ </label>
+ <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>
+ <span className='opacity-65 text-xs'>
+ isi dengan nama pejabat yang berwewenang di perusahaan
+ anda{' '}
+ </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'>
+ Jabatan PIC
+ </label>
+ <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>
+ <span className='opacity-65 text-xs'>
+ isi dengan jabatan 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={({ field }) => (
+ <input
+ {...field}
+ 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 Bisnis
+ </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 Bisnis
+ </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 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-center 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-center 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'>
+ <label className='form-label text-nowrap'>
+ NPWP{' '}
+ {!isPkp && <span className=' opacity-60'>(Opsional)</span>}
+ </label>
+ <div className='flex flex-row items-center 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-center 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 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-center 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-center 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=' 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='flex flex-col'>
+ <label className='form-label text-nowrap'>Tipe Bisnis</label>
+ <div className='flex flex-col '>
+ <Controller
+ name='bisnisType'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataBisnisType}
+ placeholder={'Pilih tipe bisnis'}
+ />
+ )}
+ />
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih tipe bisnis yang sesuai
+ </span>
+ )}
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.bisnisType?.message}
+ </div>
+ </div>
+ </div>
+ <div className='flex flex-col'>
+ <label className='form-label text-nowrap'>
+ Kategori Perusahaan
+ </label>
+ <div className='flex flex-col '>
+ <Controller
+ name='categoryPerusahaan'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataCategoryPerusahaan}
+ placeholder={'Pilih category perusahaan'}
+ />
+ )}
+ />
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih kategori perusahaan yang sesuai
+ </span>
+ )}
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.categoryPerusahaan?.message}
+ </div>
+ </div>
+ </div>
+ <div className='w-full flex flex-col'>
+ <label className='form-label text-nowrap'>Website</label>
+ <input
+ {...register('website')}
+ placeholder='Masukkan website'
+ type='text'
+ className='form-input'
+ />
+ {!isKonfirmasi && (
+ <span className='opacity-65 text-xs'>
+ isi dengan website perusahaan anda
+ </span>
+ )}
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.website?.message}
+ </div>
+ </div> */}
+
+ <div className=''>
+ {/* <div>
+ <ReCAPTCHA
+ ref={recaptchaRef}
+ sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE}
+ />
+ </div> */}
+ </div>
+ <div className='flex justify-center w-full '>
+ {/* <Button
+ colorScheme='red'
+ className='w-full md:w-fit'
+ type='submit'
+ >
+ Daftar Merchant{' '}
+ {<ChevronRightIcon className='w-5' color='white' />}
+ </Button> */}
+ {!isKonfirmasi && (
+ <div className='w-full'>
+ <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-full py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-center hover:bg-red-400'
+ >
+ <span className={` `}>Daftar Merchant</span>
+ {<ChevronRightIcon className='w-5' />}
+ </button>
+ </div>
+ )}
+ </div>
+ </form>
+ <PageContent path='/daftar-merchant' />
+ </div>
+ </div>
+ </MobileView>
+ </>
+ );
+ }
+);
+
+const validationSchema = Yup.object().shape({
+ bisnisType: Yup.string().required('Harus dipilih'),
+ name: Yup.string().required('Harus di-isi'),
+ address: Yup.string().required('Harus di-isi'),
+ state: Yup.string().required('Harus dipilih'),
+ city: Yup.string().required('Harus dipilih'),
+ district: Yup.string().required('Harus dipilih'),
+ subDistrict: Yup.string().required('Harus dipilih'),
+ zip: Yup.string().required('Harus di-isi'),
+ bank: Yup.string().required('Harus di-isi'),
+ rekening: Yup.string().required('Harus di-isi'),
+ accountNumber: Yup.string().required('Harus di-isi'),
+ 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'),
+ mobile: Yup.string().required('Harus di-isi'),
+});
+const defaultValues = {
+ name: '',
+ address: '',
+ state: '',
+ city: '',
+ district: '',
+ subDistrict: '',
+ zip: '',
+ email: '',
+ emailSales: '',
+ emailFinance: '',
+ bank: '',
+ rekening: '',
+ accountNumber: '',
+ phone: '',
+ mobile: '',
+ bisnisType: '',
+};
+
+export default CreateMerchant;
diff --git a/src/lib/merchant/components/InformasiVendor.jsx b/src/lib/merchant/components/InformasiVendor.jsx
new file mode 100644
index 00000000..d00f27ed
--- /dev/null
+++ b/src/lib/merchant/components/InformasiVendor.jsx
@@ -0,0 +1,748 @@
+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,
+ 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';
+import useAuth from '@/core/hooks/useAuth';
+import { Radio, RadioGroup, Stack, Checkbox, Button } from '@chakra-ui/react';
+import { EyeIcon } from '@heroicons/react/24/outline';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import Image from 'next/image';
+import ImageBanner from '~/components/ui/image';
+import { ChevronRightIcon } from '@heroicons/react/24/outline';
+import MobileView from '@/core/components/views/MobileView';
+import DesktopView from '@/core/components/views/DesktopView';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import odooApi from '~/libs/odooApi';
+import { formatValue } from 'react-currency-input-field';
+const InformasiVendor = forwardRef(({ handleIsError, isKonfirmasi }, 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,
+ });
+ const [categoryProduk, setCategoryProduk] = useState([]);
+ const [isExample, setIsExample] = useState(false);
+
+ const router = useRouter();
+
+ const auth = useAuth();
+ if (auth == false) {
+ router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`);
+ }
+ const dataTerhitungSejak = [
+ { value: 1, label: 'Terima PO' },
+ { value: 2, label: 'Barang Dikirimkan' },
+ { value: 3, label: 'Tukar Faktur' },
+ ];
+
+ const dataTempo = [
+ { value: 24, label: 'Tempo 14 Hari' },
+ { value: 25, label: 'Tempo 30 Hari' },
+ { value: 28, label: 'Tempo 60 Hari' },
+ { value: 31, label: 'Tempo 90 Hari' },
+ ];
+
+ const midIndex = Math.ceil(categoryProduk.length / 2);
+ const firstColumn = categoryProduk.slice(0, midIndex);
+ const secondColumn = categoryProduk.slice(midIndex);
+ const [kreditLimitFormat, setKreditLimitFormat] = useState();
+
+ useEffect(() => {
+ const loadData = async () => {
+ const data = await getMerchantApi();
+ if (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) => {
+ let value = e.target?.value ? e.target.value : e;
+
+ // Hapus semua karakter non-numeric
+ value = value.replace(/[^\d]/g, '');
+
+ // Format angka sebagai Rupiah tanpa mengubah nilai sebenarnya
+ const formattedValue1 = formatValue({
+ value: value,
+ groupSeparator: '.',
+ decimalSeparator: ',',
+ prefix: 'Rp ',
+ });
+
+ setKreditLimitFormat(formattedValue1);
+ setValue('kreditLimit', formattedValue1);
+ };
+
+ const [selectedIds, setSelectedIds] = useState(
+ watch('categoryProduk')
+ ? watch('categoryProduk').split(',').map(Number)
+ : []
+ // form.categoryProduk ? form.categoryProduk.split(',').map(Number) : [] // Parse string menjadi array angka
+ // [] // Parse string menjadi array angka
+ );
+ const handleCheckboxChange = (id) => {
+ const updatedSelected = selectedIds.includes(id)
+ ? selectedIds.filter((selectedId) => selectedId !== id)
+ : [...selectedIds, id];
+
+ setSelectedIds(updatedSelected);
+
+ // Mengubah array kembali menjadi string yang dipisahkan oleh koma
+ setValue('categoryProduk', updatedSelected.join(','));
+ };
+
+ const isChecked = (id) => selectedIds.includes(id);
+
+ const handleCheckboxPortalChange = (value) => {
+ setValue('isPengajuanTempo', `${value}`);
+ };
+
+ useEffect(() => {
+ if (!isKonfirmasi) {
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth',
+ });
+ }
+ }, []);
+
+ useEffect(() => {
+ const loadCategories = async () => {
+ let dataCategories = await odooApi('GET', '/api/v1/category/tree');
+ const formattedCategories = dataCategories.map((category) => ({
+ id: category.id,
+ name: category.name,
+ }));
+ // Simpan hasil ke state
+ setCategoryProduk(formattedCategories);
+ };
+ loadCategories();
+ }, []);
+
+ const onSubmitHandler = async (values) => {
+ const toastId = toast.loading('Mengirimkan formulir merchant...');
+ const data = {
+ harga_tayang: values.hargaTayang,
+ categoryProduk: values.categoryProduk,
+ merk_dagang: values.merkDagang,
+ is_pengajuan_tempo: values.isPengajuanTempo,
+ tempo_duration: values.tempoDuration,
+ kredit_limit: values.kreditLimit,
+ waktu_pengiriman: values.waktuPengiriman,
+ terhitung_sejak: values.terhitungSejak,
+ };
+ const create_leads = await createMerchantApi({ data });
+ if (create_leads) {
+ toast.dismiss(toastId);
+ isError(false);
+ toast.success('Berhasil menambahkan data');
+ reset();
+ // router.push('/+');
+ } else {
+ toast.dismiss(toastId);
+ toast.error('Gagal menambahkan data');
+ }
+ };
+
+ // const DownLoadSurat = () => {
+ // download surat dari /public/file/Surat Pernyataan Nomor Rekening.docx
+ // };
+
+ if (!auth) {
+ return;
+ }
+
+ 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 Vendor
+ </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'>
+ Harga Tayang (HET){' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <textarea
+ {...register('hargaTayang')}
+ placeholder='Jelaskan detail HET yang anda miliki'
+ type='textarea'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.hargaTayang?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className={`flex flex-row justify-between items-start`}>
+ <div className='w-2/5 text-nowrap'>
+ <label
+ className={`form-label ${isKonfirmasi && 'text-wrap'}`}
+ >
+ Tipe Kategori Produk yang Digunakan
+ </label>
+ {!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 gap-2'>
+ <div
+ className='flex flex-col gap-2'
+ // ref={categoryProdukRef}
+ >
+ {firstColumn.map((item) => (
+ <Checkbox
+ colorScheme='red'
+ key={item.id}
+ onChange={() => handleCheckboxChange(item.id)}
+ isChecked={isChecked(item.id)}
+ >
+ {item.name}
+ </Checkbox>
+ ))}
+ </div>
+ <div className='flex flex-col gap-2 '>
+ {secondColumn.map((item) => (
+ <Checkbox
+ colorScheme='red'
+ key={item.id}
+ isChecked={isChecked(item.id)}
+ onChange={() => handleCheckboxChange(item.id)}
+ >
+ {item.name}
+ </Checkbox>
+ ))}
+ </div>
+ </div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.categoryProduk?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>Merk Dagang</label>
+ </div>
+ <div className='w-3/5'>
+ <input
+ {...register('merkDagang')}
+ placeholder='Merk 1, Merk 2, Merk 3'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.merkDagang?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap '>
+ Apakah anda memiliki Form Pengajuan Tempo?
+ </label>
+ </div>
+ <div className='w-3/5 flex flex-col justify-start'>
+ <div className='flex gap-x-4'>
+ <RadioGroup
+ onChange={handleCheckboxPortalChange}
+ value={watch('isPengajuanTempo')}
+ >
+ <Stack direction='row'>
+ <Radio colorScheme='red' value='ada'>
+ Ya, ada
+ </Radio>
+ <Radio colorScheme='red' value='tidak'>
+ Tidak ada
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ </div>
+
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.isPengajuanTempo?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-center'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>Durasi Tempo</label>
+ {!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={`${!isKonfirmasi && 'w-[25%]'}`}>
+ <Controller
+ name='tempoDuration'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataTempo}
+ placeholder={'Pilih Durasi Tempo'}
+ />
+ )}
+ />
+
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoDuration?.message}
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Jumlah Kredit Limit
+ </label>
+ {!isKonfirmasi && (
+ <span className='opacity-65 text-xs'>
+ isi dengan kredit limit perusahaan anda
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ value={kreditLimitFormat}
+ onChange={handleKreditLimitChange}
+ placeholder='Masukkan jumlah kredit limit'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.kreditLimit?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Waktu Pengiriman
+ </label>
+ {!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'>
+ <input
+ {...register('waktuPengiriman')}
+ placeholder='Masukkan waktu pengiriman'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.waktuPengiriman?.message}
+ </div>
+ </div>
+ <div className='w-2/3 '>
+ <div className='flex flex-row items-center gap-2'>
+ <label className=' text-nowrap text-sm opacity-70 italic'>
+ terhitung sejak
+ </label>
+
+ <Controller
+ name='terhitungSejak'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataTerhitungSejak}
+ placeholder={'waktu pengiriman'}
+ />
+ )}
+ />
+ </div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.terhitungSejak?.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'>
+ {!isKonfirmasi && (
+ <h2 className='font-semibold mb-6 text-xl'>Informasi Vendor</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'>
+ Harga Tayang (HET){' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <input
+ {...register('hargaTayang')}
+ placeholder='Jelaskan detail HET yang anda miliki'
+ type='textarea'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.hargaTayang?.message}
+ </div>
+ </div>
+ </div>
+ <div
+ className={`flex flex-col gap-2 justify-between ${
+ isKonfirmasi ? 'items-start' : 'items-start'
+ }`}
+ >
+ <label className='form-label '>
+ Tipe Kategori Produk yang Digunakan
+ </label>
+ <div className='flex flex-col justify-between gap-2 '>
+ <div className='flex flex-col gap-2'>
+ {firstColumn.map((item) => (
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key={item.id}
+ onChange={() => handleCheckboxChange(item.id)}
+ isChecked={isChecked(item.id)}
+ >
+ {item.name}
+ </Checkbox>
+ ))}
+ </div>
+ <div className='flex flex-col gap-2'>
+ {secondColumn.map((item) => (
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key={item.id}
+ isChecked={isChecked(item.id)}
+ onChange={() => handleCheckboxChange(item.id)}
+ >
+ {item.name}
+ </Checkbox>
+ ))}
+ </div>
+ </div>
+
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.categoryProduk?.message}
+ </div>
+ </div>
+ <div className='w-full flex flex-col'>
+ <div className='w-full'>
+ <label className='form-label text-nowrap'>Merk Dagang</label>
+ <input
+ {...register('merkDagang')}
+ placeholder='Merk 1, Merk 2, Merk 3'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.merkDagang?.message}
+ </div>
+ </div>
+ </div>
+ <div className='w-full flex flex-col'>
+ <label className='form-label text-nowrap'>
+ Apakah anda memiliki Form Pengajuan Tempo?
+ </label>
+ <div className='flex gap-x-4'>
+ <RadioGroup
+ onChange={handleCheckboxPortalChange}
+ value={watch('isPengajuanTempo')}
+ >
+ <Stack direction='row'>
+ <Radio colorScheme='red' value='ada'>
+ Ya, ada
+ </Radio>
+ <Radio colorScheme='red' value='tidak'>
+ Tidak ada
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ </div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.isPengajuanTempo?.message}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-col'>
+ <label className='form-label text-nowrap'>Durasi Tempo</label>
+ <Controller
+ name='tempoDuration'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataTempo}
+ placeholder={'Pilih Durasi Tempo'}
+ />
+ )}
+ />
+
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoDuration?.message}
+ </div>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih durasi tempo yang anda inginkan
+ </span>
+ )}
+ </div>
+ <div className='w-full flex flex-col'>
+ <label className='form-label text-nowrap'>
+ Jumlah Kredit Limit
+ </label>
+ <input
+ value={kreditLimitFormat}
+ onChange={handleKreditLimitChange}
+ placeholder='Masukkan jumlah kredit limit'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.kreditLimit?.message}
+ </div>
+ {!isKonfirmasi && (
+ <span className='opacity-65 text-xs'>
+ isi dengan kredit limit perusahaan anda
+ </span>
+ )}
+ </div>
+ <div className='w-full flex flex-col'>
+ <label className='form-label text-nowrap'>
+ {' '}
+ Waktu Pengiriman
+ </label>
+ <div className='w-full flex flex-row gap-2'>
+ <div className='w-1/3'>
+ <input
+ {...register('waktuPengiriman')}
+ placeholder='Masukkan waktu pengiriman'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.waktuPengiriman?.message}
+ </div>
+ </div>
+ <div className='w-2/3 '>
+ <div className='flex flex-row items-center gap-2'>
+ <label className=' text-nowrap text-sm opacity-70 italic'>
+ terhitung sejak
+ </label>
+
+ <Controller
+ name='terhitungSejak'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataTerhitungSejak}
+ placeholder={'waktu pengiriman'}
+ />
+ )}
+ />
+ </div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.terhitungSejak?.message}
+ </div>
+ </div>
+ </div>
+ {!isKonfirmasi && (
+ <span className='opacity-65 text-xs'>
+ isi dengan waktu pengiriman anda
+ </span>
+ )}
+ </div>
+
+ <div className=''>
+ {/* <div>
+ <ReCAPTCHA
+ ref={recaptchaRef}
+ sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE}
+ />
+ </div> */}
+ </div>
+ <div className='flex justify-center w-full '>
+ {/* <Button
+ colorScheme='red'
+ className='w-full md:w-fit'
+ type='submit'
+ >
+ Daftar Merchant{' '}
+ {<ChevronRightIcon className='w-5' color='white' />}
+ </Button> */}
+ {!isKonfirmasi && (
+ <div className='w-full'>
+ <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-full py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-center hover:bg-red-400'
+ >
+ <span className={` `}>Langkah Selanjutnya</span>
+ {<ChevronRightIcon className='w-5' />}
+ </button>
+ </div>
+ )}
+ </div>
+ </form>
+ <PageContent path='/daftar-merchant' />
+ </div>
+ </div>
+ </MobileView>
+ </>
+ );
+});
+const validationSchema = Yup.object().shape({
+ categoryProduk: Yup.string().required('Harus di-pilih'),
+ merkDagang: Yup.string().required('Harus di-isi'),
+ isPengajuanTempo: Yup.string().required('Harus di-pilih'),
+ tempoDuration: Yup.string().required('Harus di-pilih'),
+ kreditLimit: Yup.string().required('Harus di-isi'),
+ waktuPengiriman: Yup.string().required('Harus di-isi'),
+ terhitungSejak: Yup.string().required('Harus di-pilih'),
+});
+const defaultValues = {
+ categoryProduk: '',
+ merkDagang: '',
+ isPengajuanTempo: '',
+ tempoDuration: '',
+ kreditLimit: '',
+ waktuPengiriman: '',
+ terhitungSejak: '',
+};
+
+export default InformasiVendor;
diff --git a/src/lib/merchant/components/Konfirmasi.jsx b/src/lib/merchant/components/Konfirmasi.jsx
new file mode 100644
index 00000000..ac5cb27b
--- /dev/null
+++ b/src/lib/merchant/components/Konfirmasi.jsx
@@ -0,0 +1,198 @@
+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 {
+ 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 InformasiVendor from './InformasiVendor';
+import SyaratDagang from './SyaratDagang';
+import Dokumen from './Dokumen';
+import createMerchantApi from '../api/createMerchantApi';
+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, 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 formRef = useRef(null);
+ const router = useRouter();
+ const handleDaftarMerchant = () => {
+ if (formRef.current) {
+ formRef.current(); // Memicu submit form di InformasiPerusahaan
+ }
+ };
+ const handleIsError = async (value) => {
+ if (!value) {
+ // goToNextStep();
+ const toastId = toast.loading('Mengirimkan formulir merchant...');
+ const data = {
+ merchant_request: true,
+ };
+ const create_leads = await createMerchantApi({ data });
+ if (create_leads) {
+ toast.dismiss(toastId);
+ toast.success('Berhasil medaftarkan merchant');
+ reset();
+ // router.push('/+');
+ } else {
+ toast.dismiss(toastId);
+ toast.error('Gagal menambahkan data');
+ }
+ }
+ reset();
+ router.push('/');
+ };
+
+ 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}
+ 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 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>
+ </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>
+ </>
+ )}
+ {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'>
+ <div className='flex flex-col justify-center items-start'>
+ <p className='font-semibold text-lg'>Informasi Perusahaan</p>
+ {/* <span className='text-xs opacity-70'>
+ Pastikan informasi usaha yang anda masukkan sudah sesuai
+ dengan data perusahaan anda
+ </span> */}
+ </div>
+ <div className='p-2 bg-gray-200'>
+ {isOpenInformasi ? (
+ <ChevronUpIcon
+ className='w-4'
+ onClick={() => setIsOpenInformasi(!isOpenInformasi)}
+ />
+ ) : (
+ <ChevronDownIcon
+ className='w-4'
+ onClick={() => setIsOpenInformasi(!isOpenInformasi)}
+ />
+ )}
+ </div>
+ </div>
+ {isOpenInformasi && <InformasiPerusahaan isKonfirmasi={true} />}
+ <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 flex-col gap-4'>
+ <div className='flex flex-row justify-between'>
+ <p className='font-semibold text-lg'>Informasi Vendor</p>
+ <div className='p-2 bg-gray-200'>
+ {isOpenKontak ? (
+ <ChevronUpIcon
+ className='w-4'
+ onClick={() => setIsOpenKontak(!isOpenKontak)}
+ />
+ ) : (
+ <ChevronDownIcon
+ className='w-4'
+ onClick={() => setIsOpenKontak(!isOpenKontak)}
+ />
+ )}
+ </div>
+ </div>
+ {isOpenKontak && <InformasiVendor isKonfirmasi={true} />}
+ <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 flex-col gap-4'>
+ <div className='flex flex-row justify-between'>
+ <p className='font-semibold text-lg'>Syarat Perdagangan</p>
+ <div className='p-2 bg-gray-200'>
+ {isOpenPengiriman ? (
+ <ChevronUpIcon
+ className='w-4'
+ onClick={() => setIsOpenPengiriman(!isOpenPengiriman)}
+ />
+ ) : (
+ <ChevronDownIcon
+ className='w-4'
+ onClick={() => setIsOpenPengiriman(!isOpenPengiriman)}
+ />
+ )}
+ </div>
+ </div>
+ {isOpenPengiriman && <SyaratDagang isKonfirmasi={true} />}
+ <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 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='full'
+ onClick={handleDaftarMerchant} // Memicu form submit
+ >
+ Daftar Merchant
+ </Button>
+ </div>
+ </form>
+ )}
+ </>
+ );
+};
+
+export default Konfirmasi;
diff --git a/src/lib/merchant/components/Merchant.jsx b/src/lib/merchant/components/Merchant.jsx
new file mode 100644
index 00000000..7323f14a
--- /dev/null
+++ b/src/lib/merchant/components/Merchant.jsx
@@ -0,0 +1,142 @@
+import React from 'react';
+import { useMemo, useState, useEffect, useRef } from 'react';
+import Image from '~/components/ui/image';
+import InformasiPerusahaan from './InformasiPerusahaan';
+import InformasiVendor from './InformasiVendor';
+import SyaratDagang from './SyaratDagang';
+import Dokumen from './Dokumen';
+import Konfirmasi from './Konfirmasi';
+import { getAuth } from '~/libs/auth';
+import { setAuth } from '@/core/utils/auth';
+import useAuth from '@/core/hooks/useAuth';
+import { useRouter } from 'next/router';
+import { Controller, useForm } from 'react-hook-form';
+import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline';
+import { Button, Checkbox, Spinner, Tooltip } from '@chakra-ui/react';
+import clsxm from '~/libs/clsxm';
+import { toast } from 'react-hot-toast';
+import useDevice from '@/core/hooks/useDevice';
+import odooApi from '@/core/api/odooApi';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import PageContent from '@/lib/content/components/PageContent';
+const Merchant = () => {
+ const { isDesktop, isMobile } = useDevice();
+ const [currentStep, setCurrentStep] = React.useState(0);
+ const NUMBER_OF_STEPS = 5;
+ const [isLoading, setIsLoading] = useState(false);
+ const [bigData, setBigData] = useState();
+ const [idTempo, setIdTempo] = useState(0);
+ const { control, watch, setValue } = useForm();
+ const auth = useAuth();
+ const router = useRouter();
+ const [BannerTempo, setBannerTempo] = useState();
+ const [notValid, setNotValid] = useState(false);
+ const [buttonSubmitClick, setButtonSubmitClick] = useState(false);
+
+ const [error, setError] = useState(false);
+
+ const handleIsError = (value) => {
+ if (!value) {
+ goToNextStep();
+ }
+ setError(value); // Memperbarui state berdasarkan isError
+ };
+ const stepDivs = [
+ <InformasiPerusahaan
+ handleIsError={handleIsError}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ <InformasiVendor
+ handleIsError={handleIsError}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ <SyaratDagang
+ handleIsError={handleIsError}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ <Konfirmasi handleIsError={handleIsError} />,
+ ];
+
+ const stepLabels = [
+ 'informasi_perusahaan',
+ 'kontak_person',
+ 'Pengiriman',
+ 'Referensi',
+ 'Konfirmasi',
+ ];
+
+ useEffect(() => {
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth',
+ });
+ }, [currentStep]);
+
+ useEffect(() => {
+ <InformasiPerusahaan buttonSubmitClick={buttonSubmitClick} />;
+ }, [buttonSubmitClick]);
+
+ const goToNextStep = () => {
+ setCurrentStep((prev) => (prev === NUMBER_OF_STEPS - 1 ? prev : prev + 1));
+ };
+
+ const goPrevStep = () => {
+ setCurrentStep((prev) => (prev === NUMBER_OF_STEPS - 1 ? prev : prev - 1));
+ };
+
+ useEffect(() => {
+ const getBanner = async () => {
+ const get = await odooApi('GET', '/api/v1/banner?type=banner-form-tempo');
+ // setBannerTempo(get[0].image);
+ setBannerTempo(
+ 'https://erp.indoteknik.com/api/image/x_banner.banner/x_banner_image/431'
+ );
+ };
+ getBanner();
+ }, []);
+ return (
+ <>
+ <div className='container flex flex-col items-center '>
+ {BannerTempo && (
+ <Image
+ src={BannerTempo}
+ alt='FORM Tempo'
+ width={500}
+ height={160}
+ className='w-full mt-6'
+ />
+ )}
+ <h1 className=' font-semibold text-center mb-6'>Form Pendafataran Merchant</h1>
+ <p
+ className={`text-center ${
+ isMobile ? 'w-full text-sm' : 'w-3/4 mb-4'
+ }`}
+ >
+ Pembayaran tempo adalah layanan pembayaran berjangka yang difasilitasi
+ indoteknik.com untuk konsumen akun bisnis yang terdaftar dengan waktu
+ pembayaran mulai dari 7, 14, 21 hingga 30 Hari.
+ </p>
+ </div>
+ <div
+ className={`h-[2px] w-full ${isMobile ? 'mt-4' : 'mb-4'} bg-gray_r-3`}
+ />
+
+ <div className={`container ${isMobile ? 'mt-4' : ''} flex flex-col`}>
+ <div>{stepDivs[currentStep]}</div>
+ {isDesktop && <section className='flex gap-10 mt-10'></section>}
+ {isMobile && (
+ <div className='h-[2px] bg-gray-300 w-[120%] inset-0 mt-4 mb-4 relative transform -translate-x-5'></div>
+ )}
+ <div
+ className={`flex ${
+ isMobile
+ ? 'flex-col justify-start items-start'
+ : 'flex-col justify-end items-end'
+ } mb-8 gap-2`}
+ ></div>
+ </div>
+ </>
+ );
+};
+
+export default Merchant;
diff --git a/src/lib/merchant/components/SyaratDagang.jsx b/src/lib/merchant/components/SyaratDagang.jsx
new file mode 100644
index 00000000..96681064
--- /dev/null
+++ b/src/lib/merchant/components/SyaratDagang.jsx
@@ -0,0 +1,822 @@
+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,
+ 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';
+import useAuth from '@/core/hooks/useAuth';
+import { Radio, RadioGroup, Stack, Checkbox, Button } from '@chakra-ui/react';
+import { EyeIcon } from '@heroicons/react/24/outline';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import Image from 'next/image';
+import ImageBanner from '~/components/ui/image';
+import { ChevronRightIcon } from '@heroicons/react/24/outline';
+import MobileView from '@/core/components/views/MobileView';
+import DesktopView from '@/core/components/views/DesktopView';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import odooApi from '~/libs/odooApi';
+const SyaratDagang = forwardRef(({ handleIsError, isKonfirmasi }, 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,
+ });
+ const [bigData, setbigData] = useState([]);
+ const [isExample, setIsExample] = useState(false);
+
+ const recaptchaRef = useRef(null);
+ const router = useRouter();
+
+ useEffect(() => {
+ const loadData = async () => {
+ const data = await getMerchantApi();
+ setbigData(data);
+ 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);
+ if (watch('sertifikatProduk') != false) {
+ setSelectedIds(watch('sertifikatProduk').split(',').map(Number));
+ }
+ if (watch('customSertifikatProduk')) {
+ // setSelectedIds([...selectedIds, 4]);
+ }
+ }
+ };
+
+ loadData();
+ }, []);
+ useEffect(() => {
+ if (!isKonfirmasi) {
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth',
+ });
+ }
+ }, []);
+ useImperativeHandle(ref, () => () => {
+ handleSubmit(onSubmitHandler)();
+ });
+ const auth = useAuth();
+ if (auth == false) {
+ router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`);
+ }
+
+ const dataGaransi = [
+ { value: 1, label: '6 Bulan Garansi' },
+ { value: 2, label: '1 Tahun Garansi' },
+ { value: 3, label: '2 Tahun Garansi' },
+ ];
+ const dataMinimumOrderQuantity = [
+ { value: 'dus', label: 'Dus' },
+ { value: 'lusin', label: 'Lusin' },
+ { value: 'minimum pembelian', label: 'Minimum pembelian' },
+ ];
+
+ const category_produk = [
+ { id: 0, name: 'TKDN' },
+ { id: 1, name: 'SNI' },
+ { id: 2, name: 'K3L' },
+ { id: 3, name: '' },
+ ];
+
+ const [selectedIds, setSelectedIds] = useState(
+ watch('sertifikatProduk')
+ ? watch('sertifikatProduk').split(',').map(Number)
+ : []
+ // form.sertifikatProduk ? form.sertifikatProduk.split(',').map(Number) : [] // Parse string menjadi array angka
+ // [] // Parse string menjadi array angka
+ );
+ const handleCheckboxChange = (id) => {
+ const updatedSelected = selectedIds.includes(id)
+ ? selectedIds.filter((selectedId) => selectedId !== id)
+ : [...selectedIds, id];
+
+ setSelectedIds(updatedSelected);
+
+ // Mengubah array kembali menjadi string yang dipisahkan oleh koma
+ setValue('sertifikatProduk', updatedSelected.join(','));
+ };
+ const custom_sertifikat_produk_handle = () => {
+ const updatedSelected = [...selectedIds, 3];
+
+ setSelectedIds(updatedSelected);
+
+ // Mengubah array kembali menjadi string yang dipisahkan oleh koma
+ setValue('sertifikatProduk', updatedSelected.join(','));
+ };
+
+ const isChecked = (id) => selectedIds.includes(id);
+
+ const handleCheckboxReturChange = (value) => {
+ setValue('isKembaliBarang', `${value}`);
+ };
+ const handleCheckboxOrderQuantityChange = (value) => {
+ setValue('isOrderQuantity', `${value}`);
+ };
+
+ const handleCheckboxTenggatWaktuChange = (value) => {
+ setValue('tenggatWaktu', `${value}`);
+ };
+
+ const onSubmitHandler = async (values) => {
+ const toastId = toast.loading('Mengirimkan formulir merchant...');
+ const data = {
+ is_kembali_barang: values.isKembaliBarang,
+ text_return: values.textReturn,
+ tenggat_waktu: values.tenggatWaktu,
+ custom_tenggat_waktu: values.customTenggatWaktu,
+ sertifikat_produk: values.sertifikatProduk,
+ custom_sertifikat_produk:
+ values.customSertifikatProduk == ''
+ ? false
+ : values.customSertifikatProduk,
+ tempo_garansi: values.tempoGaransi,
+ explain_garansi: values.explainGaransi,
+ is_order_quantity: values.isOrderQuantity,
+ minimum_pembelian: values.minimumPembelian,
+ };
+ 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
+ // };
+
+ if (!auth) {
+ return;
+ }
+ // Tetap di bagian atas, tidak boleh ada kondisi sebelum hook
+
+ 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 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 '>
+ <form
+ onSubmit={handleSubmit(onSubmitHandler)}
+ className='flex flex-col gap-4'
+ >
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap '>
+ Syarat Pengembalian Barang
+ </label>
+ </div>
+ <div className='w-3/5 flex flex-row justify-start'>
+ <div className='flex gap-x-4 flex-col w-full'>
+ <RadioGroup
+ onChange={handleCheckboxReturChange}
+ value={watch('isKembaliBarang')}
+ >
+ <Stack direction='column'>
+ <div className='flex flex-row text-nowrap gap-2'>
+ <Radio colorScheme='red' value='ya'>
+ Ya, dapat diretur
+ </Radio>
+ {watch('isKembaliBarang') == 'ya' && (
+ <textarea
+ {...register('textReturn')}
+ placeholder='jelaskan syarat pengembalian'
+ type='textarea'
+ className='form-input w-full'
+ />
+ )}
+ </div>
+ <Radio colorScheme='red' value='tidak'>
+ Tidak dapat diretur
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.isKembaliBarang?.message}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap '>
+ Tenggat Waktu Perubahan Harga
+ </label>
+ </div>
+ <div className='w-3/5 flex flex-row justify-start'>
+ <div className='flex gap-x-4 flex-col w-full'>
+ <RadioGroup
+ onChange={handleCheckboxTenggatWaktuChange}
+ value={watch('tenggatWaktu')}
+ >
+ <Stack direction='column'>
+ <Radio
+ colorScheme='red'
+ value='14'
+ onChange={() => setValue('customTenggatWaktu', ' ')}
+ >
+ 14 hari sejak data dikirimkan
+ </Radio>
+ <Radio
+ colorScheme='red'
+ value='30'
+ onChange={() => setValue('customTenggatWaktu', ' ')}
+ >
+ 30 hari sejak data dikirimkan
+ </Radio>
+ <div className='flex flex-row gap-2'>
+ <Radio colorScheme='red' value='custom'></Radio>
+ <input
+ {...register('customTenggatWaktu')}
+ placeholder='Masukkan jumlah hari untuk tenggat waktu'
+ type='text'
+ onFocus={() => setValue('tenggatWaktu', 'custom')}
+ className='form-input mt-2'
+ />
+ </div>
+ </Stack>
+ </RadioGroup>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tenggatWaktu?.message}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className={`flex flex-row justify-between items-start`}>
+ <div className='w-2/5 text-nowrap'>
+ <label
+ className={`form-label ${isKonfirmasi && 'text-wrap'}`}
+ >
+ Dokumen/Sertifikat yang Dimiliki Oleh Brand
+ </label>
+ {!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'>
+ <div
+ className='flex flex-col gap-2 w-full'
+ // ref={categoryProdukRef}
+ >
+ <Checkbox
+ colorScheme='red'
+ key={0}
+ onChange={() => handleCheckboxChange(0)}
+ isChecked={isChecked(0)}
+ >
+ TKDN
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key={1}
+ onChange={() => handleCheckboxChange(1)}
+ isChecked={isChecked(1)}
+ >
+ SNI
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key={2}
+ onChange={() => handleCheckboxChange(2)}
+ isChecked={isChecked(2)}
+ >
+ K3L
+ </Checkbox>
+ <div className='flex flex-row gap-2 w-full'>
+ <Checkbox
+ colorScheme='red'
+ key={3}
+ onChange={() => handleCheckboxChange(3)}
+ isChecked={isChecked(3)}
+ ></Checkbox>
+ <input
+ {...register('customSertifikatProduk')}
+ placeholder='Masukkan Dokumen/Sertifikat yang dimiliki oleh brand'
+ type='text'
+ onFocus={() => {
+ custom_sertifikat_produk_handle();
+ }}
+ // onFocus={() => handleCheckboxChange(4)}
+ className='form-input mt-2'
+ />
+ </div>
+ </div>
+ </div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.sertifikatProduk?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-center'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>Garansi</label>
+ {!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={`${!isKonfirmasi && 'w-[25%]'}`}>
+ <Controller
+ name='tempoGaransi'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataGaransi}
+ placeholder={'Pilih durasi garansi'}
+ />
+ )}
+ />
+
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoGaransi?.message}
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Jelaskan Garansi yang dimaksud!
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <textarea
+ {...register('explainGaransi')}
+ placeholder='Jelaskan bagian apa yang termasuk garansi'
+ type='textarea'
+ className='form-input'
+ rows={4}
+ cols={40}
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.explainGaransi?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap '>
+ Apakah Memiliki Minimum Order Quantity (MOQ)
+ </label>
+ </div>
+ <div className='w-3/5 flex flex-row justify-start'>
+ <div className='flex gap-x-4 flex-col w-full'>
+ <RadioGroup
+ onChange={handleCheckboxOrderQuantityChange}
+ value={
+ watch('minimumPembelian')
+ ? 'ya'
+ : watch('isOrderQuantity')
+ }
+ >
+ <Stack direction='column'>
+ <div className='flex flex-row text-nowrap gap-2'>
+ <Radio
+ colorScheme='red'
+ value='ya'
+ onChange={() => setValue('isOrderQuantity', 'ya')}
+ >
+ Ya
+ </Radio>
+
+ <Controller
+ name='minimumPembelian'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataMinimumOrderQuantity}
+ placeholder={
+ 'Pilih jenis minimum order quantity'
+ }
+ onFocus={() =>
+ setValue('isOrderQuantity', 'ya')
+ }
+ />
+ )}
+ />
+ </div>
+ <Radio
+ colorScheme='red'
+ value='tidak'
+ onChange={() => setValue('minimumPembelian', '')}
+ >
+ Tidak Ada
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.isOrderQuantity?.message}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ {!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>
+ )}
+ </form>
+ </div>
+ </div>
+ </DesktopView>
+ <MobileView>
+ <div className='container flex flex-col items-star py-4'>
+ {!isKonfirmasi && (
+ <h2 className='font-semibold mb-6 text-xl'>Syarat Perdagangan</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'>
+ Syarat Pengembalian Barang
+ </label>
+ <div className='flex gap-x-4 flex-col w-full'>
+ <RadioGroup
+ onChange={handleCheckboxReturChange}
+ value={watch('isKembaliBarang')}
+ >
+ <Stack direction='column'>
+ <div className='flex flex-row text-nowrap gap-2'>
+ <Radio colorScheme='red' value='ya'>
+ Ya, dapat diretur
+ </Radio>
+ {watch('isKembaliBarang') == 'ya' && (
+ <textarea
+ {...register('textReturn')}
+ placeholder='jelaskan syarat pengembalian'
+ type='textarea'
+ className='form-input w-full'
+ />
+ )}
+ </div>
+ <Radio colorScheme='red' value='tidak'>
+ Tidak dapat diretur
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.isKembaliBarang?.message}
+ </div>
+ </div>
+ </div>
+ </div>
+ <div className='w-full flex flex-col'>
+ <div className='w-full'>
+ <label className='form-label text-nowrap'>
+ Tenggat Waktu Perubahan Harga
+ </label>
+ <div className='flex gap-x-4 flex-col w-full'>
+ <RadioGroup
+ onChange={handleCheckboxTenggatWaktuChange}
+ value={watch('tenggatWaktu')}
+ >
+ <Stack direction='column'>
+ <Radio
+ colorScheme='red'
+ value='14'
+ onChange={() => setValue('customTenggatWaktu', ' ')}
+ >
+ 14 hari sejak data dikirimkan
+ </Radio>
+ <Radio
+ colorScheme='red'
+ value='30'
+ onChange={() => setValue('customTenggatWaktu', ' ')}
+ >
+ 30 hari sejak data dikirimkan
+ </Radio>
+ <div className='flex flex-row gap-2'>
+ <Radio colorScheme='red' value='custom'></Radio>
+ <input
+ {...register('customTenggatWaktu')}
+ placeholder='Masukkan jumlah hari untuk tenggat waktu'
+ type='text'
+ onFocus={() => setValue('tenggatWaktu', 'custom')}
+ className='form-input mt-2'
+ />
+ </div>
+ </Stack>
+ </RadioGroup>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tenggatWaktu?.message}
+ </div>
+ </div>
+ </div>
+ </div>
+ <div className='w-full flex flex-col'>
+ <div className='w-full'>
+ <label className='form-label text-nowrap'>
+ Dokumen/Sertifikat yang Dimiliki Oleh Brand
+ </label>
+ <div
+ className='flex flex-col gap-2 w-full'
+ // ref={categoryProdukRef}
+ >
+ <Checkbox
+ colorScheme='red'
+ key={0}
+ onChange={() => handleCheckboxChange(0)}
+ isChecked={isChecked(0)}
+ >
+ TKDN
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key={1}
+ onChange={() => handleCheckboxChange(1)}
+ isChecked={isChecked(1)}
+ >
+ SNI
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key={2}
+ onChange={() => handleCheckboxChange(2)}
+ isChecked={isChecked(2)}
+ >
+ K3L
+ </Checkbox>
+ <div className='flex flex-row gap-2 w-full'>
+ <Checkbox
+ colorScheme='red'
+ key={3}
+ onChange={() => handleCheckboxChange(3)}
+ isChecked={isChecked(3)}
+ ></Checkbox>
+ <input
+ {...register('customSertifikatProduk')}
+ placeholder='Masukkan Dokumen/Sertifikat yang dimiliki oleh brand'
+ type='text'
+ onFocus={() => {
+ custom_sertifikat_produk_handle();
+ }}
+ // onFocus={() => handleCheckboxChange(4)}
+ className='form-input mt-2'
+ />
+ </div>
+ </div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.sertifikatProduk?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className='w-full flex flex-col'>
+ <label className='form-label text-nowrap'>Garansi</label>
+ <div className='w-full flex flex-row gap-2'>
+ <Controller
+ name='tempoGaransi'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataGaransi}
+ placeholder={'Pilih durasi garansi'}
+ />
+ )}
+ />
+
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoGaransi?.message}
+ </div>
+ </div>
+ </div>
+ <div className='w-full flex flex-col'>
+ <label className='form-label text-nowrap'>
+ Jelaskan Garansi yang dimaksud!
+ </label>
+ <textarea
+ {...register('explainGaransi')}
+ placeholder='Jelaskan bagian apa yang termasuk garansi'
+ type='textarea'
+ className='form-input'
+ rows={4}
+ cols={40}
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.explainGaransi?.message}
+ </div>
+ </div>
+ <div className='w-full flex flex-col'>
+ <label className='form-label text-nowrap'>
+ Apakah Memiliki Minimum Order Quantity (MOQ)
+ </label>
+ <div className='flex gap-x-4 flex-col w-full'>
+ <RadioGroup
+ onChange={handleCheckboxOrderQuantityChange}
+ value={
+ watch('minimumPembelian')
+ ? 'ya'
+ : watch('isOrderQuantity')
+ }
+ >
+ <Stack direction='column'>
+ <div className='flex flex-row text-nowrap gap-2'>
+ <Radio
+ colorScheme='red'
+ value='ya'
+ onChange={() => setValue('isOrderQuantity', 'ya')}
+ >
+ Ya
+ </Radio>
+
+ <Controller
+ name='minimumPembelian'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={dataMinimumOrderQuantity}
+ placeholder={'Pilih jenis minimum order quantity'}
+ onFocus={() => setValue('isOrderQuantity', 'ya')}
+ />
+ )}
+ />
+ </div>
+ <Radio
+ colorScheme='red'
+ value='tidak'
+ onChange={() => setValue('minimumPembelian', '')}
+ >
+ Tidak Ada
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.isOrderQuantity?.message}
+ </div>
+ </div>
+ </div>
+
+ <div className=''>
+ {/* <div>
+ <ReCAPTCHA
+ ref={recaptchaRef}
+ sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE}
+ />
+ </div> */}
+ </div>
+ <div className='flex justify-center w-full '>
+ {/* <Button
+ colorScheme='red'
+ className='w-full md:w-fit'
+ type='submit'
+ >
+ Daftar Merchant{' '}
+ {<ChevronRightIcon className='w-5' color='white' />}
+ </Button> */}
+ {!isKonfirmasi && (
+ <div className='w-full'>
+ <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-full py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-center hover:bg-red-400'
+ >
+ <span className={` `}>Langkah Selanjutnya</span>
+ {<ChevronRightIcon className='w-5' />}
+ </button>
+ </div>
+ )}
+ </div>
+ </form>
+ <PageContent path='/daftar-merchant' />
+ </div>
+ </div>
+ </MobileView>
+ </>
+ );
+});
+const validationSchema = Yup.object().shape({
+ isKembaliBarang: Yup.string().required('Harus di-pilih'),
+ tenggatWaktu: Yup.string().required('Harus di-pilih'),
+ sertifikatProduk: Yup.string().required('Harus di-pilih'),
+ tempoGaransi: Yup.string().required('Harus di-pilih'),
+ explainGaransi: Yup.string().required('Harus di-isi'),
+ isOrderQuantity: Yup.string().required('Harus di-isi'),
+});
+const defaultValues = {
+ isKembaliBarang: '',
+ tenggatWaktu: '',
+ sertifikatProduk: '',
+ explainGaransi: '',
+ isOrderQuantity: '',
+};
+
+export default SyaratDagang;