summaryrefslogtreecommitdiff
path: root/src/lib/form/components
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2024-12-24 08:51:37 +0700
committerit-fixcomart <it@fixcomart.co.id>2024-12-24 08:51:37 +0700
commit22bf497d3fd524a95982e090f2c8a1be6bde656b (patch)
tree1c394154c78ea81e06b302eeffcb9dfb14497144 /src/lib/form/components
parentb2afb5c847c9983b098a3223fbcfdb666e65c8cb (diff)
parentd76f96c44f85e7e0efbd544e6b97bd80920b0039 (diff)
Merge branch 'new-release' into Feature/switch-account
# Conflicts: # src-migrate/modules/register/components/FormBisnis.tsx # src/lib/auth/components/Menu.jsx
Diffstat (limited to 'src/lib/form/components')
-rw-r--r--src/lib/form/components/KunjunganSales.jsx215
-rw-r--r--src/lib/form/components/KunjunganService.jsx361
-rw-r--r--src/lib/form/components/Merchant.jsx56
-rw-r--r--src/lib/form/components/RequestForQuotation.jsx215
-rw-r--r--src/lib/form/components/SuratDukungan.jsx33
5 files changed, 569 insertions, 311 deletions
diff --git a/src/lib/form/components/KunjunganSales.jsx b/src/lib/form/components/KunjunganSales.jsx
index ffa8f135..3779b836 100644
--- a/src/lib/form/components/KunjunganSales.jsx
+++ b/src/lib/form/components/KunjunganSales.jsx
@@ -1,17 +1,18 @@
-import odooApi from '@/core/api/odooApi'
-import HookFormSelect from '@/core/components/elements/Select/HookFormSelect'
-import cityApi from '@/lib/address/api/cityApi'
-import { yupResolver } from '@hookform/resolvers/yup'
-import React, { useEffect, useRef, useState } from 'react'
-import ReCAPTCHA from 'react-google-recaptcha'
-import { Controller, useForm } from 'react-hook-form'
-import { toast } from 'react-hot-toast'
-import * as Yup from 'yup'
-import createLeadApi from '../api/createLeadApi'
-import PageContent from '@/lib/content/components/PageContent'
-
-import useAuth from '@/core/hooks/useAuth'
-import { useRouter } from 'next/router'
+import odooApi from '@/core/api/odooApi';
+import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
+import cityApi from '@/lib/address/api/cityApi';
+import stateApi from '@/lib/address/api/stateApi.js';
+import { yupResolver } from '@hookform/resolvers/yup';
+import React, { useEffect, useRef, useState } from 'react';
+import ReCAPTCHA from 'react-google-recaptcha';
+import { Controller, useForm } from 'react-hook-form';
+import { toast } from 'react-hot-toast';
+import * as Yup from 'yup';
+import createLeadApi from '../api/createLeadApi';
+import PageContent from '@/lib/content/components/PageContent';
+
+import useAuth from '@/core/hooks/useAuth';
+import { useRouter } from 'next/router';
const KunjunganSales = () => {
const {
@@ -19,44 +20,72 @@ const KunjunganSales = () => {
handleSubmit,
formState: { errors },
control,
- reset
+ reset,
+ watch,
+ setValue,
} = useForm({
resolver: yupResolver(validationSchema),
- defaultValues
- })
- const [cities, setCities] = useState([])
- const [companyTypes, setCompanyTypes] = useState([])
- const router = useRouter()
+ defaultValues,
+ });
+ const [cities, setCities] = useState([]);
+ const [state, setState] = useState([]);
+ const [companyTypes, setCompanyTypes] = useState([]);
+ const router = useRouter();
+
+ const auth = useAuth();
- const auth = useAuth()
+ const recaptchaRef = useRef(null);
-
+ if (auth == false) {
+ router.push(`/login?next=${encodeURIComponent('/kunjungan-sales')}`);
+ }
+
+ useEffect(() => {
+ const loadState = async () => {
+ let dataState = await stateApi();
+ dataState = dataState.map((state) => ({
+ value: state.id,
+ label: state.name,
+ }));
+ setState(dataState);
+ };
+ loadState();
+ }, []);
- const recaptchaRef = useRef(null)
+ const watchState = watch('state');
useEffect(() => {
- if(auth == false) {
- router.push('/login')
+ if (auth == false) {
+ return;
}
const loadCities = async () => {
- let dataCities = await cityApi()
- dataCities = dataCities.map((obj) => ({ value: obj.name, label: obj.name }))
- setCities(dataCities)
- }
+ setValue('city', '');
+ let dataCities = await cityApi({ stateId: watchState });
+ dataCities = dataCities?.map((obj) => ({
+ value: obj.name,
+ label: obj.name,
+ }));
+ setCities(dataCities);
+ };
const loadCompanyTypes = async () => {
- const dataCompanyTypes = await odooApi('GET', '/api/v1/partner/company_type')
- setCompanyTypes(dataCompanyTypes?.map((obj) => ({ value: obj.name, label: obj.name })))
- }
+ const dataCompanyTypes = await odooApi(
+ 'GET',
+ '/api/v1/partner/company_type'
+ );
+ setCompanyTypes(
+ dataCompanyTypes?.map((obj) => ({ value: obj.name, label: obj.name }))
+ );
+ };
- loadCompanyTypes()
- loadCities()
- }, [auth])
+ loadCompanyTypes();
+ loadCities();
+ }, [auth, watchState, setValue]);
const onSubmitHandler = async (values) => {
- const recaptchaValue = recaptchaRef.current.getValue()
+ const recaptchaValue = recaptchaRef.current.getValue();
if (!recaptchaValue) {
- toast.error('Recaptcha harus diisi')
- return
+ toast.error('Recaptcha harus diisi');
+ return;
}
const data = {
@@ -71,29 +100,37 @@ const KunjunganSales = () => {
`Unit Perusahaan: ${values.companyType}`,
`No. Handphone: ${values.mobile}`,
`Alamat Email: ${values.email}`,
- `Keterangan: ${values.description}`
- ].join('\n')
- }
+ `Keterangan: ${values.description}`,
+ ].join('\n'),
+ };
- const createLead = await createLeadApi({ data })
+ const createLead = await createLeadApi({ data });
if (createLead) {
- toast.success('Berhasil mengirimkan formulir kunjungan sales')
- reset()
- recaptchaRef.current.reset()
+ toast.success('Berhasil mengirimkan formulir kunjungan sales');
+ reset();
+ recaptchaRef.current.reset();
}
+ };
+ if (!auth) {
+ return;
}
return (
<div className='container mx-auto p-4 md:p-0 my-0 md:my-10'>
- <h1 className='text-h-sm md:text-title-sm font-semibold mb-6'>Kunjungan Sales</h1>
+ <h1 className='text-h-sm md:text-title-sm font-semibold mb-6'>
+ Kunjungan Sales
+ </h1>
<div className='w-full grid grid-cols-1 md:grid-cols-2 gap-x-2'>
- <form onSubmit={handleSubmit(onSubmitHandler)} className='grid grid-cols-1 gap-y-6'>
+ <form
+ onSubmit={handleSubmit(onSubmitHandler)}
+ className='grid grid-cols-1 gap-y-6'
+ >
<div
className='flex items-center bg-blue-100 border border-blue-300 text-blue-500 font-medium px-4 py-3 rounded leading-6'
role='alert'
>
- Hubungi kami untuk mendapatkan kunjungan sales kami dan dapatkan berbagai kelebihannya
- dengan menjadi pelanggan korporat kami.
+ Hubungi kami untuk mendapatkan kunjungan sales kami dan dapatkan
+ berbagai kelebihannya dengan menjadi pelanggan korporat kami.
</div>
<div>
<label className='form-label mb-2'>Nama Perusahan*</label>
@@ -104,7 +141,9 @@ const KunjunganSales = () => {
className='form-input'
aria-invalid={errors.company?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.company?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.company?.message}
+ </div>
</div>
<div>
@@ -116,7 +155,9 @@ const KunjunganSales = () => {
className='form-input'
aria-invalid={errors.phone?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.phone?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.phone?.message}
+ </div>
</div>
<div>
@@ -128,7 +169,21 @@ const KunjunganSales = () => {
className='form-input'
aria-invalid={errors.address?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.address?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.address?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className='form-label mb-2'>Provinsi*</label>
+ <Controller
+ name='state'
+ control={control}
+ render={(props) => <HookFormSelect {...props} options={state} />}
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.stateId?.message}
+ </div>
</div>
<div>
@@ -138,7 +193,9 @@ const KunjunganSales = () => {
control={control}
render={(props) => <HookFormSelect {...props} options={cities} />}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.city?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.city?.message}
+ </div>
</div>
<div>
@@ -146,9 +203,13 @@ const KunjunganSales = () => {
<Controller
name='companyType'
control={control}
- render={(props) => <HookFormSelect {...props} options={companyTypes} />}
+ render={(props) => (
+ <HookFormSelect {...props} options={companyTypes} />
+ )}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.companyType?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.companyType?.message}
+ </div>
</div>
<div>
@@ -160,7 +221,9 @@ const KunjunganSales = () => {
className='form-input'
aria-invalid={errors.mobile?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.mobile?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.mobile?.message}
+ </div>
</div>
<div>
@@ -172,34 +235,49 @@ const KunjunganSales = () => {
className='form-input'
aria-invalid={errors.email?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.email?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.email?.message}
+ </div>
</div>
<div>
<label className='form-label mb-2'>Keterangan</label>
- <textarea {...register('description')} type='text' className='form-input' />
+ <textarea
+ {...register('description')}
+ type='text'
+ className='form-input'
+ />
</div>
- <ReCAPTCHA ref={recaptchaRef} sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} />
+ <ReCAPTCHA
+ ref={recaptchaRef}
+ sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE}
+ />
- <button type='submit' className='btn-yellow w-full md:w-fit ml-0 md:ml-auto'>
+ <button
+ type='submit'
+ className='btn-yellow w-full md:w-fit ml-0 md:ml-auto'
+ >
Simpan
</button>
</form>
<PageContent path='/kunjungan-sales' />
</div>
</div>
- )
-}
+ );
+};
const validationSchema = Yup.object().shape({
- email: Yup.string().email('Format harus seperti contoh@email.com').required('Harus di-isi'),
+ email: Yup.string()
+ .email('Format harus seperti contoh@email.com')
+ .required('Harus di-isi'),
company: Yup.string().required('Harus di-isi'),
phone: Yup.string().required('Harus di-isi'),
mobile: Yup.string().required('Harus di-isi'),
address: Yup.string().required('Harus di-isi'),
- city: Yup.string().required('Harus dipilih')
-})
+ city: Yup.string().required('Harus dipilih'),
+ state: Yup.string().required('Harus dipilih'),
+});
const defaultValues = {
email: '',
@@ -208,8 +286,9 @@ const defaultValues = {
mobile: '',
address: '',
city: '',
+ state: '',
companyType: '',
- description: ''
-}
+ description: '',
+};
-export default KunjunganSales
+export default KunjunganSales;
diff --git a/src/lib/form/components/KunjunganService.jsx b/src/lib/form/components/KunjunganService.jsx
index 5720d14e..e3c83f78 100644
--- a/src/lib/form/components/KunjunganService.jsx
+++ b/src/lib/form/components/KunjunganService.jsx
@@ -1,16 +1,17 @@
-import HookFormSelect from '@/core/components/elements/Select/HookFormSelect'
-import cityApi from '@/lib/address/api/cityApi'
-import { yupResolver } from '@hookform/resolvers/yup'
-import React, { useEffect, useRef, useState } from 'react'
-import ReCAPTCHA from 'react-google-recaptcha'
-import { Controller, useForm } from 'react-hook-form'
-import { toast } from 'react-hot-toast'
-import * as Yup from 'yup'
-import createLeadApi from '../api/createLeadApi'
-import PageContent from '@/lib/content/components/PageContent'
-import { useRouter } from 'next/router'
+import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
+import cityApi from '@/lib/address/api/cityApi';
+import stateApi from '@/lib/address/api/stateApi.js';
+import { yupResolver } from '@hookform/resolvers/yup';
+import React, { useEffect, useRef, useState } from 'react';
+import ReCAPTCHA from 'react-google-recaptcha';
+import { Controller, useForm } from 'react-hook-form';
+import { toast } from 'react-hot-toast';
+import * as Yup from 'yup';
+import createLeadApi from '../api/createLeadApi';
+import PageContent from '@/lib/content/components/PageContent';
+import { useRouter } from 'next/router';
-import useAuth from '@/core/hooks/useAuth'
+import useAuth from '@/core/hooks/useAuth';
const CreateKunjunganService = () => {
const {
@@ -18,37 +19,61 @@ const CreateKunjunganService = () => {
handleSubmit,
formState: { errors },
control,
- reset
+ reset,
+ watch,
+ setValue,
} = useForm({
resolver: yupResolver(validationSchema),
- defaultValues
- })
- const [cities, setCities] = useState([])
- const [company_unit, setCompany_unit] = useState([])
-
- const router = useRouter()
+ defaultValues,
+ });
+ const [cities, setCities] = useState([]);
+ const [state, setState] = useState([]);
+ const [company_unit, setCompany_unit] = useState([]);
- const auth = useAuth()
+ const router = useRouter();
- const recaptchaRef = useRef(null)
+ const auth = useAuth();
+ if (auth == false) {
+ router.push(`/login?next=${encodeURIComponent('/kunjungan-service')}`);
+ }
+
+ const recaptchaRef = useRef(null);
+
+ useEffect(() => {
+ const loadState = async () => {
+ let dataState = await stateApi();
+ dataState = dataState.map((state) => ({
+ value: state.id,
+ label: state.name,
+ }));
+ setState(dataState);
+ };
+ loadState();
+ }, []);
+
+ const watchState = watch('state');
useEffect(() => {
- if(auth == false) {
- router.push('/login')
+ if (auth == false) {
+ return;
}
const loadCities = async () => {
- let dataCities = await cityApi()
- dataCities = dataCities.map((city) => ({ value: city.id, label: city.name }))
- setCities(dataCities)
- }
- loadCities()
- }, [auth])
+ setValue('city', '');
+ let dataCities = await cityApi({ stateId: watchState });
+ dataCities = dataCities.map((city) => ({
+ value: city.id,
+ label: city.name,
+ }));
+ setCities(dataCities);
+ };
+ loadCities();
+ }, [auth, watchState, setValue]);
const onSubmitHandler = async (values) => {
- const recaptchaValue = recaptchaRef.current.getValue()
+ const recaptchaValue = recaptchaRef.current.getValue();
if (!recaptchaValue) {
- toast.error('Catcha harus diisi')
- return
+ toast.error('Catcha harus diisi');
+ return;
}
const data = {
...values,
@@ -70,164 +95,212 @@ const CreateKunjunganService = () => {
' \r\n Email : ' +
values.email +
' \r\n Keterangan : ' +
- values.description
- }
+ values.description,
+ };
- const create_leads = await createLeadApi({ data })
+ const create_leads = await createLeadApi({ data });
if (create_leads) {
- toast.success('Berhasil menambahkan alamat')
- reset()
- recaptchaRef.current.reset()
+ toast.success('Berhasil menambahkan alamat');
+ reset();
+ recaptchaRef.current.reset();
}
+ };
+ if (!auth) {
+ return;
}
return (
<div className='container mx-auto p-4 md:p-0 my-0 md:my-10'>
- <h1 className='text-h-sm md:text-title-sm font-semibold mb-6'>Kunjungan Service</h1>
+ <h1 className='text-h-sm md:text-title-sm font-semibold mb-6'>
+ Kunjungan Service
+ </h1>
<div className='w-full p-4 bg-white border border-gray_r-6 rounded'>
<div
className='flex items-center bg-blue-100 border border-blue-400 text-blue-500 font-bold px-4 py-3 mb-4'
role='alert'
>
<p>
- Tidak punya waktu untuk melakukan service atau perawatan rutin? Silahkan hubungi teknisi
- kami untuk melakukan kunjungan ke tempat Anda di Jabodetabek.
+ Tidak punya waktu untuk melakukan service atau perawatan rutin?
+ Silahkan hubungi teknisi kami untuk melakukan kunjungan ke tempat
+ Anda di Jabodetabek.
</p>
</div>
<div className='w-full grid grid-cols-2 gap-x-2'>
-
- <form onSubmit={handleSubmit(onSubmitHandler)}>
- <div className=''>
- <div>
- <label className='form-label mb-2'>Nama Perusahan *</label>
- <input
- {...register('company')}
- placeholder='PT.Indoteknik'
- type='text'
- className='form-input'
- />
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.company?.message}</div>
+ <form onSubmit={handleSubmit(onSubmitHandler)}>
+ <div className=''>
+ <div>
+ <label className='form-label mb-2'>Nama Perusahan *</label>
+ <input
+ {...register('company')}
+ placeholder='PT.Indoteknik'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.company?.message}
+ </div>
+ </div>
</div>
- </div>
- <div className=''>
- <div>
- <label className='form-label mb-2'>No. Telp *</label>
- <input
- {...register('phone')}
- placeholder='021-XXXX'
- type='text'
- className='form-input'
- />
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.phone?.message}</div>
+ <div className=''>
+ <div>
+ <label className='form-label mb-2'>No. Telp *</label>
+ <input
+ {...register('phone')}
+ placeholder='021-XXXX'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.phone?.message}
+ </div>
+ </div>
</div>
- </div>
- <div className=''>
- <div>
- <label className='form-label mb-2'>Alamat*</label>
- <input
- {...register('address')}
- placeholder='jl. Bandengan no.31 '
- type='text'
- className='form-input'
- />
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.address?.message}</div>
+ <div className=''>
+ <div>
+ <label className='form-label mb-2'>Alamat*</label>
+ <input
+ {...register('address')}
+ placeholder='jl. Bandengan no.31 '
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.address?.message}
+ </div>
+ </div>
</div>
- </div>
- <div className=''>
<div>
- <label className='form-label mb-2'>Kota*</label>
+ <label className='form-label mb-2'>Provinsi*</label>
<Controller
- name='city'
+ name='state'
control={control}
- render={(props) => <HookFormSelect {...props} options={cities} />}
+ render={(props) => (
+ <HookFormSelect {...props} options={state} />
+ )}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.city?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.state?.message}
+ </div>
</div>
- </div>
- <div className=''>
- <div>
- <label className='form-label mb-2'>Contact Person*</label>
- <input
- {...register('cp')}
- placeholder='Jhone doe'
- type='text'
- className='form-input'
- />
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.cp?.message}</div>
+ <div className=''>
+ <div>
+ <label className='form-label mb-2'>Kota*</label>
+ <Controller
+ name='city'
+ control={control}
+ render={(props) => (
+ <HookFormSelect {...props} options={cities} />
+ )}
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.city?.message}
+ </div>
+ </div>
</div>
- </div>
- <div className=''>
- <div>
- <label className='form-label mb-2'>No HP *</label>
- <input
- {...register('mobile')}
- placeholder='628XXXXXXX'
- type='text'
- className='form-input'
- />
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.mobile?.message}</div>
+ <div className=''>
+ <div>
+ <label className='form-label mb-2'>Contact Person*</label>
+ <input
+ {...register('cp')}
+ placeholder='Jhone doe'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.cp?.message}
+ </div>
+ </div>
</div>
- </div>
- <div className=''>
- <div>
- <label className='form-label mb-2'>Alamat Email *</label>
- <input
- {...register('email')}
- placeholder='contoh@email.com'
- type='email'
- className='form-input'
- />
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.email?.message}</div>
+ <div className=''>
+ <div>
+ <label className='form-label mb-2'>No HP *</label>
+ <input
+ {...register('mobile')}
+ placeholder='628XXXXXXX'
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.mobile?.message}
+ </div>
+ </div>
</div>
- </div>
- <div className=''>
- <div>
- <label className='form-label mb-2'>
- Sebutkan: Merek, Tipe, Permasalahan, Service, Perawatan
- </label>
- <textarea {...register('description')} type='text' className='form-input' />
- <div className='text-caption-2 text-danger-500 mt-1'>
- {errors.description?.message}
+ <div className=''>
+ <div>
+ <label className='form-label mb-2'>Alamat Email *</label>
+ <input
+ {...register('email')}
+ placeholder='contoh@email.com'
+ type='email'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.email?.message}
+ </div>
</div>
</div>
- </div>
- <div className=''>
- <div>
- <ReCAPTCHA ref={recaptchaRef} sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} />
+ <div className=''>
+ <div>
+ <label className='form-label mb-2'>
+ Sebutkan: Merek, Tipe, Permasalahan, Service, Perawatan
+ </label>
+ <textarea
+ {...register('description')}
+ type='text'
+ className='form-input'
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.description?.message}
+ </div>
+ </div>
</div>
- </div>
- <div className=''>
- <div>
- <button type='submit' className='btn-yellow w-full md:w-fit mt-6 ml-0 md:ml-auto'>
- Simpan
- </button>
+ <div className=''>
+ <div>
+ <ReCAPTCHA
+ ref={recaptchaRef}
+ sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE}
+ />
+ </div>
+ </div>
+ <div className=''>
+ <div>
+ <button
+ type='submit'
+ className='btn-yellow w-full md:w-fit mt-6 ml-0 md:ml-auto'
+ >
+ Simpan
+ </button>
+ </div>
</div>
- </div>
- </form>
- <PageContent path='/kunjungan-service' />
+ </form>
+ <PageContent path='/kunjungan-service' />
</div>
</div>
</div>
- )
-}
+ );
+};
const validationSchema = Yup.object().shape({
company: Yup.string().required('Harus di-isi'),
- email: Yup.string().email('Format harus seperti contoh@email.com').required('Harus di-isi'),
+ email: Yup.string()
+ .email('Format harus seperti contoh@email.com')
+ .required('Harus di-isi'),
phone: Yup.string().required('Harus di-isi'),
city: Yup.string().required('Harus di-isi'),
+ state: Yup.string().required('Harus dipilih'),
cp: Yup.string().required('Harus di-isi'),
mobile: Yup.string().required('Harus di-isi'),
email: Yup.string().required('Harus di-isi'),
- address: Yup.string().required('Harus di-isi')
-})
+ address: Yup.string().required('Harus di-isi'),
+});
const defaultValues = {
company: '',
email: '',
phone: '',
city: '',
+ state: '',
cp: '',
mobile: '',
email: '',
- address: ''
-}
+ address: '',
+};
-export default CreateKunjunganService
+export default CreateKunjunganService;
diff --git a/src/lib/form/components/Merchant.jsx b/src/lib/form/components/Merchant.jsx
index 85f72bf8..ee7d177d 100644
--- a/src/lib/form/components/Merchant.jsx
+++ b/src/lib/form/components/Merchant.jsx
@@ -1,5 +1,6 @@
import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
import cityApi from '@/lib/address/api/cityApi';
+import stateApi from '@/lib/address/api/stateApi.js';
import { yupResolver } from '@hookform/resolvers/yup';
import React, { useEffect, useRef, useState } from 'react';
import ReCAPTCHA from 'react-google-recaptcha';
@@ -9,8 +10,7 @@ import * as Yup from 'yup';
import createLeadApi from '../api/createLeadApi';
import PageContent from '@/lib/content/components/PageContent';
import { useRouter } from 'next/router';
-import useAuth from '@/core/hooks/useAuth'
-
+import useAuth from '@/core/hooks/useAuth';
const CreateMerchant = () => {
const {
@@ -19,6 +19,8 @@ const CreateMerchant = () => {
formState: { errors },
control,
reset,
+ watch,
+ setValue,
} = useForm({
resolver: yupResolver(validationSchema),
defaultValues,
@@ -50,27 +52,45 @@ const CreateMerchant = () => {
},
];
const [cities, setCities] = useState([]);
+ const [state, setState] = useState([]);
const [company_unit, setCompany_unit] = useState(list_unit);
const recaptchaRef = useRef(null);
- const router = useRouter()
+ const router = useRouter();
+
+ const auth = useAuth();
+ if (auth == false) {
+ router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`);
+ }
- const auth = useAuth()
+ useEffect(() => {
+ const loadState = async () => {
+ let dataState = await stateApi();
+ dataState = dataState.map((state) => ({
+ value: state.id,
+ label: state.name,
+ }));
+ setState(dataState);
+ };
+ loadState();
+ }, []);
+ const watchState = watch('state');
useEffect(() => {
- if(auth == false) {
- router.push('/login')
+ if (auth == false) {
+ return;
}
const loadCities = async () => {
- let dataCities = await cityApi();
- dataCities = dataCities.map((city) => ({
+ setValue('city', '');
+ let dataCities = await cityApi({ stateId: watchState });
+ dataCities = dataCities?.map((city) => ({
value: city.id,
label: city.name,
}));
setCities(dataCities);
};
loadCities();
- }, [auth]);
+ }, [auth, watchState, setValue]);
const onSubmitHandler = async (values) => {
const recaptchaValue = recaptchaRef.current.getValue();
@@ -111,6 +131,9 @@ const CreateMerchant = () => {
recaptchaRef.current.reset();
}
};
+ if (!auth) {
+ return;
+ }
return (
<div className='container mx-auto p-4 md:p-0 my-0 md:my-10'>
<h1 className='text-h-sm md:text-title-sm font-semibold mb-6'>
@@ -172,6 +195,19 @@ const CreateMerchant = () => {
</div>
</div>
</div>
+ <div>
+ <label className='form-label mb-2'>Provinsi*</label>
+ <Controller
+ name='state'
+ control={control}
+ render={(props) => (
+ <HookFormSelect {...props} options={state} />
+ )}
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.state?.message}
+ </div>
+ </div>
<div className=''>
<div>
<label className='form-label mb-2'>Kota*</label>
@@ -290,6 +326,7 @@ const validationSchema = Yup.object().shape({
.required('Harus di-isi'),
phone: Yup.string().required('Harus di-isi'),
cp: Yup.string().required('Harus di-isi'),
+ state: Yup.string().required('Harus dipilih'),
city: Yup.string().required('Harus di-isi'),
company_unit: Yup.string().required('Harus di-isi'),
address: Yup.string().required('Harus di-isi'),
@@ -300,6 +337,7 @@ const defaultValues = {
company: '',
email: '',
phone: '',
+ state: '',
city: '',
company_unit: '',
cp: '',
diff --git a/src/lib/form/components/RequestForQuotation.jsx b/src/lib/form/components/RequestForQuotation.jsx
index 68b7fa17..170a5c62 100644
--- a/src/lib/form/components/RequestForQuotation.jsx
+++ b/src/lib/form/components/RequestForQuotation.jsx
@@ -1,18 +1,19 @@
-import odooApi from '@/core/api/odooApi'
-import HookFormSelect from '@/core/components/elements/Select/HookFormSelect'
-import cityApi from '@/lib/address/api/cityApi'
-import { yupResolver } from '@hookform/resolvers/yup'
-import React, { useEffect, useRef, useState } from 'react'
-import ReCAPTCHA from 'react-google-recaptcha'
-import { Controller, useForm } from 'react-hook-form'
-import { toast } from 'react-hot-toast'
-import * as Yup from 'yup'
-import createLeadApi from '../api/createLeadApi'
-import getFileBase64 from '@/core/utils/getFileBase64'
-import PageContent from '@/lib/content/components/PageContent'
-import { useRouter } from 'next/router'
-
-import useAuth from '@/core/hooks/useAuth'
+import odooApi from '@/core/api/odooApi';
+import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
+import cityApi from '@/lib/address/api/cityApi';
+import stateApi from '@/lib/address/api/stateApi.js';
+import { yupResolver } from '@hookform/resolvers/yup';
+import React, { useEffect, useRef, useState } from 'react';
+import ReCAPTCHA from 'react-google-recaptcha';
+import { Controller, useForm } from 'react-hook-form';
+import { toast } from 'react-hot-toast';
+import * as Yup from 'yup';
+import createLeadApi from '../api/createLeadApi';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import PageContent from '@/lib/content/components/PageContent';
+import { useRouter } from 'next/router';
+
+import useAuth from '@/core/hooks/useAuth';
const RequestForQuotation = () => {
const {
@@ -20,47 +21,69 @@ const RequestForQuotation = () => {
handleSubmit,
formState: { errors },
control,
- reset
+ reset,
+ watch,
+ setValue,
} = useForm({
resolver: yupResolver(validationSchema),
- defaultValues
- })
- const [cities, setCities] = useState([])
+ defaultValues,
+ });
+ const [cities, setCities] = useState([]);
+ const [state, setState] = useState([]);
- const quotationFileRef = useRef(null)
- const recaptchaRef = useRef(null)
- const router = useRouter()
+ const quotationFileRef = useRef(null);
+ const recaptchaRef = useRef(null);
+ const router = useRouter();
- const auth = useAuth()
+ const auth = useAuth();
+ if (auth == false) {
+ router.push(`/login?next=${encodeURIComponent('/request-for-quotation')}`);
+ }
+ useEffect(() => {
+ const loadState = async () => {
+ let dataState = await stateApi();
+ dataState = dataState.map((state) => ({
+ value: state.id,
+ label: state.name,
+ }));
+ setState(dataState);
+ };
+ loadState();
+ }, []);
+ const watchState = watch('state');
useEffect(() => {
- if(auth == false) {
- router.push('/login')
+ if (!auth) {
+ return;
}
const loadCities = async () => {
- let dataCities = await cityApi()
- dataCities = dataCities.map((obj) => ({ value: obj.name, label: obj.name }))
- setCities(dataCities)
- }
- loadCities()
- }, [auth])
+ setValue('city', '');
+ let dataCities = await cityApi({ stateId: watchState });
+ dataCities = dataCities?.map((obj) => ({
+ value: obj.name,
+ label: obj.name,
+ }));
+ setCities(dataCities);
+ };
+ loadCities();
+ }, [auth, watchState, setValue]);
const onSubmitHandler = async (values) => {
- const recaptchaValue = recaptchaRef.current.getValue()
+ const recaptchaValue = recaptchaRef.current.getValue();
if (!recaptchaValue) {
- toast.error('Recaptcha harus diisi')
- return
+ toast.error('Recaptcha harus diisi');
+ return;
}
- const file = quotationFileRef.current.files[0]
- let fileBase64 = null
+ const file = quotationFileRef.current.files[0];
+ let fileBase64 = null;
if (typeof file !== 'undefined') {
if (file.size > 5000000) {
- toast.error('Maksimal ukuran file adalah 5MB')
- return
+ toast.error('Maksimal ukuran file adalah 5MB');
+ return;
}
- fileBase64 = await getFileBase64(file)
+ fileBase64 = await getFileBase64(file);
}
const data = {
@@ -73,33 +96,42 @@ const RequestForQuotation = () => {
`Kota: ${values.city}`,
`No. Handphone: ${values.mobile}`,
`Alamat Email: ${values.email}`,
- `Keterangan: ${values.description}`
- ].join('\n')
- }
+ `Keterangan: ${values.description}`,
+ ].join('\n'),
+ };
- if (fileBase64) data.file_quotation = fileBase64
+ if (fileBase64) data.file_quotation = fileBase64;
- const createLead = await createLeadApi({ data })
+ const createLead = await createLeadApi({ data });
if (createLead) {
- toast.success('Berhasil mengirimkan formulir request for quotation')
- reset()
- recaptchaRef.current.reset()
+ toast.success('Berhasil mengirimkan formulir request for quotation');
+ reset();
+ recaptchaRef.current.reset();
}
+ };
+ if (!auth) {
+ return;
}
return (
<div className='container mx-auto p-4 md:p-0 my-0 md:my-10'>
- <h1 className='text-h-sm md:text-title-sm font-semibold mb-6'>Request for Quotation</h1>
+ <h1 className='text-h-sm md:text-title-sm font-semibold mb-6'>
+ Request for Quotation
+ </h1>
<div className='w-full grid grid-cols-1 md:grid-cols-2 gap-x-2'>
- <form onSubmit={handleSubmit(onSubmitHandler)} className='grid grid-cols-1 gap-y-6'>
+ <form
+ onSubmit={handleSubmit(onSubmitHandler)}
+ className='grid grid-cols-1 gap-y-6'
+ >
<div
className='flex items-center bg-blue-100 border border-blue-300 text-blue-500 font-medium px-4 py-3 rounded leading-6'
role='alert'
>
- Halaman untuk pengajuan penawaran harga, lengkapi data di bawah ini dengan jelas untuk
- mempermudah tim support kami melayani kebutuhan Anda. Tim kami akan sesegera mungkin
- untuk membuatkan penawaran harga terbaik, hubungi kami melalui telpon jika ada
- keterlambatan pelayanan.
+ Halaman untuk pengajuan penawaran harga, lengkapi data di bawah ini
+ dengan jelas untuk mempermudah tim support kami melayani kebutuhan
+ Anda. Tim kami akan sesegera mungkin untuk membuatkan penawaran
+ harga terbaik, hubungi kami melalui telpon jika ada keterlambatan
+ pelayanan.
</div>
<div>
<label className='form-label mb-2'>Nama Perusahan*</label>
@@ -110,7 +142,9 @@ const RequestForQuotation = () => {
className='form-input'
aria-invalid={errors.company?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.company?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.company?.message}
+ </div>
</div>
<div>
@@ -122,7 +156,21 @@ const RequestForQuotation = () => {
className='form-input'
aria-invalid={errors.phone?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.phone?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.phone?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className='form-label mb-2'>Provinsi*</label>
+ <Controller
+ name='state'
+ control={control}
+ render={(props) => <HookFormSelect {...props} options={state} />}
+ />
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.state?.message}
+ </div>
</div>
<div>
@@ -132,7 +180,9 @@ const RequestForQuotation = () => {
control={control}
render={(props) => <HookFormSelect {...props} options={cities} />}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.city?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.city?.message}
+ </div>
</div>
<div>
@@ -144,7 +194,9 @@ const RequestForQuotation = () => {
className='form-input'
aria-invalid={errors.contactPerson?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.contactPerson?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.contactPerson?.message}
+ </div>
</div>
<div>
@@ -156,7 +208,9 @@ const RequestForQuotation = () => {
className='form-input'
aria-invalid={errors.mobile?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.mobile?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.mobile?.message}
+ </div>
</div>
<div>
@@ -168,39 +222,59 @@ const RequestForQuotation = () => {
className='form-input'
aria-invalid={errors.email?.message}
/>
- <div className='text-caption-2 text-danger-500 mt-1'>{errors.email?.message}</div>
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.email?.message}
+ </div>
</div>
<div>
<label className='form-label mb-2'>Keterangan</label>
- <textarea {...register('description')} type='text' className='form-input' />
+ <textarea
+ {...register('description')}
+ type='text'
+ className='form-input'
+ />
</div>
<div>
<label className='form-label mb-2'>File Daftar Produk</label>
- <input type="file" name="quotationFile" className='form-input' ref={quotationFileRef} />
+ <input
+ type='file'
+ name='quotationFile'
+ className='form-input'
+ ref={quotationFileRef}
+ />
</div>
- <ReCAPTCHA ref={recaptchaRef} sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} />
+ <ReCAPTCHA
+ ref={recaptchaRef}
+ sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE}
+ />
- <button type='submit' className='btn-yellow w-full md:w-fit ml-0 md:ml-auto'>
+ <button
+ type='submit'
+ className='btn-yellow w-full md:w-fit ml-0 md:ml-auto'
+ >
Simpan
</button>
</form>
<PageContent path='/request-for-quotation' />
</div>
</div>
- )
-}
+ );
+};
const validationSchema = Yup.object().shape({
- email: Yup.string().email('Format harus seperti contoh@email.com').required('Harus di-isi'),
+ email: Yup.string()
+ .email('Format harus seperti contoh@email.com')
+ .required('Harus di-isi'),
company: Yup.string().required('Harus di-isi'),
phone: Yup.string().required('Harus di-isi'),
mobile: Yup.string().required('Harus di-isi'),
city: Yup.string().required('Harus dipilih'),
+ state: Yup.string().required('Harus dipilih'),
contactPerson: Yup.string().required('Harus dipilih'),
-})
+});
const defaultValues = {
email: '',
@@ -209,7 +283,8 @@ const defaultValues = {
mobile: '',
address: '',
city: '',
- description: ''
-}
+ state: '',
+ description: '',
+};
-export default RequestForQuotation
+export default RequestForQuotation;
diff --git a/src/lib/form/components/SuratDukungan.jsx b/src/lib/form/components/SuratDukungan.jsx
index 31e7ee83..fadb2c57 100644
--- a/src/lib/form/components/SuratDukungan.jsx
+++ b/src/lib/form/components/SuratDukungan.jsx
@@ -1,5 +1,6 @@
import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
import cityApi from '@/lib/address/api/cityApi';
+import stateApi from '@/lib/address/api/stateApi.js';
import { yupResolver } from '@hookform/resolvers/yup';
import React, { useEffect, useRef, useState } from 'react';
import ReCAPTCHA from 'react-google-recaptcha';
@@ -10,7 +11,7 @@ import createLeadsApi from '../api/createLeadApi';
import PageContent from '@/lib/content/components/PageContent';
-import useAuth from '@/core/hooks/useAuth'
+import useAuth from '@/core/hooks/useAuth';
import { useRouter } from 'next/router';
const CreateSuratDukungan = () => {
@@ -20,32 +21,21 @@ const CreateSuratDukungan = () => {
formState: { errors },
control,
reset,
+ watch,
+ setValue,
} = useForm({
resolver: yupResolver(validationSchema),
defaultValues,
});
- const [cities, setCities] = useState([]);
const [company_unit, setCompany_unit] = useState([]);
const recaptchaRef = useRef(null);
- const router = useRouter()
+ const router = useRouter();
- const auth = useAuth()
-
- useEffect(() => {
- if(auth == false) {
- router.push('/login')
- }
- const loadCities = async () => {
- let dataCities = await cityApi();
- dataCities = dataCities.map((city) => ({
- value: city.id,
- label: city.name,
- }));
- setCities(dataCities);
- };
- loadCities();
- }, [auth]);
+ const auth = useAuth();
+ if (auth == false) {
+ router.push(`/login?next=${encodeURIComponent('/surat-dukungan')}`);
+ }
const onSubmitHandler = async (values) => {
const recaptchaValue = recaptchaRef.current.getValue();
@@ -85,6 +75,9 @@ const CreateSuratDukungan = () => {
recaptchaRef.current.reset();
}
};
+ if (!auth) {
+ return;
+ }
return (
<div className='container mx-auto p-4 md:p-0 my-0 md:my-10'>
<h1 className='text-h-sm md:text-title-sm font-semibold mb-6'>
@@ -241,7 +234,7 @@ const CreateSuratDukungan = () => {
</div>
</form>
</div>
- <PageContent path='/surat-dukungan'/>
+ <PageContent path='/surat-dukungan' />
</div>
</div>
</div>