diff options
Diffstat (limited to 'src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx')
| -rw-r--r-- | src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx | 1630 |
1 files changed, 1630 insertions, 0 deletions
diff --git a/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx new file mode 100644 index 00000000..25a3a7ee --- /dev/null +++ b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx @@ -0,0 +1,1630 @@ +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 odooApi from '~/libs/odooApi'; +import stateApi from '@/lib/address/api/stateApi.js'; +import cityApi from '@/lib/address/api/cityApi'; +import districtApi from '@/lib/address/api/districtApi'; +import subDistrictApi from '@/lib/address/api/subDistrictApi'; +import { Radio, RadioGroup, Stack, Checkbox } from '@chakra-ui/react'; +import { usePengajuanTempoStore } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; +import useDevice from '@/core/hooks/useDevice'; +import Divider from '@/core/components/elements/Divider/Divider'; +import { getAuth } from '~/libs/auth'; +import addressApi from '@/lib/address/api/addressApi'; +import { toast } from 'react-hot-toast'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import { useRouter } from 'next/router'; +const InformasiPerusahaan = ({ + chekValid, + buttonSubmitClick, + isKonfirmasi, +}) => { + const auth = getAuth(); + const router = useRouter(); + const { isDesktop, isMobile } = useDevice(); + const { control, watch, setValue, getValues } = useForm(); + const { form, errors, validate, updateForm } = usePengajuanTempoStore(); + const [states, setState] = useState([]); + const [cities, setCities] = useState([]); + const [districts, setDistricts] = useState([]); + const [subDistricts, setSubDistricts] = useState([]); + const [zips, setZips] = useState([]); + const [industries, setIndustries] = useState([]); + const [paymentTerm, setPaymentTerm] = useState([]); + const [selectedCategory, setSelectedCategory] = useState(''); + const [bersedia, setBersedia] = useState(null); + const [changeConfirmation, setChangeConfirmation] = useState(false); + const category_produk = [ + { id: 2040, name: 'Pengaman, Kesehatan & Keamanan' }, + { id: 2097, name: 'Perkakas Tangan, Listrik & Pneumatic' }, + { id: 2161, name: 'Mesin Industrial' }, + { id: 2222, name: 'Mesin Pertanian & Perkebunan' }, + { id: 2246, name: 'Mesin Pembersih & Janitorial' }, + { id: 2273, name: 'Cairan Berbahan Kimia' }, + { id: 2315, name: 'Perlengkapan Pengukuran & Pengujian' }, + { id: 2354, name: 'Peralatan Listrik & Elektronik' }, + { id: 2394, name: 'Perlengkapan Logistik & Gudang' }, + { id: 2420, name: 'Peralatan Kantor & Stationery' }, + { id: 2445, name: 'Komponen & Aksesoris' }, + { id: 2477, name: 'Peralatan Horeca & Food Service' }, + ]; + const radioOptions = [ + { label: '5.000.000', value: '5000000' }, + { label: '10.000.000', value: '10000000' }, + { label: '15.000.000', value: '15000000' }, + { label: '20.000.000', value: '20000000' }, + { label: '25.000.000', value: '25000000' }, + { label: '30.000.000', value: '30000000' }, + { label: '35.000.000', value: '35000000' }, + ]; + + useEffect(() => { + const loadState = async () => { + let dataState = await stateApi({ tempo: true }); + dataState = dataState.map((state) => ({ + value: state.id, + label: state.name, + })); + setState(dataState); + }; + loadState(); + }, []); + + const watchState = watch('state'); + useEffect(() => { + if (watchState) { + updateForm('state', `${watchState}`); + validate(); + const loadCities = async () => { + let dataCities = await cityApi({ stateId: watchState }); + dataCities = dataCities.map((city) => ({ + value: city.id, + label: city.name, + })); + setCities(dataCities); + }; + loadCities(); + } + }, [watchState]); + + const watchCity = watch('city'); + + // Untuk memperbarui form.city + useEffect(() => { + if (watchCity && form.city !== `${watchCity}`) { + updateForm('city', `${watchCity}`); + validate(); + } + }, [watchCity]); + + // Untuk memuat distrik + useEffect(() => { + if (watchCity) { + const loadDistricts = async () => { + let dataDistricts = await districtApi({ cityId: watchCity }); + dataDistricts = dataDistricts.map((district) => ({ + value: district.id, + label: district.name, + })); + setDistricts(dataDistricts); + }; + loadDistricts(); + } + }, [watchCity]); + + const watchDistrict = watch('district'); + useEffect(() => { + setValue('subDistrict', ''); + if (watchDistrict) { + updateForm('district', `${watchDistrict}`); + validate(); + const loadSubDistricts = async () => { + let dataSubDistricts = await subDistrictApi({ + districtId: watchDistrict, + }); + dataSubDistricts = dataSubDistricts.map((district) => ({ + value: district.id, + label: district.name, + })); + setSubDistricts(dataSubDistricts); + }; + loadSubDistricts(); + } + }, [watchDistrict, setValue]); + + const watchsubDistrict = watch('subDistrict'); + + useEffect(() => { + let kelurahan = ''; + let kecamatan = ''; + + if (watchDistrict) { + for (const data in districts) { + if (districts[data].value == watchDistrict) { + kecamatan = districts[data].label.toLowerCase(); + } + } + } + + if (watchsubDistrict) { + updateForm('subDistrict', `${watchsubDistrict}`); + validate(); + for (const data in subDistricts) { + if (subDistricts[data].value == watchsubDistrict) { + kelurahan = subDistricts[data].label.toLowerCase(); + } + } + const loadZip = async () => { + const response = await fetch( + `https://alamat.thecloudalert.com/api/cari/index/?keyword=${kelurahan}` + ); + + let dataMasuk = []; // Array untuk menyimpan kode pos yang sudah diproses + + const result = await response.json(); + + // Filter dan map data + const dataZips = result.result + .filter((zip) => zip.kecamatan.toLowerCase() === kecamatan) // Filter berdasarkan kecamatan + .filter((zip) => { + // Pastikan zip.kodepos belum ada di dataMasuk + if (dataMasuk.includes(zip.kodepos)) { + return false; // Jika sudah ada, maka skip (tidak akan ditambahkan) + } else { + dataMasuk.push(zip.kodepos); // Tambahkan ke dataMasuk + return true; // Tambahkan zip ke hasil + } + }) + .map((zip) => ({ + value: parseInt(zip.kodepos), + label: zip.kodepos, + })); + + setZips(dataZips); // Set hasil ke state + }; + + loadZip(); + } + }, [watchsubDistrict, setValue, subDistricts]); + + const watchZip = watch('zip'); + useEffect(() => { + if (watchZip) { + updateForm('zip', `${watchZip}`); + validate(); + } + }, [watchZip]); + + useEffect(() => { + const loadIndustries = async () => { + const dataIndustries = await odooApi('GET', '/api/v1/partner/industry'); + setIndustries( + dataIndustries?.map((o) => ({ + value: o.id, + label: o.name, + category: o.category, + })) + ); + }; + loadIndustries(); + }, []); + useEffect(() => { + const selectedIndustryType = industries.find( + (industry) => industry.value === watch('industryId') + ); + if (selectedIndustryType) { + updateForm('industryId', `${selectedIndustryType?.value}`); + validate(); + setSelectedCategory(selectedIndustryType.category); + } + }, [watch('industryId'), industries]); + + useEffect(() => { + const loadPaymentTerm = async () => { + const dataPaymentTerm = [ + { id: 29, name: 'Tempo 7 Hari' }, + { id: 24, name: 'Tempo 14 Hari' }, + { id: 32, name: 'Tempo 21 Hari' }, + { id: 25, name: 'Tempo 30 Hari' }, + ]; + setPaymentTerm( + dataPaymentTerm?.map((o) => ({ + value: o.id, + label: o.name, + })) + ); + }; + loadPaymentTerm(); + }, []); + useEffect(() => { + const selectedPaymentTerm = paymentTerm.find( + (industry) => industry.value === watch('tempoDuration') + ); + if (selectedPaymentTerm) { + updateForm('tempoDuration', `${selectedPaymentTerm?.value}`); + validate(); + } + }, [watch('tempoDuration'), paymentTerm]); + + const estimasiValue = watch('estimasi'); + const tempoLimitValue = watch('tempoLimit'); + + // Memformat angka menjadi format rupiah + const formatRupiah = (value) => { + if (!value) return ''; + const numberString = value.replace(/[^0-9]/g, ''); // Menghapus karakter non-digit + return numberString + ? 'Rp ' + new Intl.NumberFormat('id-ID').format(numberString) + : ''; + }; + + const handleChange = (e) => { + const value = e.target.value; + const formattedValue = formatRupiah(value); + updateForm('estimasi', formattedValue.replace(/^Rp\s*/, '')); + validate(); + }; + + const [isCustom, setIsCustom] = React.useState(false); + const [tempoLimitValueEx, setTempoLimitValueEx] = React.useState(''); + const handleCheckboxBersediaChange = (value) => { + // if (value === 'bersedia') { + // setBersedia(true); + // } else if (value === 'tidakBersedia') { + // setBersedia(false); + // } + // updateForm('bersedia', `${value === 'bersedia'}`); + updateForm('bersedia', `${value}`); + validate(); + }; + const handleCheckboxPortalChange = (value) => { + // if (value === 'bersedia') { + // setBersedia(true); + // } else if (value === 'tidakBersedia') { + // setBersedia(false); + // } + // updateForm('bersedia', `${value === 'bersedia'}`); + updateForm('portal', `${value}`); + validate(); + }; + const [selectedIds, setSelectedIds] = useState( + form.categoryProduk ? form.categoryProduk.split(',').map(Number) : [] // 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 + updateForm('categoryProduk', updatedSelected.join(',')); + validate(); + }; + + useEffect(() => { + if (form.categoryProduk) { + setSelectedIds(form.categoryProduk.split(',').map(Number)); // Parse string menjadi array angka + } + }, [form.categoryProduk]); + const isChecked = (id) => selectedIds.includes(id); + + const handleInputChange = (event) => { + const { name, value } = event.target; + updateForm(name, value); + validate(); + }; + + const midIndex = Math.ceil(category_produk.length / 2); + const firstColumn = category_produk.slice(0, midIndex); + const secondColumn = category_produk.slice(midIndex); + const isFormValid = useMemo(() => Object.keys(errors).length === 0, [errors]); + + const nameRef = useRef(null); + const industry_idRef = useRef(null); + const streetRef = useRef(null); + const stateRef = useRef(null); + const cityRef = useRef(null); + const districtRef = useRef(null); + const subDistrictRef = useRef(null); + const zipRef = useRef(null); + const mobileRef = useRef(null); + const bankNameRef = useRef(null); + const accountNameRef = useRef(null); + const accountNumberRef = useRef(null); + const estimasiRef = useRef(null); + const tempoDurationRef = useRef(null); + const bersediaRef = useRef(null); + const portalRef = useRef(null); + const categoryProdukRef = useRef(null); + const tempoLimitRef = useRef(null); + + useEffect(() => { + const options = { + behavior: 'smooth', + block: 'center', + }; + const loadIndustries = async () => { + if (!isFormValid) { + if (errors.name && nameRef.current) { + nameRef.current.scrollIntoView(options); + return; + } + if (errors.industryId && industry_idRef.current) { + industry_idRef.current.scrollIntoView(options); + return; + } + if (errors.street && streetRef.current) { + streetRef.current.scrollIntoView(options); + return; + } + if (errors.state && stateRef.current) { + stateRef.current.scrollIntoView(options); + return; + } + if (errors.city && cityRef.current) { + cityRef.current.scrollIntoView(options); + return; + } + if (errors.district && districtRef.current) { + districtRef.current.scrollIntoView(options); + return; + } + if (errors.subDistrict && subDistrictRef.current) { + subDistrictRef.current.scrollIntoView(options); + return; + } + if (errors.zip && zipRef.current) { + zipRef.current.scrollIntoView(options); + return; + } + if (errors.mobile && mobileRef.current) { + mobileRef.current.scrollIntoView(options); + return; + } + if (errors.bankName && bankNameRef.current) { + bankNameRef.current.scrollIntoView(options); + return; + } + if (errors.accountName && accountNameRef.current) { + accountNameRef.current.scrollIntoView(options); + return; + } + if (errors.accountNumber && accountNumberRef.current) { + accountNumberRef.current.scrollIntoView(options); + return; + } + if (errors.estimasi && estimasiRef.current) { + estimasiRef.current.scrollIntoView(options); + return; + } + if (errors.tempoDuration && tempoDurationRef.current) { + tempoDurationRef.current.scrollIntoView(options); + return; + } + if (errors.bersedia && bersediaRef.current) { + bersediaRef.current.scrollIntoView(options); + return; + } + if (errors.portal && portalRef.current) { + portalRef.current.scrollIntoView(options); + return; + } + if (errors.categoryProduk && categoryProdukRef.current) { + categoryProdukRef.current.scrollIntoView(options); + return; + } + if (errors.tempoLimit && tempoLimitRef.current) { + tempoLimitRef.current.scrollIntoView(options); + return; + } + } + }; + loadIndustries(); + }, [buttonSubmitClick, chekValid]); + useEffect(() => { + if (form.industryId) { + setValue('industryId', parseInt(form.industryId)); + } + if (form.state) { + setValue('state', parseInt(form.state)); + } + + if (form.district) { + setValue('district', parseInt(form.district)); + } + if (form.subDistrict) { + setValue('subDistrict', parseInt(form.subDistrict)); + } + if (form.zip) { + setValue('zip', parseInt(form.zip)); + } + if (form.tempoDuration) { + setValue('tempoDuration', parseInt(form.tempoDuration)); + } + if (form.tempoLimit) { + setValue('tempoLimit', form.tempoLimit); + } + if (form.tempoLimit) { + const isValueInOptions = radioOptions.some( + (option) => option.value === form.tempoLimit + ); + + if (isValueInOptions) { + setValue('tempoLimit', form.tempoLimit); // Set value dari radio options + setIsCustom(false); // Pastikan custom tidak aktif + } else { + setValue('tempoLimit', 'custom'); // Set value ke custom jika tidak termasuk dalam options + setIsCustom(true); // Aktifkan custom input + setTempoLimitValueEx(form.tempoLimit); // Set nilai input custom ke form.tempoLimit + } + } + }, [form]); + useEffect(() => { + if (form.city) { + setValue('city', parseInt(form.city)); + } + }, [form.city]); + useEffect(() => { + const loadProfile = async () => { + try { + const dataProfile = await addressApi({ id: auth.parentId }); + if (dataProfile.name) { + updateForm('name', dataProfile.name); + } + if (dataProfile.street) { + updateForm('street', dataProfile.street); + } + if (dataProfile.stateId.id) { + updateForm('state', `${dataProfile.stateId.id}`); + } + if (dataProfile.city.id) { + updateForm('city', `${dataProfile.city.id}`); + } + if (dataProfile.district.id) { + updateForm('district', `${dataProfile.district.id}`); + } + if (dataProfile.subDistrict.id) { + updateForm('subDistrict', `${dataProfile.subDistrict.id}`); + } + if (dataProfile.zip) { + updateForm('zip', dataProfile.zip); + } + if (dataProfile.mobile) { + updateForm('mobile', dataProfile.mobile.replace(/\D/g, '')); + } else { + setChangeConfirmation(true); + } + if (!dataProfile.email) { + setChangeConfirmation(true); + } + } catch (error) { + console.error('Error loading profile:', error); + } finally { + validate(); + } + }; + + if (auth?.parentId) { + loadProfile(); + } + }, [auth?.parentId]); + useEffect(() => { + const loadProfile = async () => { + try { + const dataProfile = await addressApi({ id: auth.parentId }); + setValue('industryId', parseInt(dataProfile.industryId)); + setValue('state', parseInt(dataProfile.stateId.id)); + setValue('city', parseInt(dataProfile.city.id)); + setValue('district', parseInt(dataProfile.district.id)); + setValue('subDistrict', parseInt(dataProfile.subDistrict.id)); + } catch (error) { + console.error('Error loading profile:', error); + } + }; + + if (auth?.parentId) { + loadProfile(); + } + }, [auth?.parentId, setValue]); + + const handleLengkapiData = () => { + router.push('/my/profile'); + }; + return ( + <> + <BottomPopup + active={changeConfirmation} + close={() => { + toast.error( + 'Mohon lengkapi data perusahaan sebelum melakukan pengajuan tempo' + ); + }} + title='Data Perusahaan Anda Belum Lengkap' + > + <div className='leading-7 text-gray_r-12/80'> + Mohon lengkapi data perusahaan sebelum melakukan pengajuan tempo + </div> + <div className='flex mt-6 gap-x-4 md:justify-end'> + <button + className='btn-solid-red flex-1 md:flex-none' + type='button' + onClick={handleLengkapiData} + > + Lengkapi Data + </button> + <button + className='btn-light flex-1 md:flex-none' + type='button' + onClick={() => { + toast.error( + 'Mohon lengkapi data perusahaan sebelum melakukan pengajuan tempo' + ); + }} + > + Batal + </button> + </div> + </BottomPopup> + {isDesktop && ( + <div className=''> + <h1 className={`font-bold ${isKonfirmasi ? 'text-xl' : ''}`}> + Informasi Perusahaan + </h1> + <form className='flex flex-col w-full '> + <div className='w-full grid grid-row-2 gap-5'> + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Nama Perusahaan + </label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + isi detail perusahaan sesuai dengan nama yang terdaftar{' '} + </span> + )} + </div> + <div className='w-3/5'> + <input + id='name' + name='name' + placeholder='Masukkan nama perusahaan' + type='text' + className='form-input' + disabled={true} + aria-invalid={errors.name} + value={form.name} + ref={nameRef} + onChange={handleInputChange} + /> + {/* {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Format: PT. INDOTEKNIK DOTCOM GEMILANG + </span> + )} */} + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.name} + </div> + )} + </div> + </div> + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5' ref={industry_idRef}> + <label className='form-label text-nowrap'>Industri</label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih jenis industri perusahaan anda + </span> + )} + </div> + <div className='w-3/5'> + <Controller + name='industryId' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={industries} + placeholder={'Pilih industri perusahaan anda'} + /> + )} + /> + {!isKonfirmasi && selectedCategory && ( + <span className='text-gray_r-11 text-xs opacity-60'> + Kategori : {selectedCategory} + </span> + )} + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.industryId} + </div> + )} + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5 text-nowrap'> + <label className='form-label '>Alamat Perusahaan</label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + alamat sesuai dengan alamat kantor pusat + </span> + )} + </div> + <div className='w-3/5 flex gap-3 flex-col'> + <div> + <input + id='street' + name='street' + ref={streetRef} + placeholder='Masukkan alamat lengkap perusahaan' + type='text' + value={form.street} + className='form-input' + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.street} + </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={`${isKonfirmasi ? 'w-full' : 'w-full'}`} + ref={stateRef} + > + <Controller + name='state' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={states} + placeholder='Provinsi' + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.state} + </div> + )} + </div> + <div + className={`${isKonfirmasi ? 'w-full' : 'w-full'}`} + ref={cityRef} + > + <Controller + name='city' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={cities} + disabled={!watchState} + placeholder='Kota' + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.city} + </div> + )} + </div> + </div> + <div + className={`flex-row flex gap-2 justify-between ${ + isKonfirmasi ? 'w-full' : 'w-3/5' + }`} + > + <div className='w-full' ref={districtRef}> + <Controller + name='district' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={districts} + disabled={!watchState || !watchCity} + placeholder='Kecamatan' + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.district} + </div> + )} + </div> + <div className='w-full' ref={subDistrictRef}> + <Controller + name='subDistrict' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={subDistricts} + disabled={!watchDistrict} + placeholder='Kelurahan' + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.district} + </div> + )} + </div> + <div className='w-full' ref={zipRef}> + <Controller + name='zip' + control={control} + render={(props) => ( + <> + {/* Jika zips tidak kosong, tampilkan dropdown */} + {zips.length > 0 ? ( + <HookFormSelect + {...props} + options={zips} + disabled={!watchsubDistrict} + placeholder='Zip' + /> + ) : ( + // Jika zips kosong, tampilkan input manual + <input + id='zip' + name='zip' + ref={zipRef} + placeholder='Kode Pos' + type='number' + disabled={!watchsubDistrict} + value={form.zip} + className='form-input' + onChange={handleInputChange} + /> + )} + </> + )} + /> + + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.zip} + </div> + )} + </div> + </div> + {/* <div className='w-1/3'> + <input + id='zip' + name='zip' + ref={zipRef} + placeholder='Kode Pos' + type='number' + disabled={!watchsubDistrict} + value={form.zip} + className='form-input' + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.zip} + </div> + )} + </div> */} + </div> + </div> + </div> + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5 text-nowrap'> + <label className='form-label '>No. HP Perusahaan</label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + isi no telfon perusahaan yang sesuai + </span> + )} + </div> + <div className='w-3/5'> + <input + id='mobile' + name='mobile' + ref={mobileRef} + placeholder='Masukkan nomor telfon perusahaan' + type='tel' + value={form.mobile} + className='form-input' + aria-invalid={errors.mobile} + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.mobile} + </div> + )} + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className=' w-2/5 text-nowrap'> + <label className='form-label'>Data Bank</label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Isi detail data bank perusahaan anda + </span> + )} + </div> + <div className='w-3/5 flex gap-3 flex-row'> + <div> + <input + id='bankName' + name='bankName' + ref={bankNameRef} + placeholder='Nama bank' + type='text' + value={form.bankName} + className='form-input' + onChange={handleInputChange} + /> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Format: BCA, Mandiri, CIMB, BNI dll + </span> + )} + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.bankName} + </div> + )} + </div> + <div> + <input + id='accountName' + name='accountName' + ref={accountNameRef} + placeholder='Nama Rekening' + type='text' + value={form.accountName} + className='form-input' + onChange={handleInputChange} + /> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Format: John Doe + </span> + )} + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountName} + </div> + )} + </div> + <div> + <input + id='accountNumber' + name='accountNumber' + ref={accountNumberRef} + placeholder='Nomor Rekening Bank' + type='text' + value={form.accountNumber} + className='form-input' + onChange={handleInputChange} + /> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Format: 01234567896 + </span> + )} + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountNumber} + </div> + )} + </div> + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5 text-nowrap'> + <label className='form-label '> + Website <span className=' opacity-60'>(Opsional)</span> + </label> + </div> + <div className='w-3/5'> + <input + id='website' + name='website' + placeholder='www.indoteknik.com' + type='text' + value={form.website} + className='form-input' + onChange={handleInputChange} + /> + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5 text-nowrap'> + <label className='form-label text-wrap'> + Estimasi Pembelian pertahun{' '} + <span className=' opacity-60 '>(Opsional)</span> + </label> + </div> + <div className='w-3/5'> + <div className='relative'> + <input + id='estimasi' + name='estimasi' + ref={estimasiRef} + // {...register('estimasi', { + // setValueAs: (value) => value.replace(/^Rp\s*/, ''), // Menyimpan hanya angka + // })} + placeholder='Isi estimasi pembelian produk pertahun' + type='text' + className='form-input' // padding untuk memberi ruang untuk "RP" + value={formatRupiah(form.estimasi)} + onChange={handleChange} // Mengatur perubahan input + /> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.estimasi} + </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> + <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-[75%]' : 'w-[25%]'}`} + ref={tempoDurationRef} + > + {/* <RadioGroup + onChange={onChangeTempoDuration} + value={form.tempoDuration} + > + <Stack direction='column' className=''> + <Radio colorScheme='red' value='7'> + 7 Hari + </Radio> + <Radio colorScheme='red' value='14' className=''> + 14 Hari + </Radio> + <Radio colorScheme='red' value='30' className=''> + 30 Hari + </Radio> + </Stack> + </RadioGroup> */} + <Controller + name='tempoDuration' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={paymentTerm} + placeholder={'Pilih Durasi Tempo'} + /> + )} + /> + + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.tempoDuration} + </div> + )} + </div> + </div> + <div className='text-red-500 text-xs mt-2'> + **Durasi tempo dapat berbeda sesuai dengan verifikasi oleh + tim Indoteknik.com + </div> + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5'> + <label className='form-label text-wrap '> + Apakah terdapat vendor portal pada perusahaan anda? + </label> + </div> + <div className='w-3/5 flex flex-col justify-start'> + <div className='flex gap-x-4' ref={portalRef}> + <RadioGroup + onChange={handleCheckboxPortalChange} + value={form.portal} + > + <Stack direction='row'> + <Radio colorScheme='red' value='ada'> + Ya, ada + </Radio> + <Radio colorScheme='red' value='tidak'> + Tidak ada + </Radio> + </Stack> + </RadioGroup> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.portal} + </div> + )} + </div> + </div> + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5'> + <label className='form-label text-wrap '> + Apakah bersedia transaksi via website? + </label> + </div> + <div className='w-3/5 flex flex-col justify-start'> + <div className='flex gap-x-4' ref={bersediaRef}> + <RadioGroup + onChange={handleCheckboxBersediaChange} + value={form.bersedia} + > + <Stack direction='row'> + <Radio colorScheme='red' value='bersedia'> + Saya bersedia + </Radio> + <Radio colorScheme='red' value='tidakBersedia'> + Tidak bersedia + </Radio> + </Stack> + </RadioGroup> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.bersedia} + </div> + )} + </div> + </div> + + <div + className={`flex flex-row justify-between ${ + isKonfirmasi ? 'items-center' : 'items-start' + }`} + > + <div className='w-2/5 text-nowrap'> + <label className='form-label '> + Kategori Produk yang Digunakan + </label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih produk bisa lebih dari 1 + </span> + )} + </div> + <div className='w-3/5 flex flex-col'> + <div className='flex flex-row justify-between'> + <div + className='flex flex-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> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.categoryProduk} + </div> + )} + </div> + </div> + </div> + </form> + </div> + )} + {isMobile && ( + <div className='text-sm'> + <h1 + className={`font-bold py-4 mt-8 ${ + isKonfirmasi ? 'hidden' : 'text-xl' + }`} + > + Informasi Perusahaan + </h1> + <form className='flex flex-col w-full '> + <div className='w-full grid grid-row-2 gap-4'> + <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label text-nowrap'> + Nama Perusahaan + </label> + <input + id='name' + name='name' + placeholder='Format: PT. INDOTEKNIK DOTCOM GEMILANG' + type='text' + className='form-input' + aria-invalid={errors.name} + value={form.name} + ref={nameRef} + onChange={handleInputChange} + /> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + isi detail perusahaan sesuai dengan nama yang terdaftar{' '} + </span> + )} + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.name} + </div> + )} + </div> + + <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label text-nowrap'>Industri</label> + <div className='w-full' ref={industry_idRef}> + <Controller + name='industryId' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={industries} + placeholder={ + 'Pilih Industri yang sesuai dengan perusahaan' + } + /> + )} + /> + </div> + {!isKonfirmasi && selectedCategory && ( + <span className='text-gray_r-11 text-xs opacity-60'> + Kategori : {selectedCategory} + </span> + )} + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.industryId} + </div> + )} + </div> + + <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label '>Alamat Perusahaan</label> + <input + id='street' + name='street' + ref={streetRef} + placeholder='Masukkan alamat lengkap perusahaan' + type='text' + value={form.street} + className='form-input' + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.street} + </div> + )} + <div className='w-full text-warp gap-3 flex flex-col'> + <div className='sub-alamat flex flex-row w-full gap-3 '> + <div className='w-full' ref={stateRef}> + <Controller + name='state' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={states} + placeholder='Provinsi' + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.state} + </div> + )} + </div> + <div className='w-full' ref={cityRef}> + <Controller + name='city' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={cities} + disabled={!watchState} + placeholder='Kota' + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.city} + </div> + )} + </div> + </div> + <div className='flex flex-row gap-3'> + <div className='w-full' ref={districtRef}> + <Controller + name='district' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={districts} + disabled={!watchCity} + placeholder='Kecamatan' + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.district} + </div> + )} + </div> + <div className='w-full' ref={subDistrictRef}> + <Controller + name='subDistrict' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={subDistricts} + disabled={!watchDistrict} + placeholder='Kelurahan' + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.district} + </div> + )} + </div> + <div className='w-full'> + <Controller + name='zip' + control={control} + render={(props) => ( + <> + {/* Jika zips tidak kosong, tampilkan dropdown */} + {zips.length > 0 ? ( + <HookFormSelect + {...props} + options={zips} + disabled={!watchsubDistrict} + placeholder='Zip' + /> + ) : ( + // Jika zips kosong, tampilkan input manual + <input + id='zip' + name='zip' + ref={zipRef} + placeholder='Kode Pos' + type='number' + disabled={!watchsubDistrict} + value={form.zip} + className='form-input' + onChange={handleInputChange} + /> + )} + </> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.zip} + </div> + )} + </div> + </div> + </div> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Isi detail alamat sesuai dengan yang terdaftar + </span> + )} + </div> + + <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label '>No. HP Perusahaan</label> + <input + id='mobile' + name='mobile' + ref={mobileRef} + placeholder='Format: 08123456789 / (021) 123 4567' + type='tel' + value={form.mobile} + className='form-input' + aria-invalid={errors.mobile} + onChange={handleInputChange} + /> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Isi detail perusahaan sesuai dengan nama yang terdaftar + </span> + )} + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.mobile} + </div> + )} + </div> + + <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label'>Data Bank</label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Isi data bank perusahaan sesuai dengan yang terdaftar + </span> + )} + <div className='flex gap-3 flex-row'> + <div> + <input + id='bankName' + name='bankName' + ref={bankNameRef} + placeholder='Nama bank' + type='text' + value={form.bankName} + className='form-input' + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.bankName} + </div> + )} + </div> + <div> + <input + id='accountName' + name='accountName' + ref={accountNameRef} + placeholder='Nama Rekening' + type='text' + value={form.accountName} + className='form-input' + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountName} + </div> + )} + </div> + <div> + <input + id='accountNumber' + name='accountNumber' + ref={accountNumberRef} + placeholder='Nomor Rekening' + type='text' + value={form.accountNumber} + className='form-input' + onChange={handleInputChange} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountNumber} + </div> + )} + </div> + </div> + </div> + + <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label '> + Website <span className=' opacity-60'>(Opsional)</span> + </label> + <input + id='website' + name='website' + placeholder='Format: www.indoteknik.com' + type='text' + value={form.website} + className='form-input' + onChange={handleInputChange} + /> + </div> + + <div className='flex flex-col gap-2 justify-between items-start'> + <label className='form-label '> + Estimasi Pembelian pertahun{' '} + <span className=' opacity-60'>(Opsional)</span> + </label> + <input + id='estimasi' + name='estimasi' + ref={estimasiRef} + // {...register('estimasi', { + // setValueAs: (value) => value.replace(/^Rp\s*/, ''), // Menyimpan hanya angka + // })} + placeholder='Isi estimasi pembelian produk pertahun' + type='text' + className='form-input' // padding untuk memberi ruang untuk "RP" + value={formatRupiah(form.estimasi)} + onChange={handleChange} // Mengatur perubahan input + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.estimasi} + </div> + )} + </div> + <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div> + <div className='flex flex-col gap-2 justify-start items-start'> + <label className='form-label text-nowrap'>Durasi Tempo</label> + <div className='w-full' ref={tempoDurationRef}> + <Controller + name='tempoDuration' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={paymentTerm} + placeholder={'Pilih Durasi Tempo'} + /> + )} + /> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.tempoDuration} + </div> + )} + </div> + </div> + + <div className='text-red-500 text-xs'> + **Durasi tempo dapat berbeda dengan verifikasi oleh tim + indoteknik.com + </div> + <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div> + + <div className='flex flex-col gap justify-between items-start'> + <label className='form-label text-wrap '> + Apakah terdapat vendor portal pada perusahaan anda? + </label> + <div className='flex gap-x-4' ref={bersediaRef}> + <RadioGroup + size='sm' + onChange={handleCheckboxPortalChange} + value={form.portal} + > + <Stack direction='col'> + <Radio colorScheme='red' value='ada'> + Ya, ada + </Radio> + <Radio colorScheme='red' value='tidak'> + Tidak ada + </Radio> + </Stack> + </RadioGroup> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.portal} + </div> + )} + </div> + <div className='flex flex-col gap justify-between items-start'> + <label className='form-label text-wrap '> + Apakah bersedia transaksi via website? + </label> + <div className='flex gap-x-4' ref={bersediaRef}> + <RadioGroup + size='sm' + onChange={handleCheckboxBersediaChange} + value={form.bersedia} + > + <Stack direction='col'> + <Radio colorScheme='red' value='bersedia'> + Saya bersedia + </Radio> + <Radio colorScheme='red' value='tidakBersedia'> + Tidak bersedia + </Radio> + </Stack> + </RadioGroup> + </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.bersedia} + </div> + )} + </div> + <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div> + + <div + className={`flex flex-col gap-2 justify-between ${ + isKonfirmasi ? 'items-start' : 'items-start' + }`} + > + <label className='form-label '> + Kategori Produk yang Digunakan + </label> + <div className='flex flex-col justify-between gap-2 '> + <div className='flex flex-col gap-2' ref={categoryProdukRef}> + {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> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.categoryProduk} + </div> + )} + </div> + </div> + </form> + </div> + )} + </> + ); +}; + +export default InformasiPerusahaan; |
