diff options
| author | Miqdad <ahmadmiqdad27@gmail.com> | 2025-05-23 09:38:22 +0700 |
|---|---|---|
| committer | Miqdad <ahmadmiqdad27@gmail.com> | 2025-05-23 09:38:22 +0700 |
| commit | a2c424ebb371ce2716d7fc55bb70807303c2e0e0 (patch) | |
| tree | 1a4bbbcf7cee381e10fa473926223abfe7c4bcf8 /src/lib/merchant/components/SyaratDagang.jsx | |
| parent | 4904573845478e7e9648735d008153728870a123 (diff) | |
| parent | 60cbad2ae4b551d8f1e6959a3c90134c16b10e26 (diff) | |
Merge branch 'new-release' of https://bitbucket.org/altafixco/next-indoteknik.giT into fix_responsive_cart
Diffstat (limited to 'src/lib/merchant/components/SyaratDagang.jsx')
| -rw-r--r-- | src/lib/merchant/components/SyaratDagang.jsx | 822 |
1 files changed, 822 insertions, 0 deletions
diff --git a/src/lib/merchant/components/SyaratDagang.jsx b/src/lib/merchant/components/SyaratDagang.jsx new file mode 100644 index 00000000..96681064 --- /dev/null +++ b/src/lib/merchant/components/SyaratDagang.jsx @@ -0,0 +1,822 @@ +import HookFormSelect from '@/core/components/elements/Select/HookFormSelect'; +import cityApi from '@/lib/address/api/cityApi'; +import stateApi from '@/lib/address/api/stateApi.js'; +import districtApi from '@/lib/address/api/districtApi'; +import subDistrictApi from '@/lib/address/api/subDistrictApi'; +import { yupResolver } from '@hookform/resolvers/yup'; +import React, { + useEffect, + useRef, + useState, + forwardRef, + useImperativeHandle, +} 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 createMerchantApi from '../api/createMerchantApi'; +import getMerchantApi from '../api/getMerchantApi'; +import addressApi from '@/lib/address/api/addressApi'; +import PageContent from '@/lib/content/components/PageContent'; +import { useRouter } from 'next/router'; +import useAuth from '@/core/hooks/useAuth'; +import { Radio, RadioGroup, Stack, Checkbox, Button } from '@chakra-ui/react'; +import { EyeIcon } from '@heroicons/react/24/outline'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import Image from 'next/image'; +import ImageBanner from '~/components/ui/image'; +import { ChevronRightIcon } from '@heroicons/react/24/outline'; +import MobileView from '@/core/components/views/MobileView'; +import DesktopView from '@/core/components/views/DesktopView'; +import getFileBase64 from '@/core/utils/getFileBase64'; +import odooApi from '~/libs/odooApi'; +const SyaratDagang = forwardRef(({ handleIsError, isKonfirmasi }, ref) => { + const isError = (value) => { + // Logika menentukan error + const result = value ? true : false; + handleIsError(result); // Panggil handleIsError dari Merchant + return result; + }; + const { + register, + handleSubmit, + formState: { errors }, + control, + reset, + watch, + setValue, + getValues, + } = useForm({ + resolver: yupResolver(validationSchema), + defaultValues, + }); + const [bigData, setbigData] = useState([]); + const [isExample, setIsExample] = useState(false); + + const recaptchaRef = useRef(null); + const router = useRouter(); + + useEffect(() => { + const loadData = async () => { + const data = await getMerchantApi(); + setbigData(data); + if (data) { + reset({ + isKembaliBarang: data.isKembaliBarang || '', + textReturn: data.textReturn || '', + tenggatWaktu: (() => { + const waktu = data.tenggatWaktu + ? data.tenggatWaktu.split(' ')[0] + : ''; + if (waktu === '14') return '14'; + if (waktu === '30') return '30'; + return 'custom'; + })(), + customTenggatWaktu: (() => { + if (watch('tenggatWaktu') === 'custom') + return data.tenggatWaktu ? data.tenggatWaktu : ''; + return ''; + })(), + sertifikatProduk: data.sertifikatProduk || '', + customSertifikatProduk: data.customSertifikatProduk || '', + tempoGaransi: parseInt(data.tempoGaransi) || '', + explainGaransi: data.explainGaransi || '', + minimumPembelian: + data.isOrderQuantity == 'tidak' ? '' : data.minimumPembelian || '', + isOrderQuantity: data.isOrderQuantity || '', + }); + // handleKreditLimitChange(data.kreditLimit); + if (watch('sertifikatProduk') != false) { + setSelectedIds(watch('sertifikatProduk').split(',').map(Number)); + } + if (watch('customSertifikatProduk')) { + // setSelectedIds([...selectedIds, 4]); + } + } + }; + + loadData(); + }, []); + useEffect(() => { + if (!isKonfirmasi) { + window.scrollTo({ + top: 0, + behavior: 'smooth', + }); + } + }, []); + useImperativeHandle(ref, () => () => { + handleSubmit(onSubmitHandler)(); + }); + const auth = useAuth(); + if (auth == false) { + router.push(`/login?next=${encodeURIComponent('/daftar-merchant')}`); + } + + const dataGaransi = [ + { value: 1, label: '6 Bulan Garansi' }, + { value: 2, label: '1 Tahun Garansi' }, + { value: 3, label: '2 Tahun Garansi' }, + ]; + const dataMinimumOrderQuantity = [ + { value: 'dus', label: 'Dus' }, + { value: 'lusin', label: 'Lusin' }, + { value: 'minimum pembelian', label: 'Minimum pembelian' }, + ]; + + const category_produk = [ + { id: 0, name: 'TKDN' }, + { id: 1, name: 'SNI' }, + { id: 2, name: 'K3L' }, + { id: 3, name: '' }, + ]; + + const [selectedIds, setSelectedIds] = useState( + watch('sertifikatProduk') + ? watch('sertifikatProduk').split(',').map(Number) + : [] + // form.sertifikatProduk ? form.sertifikatProduk.split(',').map(Number) : [] // Parse string menjadi array angka + // [] // Parse string menjadi array angka + ); + const handleCheckboxChange = (id) => { + const updatedSelected = selectedIds.includes(id) + ? selectedIds.filter((selectedId) => selectedId !== id) + : [...selectedIds, id]; + + setSelectedIds(updatedSelected); + + // Mengubah array kembali menjadi string yang dipisahkan oleh koma + setValue('sertifikatProduk', updatedSelected.join(',')); + }; + const custom_sertifikat_produk_handle = () => { + const updatedSelected = [...selectedIds, 3]; + + setSelectedIds(updatedSelected); + + // Mengubah array kembali menjadi string yang dipisahkan oleh koma + setValue('sertifikatProduk', updatedSelected.join(',')); + }; + + const isChecked = (id) => selectedIds.includes(id); + + const handleCheckboxReturChange = (value) => { + setValue('isKembaliBarang', `${value}`); + }; + const handleCheckboxOrderQuantityChange = (value) => { + setValue('isOrderQuantity', `${value}`); + }; + + const handleCheckboxTenggatWaktuChange = (value) => { + setValue('tenggatWaktu', `${value}`); + }; + + const onSubmitHandler = async (values) => { + const toastId = toast.loading('Mengirimkan formulir merchant...'); + const data = { + is_kembali_barang: values.isKembaliBarang, + text_return: values.textReturn, + tenggat_waktu: values.tenggatWaktu, + custom_tenggat_waktu: values.customTenggatWaktu, + sertifikat_produk: values.sertifikatProduk, + custom_sertifikat_produk: + values.customSertifikatProduk == '' + ? false + : values.customSertifikatProduk, + tempo_garansi: values.tempoGaransi, + explain_garansi: values.explainGaransi, + is_order_quantity: values.isOrderQuantity, + minimum_pembelian: values.minimumPembelian, + }; + const create_leads = await createMerchantApi({ data }); + if (create_leads) { + toast.dismiss(toastId); + toast.success('Berhasil menambahkan data'); + isError(false); + reset(); + // router.push('/'); + } else { + toast.dismiss(toastId); + toast.error('Gagal menambahkan data'); + } + }; + + // const DownLoadSurat = () => { + // download surat dari /public/file/Surat Pernyataan Nomor Rekening.docx + // }; + + if (!auth) { + return; + } + // Tetap di bagian atas, tidak boleh ada kondisi sebelum hook + + return ( + <> + <BottomPopup + className='' + title='Contoh SPPKP' + active={isExample} + close={() => setIsExample(false)} + > + <div className='flex p-2'> + <Image + src='/images/NO-SPPKP-FORMAT-TEMPLATE.jpg' + alt='Contoh SPPKP' + className='w-full h-full ' + width={800} + height={800} + quality={85} + /> + </div> + </BottomPopup> + <DesktopView> + <div + className={`container flex flex-col h-fit items-start ${ + !isKonfirmasi && 'py-4' + }`} + > + <h2 className='text-xs md:text-title-sm font-semibold mb-6'> + Syarat Perdagangan + </h2> + + <div className='w-full mt-4 '> + <form + onSubmit={handleSubmit(onSubmitHandler)} + className='flex flex-col gap-4' + > + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5'> + <label className='form-label text-wrap '> + Syarat Pengembalian Barang + </label> + </div> + <div className='w-3/5 flex flex-row justify-start'> + <div className='flex gap-x-4 flex-col w-full'> + <RadioGroup + onChange={handleCheckboxReturChange} + value={watch('isKembaliBarang')} + > + <Stack direction='column'> + <div className='flex flex-row text-nowrap gap-2'> + <Radio colorScheme='red' value='ya'> + Ya, dapat diretur + </Radio> + {watch('isKembaliBarang') == 'ya' && ( + <textarea + {...register('textReturn')} + placeholder='jelaskan syarat pengembalian' + type='textarea' + className='form-input w-full' + /> + )} + </div> + <Radio colorScheme='red' value='tidak'> + Tidak dapat diretur + </Radio> + </Stack> + </RadioGroup> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.isKembaliBarang?.message} + </div> + </div> + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5'> + <label className='form-label text-wrap '> + Tenggat Waktu Perubahan Harga + </label> + </div> + <div className='w-3/5 flex flex-row justify-start'> + <div className='flex gap-x-4 flex-col w-full'> + <RadioGroup + onChange={handleCheckboxTenggatWaktuChange} + value={watch('tenggatWaktu')} + > + <Stack direction='column'> + <Radio + colorScheme='red' + value='14' + onChange={() => setValue('customTenggatWaktu', ' ')} + > + 14 hari sejak data dikirimkan + </Radio> + <Radio + colorScheme='red' + value='30' + onChange={() => setValue('customTenggatWaktu', ' ')} + > + 30 hari sejak data dikirimkan + </Radio> + <div className='flex flex-row gap-2'> + <Radio colorScheme='red' value='custom'></Radio> + <input + {...register('customTenggatWaktu')} + placeholder='Masukkan jumlah hari untuk tenggat waktu' + type='text' + onFocus={() => setValue('tenggatWaktu', 'custom')} + className='form-input mt-2' + /> + </div> + </Stack> + </RadioGroup> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.tenggatWaktu?.message} + </div> + </div> + </div> + </div> + + <div className={`flex flex-row justify-between items-start`}> + <div className='w-2/5 text-nowrap'> + <label + className={`form-label ${isKonfirmasi && 'text-wrap'}`} + > + Dokumen/Sertifikat yang Dimiliki Oleh Brand + </label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih dokumen/sertifikat bisa lebih dari 1 + </span> + )} + </div> + <div className='w-3/5 flex flex-col'> + <div className='flex flex-row justify-between w-full'> + <div + className='flex flex-col gap-2 w-full' + // ref={categoryProdukRef} + > + <Checkbox + colorScheme='red' + key={0} + onChange={() => handleCheckboxChange(0)} + isChecked={isChecked(0)} + > + TKDN + </Checkbox> + <Checkbox + colorScheme='red' + key={1} + onChange={() => handleCheckboxChange(1)} + isChecked={isChecked(1)} + > + SNI + </Checkbox> + <Checkbox + colorScheme='red' + key={2} + onChange={() => handleCheckboxChange(2)} + isChecked={isChecked(2)} + > + K3L + </Checkbox> + <div className='flex flex-row gap-2 w-full'> + <Checkbox + colorScheme='red' + key={3} + onChange={() => handleCheckboxChange(3)} + isChecked={isChecked(3)} + ></Checkbox> + <input + {...register('customSertifikatProduk')} + placeholder='Masukkan Dokumen/Sertifikat yang dimiliki oleh brand' + type='text' + onFocus={() => { + custom_sertifikat_produk_handle(); + }} + // onFocus={() => handleCheckboxChange(4)} + className='form-input mt-2' + /> + </div> + </div> + </div> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.sertifikatProduk?.message} + </div> + </div> + </div> + + <div className='flex flex-row justify-between items-center'> + <div className='w-2/5'> + <label className='form-label text-nowrap'>Garansi</label> + {!isKonfirmasi && ( + <span className='text-xs opacity-60'> + Pilih waktu garansi yang diberikan + </span> + )} + </div> + <div className='w-3/5 flex flex-col '> + <div className='flex flex-row items-center gap-3'> + <div className={`${!isKonfirmasi && 'w-[25%]'}`}> + <Controller + name='tempoGaransi' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={dataGaransi} + placeholder={'Pilih durasi garansi'} + /> + )} + /> + + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.tempoGaransi?.message} + </div> + </div> + </div> + </div> + </div> + + <div className='w-full flex flex-row'> + <div className='w-2/5'> + <label className='form-label text-nowrap'> + Jelaskan Garansi yang dimaksud! + </label> + </div> + <div className='w-3/5'> + <textarea + {...register('explainGaransi')} + placeholder='Jelaskan bagian apa yang termasuk garansi' + type='textarea' + className='form-input' + rows={4} + cols={40} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.explainGaransi?.message} + </div> + </div> + </div> + + <div className='flex flex-row justify-between items-start'> + <div className='w-2/5'> + <label className='form-label text-wrap '> + Apakah Memiliki Minimum Order Quantity (MOQ) + </label> + </div> + <div className='w-3/5 flex flex-row justify-start'> + <div className='flex gap-x-4 flex-col w-full'> + <RadioGroup + onChange={handleCheckboxOrderQuantityChange} + value={ + watch('minimumPembelian') + ? 'ya' + : watch('isOrderQuantity') + } + > + <Stack direction='column'> + <div className='flex flex-row text-nowrap gap-2'> + <Radio + colorScheme='red' + value='ya' + onChange={() => setValue('isOrderQuantity', 'ya')} + > + Ya + </Radio> + + <Controller + name='minimumPembelian' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={dataMinimumOrderQuantity} + placeholder={ + 'Pilih jenis minimum order quantity' + } + onFocus={() => + setValue('isOrderQuantity', 'ya') + } + /> + )} + /> + </div> + <Radio + colorScheme='red' + value='tidak' + onChange={() => setValue('minimumPembelian', '')} + > + Tidak Ada + </Radio> + </Stack> + </RadioGroup> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.isOrderQuantity?.message} + </div> + </div> + </div> + </div> + + {!isKonfirmasi && ( + <div className='flex justify-end'> + <div> + <span className='text-xs opacity-60'> + *Pastikan data yang anda masukan sudah benar dan sesuai + </span> + <button + type='submit' + className='btn-light bg-red-500 rounded-lg text-white w-fit py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-between hover:bg-red-400' + > + <span className={` `}>Langkah Selanjutnya</span> + {<ChevronRightIcon className='w-5' />} + </button> + </div> + </div> + )} + </form> + </div> + </div> + </DesktopView> + <MobileView> + <div className='container flex flex-col items-star py-4'> + {!isKonfirmasi && ( + <h2 className='font-semibold mb-6 text-xl'>Syarat Perdagangan</h2> + )} + + <div className='w-full mt-4'> + <form + onSubmit={handleSubmit(onSubmitHandler)} + className='flex flex-col gap-4' + > + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'> + Syarat Pengembalian Barang + </label> + <div className='flex gap-x-4 flex-col w-full'> + <RadioGroup + onChange={handleCheckboxReturChange} + value={watch('isKembaliBarang')} + > + <Stack direction='column'> + <div className='flex flex-row text-nowrap gap-2'> + <Radio colorScheme='red' value='ya'> + Ya, dapat diretur + </Radio> + {watch('isKembaliBarang') == 'ya' && ( + <textarea + {...register('textReturn')} + placeholder='jelaskan syarat pengembalian' + type='textarea' + className='form-input w-full' + /> + )} + </div> + <Radio colorScheme='red' value='tidak'> + Tidak dapat diretur + </Radio> + </Stack> + </RadioGroup> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.isKembaliBarang?.message} + </div> + </div> + </div> + </div> + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'> + Tenggat Waktu Perubahan Harga + </label> + <div className='flex gap-x-4 flex-col w-full'> + <RadioGroup + onChange={handleCheckboxTenggatWaktuChange} + value={watch('tenggatWaktu')} + > + <Stack direction='column'> + <Radio + colorScheme='red' + value='14' + onChange={() => setValue('customTenggatWaktu', ' ')} + > + 14 hari sejak data dikirimkan + </Radio> + <Radio + colorScheme='red' + value='30' + onChange={() => setValue('customTenggatWaktu', ' ')} + > + 30 hari sejak data dikirimkan + </Radio> + <div className='flex flex-row gap-2'> + <Radio colorScheme='red' value='custom'></Radio> + <input + {...register('customTenggatWaktu')} + placeholder='Masukkan jumlah hari untuk tenggat waktu' + type='text' + onFocus={() => setValue('tenggatWaktu', 'custom')} + className='form-input mt-2' + /> + </div> + </Stack> + </RadioGroup> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.tenggatWaktu?.message} + </div> + </div> + </div> + </div> + <div className='w-full flex flex-col'> + <div className='w-full'> + <label className='form-label text-nowrap'> + Dokumen/Sertifikat yang Dimiliki Oleh Brand + </label> + <div + className='flex flex-col gap-2 w-full' + // ref={categoryProdukRef} + > + <Checkbox + colorScheme='red' + key={0} + onChange={() => handleCheckboxChange(0)} + isChecked={isChecked(0)} + > + TKDN + </Checkbox> + <Checkbox + colorScheme='red' + key={1} + onChange={() => handleCheckboxChange(1)} + isChecked={isChecked(1)} + > + SNI + </Checkbox> + <Checkbox + colorScheme='red' + key={2} + onChange={() => handleCheckboxChange(2)} + isChecked={isChecked(2)} + > + K3L + </Checkbox> + <div className='flex flex-row gap-2 w-full'> + <Checkbox + colorScheme='red' + key={3} + onChange={() => handleCheckboxChange(3)} + isChecked={isChecked(3)} + ></Checkbox> + <input + {...register('customSertifikatProduk')} + placeholder='Masukkan Dokumen/Sertifikat yang dimiliki oleh brand' + type='text' + onFocus={() => { + custom_sertifikat_produk_handle(); + }} + // onFocus={() => handleCheckboxChange(4)} + className='form-input mt-2' + /> + </div> + </div> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.sertifikatProduk?.message} + </div> + </div> + </div> + + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'>Garansi</label> + <div className='w-full flex flex-row gap-2'> + <Controller + name='tempoGaransi' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={dataGaransi} + placeholder={'Pilih durasi garansi'} + /> + )} + /> + + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.tempoGaransi?.message} + </div> + </div> + </div> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'> + Jelaskan Garansi yang dimaksud! + </label> + <textarea + {...register('explainGaransi')} + placeholder='Jelaskan bagian apa yang termasuk garansi' + type='textarea' + className='form-input' + rows={4} + cols={40} + /> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.explainGaransi?.message} + </div> + </div> + <div className='w-full flex flex-col'> + <label className='form-label text-nowrap'> + Apakah Memiliki Minimum Order Quantity (MOQ) + </label> + <div className='flex gap-x-4 flex-col w-full'> + <RadioGroup + onChange={handleCheckboxOrderQuantityChange} + value={ + watch('minimumPembelian') + ? 'ya' + : watch('isOrderQuantity') + } + > + <Stack direction='column'> + <div className='flex flex-row text-nowrap gap-2'> + <Radio + colorScheme='red' + value='ya' + onChange={() => setValue('isOrderQuantity', 'ya')} + > + Ya + </Radio> + + <Controller + name='minimumPembelian' + control={control} + render={(props) => ( + <HookFormSelect + {...props} + options={dataMinimumOrderQuantity} + placeholder={'Pilih jenis minimum order quantity'} + onFocus={() => setValue('isOrderQuantity', 'ya')} + /> + )} + /> + </div> + <Radio + colorScheme='red' + value='tidak' + onChange={() => setValue('minimumPembelian', '')} + > + Tidak Ada + </Radio> + </Stack> + </RadioGroup> + <div className='text-caption-2 text-danger-500 mt-1'> + {errors.isOrderQuantity?.message} + </div> + </div> + </div> + + <div className=''> + {/* <div> + <ReCAPTCHA + ref={recaptchaRef} + sitekey={process.env.NEXT_PUBLIC_RECAPTCHA_GOOGLE} + /> + </div> */} + </div> + <div className='flex justify-center w-full '> + {/* <Button + colorScheme='red' + className='w-full md:w-fit' + type='submit' + > + Daftar Merchant{' '} + {<ChevronRightIcon className='w-5' color='white' />} + </Button> */} + {!isKonfirmasi && ( + <div className='w-full'> + <span className='text-xs opacity-60'> + *Pastikan data yang anda masukan sudah benar dan sesuai + </span> + <button + type='submit' + className='btn-light bg-red-500 rounded-lg text-white w-full py-2 px-4 md:w-fit mt-2 ml-0 md:ml-auto flex justify-center hover:bg-red-400' + > + <span className={` `}>Langkah Selanjutnya</span> + {<ChevronRightIcon className='w-5' />} + </button> + </div> + )} + </div> + </form> + <PageContent path='/daftar-merchant' /> + </div> + </div> + </MobileView> + </> + ); +}); +const validationSchema = Yup.object().shape({ + isKembaliBarang: Yup.string().required('Harus di-pilih'), + tenggatWaktu: Yup.string().required('Harus di-pilih'), + sertifikatProduk: Yup.string().required('Harus di-pilih'), + tempoGaransi: Yup.string().required('Harus di-pilih'), + explainGaransi: Yup.string().required('Harus di-isi'), + isOrderQuantity: Yup.string().required('Harus di-isi'), +}); +const defaultValues = { + isKembaliBarang: '', + tenggatWaktu: '', + sertifikatProduk: '', + explainGaransi: '', + isOrderQuantity: '', +}; + +export default SyaratDagang; |
