diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2024-10-17 14:39:17 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2024-10-17 14:39:17 +0700 |
| commit | f555e7bc9d070e7e0bd4900941592480d4ba6c6a (patch) | |
| tree | 3403b6a19c7f05d73428ba269cff1832bf5074f5 | |
| parent | 6ea86ff925228528d0323df1ca2fc157afca8fab (diff) | |
<iman> update pengajuan tempo
| -rw-r--r-- | src-migrate/modules/register/stores/usePengajuanTempoStore.ts | 93 | ||||
| -rw-r--r-- | src-migrate/types/tempo.ts | 59 | ||||
| -rw-r--r-- | src-migrate/validations/tempo.ts | 28 | ||||
| -rw-r--r-- | src/lib/pengajuan-tempo/component/PengajuanTempo.jsx | 56 | ||||
| -rw-r--r-- | src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx | 472 | ||||
| -rw-r--r-- | src/lib/pengajuan-tempo/stores/useTempoStore.ts | 0 |
6 files changed, 513 insertions, 195 deletions
diff --git a/src-migrate/modules/register/stores/usePengajuanTempoStore.ts b/src-migrate/modules/register/stores/usePengajuanTempoStore.ts new file mode 100644 index 00000000..6f3bc13d --- /dev/null +++ b/src-migrate/modules/register/stores/usePengajuanTempoStore.ts @@ -0,0 +1,93 @@ +import { create } from 'zustand'; +import { TempoProps } from '~/types/tempo'; +import { TempoSchema } from '~/validations/tempo'; +import { boolean, ZodError } from 'zod'; + +type State = { + form: TempoProps; + errors: { + [key in keyof TempoProps]?: string; + }; + isCheckedTNC: boolean; + isOpenTNC: boolean; + isValidCaptcha: boolean; +}; + +type Action = { + updateForm: (name: string, value: string) => void; + updateValidCaptcha: (value: boolean) => void; + toggleCheckTNC: () => void; + openTNC: () => void; + closeTNC: () => void; + validate: () => void; + resetForm: () => void; +}; + +export const usePengajuanTempoStore = create<State & Action>((set, get) => ({ + form: { + name: '', + industry_id: '', + street: '', + state: '', + city: '', + zip: '', + mobile: '', + bankName: '', + accountName: '', + accountNumber: '', + estimasi: '', + tempoDuration: '', + bersedia: '', + categoryProduk: '', + tempoLimit: '', + }, + updateForm: (name, value) => + set((state) => ({ form: { ...state.form, [name]: value } })), + + errors: {}, + validate: () => { + try { + TempoSchema.parse(get().form); + set({ errors: {} }); + } catch (error) { + if (error instanceof ZodError) { + const errors: State['errors'] = {}; + error.errors.forEach( + (e) => (errors[e.path[0] as keyof TempoProps] = e.message) + ); + set({ errors }); + } + } + }, + + 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: () => + set({ + form: { + name: '', + industry_id: '', + street: '', + state: '', + city: '', + zip: '', + mobile: '', + bankName: '', + accountName: '', + accountNumber: '', + estimasi: '', + tempoDuration: '', + bersedia: '', + categoryProduk: '', + tempoLimit: '', + }, + }), +})); diff --git a/src-migrate/types/tempo.ts b/src-migrate/types/tempo.ts new file mode 100644 index 00000000..f8a3c5b8 --- /dev/null +++ b/src-migrate/types/tempo.ts @@ -0,0 +1,59 @@ +import { TempoSchema } from '~/validations/tempo'; +import { OdooApiRes } from './odoo'; +import { z } from 'zod'; + +export type tempoProps = { + name: string; + industry_id: string; + street: string; + state: string; + city: string; + zip: string; + mobile: string; + bankName: string; + accountName: string; + accountNumber: string; + estimasi: string; + tempoDuration: string; + bersedia: string; +}; + +export type TempoApiProps = OdooApiRes<TempoProps>; + +export type TempoProps = z.infer<typeof TempoSchema>; + +export type TempoResApiProps = { + Tempo: boolean; + reason: 'EMAIL_USED' | 'NOT_ACTIVE' | null; +}; + +type ActivationResProps = { + activation: boolean; + user: TempoProps | null; +}; + +export type ActivationTokenProps = { + token: string; +}; + +export type ActivationTokenResApiProps = ActivationResProps & { + reason: 'INVALID_TOKEN' | null; +}; + +export type ActivationOtpProps = { + email: string; + otp: string; +}; + +export type ActivationOtpResApiProps = ActivationResProps & { + reason: 'INVALID_OTP' | null; +}; + +export type ActivationReqProps = { + email: string; +}; + +export type ActivationReqResApiProps = { + activation_request: boolean; + reason: 'NOT_FOUND' | 'ACTIVE' | null; +}; diff --git a/src-migrate/validations/tempo.ts b/src-migrate/validations/tempo.ts new file mode 100644 index 00000000..6999c1c6 --- /dev/null +++ b/src-migrate/validations/tempo.ts @@ -0,0 +1,28 @@ +import { z } from 'zod'; + +export const TempoSchema = z.object({ + name: z.string().min(1, { message: 'Nama harus diisi' }), + 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' }), + mobile: z + .string() + .min(1, { message: 'Nomor telepon harus diisi' }) + .refine((val) => /^\d{10,12}$/.test(val), { + message: 'Format nomor telepon tidak valid, contoh: 081234567890', + }), + 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 + .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 + .string() + .min(1, { message: 'Category produk harus dipilih' }), +}); diff --git a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx index 5ef5374e..bc7dcb69 100644 --- a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx +++ b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx @@ -1,14 +1,22 @@ import React from 'react'; +import { useMemo, useState, useEffect, useRef } from 'react'; import Stepper from './Stepper'; -import InformasiPerusahaan from './informasiPerusahaan'; // Make sure this component exists - +import InformasiPerusahaan from './informasiPerusahaan'; +import { Controller, useForm } from 'react-hook-form'; +import { usePengajuanTempoStore } 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; - - // Use the component directly in the array + const { form, errors, validate, updateForm } = usePengajuanTempoStore(); + const [notValid, setNotValid] = useState(false); + const isFormValid = useMemo(() => Object.keys(errors).length === 0, [errors]); + const [buttonSubmitClick, setButtonSubmitClick] = useState(false); const stepDivs = [ - <InformasiPerusahaan />, // Call the component correctly + <InformasiPerusahaan + chekValid={notValid} + buttonSubmitClick={buttonSubmitClick} + />, <div>Kontak Person</div>, <div>Pengiriman</div>, <div>Referensi</div>, @@ -16,8 +24,22 @@ const PengajuanTempo = () => { <div>Konfirmasi</div>, ]; - const goToNextStep = () => + useEffect(() => { + validate(); + }, []); + + const goToNextStep = () => { + if (!isFormValid) { + setNotValid(true); + setButtonSubmitClick(!buttonSubmitClick); + console.log('form', form); + return; + } else { + setButtonSubmitClick(!buttonSubmitClick); + setNotValid(false); + } setCurrentStep((prev) => (prev === NUMBER_OF_STEPS - 1 ? prev : prev + 1)); + }; const goToPreviousStep = () => setCurrentStep((prev) => (prev <= 0 ? prev : prev - 1)); @@ -42,21 +64,33 @@ const PengajuanTempo = () => { </div> <div>{stepDivs[currentStep]}</div> <section className='flex gap-10 mt-10'> - <button + {/* <button onClick={goToPreviousStep} className='bg-blue-600 text-white p-2 rounded-md' disabled={currentStep === 0} // Disable if on the first step > Previous step - </button> - <button + </button> */} + {/* <button onClick={goToNextStep} className='bg-blue-600 text-white p-2 rounded-md' disabled={currentStep === NUMBER_OF_STEPS - 1} // Disable if on the last step - > + > Next step - </button> + </button> */} </section> + <div className='flex flex-row justify-end items-center gap-4 mb-8'> + <span className='text-xs opacity-60'> + *Pastikan data yang anda masukan sudah benar dan sesuai + </span> + <button + onClick={goToNextStep} + disabled={currentStep === NUMBER_OF_STEPS - 1} + className='bg-red-600 border border-red-600 rounded-md text-sm text-white p-2 h-11 mb-1 content-center flex flex-row justify-center items-center' + > + Langkah Selanjutnya {<ChevronRightIcon className='w-5' />} + </button> + </div> </div> </> ); diff --git a/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx index 62280f13..82cf4aee 100644 --- a/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx +++ b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx @@ -1,32 +1,19 @@ -import React, { useState, useEffect } from 'react'; -import * as Yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { Controller, useForm } from 'react-hook-form'; +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 { Radio, RadioGroup, Stack, Checkbox } from '@chakra-ui/react'; -const informasiPerusahaan = ({}) => { - const { - register, - handleSubmit, - formState: { errors }, - control, - reset, - watch, - setValue, - getValues, - values, - } = useForm({ - resolver: yupResolver(validationSchema), - defaultValues, - }); +import { usePengajuanTempoStore } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore'; +const informasiPerusahaan = ({ chekValid, buttonSubmitClick }) => { + const { control, watch } = useForm(); + const { form, errors, validate, updateForm } = usePengajuanTempoStore(); const [industries, setIndustries] = useState([]); const [selectedCategory, setSelectedCategory] = useState(''); const [states, setState] = useState([]); const [cities, setCities] = useState([]); - const [bersedia, setBersedia] = useState(true); + const [bersedia, setBersedia] = useState(null); const category_produk = [ { id: 1, name: 'Pengaman, Kesehatan & Keamanan' }, { id: 2, name: 'Perkakas Tangan, Listrik & Pneumatic' }, @@ -41,7 +28,7 @@ const informasiPerusahaan = ({}) => { { id: 11, name: 'Komponen & Aksesoris' }, { id: 12, name: 'Peralatan Horeca & Food Service' }, ]; - console.log('defaultValues', getValues()); + useEffect(() => { const loadState = async () => { let dataState = await stateApi(); @@ -56,8 +43,10 @@ const informasiPerusahaan = ({}) => { const watchState = watch('state'); useEffect(() => { - setValue('city', ''); + updateForm('city', ''); if (watchState) { + updateForm('state', `${watchState}`); + validate(); const loadCities = async () => { let dataCities = await cityApi({ stateId: watchState }); dataCities = dataCities.map((city) => ({ @@ -68,7 +57,15 @@ const informasiPerusahaan = ({}) => { }; loadCities(); } - }, [watchState, setValue]); + }, [watchState]); + + const watchCity = watch('city'); + useEffect(() => { + if (watchCity) { + updateForm('city', `${watchCity}`); + validate(); + } + }, [watchCity]); useEffect(() => { const loadIndustries = async () => { @@ -89,16 +86,12 @@ const informasiPerusahaan = ({}) => { (industry) => industry.value === watch('industry_id') ); if (selectedIndustryType) { - // updateForm('industry_id', `${selectedIndustryType?.value}`); + updateForm('industry_id', `${selectedIndustryType?.value}`); + validate(); setSelectedCategory(selectedIndustryType.category); } }, [watch('industry_id'), industries]); - const onSubmitHandler = async (values) => { - setValue('bersedia', `${bersedia}`); - console.log('values', values); - }; - const estimasiValue = watch('estimasi'); const tempoLimitValue = watch('tempoLimit'); @@ -111,22 +104,30 @@ const informasiPerusahaan = ({}) => { : ''; }; - // Memperbarui nilai input dengan format rupiah const handleChange = (e) => { const value = e.target.value; const formattedValue = formatRupiah(value); - setValue('estimasi', formattedValue); // Mengupdate nilai di react-hook-form + console.log('formattedValue', formattedValue); + updateForm('estimasi', formattedValue.replace(/^Rp\s*/, '')); + validate(); }; const onChangeTempoDuration = (e) => { - setValue('tempoDuration', `${e}`); // Mengupdate nilai di react-hook-form + updateForm('tempoDuration', `${e}`); + validate(); }; const onChangeTempoLimit = (e) => { - setValue('tempoLimit', `${e}`); // Mengupdate nilai di react-hook-form + updateForm('tempoLimit', `${e}`); + validate(); }; - const handleBersediaChange = () => { - setBersedia(!bersedia); - setValue('bersedia', `${bersedia}`); + const handleCheckboxBersediaChange = (value) => { + if (value === 'bersedia') { + setBersedia(true); + } else if (value === 'tidakBersedia') { + setBersedia(false); + } + updateForm('bersedia', value === 'bersedia'); + validate(); }; const [selectedIds, setSelectedIds] = useState([]); @@ -136,21 +137,113 @@ const informasiPerusahaan = ({}) => { ? prevSelected.filter((selectedId) => selectedId !== id) : [...prevSelected, id] ); - setValue('categoryProduk', `${selectedIds}`); + updateForm('categoryProduk', `${selectedIds}`); + validate(); + }; + + 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 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) { + const options = { + 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); + return; + } + if (errors.state && stateRef.current) { + stateRef.current.scrollIntoView(options); + return; + } + if (errors.city && cityRef.current) { + cityRef.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.categoryProduk && categoryProdukRef.current) { + categoryProdukRef.current.scrollIntoView(options); + return; + } + if (errors.tempoLimit && tempoLimitRef.current) { + tempoLimitRef.current.scrollIntoView(options); + return; + } + } + }; + loadIndustries(); + }, [buttonSubmitClick, chekValid]); return ( <> <div className='flex justify-start'> <h1>Informasi Perusahaan</h1> </div> - <form - onSubmit={handleSubmit(onSubmitHandler)} - className='flex mt-4 flex-col w-full ' - > + <form className='flex mt-4 flex-col w-full '> <div className='w-full grid grid-row-2 gap-5'> <div className='flex flex-row justify-between items-start'> <div> @@ -163,22 +256,27 @@ const informasiPerusahaan = ({}) => { </div> <div className='w-3/5'> <input - {...register('name')} + id='name' + name='name' placeholder='Masukkan nama perusahaan' type='text' className='form-input' - aria-invalid={errors.name?.message} + aria-invalid={errors.name} + ref={nameRef} + onChange={handleInputChange} /> <span className='text-xs opacity-60'> Format: PT. INDOTEKNIK DOTCOM GEMILANG </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.name?.message} - </div> + {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> + <div ref={industry_idRef}> <label className='form-label w-2/5 text-nowrap'>Industri</label> <span className='text-xs opacity-60'> isi detail perusahaan sesuai dengan nama yang terdaftar @@ -186,7 +284,7 @@ const informasiPerusahaan = ({}) => { </div> <div className='w-3/5'> <Controller - {...register('industry_id')} + name='industry_id' control={control} render={(props) => ( <HookFormSelect @@ -201,9 +299,11 @@ const informasiPerusahaan = ({}) => { Kategori : {selectedCategory} </span> )} - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.industry_id?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.industry_id} + </div> + )} </div> </div> @@ -219,17 +319,22 @@ const informasiPerusahaan = ({}) => { <div className='w-3/5 flex gap-3 flex-col'> <div> <input - {...register('street')} + id='street' + name='street' + ref={streetRef} placeholder='Masukkan alamat lengkap perusahaan' type='text' className='form-input' + onChange={handleInputChange} /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.street?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.street} + </div> + )} </div> <div className='sub-alamat flex flex-row w-full gap-3'> - <div className='w-2/5'> + <div className='w-2/5' ref={stateRef}> <Controller name='state' control={control} @@ -241,11 +346,13 @@ const informasiPerusahaan = ({}) => { /> )} /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.state?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.state} + </div> + )} </div> - <div className='w-1/3'> + <div className='w-1/3' ref={cityRef}> <Controller name='city' control={control} @@ -258,20 +365,27 @@ const informasiPerusahaan = ({}) => { /> )} /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.city?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.city} + </div> + )} </div> <div className='w-1/3'> <input - {...register('zip')} + id='zip' + name='zip' + ref={zipRef} placeholder='Kode Pos' type='number' className='form-input' + onChange={handleInputChange} /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.zip?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.zip} + </div> + )} </div> </div> </div> @@ -287,15 +401,20 @@ const informasiPerusahaan = ({}) => { </div> <div className='w-3/5'> <input - {...register('mobile')} + id='mobile' + name='mobile' + ref={mobileRef} placeholder='Masukkan nomor telfon perusahaan' type='text' className='form-input' - aria-invalid={errors.mobile?.message} + aria-invalid={errors.mobile} + onChange={handleInputChange} /> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.mobile?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.mobile} + </div> + )} </div> </div> @@ -309,41 +428,56 @@ const informasiPerusahaan = ({}) => { <div className='w-3/5 flex gap-3 flex-row'> <div> <input - {...register('bankName')} + id='bankName' + name='bankName' + ref={bankNameRef} placeholder='Nama bank' type='text' className='form-input' + onChange={handleInputChange} /> <span className='text-xs opacity-60'> Format: BCA, Mandiri, CIMB, BNI dll </span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.bankName?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.bankName} + </div> + )} </div> <div> <input - {...register('accountName')} + id='accountName' + name='accountName' + ref={accountNameRef} placeholder='Nama Rekening' type='text' className='form-input' + onChange={handleInputChange} /> <span className='text-xs opacity-60'>Format: John Doe</span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.accountName?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountName} + </div> + )} </div> <div> <input - {...register('accountNumber')} + id='accountNumber' + name='accountNumber' + ref={accountNumberRef} placeholder='Nomor Rekening Bank' type='text' className='form-input' + onChange={handleInputChange} /> <span className='text-xs opacity-60'>Format: 01234567896</span> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.accountNumber?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.accountNumber} + </div> + )} </div> </div> </div> @@ -353,16 +487,15 @@ const informasiPerusahaan = ({}) => { <label className='form-label w-2/5 text-nowrap'> Website <span className=' opacity-60'>(Opsional)</span> </label> - <span className='text-xs opacity-60'> - isi no telfon perusahaan yang sesuai - </span> </div> <div className='w-3/5'> <input - {...register('website')} + id='website' + name='website' placeholder='www.indoteknik.com' type='text' className='form-input' + onChange={handleInputChange} /> </div> </div> @@ -376,19 +509,24 @@ const informasiPerusahaan = ({}) => { <div className='w-3/5'> <div className='relative'> <input - {...register('estimasi', { - setValueAs: (value) => value.replace(/^Rp\s*/, ''), // Menyimpan hanya angka - })} + 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(estimasiValue)} // Menampilkan nilai terformat + value={formatRupiah(form.estimasi)} onChange={handleChange} // Mengatur perubahan input /> </div> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.estimasi?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.estimasi} + </div> + )} </div> </div> @@ -402,7 +540,7 @@ const informasiPerusahaan = ({}) => { </span> </div> <div className='w-3/5 flex flex-row items-center'> - <div className='w-1/5 '> + <div className='w-1/5' ref={tempoDurationRef}> <RadioGroup onChange={onChangeTempoDuration} // value={selectedValue} @@ -419,6 +557,11 @@ const informasiPerusahaan = ({}) => { </Radio> </Stack> </RadioGroup> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.tempoDuration} + </div> + )} </div> <div className='w-4/5 flex flex-row justify-between items-center '> <div> @@ -429,10 +572,13 @@ const informasiPerusahaan = ({}) => { Ajukan nilai limit yang anda mau </span> </div> - <div className='flex items-center'> + <div + className='flex flex-col justify-start items-start' + ref={tempoLimitRef} + > <RadioGroup onChange={onChangeTempoLimit} - className='flex items-center justify-between' + className='flex items-center justify-between ' > <Stack direction='row' className=''> {/* Kolom 1 */} @@ -472,24 +618,20 @@ const informasiPerusahaan = ({}) => { onChange={(e) => { const value = e.target.value; const formattedValue = formatRupiah(value); - setValue('tempoLimit', formattedValue); // Mengupdate nilai di react-hook-form + updateForm('tempoLimit', formattedValue); // Mengupdate nilai di react-hook-form }} /> </div> </Stack> </Stack> </RadioGroup> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.tempoLimit} + </div> + )} </div> </div> - {/* <input - {...register('tempoDuration')} - placeholder='Nomor Rekening Bank' - type='text' - className='form-input' - /> */} - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.tempoDuration?.message} - </div> </div> </div> @@ -507,13 +649,13 @@ const informasiPerusahaan = ({}) => { Pilih produk bisa lebih dari 1 </span> </div> - <div className='w-3/5 flex justify-start'> - <div className='flex gap-x-4'> + <div className='w-3/5 flex flex-col justify-start'> + <div className='flex gap-x-4' ref={bersediaRef}> <Checkbox borderColor='gray.600' colorScheme='red' - isChecked={bersedia} - onChange={handleBersediaChange} + isChecked={bersedia === true} // Checked when bersedia is true + onChange={() => handleCheckboxBersediaChange('bersedia')} value={true} size='md' > @@ -522,17 +664,19 @@ const informasiPerusahaan = ({}) => { <Checkbox borderColor='gray.600' colorScheme='red' - isChecked={!bersedia} - onChange={handleBersediaChange} + isChecked={bersedia === false} // Checked when bersedia is false + onChange={() => handleCheckboxBersediaChange('tidakBersedia')} value={false} size='md' > Tidak bersedia </Checkbox> </div> - <div className='text-caption-2 text-danger-500 mt-1'> - {errors.estimasi?.message} - </div> + {chekValid && ( + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.estimasi} + </div> + )} </div> </div> @@ -545,80 +689,40 @@ const informasiPerusahaan = ({}) => { Pilih produk bisa lebih dari 1 </span> </div> - <div className='w-3/5 flex flex-row justify-between'> - <div className='flex flex-col gap-2'> - {firstColumn.map((item) => ( - <Checkbox - key={item.id} - onChange={() => handleCheckboxChange(item.id)} - > - {item.name} - </Checkbox> - ))} - </div> - <div className='flex flex-col gap-2'> - {secondColumn.map((item) => ( - <Checkbox - key={item.id} - onChange={() => handleCheckboxChange(item.id)} - > - {item.name} - </Checkbox> - ))} + <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 + key={item.id} + onChange={() => handleCheckboxChange(item.id)} + > + {item.name} + </Checkbox> + ))} + </div> + <div className='flex flex-col gap-2'> + {secondColumn.map((item) => ( + <Checkbox + key={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 className='flex flex-row justify-end items-center gap-4 mb-8'> - <span className='text-xs opacity-60'> - *Pastikan data yang anda masukan sudah benar dan sesuai - </span> - <button - type='submit' - className='bg-red-600 border border-red-600 rounded-md text-sm text-white w-28 h-11 mb-1 content-center flex flex-row justify-center items-center' - > - <p>Selanjutnya</p> - </button> - </div> </div> </form> </> ); }; -const validationSchema = Yup.object().shape({ - // email: Yup.string() - // .email('Format harus seperti contoh@email.com') - // .required('Harus di-isi'), - name: Yup.string().required('Harus di-isi'), - industry_id: Yup.string().required('Harus di-pilih'), - street: Yup.string().required('Harus di-isi'), - zip: Yup.string().required('Harus di-isi'), - state: Yup.string().required('Harus di-pilih'), - city: Yup.string().required('Harus di-pilih'), - mobile: Yup.string().required('Harus di-isi'), - bankName: Yup.string().required('Harus di-isi'), - accountName: Yup.string().required('Harus di-isi'), - accountNumber: Yup.string().required('Harus di-isi'), - estimasi: Yup.string().required('Harus di-isi'), - tempoDuration: Yup.string().required('Harus di-isi'), - bersedia: Yup.string().required('Harus di-pilih'), -}); - -const defaultValues = { - // email: '', - name: '', - industry_id: '', - street: '', - state: '', - city: '', - zip: '', - mobile: '', - bankName: '', - accountName: '', - accountNumber: '', - estimasi: '', - tempoDuration: '', - bersedia: '', -}; - export default informasiPerusahaan; diff --git a/src/lib/pengajuan-tempo/stores/useTempoStore.ts b/src/lib/pengajuan-tempo/stores/useTempoStore.ts deleted file mode 100644 index e69de29b..00000000 --- a/src/lib/pengajuan-tempo/stores/useTempoStore.ts +++ /dev/null |
