diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-01-13 17:03:51 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-01-13 17:03:51 +0700 |
| commit | b517722a1d370cbd7457cf98866b806832d61680 (patch) | |
| tree | 907fedb193ece168f84cdc046c3fb9490406fe4c /src | |
| parent | 99c4d78b198d6baaded5b96a604525feb1b099ba (diff) | |
Formik and yup implement
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/SelectFormik.js | 18 | ||||
| -rw-r--r-- | src/pages/my/address/create.js | 266 | ||||
| -rw-r--r-- | src/styles/globals.css | 13 |
3 files changed, 181 insertions, 116 deletions
diff --git a/src/components/SelectFormik.js b/src/components/SelectFormik.js new file mode 100644 index 00000000..4fd711c5 --- /dev/null +++ b/src/components/SelectFormik.js @@ -0,0 +1,18 @@ +import ReactSelect from "react-select"; + +const SelectFormik = ({ + options, + field, + form +}) => { + return <ReactSelect + options={options} + name={field.name} + value={options ? options.find(option => option.value === field.value) : ''} + onChange={(option) => form.setFieldValue(field.name, option.value)} + onBlur={field.onBlur} + classNamePrefix={field} + /> +} + +export default SelectFormik;
\ No newline at end of file diff --git a/src/pages/my/address/create.js b/src/pages/my/address/create.js index 457429e3..f11a7b67 100644 --- a/src/pages/my/address/create.js +++ b/src/pages/my/address/create.js @@ -9,6 +9,9 @@ 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, @@ -20,7 +23,13 @@ const initialFormValue = { district: null, subDistrict: null, zip: '' -} +}; + +const validationSchema = Yup.object().shape({ + name: Yup.string() + .min(2, 'Minimal karakter 2') + .required('Harus di-isi') +}); const validationScheme = { type: ['label:Label Alamat', 'required'], @@ -110,126 +119,153 @@ export default function CreateAddress() { router.back(); } } + + // useEffect(() => { + // }, [formInputs]); + // console.log(_.isEmpty(formInputs), formInputs); return ( <WithAuth> <Layout> <AppBar title="Tambah 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> - ) } + <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) } + <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> </Layout> </WithAuth> ); diff --git a/src/styles/globals.css b/src/styles/globals.css index e223036b..6c0a7607 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -124,7 +124,8 @@ html, body { .btn-yellow, .btn-light, - .btn-red { + .btn-red, + .btn-green { @apply block w-fit @@ -159,6 +160,16 @@ html, body { ; } + .btn-green { + @apply + bg-green_r-3 + border-green_r-6 + text-green_r-11 + disabled:text-green_r-10 + disabled:bg-green_r-6 + ; + } + .btn-light { @apply bg-gray_r-3 |
