From b3be7e6d5c320764ef3ca38df196218abf9be25b Mon Sep 17 00:00:00 2001
From: it-fixcomart <it@fixcomart.co.id>
Date: Tue, 10 Dec 2024 10:05:47 +0700
Subject: <iman> move formulis & add state field

---
 src/lib/form/components/RequestForQuotation.jsx | 215 ++++++++++++++++--------
 1 file changed, 145 insertions(+), 70 deletions(-)

(limited to 'src/lib/form/components/RequestForQuotation.jsx')

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;
-- 
cgit v1.2.3


From 9c4951174cf6cf5c15b0b2a808d5d14befac6169 Mon Sep 17 00:00:00 2001
From: it-fixcomart <it@fixcomart.co.id>
Date: Wed, 15 Jan 2025 13:40:59 +0700
Subject: <iman> update code filter bad words registrasi

---
 src/lib/form/components/RequestForQuotation.jsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/lib/form/components/RequestForQuotation.jsx')

diff --git a/src/lib/form/components/RequestForQuotation.jsx b/src/lib/form/components/RequestForQuotation.jsx
index 170a5c62..8861338f 100644
--- a/src/lib/form/components/RequestForQuotation.jsx
+++ b/src/lib/form/components/RequestForQuotation.jsx
@@ -42,7 +42,7 @@ const RequestForQuotation = () => {
 
   useEffect(() => {
     const loadState = async () => {
-      let dataState = await stateApi();
+      let dataState = await stateApi({ tempo: false });
       dataState = dataState.map((state) => ({
         value: state.id,
         label: state.name,
-- 
cgit v1.2.3

