diff options
| -rw-r--r-- | src/components/Fields.js | 22 | ||||
| -rw-r--r-- | src/pages/my/address/[id]/edit.js | 375 | ||||
| -rw-r--r-- | src/pages/my/address/create.js | 307 |
3 files changed, 340 insertions, 364 deletions
diff --git a/src/components/Fields.js b/src/components/Fields.js new file mode 100644 index 00000000..3db8bfdd --- /dev/null +++ b/src/components/Fields.js @@ -0,0 +1,22 @@ +import ReactSelect from "react-select"; + +const Select = ({ + options, + name, + setFieldValue, + value, + disabled +}) => ( + <ReactSelect + classNamePrefix="form-select" + options={options} + name={name} + onChange={(option) => setFieldValue(name, option.value)} + value={value ? options.find(option => option.value === value) : ''} + isDisabled={disabled} + /> +); + +export { + Select +};
\ No newline at end of file diff --git a/src/pages/my/address/[id]/edit.js b/src/pages/my/address/[id]/edit.js index d2de2815..092f0cb5 100644 --- a/src/pages/my/address/[id]/edit.js +++ b/src/pages/my/address/[id]/edit.js @@ -1,27 +1,26 @@ -import { useRouter } from "next/router"; -import AppBar from "../../../../components/AppBar"; -import Layout from "../../../../components/Layout"; +import { useFormik } from "formik"; +import * as Yup from "yup"; import WithAuth from "../../../../components/WithAuth"; -import { useAuth } from "../../../../helpers/auth"; -import useFormValidation from "../../../../helpers/formValidation"; +import Layout from "../../../../components/Layout"; +import AppBar from "../../../../components/AppBar"; +import { Select } from "../../../../components/fields"; import { useEffect, useState } from "react"; import apiOdoo from "../../../../helpers/apiOdoo"; -import ReactSelect from "react-select"; -import convertToOption from "../../../../helpers/convertToOption"; +import { useAuth } from "../../../../helpers/auth"; import { toast } from "react-hot-toast"; -import _ from "lodash"; - -const validationScheme = { - type: ['label:Label Alamat', 'required'], - name: ['label:Nama', 'required'], - email: ['label:Email', 'required', 'email'], - mobile: ['label:No. Handphone', 'required', 'maxLength:16'], - street: ['label:Alamat', 'required'], - city: ['label:Kota', 'required'], - zip: ['label:Kode Pos', 'required'] -}; - -const typesSelection = [ +import { useRouter } from "next/router"; + +const validationSchema = Yup.object().shape({ + type: Yup.string().required('Harus di-pilih'), + name: Yup.string().min(3, 'Minimal 3 karakter').required('Harus di-isi'), + email: Yup.string().email('Format harus seperti johndoe@example.com').required('Harus di-isi'), + mobile: Yup.string().required('Harus di-isi'), + street: Yup.string().required('Harus di-isi'), + zip: Yup.string().required('Harus di-isi'), + city: Yup.number().required('Harus di-pilih'), +}); + +const types = [ { value: 'contact', label: 'Contact Address' }, { value: 'invoice', label: 'Invoice Address' }, { value: 'delivery', label: 'Delivery Address' }, @@ -31,209 +30,205 @@ const typesSelection = [ export async function getServerSideProps( context ) { const { id } = context.query; const address = await apiOdoo('GET', `/api/v1/partner/${id}/address`); - let initialFormValue = { - type: typesSelection.find((x) => x.value == address.type), + let initialValues = { + type: address.type, name: address.name, email: address.email, mobile: address.mobile, street: address.street, zip: address.zip, - city: convertToOption(address.city), - district: convertToOption(address.district), - subDistrict: convertToOption(address.sub_district) + city: address.city?.id, + district: address.district?.id || null, + subDistrict: address.sub_district?.id || null }; - return { props: { id, initialFormValue } }; + return { props: { id, initialValues } }; } -export default function EditAddress({ id, initialFormValue }) { - const [auth] = useAuth(); +export default function EditAddress({ id, initialValues }) { const router = useRouter(); + + const onSubmit = async (values) => { + const parameters = { + ...values, + city_id: values.city, + district_id: values.district, + sub_district_id: values.subDistrict + } - // Master Data - const [cities, setCities] = useState([]); - const [districts, setDistricts] = useState([]); - const [subDistricts, setSubDistricts] = useState([]); + const address = await apiOdoo('PUT', `/api/v1/partner/${id}/address`, parameters); + if (address?.id) { + toast.success('Berhasil mengubah alamat'); + router.back(); + } + }; + + const form = useFormik({ initialValues, validationSchema, onSubmit }); - const { - formInputs, - formErrors, - handleInputChange, - handleSelectChange, - handleFormSubmit, - hasChangedInputs - } = useFormValidation({ validationScheme, initialFormValue }); + const { + values, + errors, + touched, + handleChange, + handleSubmit, + setFieldValue, + } = form; + + const [ cities, setCities ] = useState([]); + const [ districts, setDistricts ] = useState([]); + const [ subDistricts, setSubDistricts ] = useState([]); useEffect(() => { - if (cities.length == 0) { - const loadCities = async () => { - let dataCities = await apiOdoo('GET', '/api/v1/city'); - dataCities = dataCities.map((city) => ({ value: city.id, label: city.name })); - setCities(dataCities); - }; - loadCities(); - } - }, [cities]); - + const loadCities = async () => { + let dataCities = await apiOdoo('GET', '/api/v1/city'); + dataCities = dataCities.map((city) => ({ value: city.id, label: city.name })); + setCities(dataCities); + }; + loadCities(); + }, []); + useEffect(() => { - if (hasChangedInputs?.city) handleSelectChange('district', null); - if (formInputs.city) { + setFieldValue('district', ''); + if (values.city) { const loadDistricts = async () => { - let dataDistricts = await apiOdoo('GET', `/api/v1/district?city_id=${formInputs.city.value}`); + let dataDistricts = await apiOdoo('GET', `/api/v1/district?city_id=${values.city}`); dataDistricts = dataDistricts.map((district) => ({ value: district.id, label: district.name })); setDistricts(dataDistricts); }; loadDistricts(); } - }, [ formInputs.city, hasChangedInputs.city, handleSelectChange ]); + }, [ values.city, setFieldValue ]); useEffect(() => { - if (hasChangedInputs?.district) handleSelectChange('subDistrict', null); - if (formInputs.district) { + setFieldValue('subDistrict', ''); + if (values.district) { const loadSubDistricts = async () => { - let dataSubDistricts = await apiOdoo('GET', `/api/v1/sub_district?district_id=${formInputs.district.value}`); - dataSubDistricts = dataSubDistricts.map((subDistrict) => ({ value: subDistrict.id, label: subDistrict.name })); + let dataSubDistricts = await apiOdoo('GET', `/api/v1/sub_district?district_id=${values.district}`); + dataSubDistricts = dataSubDistricts.map((district) => ({ value: district.id, label: district.name })); setSubDistricts(dataSubDistricts); }; loadSubDistricts(); } - }, [ formInputs.district, hasChangedInputs.district, handleSelectChange ]); - - const onSubmit = async () => { - const parameters = { - ...formInputs, - city_id: formInputs.city?.value, - district_id: formInputs.district?.value, - sub_district_id: formInputs.subDistrict?.value, - type: formInputs.type?.value - }; - - const address = await apiOdoo('PUT', `/api/v1/partner/${id}/address`, parameters); - if (address?.id) { - toast.success('Berhasil mengubah alamat'); - router.back(); - } - } + }, [ values.district, setFieldValue ]); return ( <WithAuth> <Layout> <AppBar title="Ubah Alamat" /> - { !_.isEmpty(formInputs) && ( - <form className="px-4 pb-4" onSubmit={(e) => handleFormSubmit(e, onSubmit)}> - <label className="form-label mt-4 mb-2">Label Alamat</label> - <ReactSelect - placeholder="Pilih label alamat..." - classNamePrefix="form-select" - options={typesSelection} - name="type" - onChange={(value) => handleSelectChange('type', value)} - value={formInputs?.type} - /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.type}</div> - - <label className="form-label mt-4 mb-2">Nama Kontak</label> - <input - type="text" - className='form-input' - placeholder="John Doe" - name="name" - onChange={handleInputChange} - value={formInputs.name} - aria-invalid={formErrors?.name} - /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.name}</div> - - <label className="form-label mt-4 mb-2">Email</label> - <input - type="text" - className='form-input' - placeholder="johndoe@gmail.com" - name="email" - value={formInputs.email} - onChange={handleInputChange} - aria-invalid={formErrors?.email} - /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.email}</div> - - <label className="form-label mt-4 mb-2">No. Handphone</label> - <input - type="number" - className='form-input' - placeholder="08xxxxxxxx" - name="mobile" - value={formInputs.mobile} - onChange={handleInputChange} - aria-invalid={formErrors?.mobile} - /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.mobile}</div> - - <label className="form-label mt-4 mb-2">Alamat</label> - <input - type="text" - className='form-input' - placeholder="Jl. Bandengan Utara" - name="street" - value={formInputs.street} - onChange={handleInputChange} - aria-invalid={formErrors?.street} - /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.street}</div> - - <label className="form-label mt-4 mb-2">Kode Pos</label> - <input - type="number" - className='form-input' - placeholder="10100" - name="zip" - value={formInputs.zip} - onChange={handleInputChange} - aria-invalid={formErrors?.zip} - /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.zip}</div> - - <label className="form-label mt-4 mb-2">Kota</label> - <ReactSelect - placeholder="Pilih kota..." - classNamePrefix="form-select" - classNames={{ control: (state) => state.menuIsOpen || state.isFocused ? '!border-yellow_r-9' : '' }} - options={cities} - value={formInputs.city} - onChange={(value) => handleSelectChange('city', value)} - /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.city}</div> - - <label className="form-label mt-4 mb-2">Kecamatan <span className="text-gray_r-10">(opsional)</span></label> - <ReactSelect - placeholder="Pilih Kecamatan..." - classNamePrefix="form-select" - classNames={{ control: (state) => state.menuIsOpen || state.isFocused ? '!border-yellow_r-9' : '' }} - options={districts} - value={formInputs.district} - onChange={(value) => handleSelectChange('district', value)} - isDisabled={!formInputs.city} - /> - - <label className="form-label mt-4 mb-2">Kelurahan <span className="text-gray_r-10">(opsional)</span></label> - <ReactSelect - placeholder="Pilih Kelurahan..." - classNamePrefix="form-select" - classNames={{ control: (state) => state.menuIsOpen || state.isFocused ? '!border-yellow_r-9' : '' }} - options={subDistricts} - onChange={(value) => handleSelectChange('subDistrict', value)} - value={formInputs.subDistrict} - isDisabled={!formInputs.district} - /> - - <button - type="submit" - className="btn-yellow mt-6 w-full" - > - Simpan - </button> - </form> - ) } + <form onSubmit={handleSubmit} className="p-4 pt-0"> + <label className="form-label mt-4 mb-2">Label Alamat</label> + <Select + name="type" + options={types} + setFieldValue={setFieldValue} + value={values.type} + /> + { errors.type && touched.type && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.type }</div> + ) } + + <label className="form-label mt-4 mb-2">Nama</label> + <input + type="text" + className="form-input" + placeholder="John Doe" + onChange={handleChange} + value={values.name} + name="name" + /> + { errors.name && touched.name && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.name }</div> + ) } + + <label className="form-label mt-4 mb-2">Email</label> + <input + type="email" + className="form-input" + placeholder="johndoe@example.com" + onChange={handleChange} + value={values.email} + name="email" + /> + { errors.email && touched.email && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.email }</div> + ) } + + <label className="form-label mt-4 mb-2">No. Handphone</label> + <input + type="tel" + className="form-input" + placeholder="08xxxxxxxx" + onChange={handleChange} + value={values.mobile} + name="mobile" + /> + { errors.mobile && touched.mobile && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.mobile }</div> + ) } + + <label className="form-label mt-4 mb-2">Alamat</label> + <input + type="text" + className="form-input" + placeholder="Jl. Bandengan Utara 85A" + onChange={handleChange} + value={values.street} + name="street" + /> + { errors.street && touched.street && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.street }</div> + ) } + + <label className="form-label mt-4 mb-2">Kode Pos</label> + <input + type="number" + className="form-input" + placeholder="10100" + onChange={handleChange} + value={values.zip} + name="zip" + /> + { errors.zip && touched.zip && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.zip }</div> + ) } + + <label className="form-label mt-4 mb-2">Kota</label> + <Select + name="city" + options={cities} + setFieldValue={setFieldValue} + value={values.city} + /> + { errors.city && touched.city && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.city }</div> + ) } + + <label className="form-label mt-4 mb-2">Kecamatan</label> + <Select + name="district" + options={districts} + setFieldValue={setFieldValue} + value={values.district} + disabled={!values.city} + /> + + <label className="form-label mt-4 mb-2">Kelurahan</label> + <Select + name="subDistrict" + options={subDistricts} + setFieldValue={setFieldValue} + value={values.subDistrict} + disabled={!values.district} + /> + + <button + type="submit" + className="btn-yellow mt-6 w-full" + > + Simpan + </button> + </form> </Layout> </WithAuth> - ); + ); }
\ No newline at end of file diff --git a/src/pages/my/address/create.js b/src/pages/my/address/create.js index f11a7b67..d9565d93 100644 --- a/src/pages/my/address/create.js +++ b/src/pages/my/address/create.js @@ -1,47 +1,38 @@ -import AppBar from "../../../components/AppBar"; -import Layout from "../../../components/Layout"; +import { useFormik } from "formik"; +import * as Yup from "yup"; import WithAuth from "../../../components/WithAuth"; -import apiOdoo from "../../../helpers/apiOdoo"; -import ReactSelect from "react-select"; +import Layout from "../../../components/Layout"; +import AppBar from "../../../components/AppBar"; +import { Select } from "../../../components/fields"; import { useEffect, useState } from "react"; +import apiOdoo from "../../../helpers/apiOdoo"; import { useAuth } from "../../../helpers/auth"; -import useFormValidation from "../../../helpers/formValidation"; import { toast } from "react-hot-toast"; import { useRouter } from "next/router"; -import _ from "lodash"; -import { Field, Form, Formik } from "formik"; -import * as Yup from "yup"; -import SelectFormik from "../../../components/SelectFormik"; -const initialFormValue = { - type: null, - name: '', +const initialValues = { + type: '', + name: '', email: '', mobile: '', street: '', - city: null, - district: null, - subDistrict: null, - zip: '' + city: '', + district: '', + subDistrict: '', + zip: '', }; const validationSchema = Yup.object().shape({ - name: Yup.string() - .min(2, 'Minimal karakter 2') - .required('Harus di-isi') + type: Yup.string().required('Harus di-pilih'), + name: Yup.string().min(3, 'Minimal 3 karakter').required('Harus di-isi'), + email: Yup.string().email('Format harus seperti johndoe@example.com').required('Harus di-isi'), + mobile: Yup.string().required('Harus di-isi'), + street: Yup.string().required('Harus di-isi'), + zip: Yup.string().required('Harus di-isi'), + city: Yup.number().required('Harus di-pilih'), }); -const validationScheme = { - type: ['label:Label Alamat', 'required'], - name: ['label:Nama', 'required'], - email: ['label:Email', 'required', 'email'], - mobile: ['label:No. Handphone', 'required', 'maxLength:16'], - street: ['label:Alamat', 'required'], - city: ['label:Kota', 'required'], - zip: ['label:Kode Pos', 'required'] -}; - -const typesSelection = [ +const types = [ { value: 'contact', label: 'Contact Address' }, { value: 'invoice', label: 'Invoice Address' }, { value: 'delivery', label: 'Delivery Address' }, @@ -51,212 +42,180 @@ const typesSelection = [ export default function CreateAddress() { const [auth] = useAuth(); const router = useRouter(); + + const onSubmit = async (values) => { + const parameters = { + ...values, + city_id: values.city, + district_id: values.district, + sub_district_id: values.subDistrict, + parent_id: auth.partner_id + } - // Master Data - const [cities, setCities] = useState([]); - const [districts, setDistricts] = useState([]); - const [subDistricts, setSubDistricts] = useState([]); + const address = await apiOdoo('POST', '/api/v1/partner/address', parameters); + if (address?.id) { + toast.success('Berhasil menambahkan alamat'); + router.back(); + } + }; + + const form = useFormik({ initialValues, validationSchema, onSubmit }); - // Input Data const { - formInputs, - formErrors, - handleInputChange, - handleSelectChange, - handleFormSubmit, - handleFormReset - } = useFormValidation({ validationScheme, initialFormValue }); - + values, + errors, + touched, + handleChange, + handleSubmit, + setFieldValue, + } = form; + + const [ cities, setCities ] = useState([]); + const [ districts, setDistricts ] = useState([]); + const [ subDistricts, setSubDistricts ] = useState([]); + useEffect(() => { - if (cities.length == 0) { - const loadCities = async () => { - let dataCities = await apiOdoo('GET', '/api/v1/city'); - dataCities = dataCities.map((city) => ({ value: city.id, label: city.name })); - setCities(dataCities); - }; - loadCities(); - } - }, [cities]); - + const loadCities = async () => { + let dataCities = await apiOdoo('GET', '/api/v1/city'); + dataCities = dataCities.map((city) => ({ value: city.id, label: city.name })); + setCities(dataCities); + }; + loadCities(); + }, []); + useEffect(() => { - handleSelectChange('district', null); - if (formInputs.city) { + setFieldValue('district', ''); + if (values.city) { const loadDistricts = async () => { - let dataDistricts = await apiOdoo('GET', `/api/v1/district?city_id=${formInputs.city.value}`); + let dataDistricts = await apiOdoo('GET', `/api/v1/district?city_id=${values.city}`); dataDistricts = dataDistricts.map((district) => ({ value: district.id, label: district.name })); setDistricts(dataDistricts); }; loadDistricts(); } - }, [ formInputs.city, handleSelectChange ]); + }, [ values.city, setFieldValue ]); useEffect(() => { - handleSelectChange('subDistrict', null); - if (formInputs.district) { + setFieldValue('subDistrict', ''); + if (values.district) { const loadSubDistricts = async () => { - let dataSubDistricts = await apiOdoo('GET', `/api/v1/sub_district?district_id=${formInputs.district.value}`); - dataSubDistricts = dataSubDistricts.map((subDistrict) => ({ value: subDistrict.id, label: subDistrict.name })); + let dataSubDistricts = await apiOdoo('GET', `/api/v1/sub_district?district_id=${values.district}`); + dataSubDistricts = dataSubDistricts.map((district) => ({ value: district.id, label: district.name })); setSubDistricts(dataSubDistricts); }; loadSubDistricts(); } - }, [ formInputs.district, handleSelectChange ]); - - const onSubmit = async () => { - const parameters = { - ...formInputs, - city_id: formInputs.city?.value, - district_id: formInputs.district?.value, - sub_district_id: formInputs.subDistrict?.value, - type: formInputs.type?.value, - parent_id: auth.partner_id, - }; - - const address = await apiOdoo('POST', '/api/v1/partner/address', parameters); - if (address?.id) { - handleFormReset(); - toast.success('Berhasil menambahkan alamat'); - router.back(); - } - } + }, [ values.district, setFieldValue ]); - // useEffect(() => { - // }, [formInputs]); - // console.log(_.isEmpty(formInputs), formInputs); - return ( <WithAuth> <Layout> <AppBar title="Tambah Alamat" /> - <Formik - initialValues={ initialFormValue } - validationSchema={ validationSchema } - > - {({ errors, touched }) => ( - <Form className="px-4 pb-4"> - <label className="form-label mt-4 mb-2">Label Alamat</label> - <Field name="type" placeholder="Pilih label alamat..." options={typesSelection} component={SelectFormik} /> - - <label className="form-label mt-4 mb-2">Nama</label> - <Field name="name" className='form-input' placeholder="John Doe" /> - { errors.name && touched.name && ( - <div className="text-caption-2 text-red_r-11 mt-1">{errors.name}</div> - ) } - - <label className="form-label mt-4 mb-2">Email</label> - <Field name="email" className='form-input' placeholder="hello@example.com" /> - { errors.email && touched.email && ( - <div className="text-caption-2 text-red_r-11 mt-1">{errors.email}</div> - ) } - </Form> - )} - </Formik> - - <form className="px-4 pb-4" onSubmit={(e) => handleFormSubmit(e, onSubmit)}> - { JSON.stringify(formInputs) } + <form onSubmit={handleSubmit} className="p-4 pt-0"> <label className="form-label mt-4 mb-2">Label Alamat</label> - <ReactSelect - placeholder="Pilih label alamat..." - classNamePrefix="form-select" - options={typesSelection} + <Select name="type" - onChange={(value) => handleSelectChange('type', value)} - value={formInputs?.type} + options={types} + setFieldValue={setFieldValue} + value={values.type} /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.type}</div> + { errors.type && touched.type && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.type }</div> + ) } - <label className="form-label mt-4 mb-2">Nama Kontak</label> + <label className="form-label mt-4 mb-2">Nama</label> <input - type="text" - className='form-input' + type="text" + className="form-input" placeholder="John Doe" + onChange={handleChange} + value={values.name} name="name" - onChange={handleInputChange} - value={formInputs.name} - aria-invalid={formErrors?.name} /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.name}</div> - + { errors.name && touched.name && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.name }</div> + ) } + <label className="form-label mt-4 mb-2">Email</label> <input - type="text" - className='form-input' - placeholder="johndoe@gmail.com" + type="email" + className="form-input" + placeholder="johndoe@example.com" + onChange={handleChange} + value={values.email} name="email" - value={formInputs.email} - onChange={handleInputChange} - aria-invalid={formErrors?.email} /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.email}</div> + { errors.email && touched.email && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.email }</div> + ) } <label className="form-label mt-4 mb-2">No. Handphone</label> <input - type="number" - className='form-input' + type="tel" + className="form-input" placeholder="08xxxxxxxx" + onChange={handleChange} + value={values.mobile} name="mobile" - value={formInputs.mobile} - onChange={handleInputChange} - aria-invalid={formErrors?.mobile} /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.mobile}</div> + { errors.mobile && touched.mobile && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.mobile }</div> + ) } <label className="form-label mt-4 mb-2">Alamat</label> <input - type="text" - className='form-input' - placeholder="Jl. Bandengan Utara" + type="text" + className="form-input" + placeholder="Jl. Bandengan Utara 85A" + onChange={handleChange} + value={values.street} name="street" - value={formInputs.street} - onChange={handleInputChange} - aria-invalid={formErrors?.street} /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.street}</div> + { errors.street && touched.street && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.street }</div> + ) } <label className="form-label mt-4 mb-2">Kode Pos</label> <input - type="number" - className='form-input' + type="number" + className="form-input" placeholder="10100" + onChange={handleChange} + value={values.zip} name="zip" - value={formInputs.zip} - onChange={handleInputChange} - aria-invalid={formErrors?.zip} /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.zip}</div> + { errors.zip && touched.zip && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.zip }</div> + ) } <label className="form-label mt-4 mb-2">Kota</label> - <ReactSelect - placeholder="Pilih kota..." - classNamePrefix="form-select" - classNames={{ control: (state) => state.menuIsOpen || state.isFocused ? '!border-yellow_r-9' : '' }} + <Select + name="city" options={cities} - value={formInputs.city} - onChange={(value) => handleSelectChange('city', value)} + setFieldValue={setFieldValue} + value={values.city} /> - <div className="text-caption-2 text-red_r-11 mt-1">{formErrors?.city}</div> + { errors.city && touched.city && ( + <div className="text-caption-2 text-red_r-11 mt-1">{ errors.city }</div> + ) } - <label className="form-label mt-4 mb-2">Kecamatan <span className="text-gray_r-10">(opsional)</span></label> - <ReactSelect - placeholder="Pilih Kecamatan..." - classNamePrefix="form-select" - classNames={{ control: (state) => state.menuIsOpen || state.isFocused ? '!border-yellow_r-9' : '' }} + <label className="form-label mt-4 mb-2">Kecamatan</label> + <Select + name="district" options={districts} - value={formInputs.district} - onChange={(value) => handleSelectChange('district', value)} - isDisabled={!formInputs.city} + setFieldValue={setFieldValue} + value={values.district} + disabled={!values.city} /> - <label className="form-label mt-4 mb-2">Kelurahan <span className="text-gray_r-10">(opsional)</span></label> - <ReactSelect - placeholder="Pilih Kelurahan..." - classNamePrefix="form-select" - classNames={{ control: (state) => state.menuIsOpen || state.isFocused ? '!border-yellow_r-9' : '' }} + <label className="form-label mt-4 mb-2">Kelurahan</label> + <Select + name="subDistrict" options={subDistricts} - onChange={(value) => handleSelectChange('subDistrict', value)} - value={formInputs.subDistrict} - isDisabled={!formInputs.district} + setFieldValue={setFieldValue} + value={values.subDistrict} + disabled={!values.district} /> <button |
