From 661d742193b62aeb3d2a2350433bdd3714667625 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 18 Oct 2024 10:39:40 +0700 Subject: add kontak perusahaan --- .../register/stores/usePengajuanTempoStore.ts | 89 ++- src-migrate/types/tempo.ts | 16 +- src-migrate/validations/tempo.ts | 29 +- .../pengajuan-tempo/component/KontakPerusahaan.jsx | 598 ++++++--------------- .../pengajuan-tempo/component/PengajuanTempo.jsx | 32 +- .../component/informasiPerusahaan.jsx | 2 +- 6 files changed, 242 insertions(+), 524 deletions(-) diff --git a/src-migrate/modules/register/stores/usePengajuanTempoStore.ts b/src-migrate/modules/register/stores/usePengajuanTempoStore.ts index 8891e6ea..247f62dd 100644 --- a/src-migrate/modules/register/stores/usePengajuanTempoStore.ts +++ b/src-migrate/modules/register/stores/usePengajuanTempoStore.ts @@ -93,83 +93,64 @@ export const usePengajuanTempoStore = create((set, get) => ({ })); type StateKontakPerson = { - form: TempoPropsKontakPerson; - errors: { + formKontakPerson: TempoPropsKontakPerson; + errorsKontakPerson: { [key in keyof TempoPropsKontakPerson]?: string; }; - isCheckedTNC: boolean; - isOpenTNC: boolean; - isValidCaptcha: boolean; +}; +type ActionKontakPerson = { + updateFormKontakPerson: (name: string, value: string) => void; + + validateKontakPerson: () => void; + resetFormKontakPerson: () => void; }; export const usePengajuanTempoStoreKontakPerson = create< - StateKontakPerson & Action + StateKontakPerson & ActionKontakPerson >((set, get) => ({ - form: { + formKontakPerson: { direkturName: '', direkturMobile: '', direkturEmail: '', - industry_id: '', - street: '', - state: '', - city: '', - zip: '', - bankName: '', - accountName: '', - accountNumber: '', - estimasi: '', - tempoDuration: '', - bersedia: '', - categoryProduk: '', - tempoLimit: '', + purchasingName: '', + purchasingEmail: '', + financeMobile: '', + financeName: '', + financeEmail: '', }, - updateForm: (name, value) => - set((state) => ({ form: { ...state.form, [name]: value } })), + updateFormKontakPerson: (name, value) => + set((state) => ({ + formKontakPerson: { ...state.formKontakPerson, [name]: value }, + })), - errors: {}, - validate: () => { + errorsKontakPerson: {}, + validateKontakPerson: () => { try { - TempoSchemaKontakPerson.parse(get().form); - set({ errors: {} }); + TempoSchemaKontakPerson.parse(get().formKontakPerson); + set({ errorsKontakPerson: {} }); } catch (error) { if (error instanceof ZodError) { - const errors: StateKontakPerson['errors'] = {}; + const errorsKontakPerson: StateKontakPerson['errorsKontakPerson'] = {}; error.errors.forEach( - (e) => (errors[e.path[0] as keyof TempoPropsKontakPerson] = e.message) + (e) => + (errorsKontakPerson[e.path[0] as keyof TempoPropsKontakPerson] = + e.message) ); - set({ errors }); + set({ errorsKontakPerson }); } } }, - isCheckedTNC: false, - toggleCheckTNC: () => set((state) => ({ isCheckedTNC: !state.isCheckedTNC })), - - isOpenTNC: false, - openTNC: () => set(() => ({ isOpenTNC: true })), - closeTNC: () => set(() => ({ isOpenTNC: false })), - - isValidCaptcha: false, - updateValidCaptcha: (value) => set(() => ({ isValidCaptcha: value })), - - resetForm: () => + resetFormKontakPerson: () => set({ - form: { + formKontakPerson: { direkturName: '', direkturMobile: '', direkturEmail: '', - industry_id: '', - street: '', - state: '', - city: '', - zip: '', - bankName: '', - accountName: '', - accountNumber: '', - estimasi: '', - tempoDuration: '', - bersedia: '', - categoryProduk: '', - tempoLimit: '', + purchasingName: '', + purchasingEmail: '', + financeName: '', + financeMobile: '', + financeEmail: '', }, }), })); diff --git a/src-migrate/types/tempo.ts b/src-migrate/types/tempo.ts index a4bd3d0a..fc920c05 100644 --- a/src-migrate/types/tempo.ts +++ b/src-migrate/types/tempo.ts @@ -22,17 +22,11 @@ export type tempoPropsKontakPerson = { direkturName: string; direkturMobile: string; direkturEmail: string; - industry_id: string; - street: string; - state: string; - city: string; - zip: string; - bankName: string; - accountName: string; - accountNumber: string; - estimasi: string; - tempoDuration: string; - bersedia: string; + purchasingName: string; + purchasingEmail: string; + financeMobile: string; + financeEmail: string; + financeName: string; }; export type TempoApiProps = OdooApiRes; diff --git a/src-migrate/validations/tempo.ts b/src-migrate/validations/tempo.ts index dca60869..45cc8cd2 100644 --- a/src-migrate/validations/tempo.ts +++ b/src-migrate/validations/tempo.ts @@ -28,31 +28,30 @@ export const TempoSchema = z.object({ }); export const TempoSchemaKontakPerson = z.object({ direkturName: z.string().min(1, { message: 'Nama harus diisi' }), + financeName: z.string().min(1, { message: 'Nama harus diisi' }), direkturMobile: z .string() .min(1, { message: 'Nomor telepon harus diisi' }) .refine((val) => /^\d{10,12}$/.test(val), { message: 'Format nomor telepon tidak valid, contoh: 081234567890', }), + financeMobile: z + .string() + .min(1, { message: 'Nomor telepon harus diisi' }) + .refine((val) => /^\d{10,12}$/.test(val), { + message: 'Format nomor telepon tidak valid, contoh: 081234567890', + }), direkturEmail: z .string() .min(1, { message: 'Email harus diisi' }) .email({ message: 'Email harus menggunakan format example@mail.com' }), - street: z.string().min(1, { message: 'Alamat harus diisi' }), - industry_id: z.string().min(1, { message: 'Jenis usaha harus dipilih' }), - zip: z.string().min(1, { message: 'Kode pos harus diisi' }), - state: z.string().min(1, { message: 'Provinsi harus dipilih' }), - city: z.string().min(1, { message: 'Kota harus dipilih' }), - bankName: z.string().min(1, { message: 'Nama bank harus diisi' }), - accountName: z.string().min(1, { message: 'Nama rekening harus diisi' }), - accountNumber: z.string().min(1, { message: 'Nomor rekening harus diisi' }), - estimasi: z + purchasingEmail: z .string() - .min(1, { message: 'Estimasi pemmbelian pertahun harus diisi' }), - tempoDuration: z.string().min(1, { message: 'Durasi tempo harus dipilih' }), - tempoLimit: z.string().min(1, { message: 'Limit tempo harus dipilih' }), - bersedia: z.string().min(1, { message: 'Harus dipilih' }), - categoryProduk: z + .min(1, { message: 'Email harus diisi' }) + .email({ message: 'Email harus menggunakan format example@mail.com' }), + financeEmail: z .string() - .min(1, { message: 'Category produk harus dipilih' }), + .min(1, { message: 'Email harus diisi' }) + .email({ message: 'Email harus menggunakan format example@mail.com' }), + purchasingName: z.string().min(1, { message: 'Nama harus diisi' }), }); diff --git a/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx b/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx index d292449b..a595ff13 100644 --- a/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx +++ b/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx @@ -5,10 +5,15 @@ import odooApi from '~/libs/odooApi'; import stateApi from '@/lib/address/api/stateApi.js'; import cityApi from '@/lib/address/api/cityApi'; import { Radio, RadioGroup, Stack, Checkbox } from '@chakra-ui/react'; -import { usePengajuanTempoStore } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; +import { usePengajuanTempoStoreKontakPerson } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => { const { control, watch } = useForm(); - const { form, errors, validate, updateForm } = usePengajuanTempoStore(); + const { + formKontakPerson, + errorsKontakPerson, + validateKontakPerson, + updateFormKontakPerson, + } = usePengajuanTempoStoreKontakPerson(); const [industries, setIndustries] = useState([]); const [selectedCategory, setSelectedCategory] = useState(''); const [states, setState] = useState([]); @@ -43,10 +48,10 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => { const watchState = watch('state'); useEffect(() => { - updateForm('city', ''); + updateFormKontakPerson('city', ''); if (watchState) { - updateForm('state', `${watchState}`); - validate(); + updateFormKontakPerson('state', `${watchState}`); + validateKontakPerson(); const loadCities = async () => { let dataCities = await cityApi({ stateId: watchState }); dataCities = dataCities.map((city) => ({ @@ -62,8 +67,8 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => { const watchCity = watch('city'); useEffect(() => { if (watchCity) { - updateForm('city', `${watchCity}`); - validate(); + updateFormKontakPerson('city', `${watchCity}`); + validateKontakPerson(); } }, [watchCity]); @@ -86,8 +91,8 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => { (industry) => industry.value === watch('industry_id') ); if (selectedIndustryType) { - updateForm('industry_id', `${selectedIndustryType?.value}`); - validate(); + updateFormKontakPerson('industry_id', `${selectedIndustryType?.value}`); + validateKontakPerson(); setSelectedCategory(selectedIndustryType.category); } }, [watch('industry_id'), industries]); @@ -108,17 +113,17 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => { const value = e.target.value; const formattedValue = formatRupiah(value); console.log('formattedValue', formattedValue); - updateForm('estimasi', formattedValue.replace(/^Rp\s*/, '')); - validate(); + updateFormKontakPerson('estimasi', formattedValue.replace(/^Rp\s*/, '')); + validateKontakPerson(); }; const onChangeTempoDuration = (e) => { - updateForm('tempoDuration', `${e}`); - validate(); + updateFormKontakPerson('tempoDuration', `${e}`); + validateKontakPerson(); }; const onChangeTempoLimit = (e) => { - updateForm('tempoLimit', `${e}`); - validate(); + updateFormKontakPerson('tempoLimit', `${e}`); + validateKontakPerson(); }; const handleCheckboxBersediaChange = (value) => { if (value === 'bersedia') { @@ -126,8 +131,8 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => { } else if (value === 'tidakBersedia') { setBersedia(false); } - updateForm('bersedia', `${value === 'bersedia'}`); - validate(); + updateFormKontakPerson('bersedia', `${value === 'bersedia'}`); + validateKontakPerson(); }; const [selectedIds, setSelectedIds] = useState([]); @@ -137,36 +142,33 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => { ? prevSelected.filter((selectedId) => selectedId !== id) : [...prevSelected, id] ); - updateForm('categoryProduk', `${selectedIds}`); - validate(); + updateFormKontakPerson('categoryProduk', `${selectedIds}`); + validateKontakPerson(); }; const handleInputChange = (event) => { const { name, value } = event.target; - updateForm(name, value); - validate(); + updateFormKontakPerson(name, value); + validateKontakPerson(); }; 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 isFormValid = useMemo( + () => Object.keys(errorsKontakPerson).length === 0, + [errorsKontakPerson] + ); + + const direkturNameRef = useRef(null); + const direkturMobileRef = useRef(null); + const direkturEmailRef = useRef(null); + const purchasingNameRef = useRef(null); + const purchasingEmailRef = useRef(null); + const financeNameRef = useRef(null); + const financeMobileRef = useRef(null); + const financeEmailRef = useRef(null); - const nameRef = useRef(null); - const industry_idRef = useRef(null); - const streetRef = useRef(null); - const stateRef = useRef(null); - const cityRef = 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 categoryProdukRef = useRef(null); - const tempoLimitRef = useRef(null); useEffect(() => { const loadIndustries = async () => { if (!isFormValid) { @@ -174,64 +176,36 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => { behavior: 'smooth', block: 'center', }; - if (errors.name && nameRef.current) { - nameRef.current.scrollIntoView(options); - return; - } - if (errors.industry_id && industry_idRef.current) { - industry_idRef.current.scrollIntoView(options); - return; - } - if (errors.street && streetRef.current) { - streetRef.current.scrollIntoView(options); + if (errorsKontakPerson.direkturName && direkturNameRef.current) { + direkturNameRef.current.scrollIntoView(options); return; } - if (errors.state && stateRef.current) { - stateRef.current.scrollIntoView(options); + if (errorsKontakPerson.direkturMobile && direkturMobileRef.current) { + direkturMobileRef.current.scrollIntoView(options); return; } - if (errors.city && cityRef.current) { - cityRef.current.scrollIntoView(options); + if (errorsKontakPerson.direkturEmail && direkturEmailRef.current) { + direkturEmailRef.current.scrollIntoView(options); return; } - if (errors.zip && zipRef.current) { - zipRef.current.scrollIntoView(options); + if (errorsKontakPerson.purchasingName && purchasingNameRef.current) { + purchasingNameRef.current.scrollIntoView(options); return; } - if (errors.mobile && mobileRef.current) { - mobileRef.current.scrollIntoView(options); + if (errorsKontakPerson.purchasingEmail && purchasingEmailRef.current) { + purchasingEmailRef.current.scrollIntoView(options); return; } - if (errors.bankName && bankNameRef.current) { - bankNameRef.current.scrollIntoView(options); + if (errorsKontakPerson.financeName && financeNameRef.current) { + financeNameRef.current.scrollIntoView(options); return; } - if (errors.accountName && accountNameRef.current) { - accountNameRef.current.scrollIntoView(options); + if (errorsKontakPerson.financeMobile && financeMobileRef.current) { + financeMobileRef.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.categoryProduk && categoryProdukRef.current) { - categoryProdukRef.current.scrollIntoView(options); - return; - } - if (errors.tempoLimit && tempoLimitRef.current) { - tempoLimitRef.current.scrollIntoView(options); + if (errorsKontakPerson.financeEmail && financeEmailRef.current) { + financeEmailRef.current.scrollIntoView(options); return; } } @@ -253,52 +227,46 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => {
- - Format: PT. INDOTEKNIK DOTCOM GEMILANG - {chekValid && (
- {errors.name} + {errorsKontakPerson.direkturName}
)}
+
-
- +
+ - isi detail perusahaan sesuai dengan nama yang terdaftar + isi nomor telpon direktur di perusahaan kamu
- ( - - )} + - {selectedCategory && ( - - Kategori : {selectedCategory} - - )} {chekValid && (
- {errors.industry_id} + {errorsKontakPerson.direkturMobile}
)}
@@ -307,371 +275,137 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => {
- alamat sesuai dengan alamat kantor pusat + isi email Direktur yang sesuai
-
-
- - {chekValid && ( -
- {errors.street} -
- )} -
-
-
- ( - - )} - /> - {chekValid && ( -
- {errors.state} -
- )} -
-
- ( - - )} - /> - {chekValid && ( -
- {errors.city} -
- )} -
-
- - {chekValid && ( -
- {errors.zip} -
- )} +
+ + {chekValid && ( +
+ {errorsKontakPerson.direkturEmail}
-
+ )}
+
- isi no telfon perusahaan yang sesuai + isi nama purchasing yang bertanggung jawab di perusahaan anda
{chekValid && (
- {errors.mobile} + {errorsKontakPerson.purchasingName}
)}
-
-
- - - Isi detail data bank perusahaan anda - -
-
-
- - - Format: BCA, Mandiri, CIMB, BNI dll - - {chekValid && ( -
- {errors.bankName} -
- )} -
-
- - Format: John Doe - {chekValid && ( -
- {errors.accountName} -
- )} -
-
- - Format: 01234567896 - {chekValid && ( -
- {errors.accountNumber} -
- )} -
-
-
-
+ + isi email purchasing benar +
-
-
- -
-
- -
-
-
- 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 && (
- {errors.estimasi} + {errorsKontakPerson.purchasingEmail}
)}
-
+
- Pilih durasi tempo yang anda inginkan + isi nama finance yang bertanggung jawab di perusahaan anda
-
-
- - - - 7 Hari - - - 14 Hari - - - 30 Hari - - - - {chekValid && ( -
- {errors.tempoDuration} -
- )} -
-
-
- - - Ajukan nilai limit yang anda mau - -
-
- - - {/* Kolom 1 */} - - - 5.000.000 - - - 10.000.000 - - - 15.000.000 - - - 20.000.000 - - - - {/* Kolom 2 */} - - - 25.000.000 - - - 30.000.000 - - - 35.000.000 - -
- - { - const value = e.target.value; - const formattedValue = formatRupiah(value); - updateForm('tempoLimit', formattedValue); // Mengupdate nilai di react-hook-form - }} - /> -
-
-
-
- {chekValid && ( -
- {errors.tempoLimit} -
- )} +
+ + {chekValid && ( +
+ {errorsKontakPerson.financeName}
-
+ )}
- -
- *Durasi dan limit dapat berbeda sesuaui dengan verifikasi oleh tim - Indoteknik.com -
-
- Pilih produk bisa lebih dari 1 + isi nomor finance yang bertanggung jawab di perusahaan anda
-
-
- handleCheckboxBersediaChange('bersedia')} - value={true} - size='md' - > - Saya bersedia - - handleCheckboxBersediaChange('tidakBersedia')} - value={false} - size='md' - > - Tidak bersedia - -
+
+ {chekValid && (
- {errors.estimasi} + {errorsKontakPerson.financeMobile}
)}
@@ -680,38 +414,26 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => {
- Pilih produk bisa lebih dari 1 + isi email finance dengan benar
-
-
-
- {firstColumn.map((item) => ( - handleCheckboxChange(item.id)} - > - {item.name} - - ))} -
-
- {secondColumn.map((item) => ( - handleCheckboxChange(item.id)} - > - {item.name} - - ))} -
-
+
+ {chekValid && (
- {errors.categoryProduk} + {errorsKontakPerson.financeEmail}
)}
diff --git a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx index c15189d1..b2e9832e 100644 --- a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx +++ b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx @@ -4,14 +4,22 @@ import Stepper from './Stepper'; import InformasiPerusahaan from './informasiPerusahaan'; import KontakPerusahaan from './KontakPerusahaan'; import { Controller, useForm } from 'react-hook-form'; -import { usePengajuanTempoStore } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; +import { + usePengajuanTempoStore, + usePengajuanTempoStoreKontakPerson, +} from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; import { ChevronRightIcon } from '@heroicons/react/24/outline'; const PengajuanTempo = () => { const [currentStep, setCurrentStep] = React.useState(0); const NUMBER_OF_STEPS = 6; const { form, errors, validate, updateForm } = usePengajuanTempoStore(); + const { + formKontakPerson, + errorsKontakPerson, + validateKontakPerson, + updateFormKontakPerson, + } = usePengajuanTempoStoreKontakPerson(); const [notValid, setNotValid] = useState(false); - const isFormValid = useMemo(() => Object.keys(errors).length === 0, [errors]); const [buttonSubmitClick, setButtonSubmitClick] = useState(false); const stepDivs = [ {
Dokumen
,
Konfirmasi
, ]; + const stepDivsError = [ + errorsKontakPerson, + errors, +
Kontak Person
, +
Pengiriman
, +
Referensi
, +
Dokumen
, +
Konfirmasi
, + ]; + const isFormValid = useMemo( + () => Object.keys(stepDivsError[currentStep]).length === 0, + [stepDivsError[currentStep]] + ); useEffect(() => { validate(); + validateKontakPerson(); }, []); - + console.log('isFormValid', isFormValid); const goToNextStep = () => { if (!isFormValid) { setNotValid(true); setButtonSubmitClick(!buttonSubmitClick); console.log('form', form); - console.log('error', errors); + console.log('error', stepDivsError[currentStep]); return; } else { console.log('form', form); - console.log('error', errors); + console.log('error', stepDivsError[currentStep]); setButtonSubmitClick(!buttonSubmitClick); setNotValid(false); } diff --git a/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx index 0a33f5fb..e5b2ff2c 100644 --- a/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx +++ b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx @@ -405,7 +405,7 @@ const informasiPerusahaan = ({ chekValid, buttonSubmitClick }) => { name='mobile' ref={mobileRef} placeholder='Masukkan nomor telfon perusahaan' - type='text' + type='tel' className='form-input' aria-invalid={errors.mobile} onChange={handleInputChange} -- cgit v1.2.3