summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-01-16 12:10:51 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-01-16 12:10:51 +0700
commit059e91523af7d5f17c8357ec27a4512aa90feee3 (patch)
tree7350cbcd128dcb439df78652d3e7efb4b71c7313
parentb517722a1d370cbd7457cf98866b806832d61680 (diff)
Fix lag if type on mobile
-rw-r--r--src/components/Fields.js22
-rw-r--r--src/pages/my/address/[id]/edit.js375
-rw-r--r--src/pages/my/address/create.js307
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