summaryrefslogtreecommitdiff
path: root/src/lib/pengajuan-tempo/component/Referensi.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pengajuan-tempo/component/Referensi.jsx')
-rw-r--r--src/lib/pengajuan-tempo/component/Referensi.jsx636
1 files changed, 636 insertions, 0 deletions
diff --git a/src/lib/pengajuan-tempo/component/Referensi.jsx b/src/lib/pengajuan-tempo/component/Referensi.jsx
new file mode 100644
index 00000000..8db321d1
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/Referensi.jsx
@@ -0,0 +1,636 @@
+import React, { useState, useEffect, useMemo, useRef } from 'react';
+import { useForm } from 'react-hook-form';
+import {
+ usePengajuanTempoStoreSupplier,
+ usePengajuanTempoStore,
+} from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore';
+import * as Yup from 'yup';
+import { yupResolver } from '@hookform/resolvers/yup';
+import { PlusCircleIcon } from '@heroicons/react/24/outline';
+import useDevice from '@/core/hooks/useDevice';
+import { Trash2Icon } from 'lucide-react';
+import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+const initialData = [];
+const Referensi = ({ chekValid, buttonSubmitClick, data }) => {
+ const [changeConfirmation, setChangeConfirmation] = useState(false);
+ const [selectedIndex, setSelectedIndex] = useState(null);
+
+ const { isDesktop, isMobile } = useDevice();
+ const [openIndexes, setOpenIndexes] = useState([]);
+
+ const {
+ register,
+ formState: { errors },
+ handleSubmit,
+ watch,
+ setValue,
+ control,
+ } = useForm({
+ resolver: yupResolver(validationSchema),
+ defaultValues,
+ });
+ const { formSupplier, updateFormSupplier, updateHasSave, hasSavedata } =
+ usePengajuanTempoStoreSupplier();
+ const { form } = usePengajuanTempoStore();
+ const [formData, setFormData] = useState([
+ {
+ supplier: '',
+ pic: '',
+ telepon: '',
+ durasiTempo: '',
+ creditLimit: '',
+ },
+ ]);
+
+ const [buttonSubmit, setButtonSubmit] = useState(false);
+ const [supplierData, setSupplierData] = useState(initialData);
+ const [newSupplier, setNewSupplier] = useState({
+ supplier: '',
+ pic: '',
+ telepon: '',
+ durasiTempo: '',
+ creditLimit: '',
+ });
+ const onChangeInput = (e, index) => {
+ updateHasSave(false);
+ const { name, value } = e.target;
+
+ let formattedValue = value;
+
+ if (name === 'durasiTempo') {
+ formattedValue = value.replace(/\s*Hari\s*/g, '');
+ } else if (name === 'creditLimit') {
+ formattedValue = value.replace(/^Rp\s*/, '');
+ }
+
+ const editData = supplierData.map((item, i) =>
+ i === index ? { ...item, [name]: formattedValue } : item
+ );
+ setSupplierData(editData);
+ if (value == '' && supplierData.supplier) {
+ updateHasSave(true);
+ }
+ };
+
+ const handleNewSupplierChange = (e) => {
+ updateHasSave(false);
+ const { name, value } = e.target;
+
+ let formattedValue = value;
+
+ if (name === 'durasiTempo') {
+ formattedValue = value.replace(/\s*Hari\s*/g, '');
+ } else if (name === 'creditLimit') {
+ formattedValue = value.replace(/^Rp\s*/, '');
+ }
+
+ const updatedSupplier = { ...newSupplier, [name]: formattedValue };
+ setNewSupplier(updatedSupplier);
+ if (value == '') {
+ updateHasSave(true);
+ }
+ };
+
+ useEffect(() => {
+ const isAllFieldsEmpty = Object.values(newSupplier).every(
+ (value) => value === ''
+ );
+ if (isAllFieldsEmpty) {
+ updateHasSave(true);
+ } else {
+ updateHasSave(false);
+ }
+ }, [newSupplier]);
+
+ const handleDeleteSupplier = () => {
+ if (selectedIndex !== null) {
+ // Logika untuk menghapus supplier
+ const updatedSuppliers = supplierData.filter(
+ (_, idx) => idx !== selectedIndex
+ );
+ setSupplierData(updatedSuppliers);
+ setChangeConfirmation(false);
+ updateHasSave(false);
+ }
+ };
+
+ const handleAddNewSupplier = () => {
+ // updateHasSave(false);
+ if (Object.values(newSupplier).every((val) => val.trim() !== '')) {
+ setSupplierData((prevData) => {
+ const newData = [...prevData, newSupplier];
+ return newData;
+ });
+
+ setNewSupplier({
+ supplier: '',
+ pic: '',
+ telepon: '',
+ durasiTempo: '',
+ creditLimit: '',
+ });
+ }
+ };
+
+ useEffect(() => {
+ handleAddNewSupplier();
+ updateFormSupplier(supplierData);
+ setButtonSubmit(!buttonSubmit);
+ }, [buttonSubmitClick]);
+ const simpanData = () => {
+ setButtonSubmit(!buttonSubmit);
+ if (Object.values(newSupplier).every((val) => val.trim() !== '')) {
+ setSupplierData((prevData) => {
+ const newData = [...prevData, newSupplier];
+ return newData;
+ });
+
+ setNewSupplier({
+ supplier: '',
+ pic: '',
+ telepon: '',
+ durasiTempo: '',
+ creditLimit: '',
+ });
+ }
+ updateHasSave(true);
+ };
+ const formatRupiah = (value) => {
+ if (!value) return '';
+ const numberString = value.replace(/[^0-9]/g, '');
+ return numberString
+ ? 'Rp ' + new Intl.NumberFormat('id-ID').format(numberString)
+ : '';
+ };
+ const formatHari = (value) => {
+ if (!value) return '';
+
+ const numberString = value.replace(/[^0-9]/g, '');
+
+ return numberString ? numberString.replace(/Hari/g, '') + ' Hari' : '';
+ };
+
+ useEffect(() => {
+ updateFormSupplier(supplierData);
+ }, [buttonSubmit]);
+ const getFromLocalStorage = (key) => {
+ const itemStr = localStorage.getItem(key);
+ if (!itemStr) return null;
+
+ const item = JSON.parse(itemStr);
+ return item;
+ };
+ useEffect(() => {
+ // const cachedData = getFromLocalStorage('Referensi');
+ if (data) {
+ setSupplierData(data);
+ updateFormSupplier(data);
+ }
+ }, [buttonSubmitClick]);
+
+ useEffect(() => {
+ setOpenIndexes(supplierData.map((_, index) => index));
+ }, [supplierData]);
+
+ const toggleOpen = (index) => {
+ setOpenIndexes((prev) =>
+ prev.includes(index) ? prev.filter((i) => i !== index) : [...prev, index]
+ );
+ };
+
+ const handleOpenConfirmation = (index) => {
+ setSelectedIndex(index);
+ setChangeConfirmation(true);
+ };
+ return (
+ <>
+ <BottomPopup
+ active={changeConfirmation}
+ close={() => setChangeConfirmation(false)}
+ title='Konfirmasi Hapus Data'
+ >
+ <div className='leading-7 text-gray_r-12/80'>
+ Apakah anda yakin menghapus data?
+ </div>
+ <div className='flex mt-6 gap-x-4 md:justify-end'>
+ <button
+ className='btn-solid-red flex-1 md:flex-none'
+ type='button'
+ onClick={handleDeleteSupplier}
+ >
+ Ya, Hapus
+ </button>
+ <button
+ className='btn-light flex-1 md:flex-none'
+ type='button'
+ onClick={() => setChangeConfirmation(false)}
+ >
+ Batal
+ </button>
+ </div>
+ </BottomPopup>
+ {isDesktop && (
+ <div className='py-4'>
+ <div className='flex flex-col justify-start'>
+ <h1 className='font-bold text-2xl'>
+ Referensi Supplier / Rekanan Bisnis Perusahaan{' '}
+ <span className=' opacity-60 text-xl'>(Opsional)</span>
+ </h1>
+ <p className='opacity-60'>
+ Data yang anda berikan hanya untuk bahan referensi internal kami
+ untuk memberikan anda credit limit dan durasi tempo
+ </p>
+ </div>
+ <form className='flex mt-4 flex-col w-full '>
+ <table className='border' border='1' cellPadding='10'>
+ <thead>
+ <tr className='border '>
+ <th className='text-left px-5 py-2'>
+ Nama Supplier / Rekanan
+ </th>
+ <th className='text-left px-5 py-2'>PIC</th>
+ <th className='text-left px-5 py-2'>Telepon</th>
+ <th className='text-left px-5 py-2'>Durasi Tempo</th>
+ <th className='text-left px-5 py-2'>Credit Limit</th>
+ </tr>
+ </thead>
+ <tbody>
+ {supplierData.map((supplier, index) => (
+ <tr key={index}>
+ <td>
+ <input
+ name='supplier'
+ value={supplier.supplier}
+ type='text'
+ onChange={(e) => onChangeInput(e, index)}
+ className='form-input border px-4 py-2'
+ placeholder='Type Supplier'
+ />
+ </td>
+ <td>
+ <input
+ name='pic'
+ value={supplier.pic}
+ type='text'
+ className='form-input border px-4 py-2'
+ onChange={(e) => onChangeInput(e, index)}
+ placeholder='Type PIC'
+ />
+ </td>
+ <td>
+ <input
+ name='telepon'
+ type='text'
+ className='form-input border px-4 py-2'
+ value={supplier.telepon}
+ onChange={(e) => onChangeInput(e, index)}
+ placeholder='Type Telepon'
+ />
+ </td>
+ <td>
+ <input
+ name='durasiTempo'
+ type='text'
+ className='form-input border px-4 py-2'
+ value={formatHari(supplier.durasiTempo)}
+ onChange={(e) => onChangeInput(e, index)}
+ placeholder='Type Durasi Tempo'
+ />
+ </td>
+ <td className='flex flex-row gap-2 justify-center items-center'>
+ <input
+ name='creditLimit'
+ type='text'
+ value={formatRupiah(supplier.creditLimit)}
+ className='form-input border px-4 py-2'
+ onChange={(e) => onChangeInput(e, index)}
+ placeholder='Type Credit Limit'
+ />
+ <Trash2Icon
+ size={18}
+ onClick={() => handleOpenConfirmation(index)}
+ className='cursor-pointer'
+ />
+ </td>
+ </tr>
+ ))}
+ <tr>
+ <td>
+ <input
+ name='supplier'
+ value={newSupplier.supplier}
+ type='text'
+ className='form-input border px-4 py-2'
+ onChange={handleNewSupplierChange}
+ placeholder='Isi nama supplier anda'
+ />
+ </td>
+ <td>
+ <input
+ name='pic'
+ value={newSupplier.pic}
+ type='text'
+ className='form-input border px-4 py-2'
+ onChange={handleNewSupplierChange}
+ placeholder='Isi PIC supplier anda'
+ />
+ </td>
+ <td>
+ <input
+ name='telepon'
+ value={newSupplier.telepon}
+ type='text'
+ onChange={handleNewSupplierChange}
+ placeholder='Isi telepon supplier anda'
+ className='form-input border px-4 py-2'
+ />
+ </td>
+ <td>
+ <input
+ name='durasiTempo'
+ value={formatHari(newSupplier.durasiTempo)}
+ type='text'
+ onChange={handleNewSupplierChange}
+ className='form-input border px-4 py-2'
+ placeholder='Durasi jatuh tempo'
+ />
+ </td>
+ <td className='flex flex-row items-center gap-2 '>
+ <input
+ name='creditLimit'
+ value={formatRupiah(newSupplier.creditLimit)}
+ type='text'
+ className='form-input border px-4 py-2'
+ onChange={handleNewSupplierChange}
+ placeholder='limit kredit'
+ />
+ {/* <Trash2Icon
+ size={18}
+ onClick={() => handleDeleteSupplier(index)}
+ /> */}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+ <div className='flex items-center gap-4 mt-8'>
+ {/* <button
+ onClick={handleAddNewSupplier}
+ className='bg-gray-200 border border-gray-500 rounded-md text-sm text-gray-500 p-2 h-11 mb-1 content-center flex flex-row justify-center items-center'
+ >
+ {<PlusCircleIcon className='w-5 mr-2' />}
+ {''} Tambah Data Baru
+ </button> */}
+ {!hasSavedata && (
+ <>
+ <button
+ onClick={simpanData}
+ className={`bg-red-500 border border-red-500 rounded-md text-sm text-white p-2 h-11 mb-1 content-center flex flex-row justify-center items-center `}
+ >
+ Simpan Data
+ </button>
+ <span className='text-sm opacity-60 text-red-500'>
+ *Klik simpan sebelum lanjut ke tahap selanjutnya
+ </span>
+ </>
+ )}
+ </div>
+ </div>
+ )}
+ {isMobile && (
+ <div className='text-sm'>
+ <div className='flex flex-col py-4 mt-8 justify-start'>
+ <h1 className='font-bold text-xl'>
+ Referensi Supplier / Rekanan Bisnis Perusahaan{' '}
+ <span className=' opacity-60 text-xl'>(Opsional)</span>
+ </h1>
+ <p className='opacity-60'>
+ Data yang anda berikan hanya untuk bahan referensi internal kami
+ untuk memberikan anda credit limit dan durasi tempo
+ </p>
+ </div>
+ <div className='flex gap-4 flex-col'>
+ <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div>
+ <h2 className='py-2 font-semibold text-base'>
+ Daftar Nama Supplier
+ </h2>
+ {/* <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div> */}
+ <div className=''>
+ {supplierData.map((supplier, index) => (
+ <div key={index}>
+ <div
+ className='flex flex-row justify-center items-center py-4'
+ onClick={() => toggleOpen(index)}
+ >
+ <p className='font-semibold text-base w-4/5'>
+ {supplier.supplier}
+ </p>
+ <div className='w-1/5 flex justify-end items-center gap-2'>
+ <Trash2Icon
+ size={16}
+ color='red'
+ onClick={() => handleOpenConfirmation(index)}
+ className='cursor-pointer'
+ />
+ {openIndexes.includes(index) ? (
+ <ChevronUpIcon className='w-4' />
+ ) : (
+ <ChevronDownIcon className='w-4' />
+ )}
+ </div>
+ </div>
+ {openIndexes.includes(index) && (
+ <form className='flex flex-col w-full'>
+ <div className='w-full grid grid-row-2 gap-4'>
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama Supplier
+ </label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ {supplier.supplier}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ PIC
+ </label>
+ </div>
+ <div className='w-3/5 opacity-70'>{supplier.pic}</div>
+ </div>
+
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Telepon
+ </label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ {supplier.telepon}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Durasi Tempo
+ </label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ {formatHari(supplier.durasiTempo)}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Kredit Limit
+ </label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ {formatRupiah(supplier.creditLimit)}
+ </div>
+ </div>
+ </div>
+ </form>
+ )}
+ </div>
+ ))}
+ </div>
+ {/* <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div> */}
+ {/* <h2 className='py-2 font-semibold text-base text-red-500 flex flex-row'>
+ <PlusCircleIcon className='w-5 mr-2' />
+ Tambah Data Baru
+ </h2> */}
+ <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div>
+ <form className='flex flex-col w-full'>
+ <div className='w-full grid grid-row-2 gap-2'>
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama Supplier
+ </label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ <input
+ name='supplier'
+ value={newSupplier.supplier}
+ type='text'
+ className='form-input border px-4 py-2'
+ onChange={handleNewSupplierChange}
+ placeholder='Format: PT. ABC TESTING INDONESIA'
+ />
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>PIC</label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ <input
+ name='pic'
+ value={newSupplier.pic}
+ type='text'
+ className='form-input border px-4 py-2'
+ onChange={handleNewSupplierChange}
+ placeholder='John Doe'
+ />
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>Telepon</label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ <input
+ name='telepon'
+ value={newSupplier.telepon}
+ type='text'
+ onChange={handleNewSupplierChange}
+ placeholder='Format: 08123456789'
+ className='form-input border px-4 py-2'
+ />
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Durasi Tempo
+ </label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ <input
+ name='durasiTempo'
+ value={formatHari(newSupplier.durasiTempo)}
+ type='text'
+ onChange={handleNewSupplierChange}
+ className='form-input border px-4 py-2'
+ placeholder='Isi durasi tempo supplier anda (hari)'
+ />
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-start items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Kredit Limit
+ </label>
+ </div>
+ <div className='w-3/5 opacity-70'>
+ <input
+ name='creditLimit'
+ value={formatRupiah(newSupplier.creditLimit)}
+ type='text'
+ className='form-input border px-4 py-2'
+ onChange={handleNewSupplierChange}
+ placeholder='Rp 999.999.999'
+ />
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+ <div className='flex flex-col justify-start items-start gap-4 mt-8'>
+ {!hasSavedata && (
+ <>
+ <span className='text-xs opacity-60 text-red-500'>
+ *Klik simpan sebelum lanjut ke tahap selanjutnya
+ </span>
+ <button
+ onClick={simpanData}
+ className={`bg-red-500 border border-red-500 rounded-md w-full text-sm text-white p-2 h-11 mb-1 content-center flex flex-row justify-center items-center`}
+ >
+ Simpan Data
+ </button>
+ </>
+ )}
+ </div>
+ </div>
+ )}
+ </>
+ );
+};
+
+const validationSchema = Yup.object().shape({
+ supplier: Yup.string().required('Harus di-isi'),
+ pic: Yup.string().required('Harus di-isi'),
+ telepon: Yup.string().required('Harus di-isi'),
+ durasiTempo: Yup.string().required('Harus di-isi'),
+ creditLimit: Yup.string().required('Harus di-isi'),
+});
+
+const defaultValues = {
+ supplier: '',
+ pic: '',
+ telepon: '',
+ durasiTempo: '',
+ creditLimit: '',
+};
+export default Referensi;