summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package.json1
-rw-r--r--public/images/REGISTRASI-TEMPO.svg9
-rw-r--r--src-migrate/modules/register/stores/usePengajuanTempoStore.ts386
-rw-r--r--src-migrate/types/tempo.ts127
-rw-r--r--src-migrate/validations/tempo.ts157
-rw-r--r--src/core/components/elements/Footer/BasicFooter.jsx5
-rw-r--r--src/lib/pengajuan-tempo/api/createPengajuanTempoApi.js14
-rw-r--r--src/lib/pengajuan-tempo/component/Dokumen.jsx952
-rw-r--r--src/lib/pengajuan-tempo/component/FinishTempo.jsx78
-rw-r--r--src/lib/pengajuan-tempo/component/Konfirmasi.jsx263
-rw-r--r--src/lib/pengajuan-tempo/component/KonfirmasiDokumen.jsx1202
-rw-r--r--src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx586
-rw-r--r--src/lib/pengajuan-tempo/component/PengajuanTempo.jsx352
-rw-r--r--src/lib/pengajuan-tempo/component/Pengiriman.jsx1489
-rw-r--r--src/lib/pengajuan-tempo/component/Referensi.jsx548
-rw-r--r--src/lib/pengajuan-tempo/component/Stepper.jsx65
-rw-r--r--src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx1401
-rw-r--r--src/pages/pengajuan-tempo/[status].jsx32
-rw-r--r--src/pages/pengajuan-tempo/index.jsx29
19 files changed, 7696 insertions, 0 deletions
diff --git a/package.json b/package.json
index 130e2f0c..3990e5cd 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"@emotion/styled": "^11.11.0",
"@heroicons/react": "^2.0.13",
"@hookform/resolvers": "^2.9.10",
+ "@ramonak/react-progress-bar": "^5.3.0",
"@react-email/components": "^0.0.2",
"@react-email/render": "^0.0.6",
"@tailwindcss/line-clamp": "^0.4.2",
diff --git a/public/images/REGISTRASI-TEMPO.svg b/public/images/REGISTRASI-TEMPO.svg
new file mode 100644
index 00000000..93746f25
--- /dev/null
+++ b/public/images/REGISTRASI-TEMPO.svg
@@ -0,0 +1,9 @@
+<svg width="494" height="498" viewBox="0 0 494 498" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<rect y="-0.00390625" width="494" height="498" fill="url(#pattern0_5944_7744)"/>
+<defs>
+<pattern id="pattern0_5944_7744" patternContentUnits="objectBoundingBox" width="1" height="1">
+<use xlink:href="#image0_5944_7744" transform="matrix(0.00203656 0 0 0.0020202 -0.0030303 0)"/>
+</pattern>
+<image id="image0_5944_7744" width="494" height="495" xlink:href="data:image/png;base64,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"/>
+</defs>
+</svg>
diff --git a/src-migrate/modules/register/stores/usePengajuanTempoStore.ts b/src-migrate/modules/register/stores/usePengajuanTempoStore.ts
new file mode 100644
index 00000000..47168a2a
--- /dev/null
+++ b/src-migrate/modules/register/stores/usePengajuanTempoStore.ts
@@ -0,0 +1,386 @@
+import { create } from 'zustand';
+import {
+ TempoProps,
+ TempoPropsKontakPerson,
+ TempoPropsPengiriman,
+ TempoPropsSupplier,
+ TempoPropsDokumen,
+} from '~/types/tempo';
+import {
+ TempoSchema,
+ TempoSchemaKontakPerson,
+ TempoSchemaPengiriman,
+ TempoSchemaSupplier,
+ TempoSchemaDokumen,
+} from '~/validations/tempo';
+import { boolean, ZodError } from 'zod';
+
+type State = {
+ form: TempoProps;
+ errors: {
+ [key in keyof TempoProps]?: string;
+ };
+ isCheckedTNC: boolean;
+ isOpenTNC: boolean;
+ isValidCaptcha: boolean;
+};
+
+type Action = {
+ updateForm: (name: string, value: string) => void;
+ updateValidCaptcha: (value: boolean) => void;
+ toggleCheckTNC: () => void;
+ openTNC: () => void;
+ closeTNC: () => void;
+ validate: () => void;
+ resetForm: () => void;
+};
+
+export const usePengajuanTempoStore = create<State & Action>((set, get) => ({
+ form: {
+ name: '',
+ industry_id: '',
+ street: '',
+ state: '',
+ city: '',
+ zip: '',
+ mobile: '',
+ bankName: '',
+ accountName: '',
+ accountNumber: '',
+ estimasi: '',
+ tempoDuration: '',
+ bersedia: '',
+ categoryProduk: '',
+ tempoLimit: '',
+ },
+ updateForm: (name, value) =>
+ set((state) => ({ form: { ...state.form, [name]: value } })),
+
+ errors: {},
+ validate: () => {
+ try {
+ TempoSchema.parse(get().form);
+ set({ errors: {} });
+ } catch (error) {
+ if (error instanceof ZodError) {
+ const errors: State['errors'] = {};
+ error.errors.forEach(
+ (e) => (errors[e.path[0] as keyof TempoProps] = e.message)
+ );
+ set({ errors });
+ }
+ }
+ },
+
+ isCheckedTNC: false,
+ toggleCheckTNC: () => set((state) => ({ isCheckedTNC: !state.isCheckedTNC })),
+
+ isOpenTNC: false,
+ openTNC: () => set(() => ({ isOpenTNC: true })),
+ closeTNC: () => set(() => ({ isOpenTNC: false })),
+
+ isValidCaptcha: false,
+ updateValidCaptcha: (value) => set(() => ({ isValidCaptcha: value })),
+
+ resetForm: () =>
+ set({
+ form: {
+ name: '',
+ industry_id: '',
+ street: '',
+ state: '',
+ city: '',
+ zip: '',
+ mobile: '',
+ bankName: '',
+ accountName: '',
+ accountNumber: '',
+ estimasi: '',
+ tempoDuration: '',
+ bersedia: '',
+ categoryProduk: '',
+ tempoLimit: '',
+ },
+ }),
+}));
+
+type StateKontakPerson = {
+ formKontakPerson: TempoPropsKontakPerson;
+ errorsKontakPerson: {
+ [key in keyof TempoPropsKontakPerson]?: string;
+ };
+};
+type ActionKontakPerson = {
+ updateFormKontakPerson: (name: string, value: string) => void;
+
+ validateKontakPerson: () => void;
+ resetFormKontakPerson: () => void;
+};
+export const usePengajuanTempoStoreKontakPerson = create<
+ StateKontakPerson & ActionKontakPerson
+>((set, get) => ({
+ formKontakPerson: {
+ direkturName: '',
+ direkturMobile: '',
+ direkturEmail: '',
+ purchasingName: '',
+ purchasingEmail: '',
+ financeMobile: '',
+ financeName: '',
+ financeEmail: '',
+ purchasingMobile: '',
+ },
+ updateFormKontakPerson: (name, value) =>
+ set((state) => ({
+ formKontakPerson: { ...state.formKontakPerson, [name]: value },
+ })),
+
+ errorsKontakPerson: {},
+ validateKontakPerson: () => {
+ try {
+ TempoSchemaKontakPerson.parse(get().formKontakPerson);
+ set({ errorsKontakPerson: {} });
+ } catch (error) {
+ if (error instanceof ZodError) {
+ const errorsKontakPerson: StateKontakPerson['errorsKontakPerson'] = {};
+ error.errors.forEach(
+ (e) =>
+ (errorsKontakPerson[e.path[0] as keyof TempoPropsKontakPerson] =
+ e.message)
+ );
+ set({ errorsKontakPerson });
+ }
+ }
+ },
+
+ resetFormKontakPerson: () =>
+ set({
+ formKontakPerson: {
+ direkturName: '',
+ direkturMobile: '',
+ direkturEmail: '',
+ purchasingName: '',
+ purchasingEmail: '',
+ financeName: '',
+ financeMobile: '',
+ financeEmail: '',
+ purchasingMobile: '',
+ },
+ }),
+}));
+
+type StatePengiriman = {
+ formPengiriman: TempoPropsPengiriman;
+ errorsPengiriman: {
+ [key in keyof TempoPropsPengiriman]?: string;
+ };
+};
+type ActionPengiriman = {
+ updateFormPengiriman: (name: string, value: string) => void;
+
+ validatePengiriman: () => void;
+ resetFormPengiriman: () => void;
+};
+export const usePengajuanTempoStorePengiriman = create<
+ StatePengiriman & ActionPengiriman
+>((set, get) => ({
+ formPengiriman: {
+ PICName: '',
+ streetPengiriman: '',
+ statePengiriman: '',
+ cityPengiriman: '',
+ zipPengiriman: '',
+ invoicePic: '',
+ isSameAddrees: '',
+ streetInvoice: '',
+ stateInvoice: '',
+ cityInvoice: '',
+ everyWeekday: false,
+ everyWeekdayInput: '',
+ everyWeek: false,
+ everyWeekInput: '',
+ tukarInvoice: false,
+ tukarInvoiceInput: '',
+ everyWeekdayPembayaran: false,
+ everyWeekdayInputPembayaran: '',
+ everyWeekPembayaran: false,
+ everyWeekInputPembayaran: '',
+ tukarInvoicePembayaran: false,
+ tukarInvoiceInputPembayaran: '',
+ dokumenPengiriman: '',
+ dokumenPengirimanInput: '',
+ dokumenPengirimanInvoice: '',
+ },
+ updateFormPengiriman: (name, value) =>
+ set((state) => ({
+ formPengiriman: { ...state.formPengiriman, [name]: value },
+ })),
+
+ errorsPengiriman: {},
+ validatePengiriman: () => {
+ try {
+ TempoSchemaPengiriman.parse(get().formPengiriman);
+ set({ errorsPengiriman: {} });
+ } catch (error) {
+ if (error instanceof ZodError) {
+ const errorsPengiriman: StatePengiriman['errorsPengiriman'] = {};
+ error.errors.forEach(
+ (e) =>
+ (errorsPengiriman[e.path[0] as keyof TempoPropsPengiriman] =
+ e.message)
+ );
+ set({ errorsPengiriman });
+ }
+ }
+ },
+
+ resetFormPengiriman: () =>
+ set({
+ formPengiriman: {
+ PICName: '',
+ streetPengiriman: '',
+ statePengiriman: '',
+ cityPengiriman: '',
+ zipPengiriman: '',
+ invoicePic: '',
+ streetInvoice: '',
+ stateInvoice: '',
+ cityInvoice: '',
+ isSameAddrees: '',
+ everyWeekday: false,
+ everyWeekdayInput: '',
+ everyWeek: false,
+ everyWeekInput: '',
+ tukarInvoice: false,
+ tukarInvoiceInput: '',
+ everyWeekdayPembayaran: false,
+ everyWeekdayInputPembayaran: '',
+ everyWeekPembayaran: false,
+ everyWeekInputPembayaran: '',
+ tukarInvoicePembayaran: false,
+ tukarInvoiceInputPembayaran: '',
+ dokumenPengiriman: '',
+ dokumenPengirimanInput: '',
+ dokumenPengirimanInvoice: '',
+ dokumenPengirimanInvoiceInput: '',
+ },
+ }),
+}));
+type StateDokumen = {
+ formDokumen: TempoPropsDokumen;
+ errorsDokumen: {
+ [key in keyof TempoPropsDokumen]?: string;
+ };
+};
+type ActionDokumen = {
+ updateFormDokumen: (
+ name: string,
+ fileName: string,
+ fileFormat: string,
+ value: string
+ ) => void;
+
+ validateDokumen: () => void;
+ resetFormDokumen: () => void;
+ getJumlahDokumenDiisi: () => void;
+};
+export const usePengajuanTempoStoreDokumen = create<
+ StateDokumen & ActionDokumen
+>((set, get) => ({
+ formDokumen: {
+ dokumenNib: { name: '', format: '', base64: '' },
+ dokumenNpwp: { name: '', format: '', base64: '' },
+ dokumenSppkp: { name: '', format: '', base64: '' },
+ dokumenAktaPerubahan: { name: '', format: '', base64: '' },
+ dokumenKtpDirut: { name: '', format: '', base64: '' },
+ dokumenAktaPendirian: { name: '', format: '', base64: '' },
+ dokumenLaporanKeuangan: { name: '', format: '', base64: '' },
+ dokumenFotoKantor: { name: '', format: '', base64: '' },
+ dokumenTempatBekerja: { name: '', format: '', base64: '' },
+ },
+
+ // Memperbarui dokumen dengan name, format, dan base64
+ updateFormDokumen: (name, fileName, fileFormat, value) =>
+ set((state) => ({
+ formDokumen: {
+ ...state.formDokumen,
+ [name]: {
+ name: fileName,
+ format: fileFormat,
+ base64: value,
+ },
+ },
+ })),
+
+ errorsDokumen: {},
+ validateDokumen: () => {
+ try {
+ TempoSchemaDokumen.parse(get().formDokumen);
+ set({ errorsDokumen: {} });
+ } catch (error) {
+ if (error instanceof ZodError) {
+ const errorsDokumen: StateDokumen['errorsDokumen'] = {};
+ error.errors.forEach(
+ (e) =>
+ (errorsDokumen[e.path[0] as keyof TempoPropsDokumen] = e.message)
+ );
+ set({ errorsDokumen });
+ }
+ }
+ },
+
+ getJumlahDokumenDiisi: () => {
+ const formDokumen = get().formDokumen;
+ // Menghitung jumlah field yang base64 tidak kosong
+ const jumlahTerisi = Object.values(formDokumen).filter(
+ (dokumen) => dokumen.base64 !== ''
+ ).length;
+ return jumlahTerisi;
+ },
+
+ resetFormDokumen: () =>
+ set({
+ formDokumen: {
+ dokumenNib: { name: '', format: '', base64: '' },
+ dokumenNpwp: { name: '', format: '', base64: '' },
+ dokumenSppkp: { name: '', format: '', base64: '' },
+ dokumenAktaPerubahan: { name: '', format: '', base64: '' },
+ dokumenKtpDirut: { name: '', format: '', base64: '' },
+ dokumenAktaPendirian: { name: '', format: '', base64: '' },
+ dokumenLaporanKeuangan: { name: '', format: '', base64: '' },
+ dokumenFotoKantor: { name: '', format: '', base64: '' },
+ dokumenTempatBekerja: { name: '', format: '', base64: '' },
+ },
+ }),
+}));
+
+type StateSupplier = {
+ hasSavedata: boolean;
+ formSupplier: TempoPropsSupplier[];
+ errorsSupplier: {
+ [key in keyof TempoPropsSupplier]?: string;
+ };
+};
+type ActionSupplier = {
+ updateFormSupplier: (data: TempoPropsSupplier[]) => void;
+ updateHasSave: (data: boolean) => void;
+ validateSupplier: () => void;
+};
+export const usePengajuanTempoStoreSupplier = create<
+ StateSupplier & ActionSupplier
+>((set, get) => ({
+ formSupplier: [],
+ hasSavedata: false,
+ updateFormSupplier: (data) => {
+ set(() => ({
+ formSupplier: data,
+ }));
+ },
+ updateHasSave: (data) => {
+ set(() => ({
+ hasSavedata: data,
+ }));
+ },
+ errorsSupplier: {},
+ validateSupplier: () => {},
+}));
diff --git a/src-migrate/types/tempo.ts b/src-migrate/types/tempo.ts
new file mode 100644
index 00000000..815a7557
--- /dev/null
+++ b/src-migrate/types/tempo.ts
@@ -0,0 +1,127 @@
+import {
+ TempoSchema,
+ TempoSchemaKontakPerson,
+ TempoSchemaPengiriman,
+ TempoSchemaSupplier,
+ TempoSchemaDokumen,
+} from '~/validations/tempo';
+import { OdooApiRes } from './odoo';
+import { z } from 'zod';
+
+export type tempoProps = {
+ name: string;
+ industry_id: string;
+ street: string;
+ state: string;
+ city: string;
+ zip: string;
+ mobile: string;
+ bankName: string;
+ accountName: string;
+ accountNumber: string;
+ estimasi: string;
+ tempoDuration: string;
+ bersedia: string;
+};
+
+export type tempoPropsKontakPerson = {
+ direkturName: string;
+ direkturMobile: string;
+ direkturEmail: string;
+ purchasingName: string;
+ purchasingEmail: string;
+ financeMobile: string;
+ financeEmail: string;
+ financeName: string;
+ purchasingMobile: string;
+};
+export type tempoPropsPengiriman = {
+ PICName: string;
+ streetPengiriman: string;
+ statePengiriman: string;
+ cityPengiriman: string;
+ streetInvoice: string;
+ zip: string;
+ invoicePic: string;
+ isSameAddrees: string;
+ stateInvoice: string;
+ cityInvoice: string;
+ everyWeekday: boolean;
+ everyWeekdayInput: string;
+ everyWeek: boolean;
+ everyWeekInput: string;
+ tukarInvoice: boolean;
+ tukarInvoiceInput: string;
+ everyWeekdayPembayaran: boolean;
+ everyWeekdayInputPembayaran: string;
+ everyWeekPembayaran: boolean;
+ everyWeekInputPembayaran: string;
+ tukarInvoicePembayaran: boolean;
+ tukarInvoiceInputPembayaran: string;
+ dokumenPengiriman: string;
+ dokumenPengirimanInput: string;
+ dokumenPengirimanInvoice: string;
+ dokumenPengirimanInvoiceInput: string;
+};
+export type tempoPropsSupplier = {
+ supplier: string;
+ pic: string;
+ telepon: string;
+ durasiTempo: string;
+ creditLimit: string;
+};
+export type tempoPropsDokumen = {
+ dokumenNib: { name: string; format: string; base64: string };
+ dokumenNpwp: { name: string; format: string; base64: string };
+ dokumenSppkp: { name: string; format: string; base64: string };
+ dokumenAktaPerubahan: { name: string; format: string; base64: string };
+ dokumenKtpDirut: { name: string; format: string; base64: string };
+ dokumenAktaPendirian: { name: string; format: string; base64: string };
+ dokumenLaporanKeuangan: { name: string; format: string; base64: string };
+ dokumenFotoKantor: { name: string; format: string; base64: string };
+ dokumenTempatBekerja: { name: string; format: string; base64: string };
+};
+
+export type TempoApiProps = OdooApiRes<TempoProps>;
+
+export type TempoProps = z.infer<typeof TempoSchema>;
+export type TempoPropsKontakPerson = z.infer<typeof TempoSchemaKontakPerson>;
+export type TempoPropsPengiriman = z.infer<typeof TempoSchemaPengiriman>;
+export type TempoPropsSupplier = z.infer<typeof TempoSchemaSupplier>;
+export type TempoPropsDokumen = z.infer<typeof TempoSchemaDokumen>;
+
+export type TempoResApiProps = {
+ Tempo: boolean;
+ reason: 'EMAIL_USED' | 'NOT_ACTIVE' | null;
+};
+
+type ActivationResProps = {
+ activation: boolean;
+ user: TempoProps | null;
+};
+
+export type ActivationTokenProps = {
+ token: string;
+};
+
+export type ActivationTokenResApiProps = ActivationResProps & {
+ reason: 'INVALID_TOKEN' | null;
+};
+
+export type ActivationOtpProps = {
+ email: string;
+ otp: string;
+};
+
+export type ActivationOtpResApiProps = ActivationResProps & {
+ reason: 'INVALID_OTP' | null;
+};
+
+export type ActivationReqProps = {
+ email: string;
+};
+
+export type ActivationReqResApiProps = {
+ activation_request: boolean;
+ reason: 'NOT_FOUND' | 'ACTIVE' | null;
+};
diff --git a/src-migrate/validations/tempo.ts b/src-migrate/validations/tempo.ts
new file mode 100644
index 00000000..7f02019c
--- /dev/null
+++ b/src-migrate/validations/tempo.ts
@@ -0,0 +1,157 @@
+import { z } from 'zod';
+
+export const TempoSchema = z.object({
+ name: z.string().min(1, { message: 'Nama harus diisi' }),
+ street: z.string().min(1, { message: 'Alamat harus diisi' }),
+ industry_id: z.string().min(1, { message: 'Jenis usaha harus dipilih' }),
+ zip: z.string().min(1, { message: 'Kode pos harus diisi' }),
+ state: z.string().min(1, { message: 'Provinsi harus dipilih' }),
+ city: z.string().min(1, { message: 'Kota harus dipilih' }),
+ mobile: z
+ .string()
+ .min(1, { message: 'Nomor telepon harus diisi' })
+ .refine((val) => /^\d{10,12}$/.test(val), {
+ message: 'Format nomor telepon tidak valid, contoh: 081234567890',
+ }),
+ bankName: z.string().min(1, { message: 'Nama bank harus diisi' }),
+ accountName: z.string().min(1, { message: 'Nama rekening harus diisi' }),
+ accountNumber: z.string().min(1, { message: 'Nomor rekening harus diisi' }),
+ estimasi: z
+ .string()
+ .min(1, { message: 'Estimasi pemmbelian pertahun harus diisi' }),
+ tempoDuration: z.string().min(1, { message: 'Durasi tempo harus dipilih' }),
+ tempoLimit: z.string().min(1, { message: 'Limit tempo harus dipilih' }),
+ bersedia: z.string().min(1, { message: 'Harus dipilih' }),
+ categoryProduk: z
+ .string()
+ .min(1, { message: 'Category produk harus dipilih' }),
+});
+
+export const TempoSchemaKontakPerson = z.object({
+ direkturName: z.string().min(1, { message: 'Nama harus diisi' }),
+ financeName: z.string().min(1, { message: 'Nama harus diisi' }),
+ direkturMobile: z
+ .string()
+ .min(1, { message: 'Nomor telepon harus diisi' })
+ .refine((val) => /^\d{10,12}$/.test(val), {
+ message: 'Format nomor telepon tidak valid, contoh: 081234567890',
+ }),
+ financeMobile: z
+ .string()
+ .min(1, { message: 'Nomor telepon harus diisi' })
+ .refine((val) => /^\d{10,12}$/.test(val), {
+ message: 'Format nomor telepon tidak valid, contoh: 081234567890',
+ }),
+ purchasingMobile: z
+ .string()
+ .min(1, { message: 'Nomor telepon harus diisi' })
+ .refine((val) => /^\d{10,12}$/.test(val), {
+ message: 'Format nomor telepon tidak valid, contoh: 081234567890',
+ }),
+ direkturEmail: z
+ .string()
+ .min(1, { message: 'Email harus diisi' })
+ .email({ message: 'Email harus menggunakan format example@mail.com' }),
+ purchasingEmail: z
+ .string()
+ .min(1, { message: 'Email harus diisi' })
+ .email({ message: 'Email harus menggunakan format example@mail.com' }),
+ financeEmail: z
+ .string()
+ .min(1, { message: 'Email harus diisi' })
+ .email({ message: 'Email harus menggunakan format example@mail.com' }),
+ purchasingName: z.string().min(1, { message: 'Nama harus diisi' }),
+});
+export const TempoSchemaPengiriman = z.object({
+ PICName: z.string().min(1, { message: 'Nama harus diisi' }),
+ streetPengiriman: z.string().min(1, { message: 'Alamat harus diisi' }),
+ statePengiriman: z.string().min(1, { message: 'Provinsi harus dipilih' }),
+ cityPengiriman: z.string().min(1, { message: 'Kota harus dipilih' }),
+ zipPengiriman: z.string().min(1, { message: 'Kode pos harus diisi' }),
+ invoicePic: z.string().min(1, { message: 'Nama pic invoice harus diisi' }),
+ streetInvoice: z.string().min(1, { message: 'Alamat invoice harus diisi' }),
+ stateInvoice: z
+ .string()
+ .min(1, { message: 'Provinsi invoice harus dipilih' }),
+ isSameAddrees: z.string(),
+ cityInvoice: z.string().min(1, { message: 'Kota invoice harus dipilih' }),
+ everyWeekday: z.boolean().optional(),
+ everyWeekdayInput: z.string().optional(),
+ everyWeek: z.boolean().optional(),
+ everyWeekInput: z.string().optional(),
+ tukarInvoice: z.boolean().optional(),
+ tukarInvoiceInput: z.string().optional(),
+ everyWeekdayPembayaran: z.boolean().optional(),
+ everyWeekdayInputPembayaran: z.string().optional(),
+ everyWeekPembayaran: z.boolean().optional(),
+ everyWeekInputPembayaran: z.string().optional(),
+ tukarInvoicePembayaran: z.boolean().optional(),
+ tukarInvoiceInputPembayaran: z.string().optional(),
+ dokumenPengiriman: z.string().min(1, {
+ message: 'dokumen lampiran saat pengiriman barang harus dipilih',
+ }),
+ dokumenPengirimanInput: z.string().optional(),
+ dokumenPengirimanInvoice: z.string().min(1, {
+ message: 'dokumen lampiran saat pengiriman barang harus dipilih',
+ }),
+ dokumenPengirimanInvoiceInput: z.string().optional(),
+});
+export const TempoSchemaSupplier = z.object({
+ supplier: z.string().min(1, { message: 'Nama supplier harus diisi' }),
+ pic: z.string().min(1, { message: 'Nama PIC harus diisi' }),
+ telepon: z
+ .string()
+ .min(1, { message: 'Nomor telepon harus diisi' })
+ .refine((val) => /^\d{10,12}$/.test(val), {
+ message: 'Format nomor telepon tidak valid, contoh: 081234567890',
+ }),
+ durasiTempo: z.string().min(1, { message: 'Durasi tempo harus diisi' }),
+ creditLimit: z.string().min(1, { message: 'Limit Kredit harus diisi' }),
+});
+export const TempoSchemaDokumen = z.object({
+ dokumenNib: z.object({
+ name: z.string().min(1, { message: 'Nama file harus diisi' }),
+ format: z.string().min(1, { message: 'Format file harus diisi' }),
+ base64: z.string().min(1, { message: 'Dokumen harus diisi' }),
+ }),
+ dokumenNpwp: z.object({
+ name: z.string().min(1, { message: 'Nama file harus diisi' }),
+ format: z.string().min(1, { message: 'Format file harus diisi' }),
+ base64: z.string().min(1, { message: 'Dokumen harus diisi' }),
+ }),
+ dokumenSppkp: z.object({
+ name: z.string().min(1, { message: 'Nama file harus diisi' }),
+ format: z.string().min(1, { message: 'Format file harus diisi' }),
+ base64: z.string().min(1, { message: 'Dokumen harus diisi' }),
+ }),
+ dokumenAktaPerubahan: z.object({
+ name: z.string().optional(),
+ format: z.string().optional(),
+ base64: z.string().optional(),
+ }),
+ dokumenKtpDirut: z.object({
+ name: z.string().optional(),
+ format: z.string().optional(),
+ base64: z.string().optional(),
+ }),
+ dokumenAktaPendirian: z.object({
+ name: z.string().optional(),
+ format: z.string().optional(),
+ base64: z.string().optional(),
+ }),
+ dokumenLaporanKeuangan: z.object({
+ name: z.string().optional(),
+ format: z.string().optional(),
+ base64: z.string().optional(),
+ }),
+ dokumenFotoKantor: z.object({
+ name: z.string().min(1, { message: 'Nama file harus diisi' }),
+ format: z.string().min(1, { message: 'Format file harus diisi' }),
+ base64: z.string().min(1, { message: 'Dokumen harus diisi' }),
+ }),
+ dokumenTempatBekerja: z.object({
+ name: z.string().min(1, { message: 'Nama file harus diisi' }),
+ format: z.string().min(1, { message: 'Format file harus diisi' }),
+ base64: z.string().min(1, { message: 'Dokumen harus diisi' }),
+ }),
+});
diff --git a/src/core/components/elements/Footer/BasicFooter.jsx b/src/core/components/elements/Footer/BasicFooter.jsx
index 4688b15b..b46d25b5 100644
--- a/src/core/components/elements/Footer/BasicFooter.jsx
+++ b/src/core/components/elements/Footer/BasicFooter.jsx
@@ -215,6 +215,11 @@ const CustomerGuide = () => (
Tracking Order
</InternalItemLink>
</li>
+ <li>
+ <InternalItemLink href='/pengajuan-tempo'>
+ Pengajuan Tempo
+ </InternalItemLink>
+ </li>
</ul>
</div>
);
diff --git a/src/lib/pengajuan-tempo/api/createPengajuanTempoApi.js b/src/lib/pengajuan-tempo/api/createPengajuanTempoApi.js
new file mode 100644
index 00000000..af1d6c3a
--- /dev/null
+++ b/src/lib/pengajuan-tempo/api/createPengajuanTempoApi.js
@@ -0,0 +1,14 @@
+import odooApi from '@/core/api/odooApi';
+import { getAuth } from '@/core/utils/auth';
+
+const createPengajuanTempoApi = async (data) => {
+ const auth = getAuth();
+ const dataPengajuanTempo = await odooApi(
+ 'POST',
+ `/api/v1/partner/pengajuan_tempo`,
+ data
+ );
+ return dataPengajuanTempo;
+};
+
+export default createPengajuanTempoApi;
diff --git a/src/lib/pengajuan-tempo/component/Dokumen.jsx b/src/lib/pengajuan-tempo/component/Dokumen.jsx
new file mode 100644
index 00000000..0873df66
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/Dokumen.jsx
@@ -0,0 +1,952 @@
+import React, { useState, useEffect, useMemo, useRef } from 'react';
+import { Controller, set, useForm } from 'react-hook-form';
+import { usePengajuanTempoStoreDokumen } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore';
+import ProgressBar from '@ramonak/react-progress-bar';
+import { UseToastOptions } from '@chakra-ui/react';
+import { toast } from 'react-hot-toast';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import useDevice from '@/core/hooks/useDevice';
+const Dokumen = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => {
+ const { control, watch } = useForm();
+ const {
+ formDokumen,
+ errorsDokumen,
+ validateDokumen,
+ updateFormDokumen,
+ getJumlahDokumenDiisi,
+ } = usePengajuanTempoStoreDokumen();
+ const { isDesktop, isMobile } = useDevice();
+ // const handleInputChange = (event) => {
+ // const { name, value } = event.target;
+ // updateFormDokumen(name, value);
+ // validateDokumen();
+ // };
+ const handleInputChange = async (event) => {
+ let fileBase64 = '';
+ const { name } = event.target;
+ const file = event.target.files?.[0];
+ // Allowed file extensions
+ const allowedExtensions = ['pdf', 'png', 'jpg', 'jpeg'];
+ let fileExtension = '';
+ if (file) {
+ fileExtension = file.name.split('.').pop()?.toLowerCase(); // Extract file extension
+
+ // Check if the file extension is allowed
+ if (!fileExtension || !allowedExtensions.includes(fileExtension)) {
+ toast.error(
+ 'Format file yang diijinkan adalah .pdf, .png, .jpg, atau .jpeg',
+ { duration: 4000 }
+ );
+
+ event.target.value = '';
+ return;
+ }
+
+ // Check for file size
+ if (file.size > 2000000) {
+ toast.error('Maksimal ukuran file adalah 2MB', { duration: 4000 });
+
+ event.target.value = '';
+ return;
+ }
+
+ // Convert file to Base64
+ fileBase64 = await getFileBase64(file);
+ updateFormDokumen(name, file.name, fileExtension, fileBase64);
+ validateDokumen();
+ }
+ };
+
+ const isFormValid = useMemo(
+ () => Object.keys(errorsDokumen).length === 0,
+ [errorsDokumen]
+ );
+ const dokumenNibRef = useRef(null);
+ const dokumenNpwpRef = useRef(null);
+ const dokumenSppkpRef = useRef(null);
+ const dokumenAktaPerubahanRef = useRef(null);
+ const dokumenKtpDirutRef = useRef(null);
+ const dokumenAktaPendirianRef = useRef(null);
+ const dokumenLaporanKeuanganRef = useRef(null);
+ const dokumenFotoKantorRef = useRef(null);
+ const dokumenTempatBekerjaRef = useRef(null);
+
+ useEffect(() => {
+ const loadIndustries = async () => {
+ if (!isFormValid) {
+ const options = {
+ behavior: 'smooth',
+ block: 'center',
+ };
+ if (errorsDokumen.dokumenNib && dokumenNibRef.current) {
+ dokumenNibRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenNpwp && dokumenNpwpRef.current) {
+ dokumenNpwpRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenSppkp && dokumenSppkpRef.current) {
+ dokumenSppkpRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenAktaPerubahan &&
+ dokumenAktaPerubahanRef.current
+ ) {
+ dokumenAktaPerubahanRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenKtpDirut && dokumenKtpDirutRef.current) {
+ dokumenKtpDirutRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenAktaPendirian &&
+ dokumenAktaPendirianRef.current
+ ) {
+ dokumenAktaPendirianRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenLaporanKeuangan &&
+ dokumenLaporanKeuanganRef.current
+ ) {
+ dokumenLaporanKeuanganRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenFotoKantor && dokumenFotoKantorRef.current) {
+ dokumenFotoKantorRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenTempatBekerja &&
+ dokumenTempatBekerjaRef.current
+ ) {
+ dokumenTempatBekerjaRef.current.scrollIntoView(options);
+ return;
+ }
+ }
+ };
+ loadIndustries();
+ }, [buttonSubmitClick, chekValid]);
+
+ useEffect(() => {
+ validateDokumen();
+ }, [buttonSubmitClick]);
+ return (
+ <>
+ {isDesktop && (
+ <div>
+ <h1 className={`font-bold ${isKonfirmasi ? 'text-xl' : ''}`}>
+ Dokumen
+ </h1>
+ <form className='flex mt-4 flex-col w-full '>
+ <div className='w-full grid grid-cols-[1fr_auto_1fr] gap-5'>
+ <div className='kolom-kiri w-full grid grid-rows-2 gap-7 '>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>
+ NIB (SIUP/TDP/SKDP)
+ </label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenNib'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenNib'
+ name='dokumenNib'
+ type='file'
+ title=' '
+ ref={dokumenNibRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenNib}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenNib?.name}
+ </span>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenNib}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>
+ NPWP Perusahaan
+ </label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenNpwp'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenNpwp'
+ name='dokumenNpwp'
+ type='file'
+ ref={dokumenNpwpRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenNpwp}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenNpwp?.name}
+ </span>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenNpwp}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>SPPKP</label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenSppkp'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen.dokumenSppkp}
+ id='dokumenSppkp'
+ name='dokumenSppkp'
+ type='file'
+ ref={dokumenSppkpRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenSppkp}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenSppkp?.name}
+ </span>
+ </div>
+
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenSppkp}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>
+ Akta Perubahan{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenAktaPerubahan'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen.dokumenAktaPerubahan}
+ id='dokumenAktaPerubahan'
+ name='dokumenAktaPerubahan'
+ type='file'
+ ref={dokumenAktaPerubahanRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenAktaPerubahan}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenAktaPerubahan?.name}
+ </span>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenAktaPerubahan}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>
+ KTP Dirut/Direktur{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenKtpDirut'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen.dokumenKtpDirut}
+ id='dokumenKtpDirut'
+ name='dokumenKtpDirut'
+ type='file'
+ ref={dokumenKtpDirutRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenKtpDirut}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenKtpDirut?.name}
+ </span>
+ </div>
+
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenKtpDirut}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ <div className='w-px bg-gray-300'></div>
+ <div className='kolom kanan w-full grid grid-rows-2 gap-10 '>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>
+ Akta Pendirian{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenAktaPendirian'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen.dokumenAktaPendirian}
+ id='dokumenAktaPendirian'
+ name='dokumenAktaPendirian'
+ type='file'
+ ref={dokumenAktaPendirianRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenAktaPendirian}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenAktaPendirian?.name}
+ </span>
+ </div>
+
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenAktaPendirian}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>
+ Laporan Keuangan
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenLaporanKeuangan'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen.dokumenLaporanKeuangan}
+ id='dokumenLaporanKeuangan'
+ name='dokumenLaporanKeuangan'
+ type='file'
+ ref={dokumenLaporanKeuanganRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenLaporanKeuangan}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenLaporanKeuangan?.name}
+ </span>
+ </div>
+
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenLaporanKeuangan}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>
+ Foto Kantor (Tampak Depan)
+ </label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenFotoKantor'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen.dokumenFotoKantor}
+ id='dokumenFotoKantor'
+ name='dokumenFotoKantor'
+ type='file'
+ ref={dokumenFotoKantorRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenFotoKantor}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenFotoKantor?.name}
+ </span>
+ </div>
+
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenFotoKantor}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full grid grid-cols-2 gap-5'>
+ <div>
+ <label className='form-label text-nowrap'>
+ Tempat Bekerja
+ </label>
+ <span className='text-xs opacity-60'>
+ Pastikan dokumen yang anda upload sudah benar
+ </span>
+ </div>
+ <div className=''>
+ <div className='flex flex-col items-start'>
+ <label
+ htmlFor='dokumenTempatBekerja'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded'
+ >
+ Upload Dokumen
+ </label>
+ <input
+ // value={formDokumen.dokumenTempatBekerja}
+ id='dokumenTempatBekerja'
+ name='dokumenTempatBekerja'
+ type='file'
+ ref={dokumenTempatBekerjaRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenTempatBekerja}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600'>
+ {formDokumen?.dokumenTempatBekerja?.name}
+ </span>
+ </div>
+
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenTempatBekerja}
+ </div>
+ )}
+ </div>
+ </div>
+ <div></div>
+ </div>
+ </div>
+ </form>
+ <div className='w-1/2 mt-8 flex gap-3 flex-col'>
+ <div className='flex justify-between'>
+ <p className='font-bold'>Upload Progress</p>
+ <p>
+ <span className='text-red-500 font-bold'>
+ {parseInt((getJumlahDokumenDiisi() / 9) * 100)} %
+ </span>
+ <span className='ml-2 opacity-60'>
+ {getJumlahDokumenDiisi() >= 4
+ ? getJumlahDokumenDiisi() == 9
+ ? 'Selesai'
+ : 'Sedikit Lagi'
+ : ''}
+ </span>
+ </p>
+ </div>
+ {/* 50 keatas baru muncul kata kata sedikit lagi */}
+ <ProgressBar
+ completed={getJumlahDokumenDiisi()}
+ bgColor='#ef4444'
+ labelAlignment='outside'
+ isLabelVisible={false}
+ baseBgColor='#E5E7EB'
+ labelColor='#e80909'
+ labelSize='0'
+ maxCompleted={9}
+ height='14 px'
+ />
+ <span className='opacity-75'>
+ Tingkatin sedikit lagi agar pengajuan tempo kamu dapat kami proses
+ dengan cepat
+ </span>
+ </div>
+ </div>
+ )}
+ {isMobile && (
+ <div>
+ <h1
+ className={`font-bold py-4 mt-8 ${
+ isKonfirmasi ? 'text-xl' : 'text-xl'
+ }`}
+ >
+ Dokumen
+ </h1>
+ <form className='flex mt-4 flex-col w-full '>
+ <div className='w-full flex flex-col gap-4'>
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>
+ NIB (SIUP/TDP/SKDP)
+ </label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenNib'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenNib?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenNib'
+ name='dokumenNib'
+ type='file'
+ title=' '
+ ref={dokumenNibRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenNib}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenNib?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenNib}
+ </div>
+ )}
+ </div>
+
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>
+ NPWP Perusahaan
+ </label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenNpwp'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenNpwp?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenNpwp'
+ name='dokumenNpwp'
+ type='file'
+ ref={dokumenNpwpRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenNpwp}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenNpwp?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenNpwp}
+ </div>
+ )}
+ </div>
+
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>SPPKP</label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenSppkp'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenSppkp?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenSppkp'
+ name='dokumenSppkp'
+ type='file'
+ ref={dokumenSppkpRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenSppkp}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenSppkp?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenSppkp}
+ </div>
+ )}
+ </div>
+
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>
+ Akta Perubahan <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenAktaPerubahan'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenAktaPerubahan?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenAktaPerubahan'
+ name='dokumenAktaPerubahan'
+ type='file'
+ ref={dokumenAktaPerubahanRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenAktaPerubahan}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenAktaPerubahan?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenAktaPerubahan}
+ </div>
+ )}
+ </div>
+
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>
+ KTP Dirut/Direktur{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenKtpDirut'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenKtpDirut?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenKtpDirut'
+ name='dokumenKtpDirut'
+ type='file'
+ ref={dokumenKtpDirutRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenKtpDirut}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenKtpDirut?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenKtpDirut}
+ </div>
+ )}
+ </div>
+
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>
+ Akta Pendirian <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenAktaPendirian'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenAktaPendirian?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenAktaPendirian'
+ name='dokumenAktaPendirian'
+ type='file'
+ ref={dokumenAktaPendirianRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenAktaPendirian}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenAktaPendirian?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenAktaPendirian}
+ </div>
+ )}
+ </div>
+
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>
+ Laporan Keuangan{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenLaporanKeuangan'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenLaporanKeuangan?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenLaporanKeuangan'
+ name='dokumenLaporanKeuangan'
+ type='file'
+ ref={dokumenLaporanKeuanganRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenLaporanKeuangan}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenLaporanKeuangan?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenLaporanKeuangan}
+ </div>
+ )}
+ </div>
+
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>
+ Foto Kantor (Tampak Depan)
+ </label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenFotoKantor'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenFotoKantor?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenFotoKantor'
+ name='dokumenFotoKantor'
+ type='file'
+ ref={dokumenFotoKantorRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenFotoKantor}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenFotoKantor?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenFotoKantor}
+ </div>
+ )}
+ </div>
+
+ <div className='w-full flex flex-col gap-2'>
+ <label className='form-label text-nowrap'>
+ Tempat Bekerja
+ </label>
+ <div className='flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenTempatBekerja'
+ className='cursor-pointer bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded w-fit min-w-40 text-nowrap text-center flex items-center justify-center'
+ >
+ {formDokumen?.dokumenTempatBekerja?.name
+ ? 'Sudah Upload'
+ : 'Upload Dokumen'}
+ </label>
+ <input
+ // value={formDokumen.dokumenNpwp}
+ id='dokumenTempatBekerja'
+ name='dokumenTempatBekerja'
+ type='file'
+ ref={dokumenTempatBekerjaRef}
+ title=' '
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenTempatBekerja}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <span className='mt-2 text-gray-600 truncate'>
+ {formDokumen?.dokumenTempatBekerja?.name}
+ </span>
+ </div>
+ <span className='text-xs opacity-60 text-red-500'>
+ Format: pdf, jpeg, jpg, png. max file size 2MB
+ </span>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenTempatBekerja}
+ </div>
+ )}
+ </div>
+ </div>
+ </form>
+ <div className='w-full mt-8 flex gap-3 flex-col'>
+ <div className='flex justify-between'>
+ <p className='font-bold'>Upload Progress</p>
+ <p>
+ <span className='text-red-500 font-bold'>
+ {parseInt((getJumlahDokumenDiisi() / 9) * 100)} %
+ </span>
+ <span className='ml-2 opacity-60'>
+ {getJumlahDokumenDiisi() >= 4
+ ? getJumlahDokumenDiisi() == 9
+ ? 'Selesai'
+ : 'Sedikit Lagi'
+ : ''}
+ </span>
+ </p>
+ </div>
+ {/* 50 keatas baru muncul kata kata sedikit lagi */}
+ <ProgressBar
+ completed={getJumlahDokumenDiisi()}
+ bgColor='#ef4444'
+ labelAlignment='outside'
+ isLabelVisible={false}
+ baseBgColor='#E5E7EB'
+ labelColor='#e80909'
+ labelSize='0'
+ maxCompleted={9}
+ height='10px'
+ />
+ <span className='opacity-75 text-xs text-red-500'>
+ Tingkatin sedikit lagi agar pengajuan tempo kamu dapat kami proses
+ dengan cepat
+ </span>
+ </div>
+ </div>
+ )}
+ </>
+ );
+};
+
+export default Dokumen;
diff --git a/src/lib/pengajuan-tempo/component/FinishTempo.jsx b/src/lib/pengajuan-tempo/component/FinishTempo.jsx
new file mode 100644
index 00000000..1670314d
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/FinishTempo.jsx
@@ -0,0 +1,78 @@
+import Link from 'next/link';
+import Image from '~/components/ui/image';
+import whatsappUrl from '@/core/utils/whatsappUrl';
+import { useEffect, useState } from 'react';
+import odooApi from '@/core/api/odooApi';
+import useDevice from '@/core/hooks/useDevice';
+import useAuth from '@/core/hooks/useAuth';
+import axios from 'axios';
+import { toast } from 'react-hot-toast';
+import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline';
+
+const FinishTempo = ({ query }) => {
+ const [data, setData] = useState();
+ const [transactionData, setTransactionData] = useState();
+ const { isDesktop, isMobile } = useDevice();
+ const auth = useAuth();
+
+ const so_order = query?.order_id?.replaceAll('-', '/');
+ useEffect(() => {
+ const fetchData = async () => {
+ const fetchedData = await odooApi(
+ 'GET',
+ `/api/v1/sale_order_number?sale_number=${so_order}`
+ );
+ setData(fetchedData[0]);
+ };
+ fetchData();
+ }, [query]);
+
+ // Kirim email ketika komponen ini dimount atau sesuai kondisi
+ const sendEmail = async () => {
+ try {
+ const send = await axios.post(
+ `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/finish-checkout?orderName=${query?.order_id}`,
+ {}
+ );
+ if (send.status === 200) {
+ toast.success('Berhasil mengirim rincian pesanan');
+ } else {
+ toast.error('Gagal mengirimkan rincian pesanan');
+ }
+ } catch (error) {
+ console.error(error);
+ toast.error('Gagal mengirimkan rincian pesanan');
+ }
+ };
+
+ return (
+ <div className='container flex flex-col items-center gap-4'>
+ <div className='flex w-2/3 justify-center items-center'>
+ <h1 className='text-red-500 text-center font-semibold text-3xl'>
+ Form Pengajuan Tempo kamu Telah Berhasil Didaftarkan Mohon menunggu
+ hingga Proses Selesai
+ </h1>
+ </div>
+ <Image
+ src='/images/REGISTRASI-TEMPO.svg'
+ alt='Checkout Pesanan'
+ width={isMobile ? 300 : 450}
+ height={isMobile ? 300 : 450}
+ />
+
+ <div className='mt-2 text-center leading-6 text-base p-4 md:p-0 w-4/5'>
+ Mohon menunggu untuk verifikasi dokumen dan kelengkapan data yang telah
+ anda berikan. Proses approval pembayaran tempo kamu berhasil atau tidak
+ akan diinfokan melalui email perusahaan / email yang mendaftar
+ </div>
+ <Link
+ href={`/my/quotations/${data?.id}`}
+ className='btn-solid-red rounded-md text-base flex flex-row'
+ >
+ Lihat Status Pendaftaran <ChevronRightIcon className='w-5' />
+ </Link>
+ </div>
+ );
+};
+
+export default FinishTempo;
diff --git a/src/lib/pengajuan-tempo/component/Konfirmasi.jsx b/src/lib/pengajuan-tempo/component/Konfirmasi.jsx
new file mode 100644
index 00000000..80845a8f
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/Konfirmasi.jsx
@@ -0,0 +1,263 @@
+import React, { useState, useEffect, useMemo, useRef } from 'react';
+import { Controller, set, useForm } from 'react-hook-form';
+import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
+import {
+ usePengajuanTempoStoreDokumen,
+ usePengajuanTempoStore,
+} from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore';
+import KontakPerusahaan from './KontakPerusahaan';
+import ProgressBar from '@ramonak/react-progress-bar';
+import { UseToastOptions } from '@chakra-ui/react';
+import odooApi from '~/libs/odooApi';
+import { toast } from 'react-hot-toast';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import { CheckCircleIcon } from '@heroicons/react/24/outline';
+import InformasiPerusahaan from './informasiPerusahaan';
+import Pengiriman from './Pengiriman';
+import KonfirmasiDokumen from './KonfirmasiDokumen';
+import useDevice from '@/core/hooks/useDevice';
+import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';
+const Konfirmasi = ({ chekValid, buttonSubmitClick }) => {
+ const { control, watch, setValue, getValues } = useForm();
+ const { isDesktop, isMobile } = useDevice();
+ const [isOpen, setIsOpen] = useState(false);
+ const [industries, setIndustries] = useState([]);
+ const {
+ formDokumen,
+ errorsDokumen,
+ validateDokumen,
+ updateFormDokumen,
+ getJumlahDokumenDiisi,
+ } = usePengajuanTempoStoreDokumen();
+ const { form, errors, validate, updateForm } = usePengajuanTempoStore();
+ const handleInputChange = async (event) => {
+ let fileBase64 = '';
+ const { name } = event.target;
+ const file = event.target.files?.[0];
+ // Allowed file extensions
+ const allowedExtensions = ['pdf', 'png', 'jpg', 'jpeg'];
+ let fileExtension = '';
+ if (file) {
+ fileExtension = file.name.split('.').pop()?.toLowerCase();
+
+ if (!fileExtension || !allowedExtensions.includes(fileExtension)) {
+ toast.error(
+ 'Format file yang diijinkan adalah .pdf, .png, .jpg, atau .jpeg',
+ { duration: 4000 }
+ );
+
+ event.target.value = '';
+ return;
+ }
+ if (file.size > 2000000) {
+ toast.error('Maksimal ukuran file adalah 2MB', { duration: 4000 });
+
+ event.target.value = '';
+ return;
+ }
+
+ fileBase64 = await getFileBase64(file);
+ updateFormDokumen(name, file.name, fileExtension, fileBase64);
+ validateDokumen();
+ }
+ };
+
+ const isFormValid = useMemo(
+ () => Object.keys(errorsDokumen).length === 0,
+ [errorsDokumen]
+ );
+ const dokumenNibRef = useRef(null);
+ const dokumenNpwpRef = useRef(null);
+ const dokumenSppkpRef = useRef(null);
+ const dokumenAktaPerubahanRef = useRef(null);
+ const dokumenKtpDirutRef = useRef(null);
+ const dokumenAktaPendirianRef = useRef(null);
+ const dokumenLaporanKeuanganRef = useRef(null);
+ const dokumenFotoKantorRef = useRef(null);
+ const dokumenTempatBekerjaRef = useRef(null);
+
+ useEffect(() => {
+ const loadIndustries = async () => {
+ if (!isFormValid) {
+ const options = {
+ behavior: 'smooth',
+ block: 'center',
+ };
+ if (errorsDokumen.dokumenNib && dokumenNibRef.current) {
+ dokumenNibRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenNpwp && dokumenNpwpRef.current) {
+ dokumenNpwpRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenSppkp && dokumenSppkpRef.current) {
+ dokumenSppkpRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenAktaPerubahan &&
+ dokumenAktaPerubahanRef.current
+ ) {
+ dokumenAktaPerubahanRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenKtpDirut && dokumenKtpDirutRef.current) {
+ dokumenKtpDirutRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenAktaPendirian &&
+ dokumenAktaPendirianRef.current
+ ) {
+ dokumenAktaPendirianRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenLaporanKeuangan &&
+ dokumenLaporanKeuanganRef.current
+ ) {
+ dokumenLaporanKeuanganRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenFotoKantor && dokumenFotoKantorRef.current) {
+ dokumenFotoKantorRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenTempatBekerja &&
+ dokumenTempatBekerjaRef.current
+ ) {
+ dokumenTempatBekerjaRef.current.scrollIntoView(options);
+ return;
+ }
+ }
+ };
+ loadIndustries();
+ }, [buttonSubmitClick, chekValid]);
+
+ useEffect(() => {
+ validateDokumen();
+ }, [buttonSubmitClick]);
+
+ useEffect(() => {
+ const loadIndustries = async () => {
+ const dataIndustries = await odooApi('GET', '/api/v1/partner/industry');
+ setIndustries(
+ dataIndustries?.map((o) => ({
+ value: o.id,
+ label: o.name,
+ category: o.category,
+ }))
+ );
+ };
+ loadIndustries();
+ }, []);
+
+ useEffect(() => {
+ const selectedIndustryType = industries.find(
+ (industry) => industry.value === watch('industry_id')
+ );
+ if (selectedIndustryType) {
+ updateForm('industry_id', `${selectedIndustryType?.value}`);
+ validate();
+ }
+ }, [watch('industry_id'), industries]);
+
+ useEffect(() => {
+ if (form.industry_id) {
+ setValue('industry_id', parseInt(form.industry_id));
+ }
+ }, [form]);
+ const handleLabelClick = () => {
+ setIndustriesOpen(!industriesOpen);
+ };
+ return (
+ <>
+ {isDesktop && (
+ <form className='flex mt-4 flex-col w-full '>
+ <div className='w-full grid grid-cols-[1fr_auto_1fr] gap-5'>
+ <div className='w-full flex flex-col gap-5 '>
+ <div className=''>
+ <InformasiPerusahaan isKonfirmasi={true} />
+ </div>
+ <div className='h-px bg-gray-300'></div>
+ <div className=''>
+ <KontakPerusahaan isKonfirmasi={true} />
+ </div>
+ </div>
+
+ <div className='w-px bg-gray-300'></div>
+ <div className='w-full grid grid-rows-[1fc_auto_1fc] gap-5'>
+ <div>
+ <Pengiriman isKonfirmasi={true} />
+ </div>
+ <div className='h-px bg-gray-300'></div>
+ <div>
+ <KonfirmasiDokumen isKonfirmasi={true} />
+ </div>
+ </div>
+ </div>
+ </form>
+ )}
+ {isMobile && (
+ <form className='flex mt-8 py-4 flex-col w-full gap-4'>
+ <div className='flex flex-col gap-4'>
+ <div className='flex flex-row justify-between'>
+ <p className='font-semibold text-lg'>Informasi Perusahaan</p>
+ <div className='p-2 bg-gray-200'>
+ {isOpen ? (
+ <ChevronUpIcon className='w-4' />
+ ) : (
+ <ChevronDownIcon className='w-4' />
+ )}
+ </div>
+ </div>
+ <InformasiPerusahaan isKonfirmasi={true} />
+ </div>
+ <div className='flex flex-col gap-4'>
+ <div className='flex flex-row justify-between'>
+ <p className='font-semibold text-lg'>Kontak Person</p>
+ <div className='p-2 bg-gray-200'>
+ {isOpen ? (
+ <ChevronUpIcon className='w-4' />
+ ) : (
+ <ChevronDownIcon className='w-4' />
+ )}
+ </div>
+ </div>
+ <KontakPerusahaan isKonfirmasi={true} />
+ </div>
+ <div className='flex flex-col gap-4'>
+ <div className='flex flex-row justify-between'>
+ <p className='font-semibold text-lg'>Pengiriman</p>
+ <div className='p-2 bg-gray-200'>
+ {isOpen ? (
+ <ChevronUpIcon className='w-4' />
+ ) : (
+ <ChevronDownIcon className='w-4' />
+ )}
+ </div>
+ </div>
+ <Pengiriman isKonfirmasi={true} />
+ </div>
+ <div className='flex flex-col gap-4'>
+ <div className='flex flex-row justify-between'>
+ <p className='font-semibold text-lg'>Dokumen</p>
+ <div className='p-2 bg-gray-200'>
+ {isOpen ? (
+ <ChevronUpIcon className='w-4' />
+ ) : (
+ <ChevronDownIcon className='w-4' />
+ )}
+ </div>
+ </div>
+ <KonfirmasiDokumen isKonfirmasi={true} />
+ </div>
+ </form>
+ )}
+ </>
+ );
+};
+
+export default Konfirmasi;
diff --git a/src/lib/pengajuan-tempo/component/KonfirmasiDokumen.jsx b/src/lib/pengajuan-tempo/component/KonfirmasiDokumen.jsx
new file mode 100644
index 00000000..9b0f1d8f
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/KonfirmasiDokumen.jsx
@@ -0,0 +1,1202 @@
+import React, { useState, useEffect, useMemo, useRef } from 'react';
+import { Controller, set, useForm } from 'react-hook-form';
+import { usePengajuanTempoStoreDokumen } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore';
+import ProgressBar from '@ramonak/react-progress-bar';
+import { UseToastOptions } from '@chakra-ui/react';
+import { toast } from 'react-hot-toast';
+import getFileBase64 from '@/core/utils/getFileBase64';
+import Image from 'next/image';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import { EyeIcon } from '@heroicons/react/24/outline';
+import useDevice from '@/core/hooks/useDevice';
+const KonfirmasiDokumen = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => {
+ const { control, watch } = useForm();
+ const [isExample, setIsExample] = useState(false);
+ const { isDesktop, isMobile } = useDevice();
+ const [base64, setBase64] = useState();
+ const [pdfData, setPdfData] = useState();
+ const [format, setFormat] = useState();
+ const [popUpSource, setSource] = useState();
+ const {
+ formDokumen,
+ errorsDokumen,
+ validateDokumen,
+ updateFormDokumen,
+ getJumlahDokumenDiisi,
+ } = usePengajuanTempoStoreDokumen();
+
+ const handleConfirmSubmit = (format, base64) => {
+ if (format == 'pdf') {
+ setFormat(`application/${format}`);
+ } else {
+ setFormat(`image/${format}`);
+ }
+ setBase64(
+ base64.trim().replace(/^"+/, '').replace(/"+$/, '').replaceAll('\\', '')
+ );
+ setIsExample(!isExample);
+ };
+ const handleInputChange = async (event) => {
+ let fileBase64 = '';
+ const { name } = event.target;
+ const file = event.target.files?.[0];
+ const allowedExtensions = ['pdf', 'png', 'jpg', 'jpeg'];
+ let fileExtension = '';
+ if (file) {
+ fileExtension = file.name.split('.').pop()?.toLowerCase();
+
+ if (!fileExtension || !allowedExtensions.includes(fileExtension)) {
+ toast.error(
+ 'Format file yang diijinkan adalah .pdf, .png, .jpg, atau .jpeg',
+ { duration: 4000 }
+ );
+
+ event.target.value = '';
+ return;
+ }
+
+ if (file.size > 2000000) {
+ toast.error('Maksimal ukuran file adalah 2MB', { duration: 4000 });
+
+ event.target.value = '';
+ return;
+ }
+
+ fileBase64 = await getFileBase64(file);
+ updateFormDokumen(name, file.name, fileExtension, fileBase64);
+ validateDokumen();
+ }
+ };
+
+ const isFormValid = useMemo(
+ () => Object.keys(errorsDokumen).length === 0,
+ [errorsDokumen]
+ );
+ const dokumenNibRef = useRef(null);
+ const dokumenNpwpRef = useRef(null);
+ const dokumenSppkpRef = useRef(null);
+ const dokumenAktaPerubahanRef = useRef(null);
+ const dokumenKtpDirutRef = useRef(null);
+ const dokumenAktaPendirianRef = useRef(null);
+ const dokumenLaporanKeuanganRef = useRef(null);
+ const dokumenFotoKantorRef = useRef(null);
+ const dokumenTempatBekerjaRef = useRef(null);
+
+ useEffect(() => {
+ const loadIndustries = async () => {
+ if (!isFormValid) {
+ const options = {
+ behavior: 'smooth',
+ block: 'center',
+ };
+ if (errorsDokumen.dokumenNib && dokumenNibRef.current) {
+ dokumenNibRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenNpwp && dokumenNpwpRef.current) {
+ dokumenNpwpRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenSppkp && dokumenSppkpRef.current) {
+ dokumenSppkpRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenAktaPerubahan &&
+ dokumenAktaPerubahanRef.current
+ ) {
+ dokumenAktaPerubahanRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenKtpDirut && dokumenKtpDirutRef.current) {
+ dokumenKtpDirutRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenAktaPendirian &&
+ dokumenAktaPendirianRef.current
+ ) {
+ dokumenAktaPendirianRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenLaporanKeuangan &&
+ dokumenLaporanKeuanganRef.current
+ ) {
+ dokumenLaporanKeuanganRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsDokumen.dokumenFotoKantor && dokumenFotoKantorRef.current) {
+ dokumenFotoKantorRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsDokumen.dokumenTempatBekerja &&
+ dokumenTempatBekerjaRef.current
+ ) {
+ dokumenTempatBekerjaRef.current.scrollIntoView(options);
+ return;
+ }
+ }
+ };
+ loadIndustries();
+ }, [buttonSubmitClick, chekValid]);
+
+ useEffect(() => {
+ validateDokumen();
+ }, [buttonSubmitClick]);
+
+ return (
+ <>
+ {isDesktop && (
+ <div>
+ <h1 className={`font-bold ${isKonfirmasi ? 'text-xl' : ''}`}>
+ Dokumen
+ </h1>
+ <form className='flex flex-col w-full gap-5'>
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ NIB (SIUP/TDP/SKDP)
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenNib?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenNib'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenNib'
+ name='dokumenNib'
+ type='file'
+ title=' '
+ ref={dokumenNibRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenNib}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenNib.format,
+ formDokumen.dokumenNib.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenNib}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ NPWP Perusahaan
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenNpwp?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenNpwp'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenNpwp'
+ name='dokumenNpwp'
+ type='file'
+ title=' '
+ ref={dokumenNpwpRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenNpwp}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenNpwp.format,
+ formDokumen.dokumenNpwp.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenNpwp}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>SPPKP</label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenSppkp?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenSppkp'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenSppkp'
+ name='dokumenSppkp'
+ type='file'
+ title=' '
+ ref={dokumenSppkpRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenSppkp}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenSppkp.format,
+ formDokumen.dokumenSppkp.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenSppkp}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ {' '}
+ Akta Perubahan <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenAktaPerubahan?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenAktaPerubahan'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenAktaPerubahan'
+ name='dokumendokumenAktaPerubahanSppkp'
+ type='file'
+ title=' '
+ ref={dokumenAktaPerubahanRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenAktaPerubahan}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenAktaPerubahan.format,
+ formDokumen.dokumenAktaPerubahan.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenAktaPerubahan}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ KTP Dirut/Direktur{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenKtpDirut?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenKtpDirut'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenKtpDirut'
+ name='dokumenKtpDirut'
+ type='file'
+ title=' '
+ ref={dokumenKtpDirutRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenKtpDirut}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenKtpDirut.format,
+ formDokumen.dokumenKtpDirut.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenKtpDirut}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Akta Pendirian <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenAktaPendirian?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenAktaPendirian'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenAktaPendirian'
+ name='dokumenAktaPendirian'
+ type='file'
+ title=' '
+ ref={dokumenAktaPendirianRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenAktaPendirian}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenAktaPendirian.format,
+ formDokumen.dokumenAktaPendirian.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenAktaPendirian}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Laporan Keuangan
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenLaporanKeuangan?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenLaporanKeuangan'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenLaporanKeuangan'
+ name='dokumenLaporanKeuangan'
+ type='file'
+ title=' '
+ ref={dokumenLaporanKeuanganRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenLaporanKeuangan}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenLaporanKeuangan.format,
+ formDokumen.dokumenLaporanKeuangan.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenLaporanKeuangan}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Foto Kantor (Tampak Depan)
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenFotoKantor?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenFotoKantor'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenFotoKantor'
+ name='dokumenFotoKantor'
+ type='file'
+ title=' '
+ ref={dokumenFotoKantorRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenFotoKantor}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenFotoKantor.format,
+ formDokumen.dokumenFotoKantor.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenFotoKantor}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Tempat Bekerja
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenTempatBekerja?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenTempatBekerja'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenTempatBekerja'
+ name='dokumenTempatBekerja'
+ type='file'
+ title=' '
+ ref={dokumenTempatBekerjaRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenTempatBekerja}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenTempatBekerja.format,
+ formDokumen.dokumenTempatBekerja.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ {/* <Image
+ src={`data:image/png;base64, ${formDokumen.dokumenNib.base64}`}
+ alt='Contoh SPPKP'
+ className='w-full h-full '
+ width={800}
+ height={800}
+ quality={85}
+ /> */}
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenTempatBekerja}
+ </div>
+ )}
+ </div>
+ </div>
+ </form>
+ </div>
+ )}
+ {isMobile && (
+ <div>
+ <h1 className={`font-bold ${isKonfirmasi ? 'hidden' : 'text-xl'}`}>
+ Dokumen
+ </h1>
+ <form className='flex flex-col w-full gap-5 text-sm'>
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ NIB (SIUP/TDP/SKDP)
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-center justify-start'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenNib?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenNib'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenNib'
+ name='dokumenNib'
+ type='file'
+ title=' '
+ ref={dokumenNibRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenNib}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenNib.format,
+ formDokumen.dokumenNib.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenNib}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>NPWP Perusahaan</label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenNpwp?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenNpwp'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenNpwp'
+ name='dokumenNpwp'
+ type='file'
+ title=' '
+ ref={dokumenNpwpRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenNpwp}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenNpwp.format,
+ formDokumen.dokumenNpwp.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenNpwp}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>SPPKP</label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenSppkp?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenSppkp'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenSppkp'
+ name='dokumenSppkp'
+ type='file'
+ title=' '
+ ref={dokumenSppkpRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenSppkp}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenSppkp.format,
+ formDokumen.dokumenSppkp.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenSppkp}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ {' '}
+ Akta Perubahan <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenAktaPerubahan?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenAktaPerubahan'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenAktaPerubahan'
+ name='dokumendokumenAktaPerubahanSppkp'
+ type='file'
+ title=' '
+ ref={dokumenAktaPerubahanRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenAktaPerubahan}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenAktaPerubahan.format,
+ formDokumen.dokumenAktaPerubahan.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenAktaPerubahan}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ KTP Dirut/Direktur{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenKtpDirut?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenKtpDirut'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenKtpDirut'
+ name='dokumenKtpDirut'
+ type='file'
+ title=' '
+ ref={dokumenKtpDirutRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenKtpDirut}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenKtpDirut.format,
+ formDokumen.dokumenKtpDirut.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenKtpDirut}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ Akta Pendirian <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenAktaPendirian?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenAktaPendirian'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenAktaPendirian'
+ name='dokumenAktaPendirian'
+ type='file'
+ title=' '
+ ref={dokumenAktaPendirianRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenAktaPendirian}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenAktaPendirian.format,
+ formDokumen.dokumenAktaPendirian.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenAktaPendirian}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ Laporan Keuangan
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenLaporanKeuangan?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenLaporanKeuangan'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenLaporanKeuangan'
+ name='dokumenLaporanKeuangan'
+ type='file'
+ title=' '
+ ref={dokumenLaporanKeuanganRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenLaporanKeuangan}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenLaporanKeuangan.format,
+ formDokumen.dokumenLaporanKeuangan.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenLaporanKeuangan}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ Foto Kantor (Tampak Depan)
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenFotoKantor?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenFotoKantor'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenFotoKantor'
+ name='dokumenFotoKantor'
+ type='file'
+ title=' '
+ ref={dokumenFotoKantorRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenFotoKantor}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenFotoKantor.format,
+ formDokumen.dokumenFotoKantor.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenFotoKantor}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='w-full flex flex-row items-center '>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>Tempat Bekerja</label>
+ </div>
+ <div className='w-3/5'>
+ <div className='flex flex-row items-start justify-between'>
+ <span className='w-3/5 text-gray-600 truncate'>
+ {formDokumen?.dokumenTempatBekerja?.name}
+ </span>
+ <div className='w-2/5 flex flex-row gap-2'>
+ <label
+ htmlFor='dokumenTempatBekerja'
+ className='cursor-pointer bg-red-500 hover:bg-red-600 text-white py-1 px-3 text-sm rounded'
+ >
+ Ubah
+ </label>
+ <input
+ // value={formDokumen?.dokumenNib?.name}
+ id='dokumenTempatBekerja'
+ name='dokumenTempatBekerja'
+ type='file'
+ title=' '
+ ref={dokumenTempatBekerjaRef}
+ className='hidden'
+ aria-invalid={errorsDokumen.dokumenTempatBekerja}
+ onChange={handleInputChange}
+ accept='.pdf,.png,.jpg,.jpeg'
+ />
+ <button
+ className='rounded text-white p-2 flex flex-row bg-red-500 hover:cursor-pointer hover:bg-red-400'
+ type='button'
+ onClick={() =>
+ handleConfirmSubmit(
+ formDokumen.dokumenTempatBekerja.format,
+ formDokumen.dokumenTempatBekerja.base64
+ )
+ }
+ >
+ <EyeIcon className={`w-4 ${isDesktop && ''}`} />
+ </button>
+ </div>
+ {/* <Image
+ src={`data:image/png;base64, ${formDokumen.dokumenNib.base64}`}
+ alt='Contoh SPPKP'
+ className='w-full h-full '
+ width={800}
+ height={800}
+ quality={85}
+ /> */}
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsDokumen.dokumenTempatBekerja}
+ </div>
+ )}
+ </div>
+ </div>
+ </form>
+ </div>
+ )}
+ {isDesktop && (
+ <BottomPopup
+ className='!container'
+ title='Dokumen'
+ active={isExample}
+ close={() => setIsExample(false)}
+ >
+ <div className='flex justify-center items-center p-2'>
+ {/* <embed
+ src={`data:${format};base64,${base64}`}
+ type={format}
+ width='100%'
+ height='600px'
+ /> */}
+ <iframe
+ src={`data:${format};base64,${base64}`}
+ width='100%'
+ height='100%'
+ title='Document'
+ ></iframe>
+ </div>
+ </BottomPopup>
+ )}
+ {isMobile && (
+ <BottomPopup
+ className='!container'
+ title='Dokumen'
+ active={isExample}
+ close={() => setIsExample(false)}
+ >
+ <div className='flex justify-center items-center p-2'>
+ {/* <embed
+ src={`data:${format};base64,${base64}`}
+ type={format}
+ width='100%'
+ height='100%'
+ /> */}
+ <object
+ data={`data:${format};base64,${base64}`}
+ type={format}
+ width='100%'
+ height='100%'
+ onError={(e) => {
+ // Jika <object> gagal menampilkan PDF, unduh otomatis
+ const link = document.createElement('a');
+ link.href = `data:${format};base64,${base64}`;
+ link.download = 'document.pdf';
+ link.click();
+ }}
+ >
+ PDF tidak dapat ditampilkan.
+ <a
+ href={`data:${format};base64,${base64}`}
+ download='document.pdf'
+ >
+ {' '}
+ Klik <span className='text-red-500'>di sini</span> untuk
+ mengunduh PDF
+ </a>
+ </object>
+ </div>
+ </BottomPopup>
+ )}
+ </>
+ );
+};
+
+export default KonfirmasiDokumen;
+
+{
+ /* <iframe
+ src={`data:application/octet-stream;base64, ${base64}`}
+ // src={`data:application/${format};base64, ${base64}`}
+ width='800px'
+ height='600px'
+ title='NPWP File'
+ frameBorder='0'
+ sandbox
+></iframe> */
+}
+{
+ /* <Image
+ src={`data:image/${format};base64, ${base64}`}
+ alt='Contoh SPPKP'
+ className='w-full h-full '
+ width={1200}
+ height={1200}
+ quality={85}
+/> */
+}
diff --git a/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx b/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx
new file mode 100644
index 00000000..e7bfdbbe
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx
@@ -0,0 +1,586 @@
+import React, { useEffect, useMemo, useRef } from 'react';
+import { usePengajuanTempoStoreKontakPerson } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore';
+import useDevice from '@/core/hooks/useDevice';
+const KontakPerusahaan = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => {
+ const {
+ formKontakPerson,
+ errorsKontakPerson,
+ validateKontakPerson,
+ updateFormKontakPerson,
+ } = usePengajuanTempoStoreKontakPerson();
+ const { isDesktop, isMobile } = useDevice();
+ const handleInputChange = (event) => {
+ const { name, value } = event.target;
+ updateFormKontakPerson(name, value);
+ validateKontakPerson();
+ };
+
+ const isFormValid = useMemo(
+ () => Object.keys(errorsKontakPerson).length === 0,
+ [errorsKontakPerson]
+ );
+
+ const direkturNameRef = useRef(null);
+ const direkturMobileRef = useRef(null);
+ const direkturEmailRef = useRef(null);
+ const purchasingNameRef = useRef(null);
+ const purchasingEmailRef = useRef(null);
+ const purchasingMobileRef = useRef(null);
+ const financeNameRef = useRef(null);
+ const financeMobileRef = useRef(null);
+ const financeEmailRef = useRef(null);
+
+ useEffect(() => {
+ const loadIndustries = async () => {
+ if (!isFormValid) {
+ const options = {
+ behavior: 'smooth',
+ block: 'center',
+ };
+ if (errorsKontakPerson.direkturName && direkturNameRef.current) {
+ direkturNameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsKontakPerson.direkturMobile && direkturMobileRef.current) {
+ direkturMobileRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsKontakPerson.direkturEmail && direkturEmailRef.current) {
+ direkturEmailRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsKontakPerson.purchasingName && purchasingNameRef.current) {
+ purchasingNameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsKontakPerson.purchasingMobile &&
+ purchasingMobileRef.current
+ ) {
+ purchasingMobileRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsKontakPerson.purchasingEmail && purchasingEmailRef.current) {
+ purchasingEmailRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsKontakPerson.financeName && financeNameRef.current) {
+ financeNameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsKontakPerson.financeMobile && financeMobileRef.current) {
+ financeMobileRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsKontakPerson.financeEmail && financeEmailRef.current) {
+ financeEmailRef.current.scrollIntoView(options);
+ return;
+ }
+ }
+ };
+ loadIndustries();
+ }, [buttonSubmitClick, chekValid]);
+
+ useEffect(() => {
+ validateKontakPerson();
+ }, [buttonSubmitClick]);
+ return (
+ <>
+ {isDesktop && (
+ <div className=''>
+ <h1 className={`font-bold ${isKonfirmasi ? 'text-xl' : ''}`}>
+ Kontak Person
+ </h1>
+ <form className='flex flex-col w-full '>
+ <div className='w-full grid grid-row-2 gap-5'>
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama Lengkap Direktur
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <input
+ value={formKontakPerson.direkturName}
+ id='direkturName'
+ name='direkturName'
+ placeholder='Masukkan nama direktur anda'
+ type='text'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.direkturName}
+ ref={direkturNameRef}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.direkturName}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ No. Telpon Direktur
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi nomor telpon direktur di perusahaan kamu
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='direkturMobile'
+ name='direkturMobile'
+ ref={direkturMobileRef}
+ placeholder='Masukkan nomor direktur anda'
+ type='tel'
+ value={formKontakPerson.direkturMobile}
+ className='form-input'
+ aria-invalid={errorsKontakPerson.direkturMobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.direkturMobile}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Email Direktur
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi email Direktur yang sesuai
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='direkturEmail'
+ name='direkturEmail'
+ ref={direkturEmailRef}
+ placeholder='contoh@email.com'
+ type='email'
+ value={formKontakPerson.direkturEmail}
+ className='form-input'
+ aria-invalid={errorsKontakPerson.direkturEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.direkturEmail}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama Purchasing
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi nama purchasing yang bertanggung jawab di perusahaan
+ anda
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='purchasingName'
+ name='purchasingName'
+ ref={purchasingNameRef}
+ placeholder='Masukkan nama purchasing anda'
+ value={formKontakPerson.purchasingName}
+ type='text'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.purchasingName}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.purchasingName}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ No. Telpon Purchasing
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi nomor purchasing yang bertanggung jawab di perusahaan
+ anda
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='purchasingMobile'
+ name='purchasingMobile'
+ ref={financeMobileRef}
+ placeholder='Masukkan nomor purchasing anda'
+ value={formKontakPerson.purchasingMobile}
+ type='tel'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.purchasingMobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.purchasingMobile}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Email Purchasing
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi email purchasing dengan benar
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='purchasingEmail'
+ name='purchasingEmail'
+ ref={purchasingEmailRef}
+ placeholder='contoh@email.com'
+ value={formKontakPerson.purchasingEmail}
+ type='email'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.purchasingEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.purchasingEmail}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama Finance
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi nama finance yang bertanggung jawab di perusahaan anda
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='financeName'
+ name='financeName'
+ ref={financeNameRef}
+ placeholder='Masukkan nama finance'
+ value={formKontakPerson.financeName}
+ type='text'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.financeName}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.financeName}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ No. Telpon Finance
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi nomor finance yang bertanggung jawab di perusahaan
+ anda
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='financeMobile'
+ name='financeMobile'
+ ref={financeMobileRef}
+ placeholder='Masukkan nomor finance'
+ value={formKontakPerson.financeMobile}
+ type='tel'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.financeMobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.financeMobile}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Email Finance
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi email finance dengan benar
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='financeEmail'
+ name='financeEmail'
+ ref={financeEmailRef}
+ placeholder='contoh@email.com'
+ type='email'
+ value={formKontakPerson.financeEmail}
+ className='form-input'
+ aria-invalid={errorsKontakPerson.financeEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.financeEmail}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+ )}
+ {isMobile && (
+ <div className='text-sm'>
+ <h1
+ className={`font-bold py-4 mt-8 ${
+ isKonfirmasi ? 'hidden' : 'text-xl'
+ }`}
+ >
+ Kontak Person
+ </h1>
+ <form className='flex flex-col w-full '>
+ <div className='w-full grid grid-row-2 gap-4'>
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Nama Lengkap Direktur
+ </label>
+ <input
+ value={formKontakPerson.direkturName}
+ id='direkturName'
+ name='direkturName'
+ placeholder='Masukkan nama direktur anda'
+ type='text'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.direkturName}
+ ref={direkturNameRef}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.direkturName}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ No. Telpon Direktur
+ </label>
+ <input
+ id='direkturMobile'
+ name='direkturMobile'
+ ref={direkturMobileRef}
+ placeholder='Masukkan nomor direktur anda'
+ type='tel'
+ value={formKontakPerson.direkturMobile}
+ className='form-input'
+ aria-invalid={errorsKontakPerson.direkturMobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.direkturMobile}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Email Direktur
+ </label>
+ <input
+ id='direkturEmail'
+ name='direkturEmail'
+ ref={direkturEmailRef}
+ placeholder='contoh@email.com'
+ type='email'
+ value={formKontakPerson.direkturEmail}
+ className='form-input'
+ aria-invalid={errorsKontakPerson.direkturEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.direkturEmail}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Nama Purchasing
+ </label>
+ <input
+ id='purchasingName'
+ name='purchasingName'
+ ref={purchasingNameRef}
+ placeholder='Masukkan nama purchasing anda'
+ value={formKontakPerson.purchasingName}
+ type='text'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.purchasingName}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.purchasingName}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ No. Telpon Purchasing
+ </label>
+ <input
+ id='purchasingMobile'
+ name='purchasingMobile'
+ ref={financeMobileRef}
+ placeholder='Masukkan nomor purchasing anda'
+ value={formKontakPerson.purchasingMobile}
+ type='tel'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.purchasingMobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.purchasingMobile}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Email Purchasing
+ </label>
+ <input
+ id='purchasingEmail'
+ name='purchasingEmail'
+ ref={purchasingEmailRef}
+ placeholder='contoh@email.com'
+ value={formKontakPerson.purchasingEmail}
+ type='email'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.purchasingEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.purchasingEmail}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>Nama Finance</label>
+ <input
+ id='financeName'
+ name='financeName'
+ ref={financeNameRef}
+ placeholder='Masukkan nama finance'
+ value={formKontakPerson.financeName}
+ type='text'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.financeName}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.financeName}
+ </div>
+ )}
+ </div>
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ No. Telpon Finance
+ </label>
+ <input
+ id='financeMobile'
+ name='financeMobile'
+ ref={financeMobileRef}
+ placeholder='Masukkan nomor finance'
+ value={formKontakPerson.financeMobile}
+ type='tel'
+ className='form-input'
+ aria-invalid={errorsKontakPerson.financeMobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.financeMobile}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>Email Finance</label>
+ <input
+ id='financeEmail'
+ name='financeEmail'
+ ref={financeEmailRef}
+ placeholder='contoh@email.com'
+ type='email'
+ value={formKontakPerson.financeEmail}
+ className='form-input'
+ aria-invalid={errorsKontakPerson.financeEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsKontakPerson.financeEmail}
+ </div>
+ )}
+ </div>
+ </div>
+ </form>
+ </div>
+ )}
+ </>
+ );
+};
+
+export default KontakPerusahaan;
diff --git a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx
new file mode 100644
index 00000000..d0e1fcc6
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx
@@ -0,0 +1,352 @@
+import React from 'react';
+import { useMemo, useState, useEffect, useRef } from 'react';
+import Stepper from './Stepper';
+import InformasiPerusahaan from './informasiPerusahaan';
+import KontakPerusahaan from './KontakPerusahaan';
+import Pengiriman from './Pengiriman';
+import Referensi from './Referensi';
+import Dokumen from './Dokumen';
+import Konfirmasi from './Konfirmasi';
+import useAuth from '@/core/hooks/useAuth';
+import { useRouter } from 'next/router';
+import { Controller, useForm } from 'react-hook-form';
+import {
+ usePengajuanTempoStore,
+ usePengajuanTempoStoreKontakPerson,
+ usePengajuanTempoStorePengiriman,
+ usePengajuanTempoStoreSupplier,
+ usePengajuanTempoStoreDokumen,
+} from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore';
+import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline';
+import createPengajuanTempoApi from '../api/createPengajuanTempoApi';
+import { Button, Checkbox, Spinner, Tooltip } from '@chakra-ui/react';
+import clsxm from '~/libs/clsxm';
+import { toast } from 'react-hot-toast';
+import useDevice from '@/core/hooks/useDevice';
+const PengajuanTempo = () => {
+ const { isDesktop, isMobile } = useDevice();
+ const [currentStep, setCurrentStep] = React.useState(0);
+ const NUMBER_OF_STEPS = 6;
+ const [isLoading, setIsLoading] = useState(false);
+ const { form, errors, validate, updateForm } = usePengajuanTempoStore();
+ const { control, watch, setValue } = useForm();
+ const auth = useAuth();
+ const router = useRouter();
+ const { formDokumen, errorsDokumen, validateDokumen, updateFormDokumen } =
+ usePengajuanTempoStoreDokumen();
+ const {
+ formKontakPerson,
+ errorsKontakPerson,
+ validateKontakPerson,
+ updateFormKontakPerson,
+ } = usePengajuanTempoStoreKontakPerson();
+ const {
+ formSupplier,
+ errorsSupplier,
+ validateSupplier,
+ updateFormSupplier,
+ hasSavedata,
+ updateHasSave,
+ } = usePengajuanTempoStoreSupplier();
+ const {
+ formPengiriman,
+ errorsPengiriman,
+ validatePengiriman,
+ updateFormPengiriman,
+ } = usePengajuanTempoStorePengiriman();
+ const [notValid, setNotValid] = useState(false);
+ const [buttonSubmitClick, setButtonSubmitClick] = useState(false);
+ const stepDivs = [
+ <InformasiPerusahaan
+ key='informasi-perusahaan'
+ chekValid={notValid}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ <KontakPerusahaan
+ key='kontak-perusahaan'
+ chekValid={notValid}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ <Pengiriman
+ key='pengiriman'
+ chekValid={notValid}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ <Referensi
+ key='referensi'
+ chekValid={notValid}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ <Dokumen
+ key='dokumen'
+ chekValid={notValid}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ <Konfirmasi
+ key='konfirmasi'
+ chekValid={notValid}
+ buttonSubmitClick={buttonSubmitClick}
+ />,
+ ];
+
+ const stepDivsError = [
+ errors,
+ errorsKontakPerson,
+ errorsPengiriman,
+ errorsSupplier,
+ errorsDokumen,
+ <div key='konfirmasi'>Konfirmasi</div>,
+ ];
+ const stepDivsForm = [
+ form,
+ formKontakPerson,
+ formPengiriman,
+ formSupplier,
+ formDokumen,
+ '',
+ ];
+ const stepDivsUpdateForm = [
+ updateForm,
+ updateFormKontakPerson,
+ updateFormPengiriman,
+ updateFormSupplier,
+ updateFormDokumen,
+ <div key='konfirmasi'>Konfirmasi</div>,
+ ];
+ const stepLabels = [
+ 'informasi_perusahaan',
+ 'kontak_person',
+ 'Pengiriman',
+ 'Referensi',
+ 'Dokumen',
+ 'Konfirmasi',
+ ];
+ const isFormValid = useMemo(
+ () => Object.keys(stepDivsError[currentStep]).length === 0,
+ [stepDivsError[currentStep]]
+ );
+ useEffect(() => {
+ validate();
+ validateKontakPerson();
+ validatePengiriman();
+ validateDokumen();
+ updateHasSave(false);
+
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth',
+ });
+ }, [currentStep, buttonSubmitClick]);
+
+ useEffect(() => {
+ const cachedData = getFromLocalStorage(stepLabels[currentStep]);
+ if (cachedData) {
+ if (currentStep == 3) {
+ stepDivsUpdateForm[currentStep](cachedData);
+ } else if (currentStep == 4) {
+ Object.keys(cachedData).forEach((key) => {
+ const { name, format, base64 } = cachedData[key];
+ stepDivsUpdateForm[currentStep](key, name, format, base64);
+ });
+ } else {
+ Object.keys(cachedData).forEach((key) => {
+ stepDivsUpdateForm[currentStep](key, cachedData[key]);
+ });
+ }
+ }
+ validate();
+ validateKontakPerson();
+ validatePengiriman();
+ validateDokumen();
+ updateHasSave(false);
+ }, [currentStep]);
+ const goToNextStep = () => {
+ if (!isFormValid) {
+ setNotValid(true);
+ setButtonSubmitClick(!buttonSubmitClick);
+ return;
+ } else {
+ saveToLocalStorage(stepLabels[currentStep], stepDivsForm[currentStep]);
+ setButtonSubmitClick(!buttonSubmitClick);
+ setNotValid(false);
+ }
+ setCurrentStep((prev) => (prev === NUMBER_OF_STEPS - 1 ? prev : prev + 1));
+ };
+
+ const handleDaftarTempo = async () => {
+ for (const error of stepDivsError) {
+ if (error.length > 0) {
+ return;
+ }
+ }
+ const productOrder = formSupplier.map((product) => ({
+ supplier: product.supplier,
+ pic: product.pic,
+ telepon: product.telepon,
+ durasiTempo: product.durasiTempo,
+ creditLimit: product.creditLimit,
+ }));
+
+ const formattedDokumen = Object.entries(formDokumen).map(([key, doc]) => ({
+ documentName: key,
+ details: {
+ name: doc.name,
+ format: doc.format,
+ base64: doc.base64,
+ },
+ }));
+
+ const data2 = {
+ user_id: auth.id,
+ ...form,
+ ...formKontakPerson,
+ ...formPengiriman,
+ formDocs: JSON.stringify(formattedDokumen),
+ formSupplier: JSON.stringify(productOrder),
+ };
+ const toastId = toast.loading('Mengirimkan formulir pengajuan tempo...');
+ setIsLoading(true);
+ try {
+ let address5;
+ const address = await createPengajuanTempoApi({
+ id: '0',
+ user_id: auth.id,
+ ...form,
+ });
+ if (address.id) {
+ const address2 = await createPengajuanTempoApi({
+ id: address.id,
+ user_id: address.userId,
+ ...formKontakPerson,
+ });
+ if (address2.id) {
+ const address3 = await createPengajuanTempoApi({
+ id: address2.id,
+ user_id: address2.userId,
+ ...formPengiriman,
+ });
+ if (address3.id) {
+ const address4 = await createPengajuanTempoApi({
+ id: address3.id,
+ user_id: address3.userId,
+ formDocs: JSON.stringify(formattedDokumen),
+ });
+ if (address4.id) {
+ address5 = await createPengajuanTempoApi({
+ id: address4.id,
+ user_id: address4.userId,
+ tempo_request: true,
+ formSupplier: JSON.stringify(productOrder),
+ });
+ }
+ }
+ }
+ }
+ toast.dismiss(toastId);
+ setIsLoading(false);
+
+ if (address5.id) {
+ toast.success('Pengajuan tempo berhasil dilakukan');
+ // removeFromLocalStorage();
+ router.push('/pengajuan-tempo/finish?tempo_id=SO-2023-06480');
+ }
+ } catch (error) {
+ toast.dismiss(toastId);
+ setIsLoading(false);
+
+ toast.error('Terjadi kesalahan dalam pengiriman formulir');
+ console.error(error);
+ }
+ };
+
+ const goToPreviousStep = () => {
+ setCurrentStep((prev) => (prev <= 0 ? prev : prev - 1));
+ };
+
+ const saveToLocalStorage = (key, form) => {
+ localStorage.setItem(key, JSON.stringify(form));
+ };
+
+ const getFromLocalStorage = (key) => {
+ const itemStr = localStorage.getItem(key);
+ if (!itemStr) return null;
+
+ const item = JSON.parse(itemStr);
+ return item;
+ };
+ const removeFromLocalStorage = () => {
+ for (const key of stepLabels) {
+ localStorage.removeItem(key);
+ }
+ };
+
+ return (
+ <>
+ <div className='container flex flex-col items-center '>
+ <h1 className='text-h-sm md:text-title-sm font-semibold text-center mb-6'>
+ Form Pengajuan Tempo
+ </h1>
+ <p className='text-center mb-4'>
+ Lorem ipsum dolor sit amet consectetur. Commodo suspendisse at enim
+ magnis ut quisque rhoncus. Felis volutpat fringilla sollicitudin
+ ultricies. Enim non eget in lorem netus. Nisl pharetra accumsan diam
+ suspendisse.
+ </p>
+ </div>
+ <div className='h-[2px] w-full mb-20 bg-gray_r-3' />
+
+ <div className='container mt-10 flex flex-col'>
+ <div className='flex items-center justify-center'>
+ <Stepper currentStep={currentStep} numberOfSteps={NUMBER_OF_STEPS} />
+ </div>
+ <div>{stepDivs[currentStep]}</div>
+ {isDesktop && <section className='flex gap-10 mt-10'></section>}
+ {isMobile && (
+ <div className='h-[2px] bg-gray-300 w-[120%] inset-0 mt-4 mb-4 relative transform -translate-x-5'></div>
+ )}
+ <div
+ className={`flex ${
+ isMobile
+ ? 'flex-col justify-start items-start'
+ : 'flex-row justify-end items-center'
+ } gap-4 mb-8`}
+ >
+ <span className='text-xs opacity-60'>
+ *Pastikan data yang anda masukan sudah benar dan sesuai
+ </span>
+ {currentStep < 5 && (
+ <Tooltip
+ label={clsxm({
+ 'Klik simpan data terlebih dahulu':
+ currentStep === 3 && !hasSavedata,
+ })}
+ >
+ <Button
+ colorScheme='red'
+ w={`${isMobile ? 'full' : 'fit'}`}
+ isDisabled={
+ (currentStep === 3 && !hasSavedata) ||
+ currentStep === NUMBER_OF_STEPS - 1
+ }
+ onClick={goToNextStep}
+ >
+ Langkah Selanjutnya {<ChevronRightIcon className='w-5' />}
+ </Button>
+ </Tooltip>
+ )}
+ {currentStep == 5 && (
+ <Button
+ colorScheme='red'
+ w={`${isMobile ? 'full' : 'fit'}`}
+ onClick={handleDaftarTempo}
+ >
+ Daftar Tempo {<ChevronRightIcon className='w-5' />}
+ </Button>
+ )}
+ </div>
+ </div>
+ </>
+ );
+};
+
+export default PengajuanTempo;
diff --git a/src/lib/pengajuan-tempo/component/Pengiriman.jsx b/src/lib/pengajuan-tempo/component/Pengiriman.jsx
new file mode 100644
index 00000000..842e43ef
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/Pengiriman.jsx
@@ -0,0 +1,1489 @@
+import React, { useState, useEffect, useMemo, useRef } from 'react';
+import { Controller, set, useForm } from 'react-hook-form';
+import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
+import odooApi from '~/libs/odooApi';
+import stateApi from '@/lib/address/api/stateApi.js';
+import cityApi from '@/lib/address/api/cityApi';
+import { Radio, RadioGroup, Stack, Checkbox } from '@chakra-ui/react';
+import { usePengajuanTempoStorePengiriman } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore';
+import useDevice from '@/core/hooks/useDevice';
+const Pengiriman = ({ chekValid, buttonSubmitClick, isKonfirmasi }) => {
+ const { control, watch, setValue } = useForm();
+ const { isDesktop, isMobile } = useDevice();
+ const {
+ formPengiriman,
+ errorsPengiriman,
+ validatePengiriman,
+ updateFormPengiriman,
+ } = usePengajuanTempoStorePengiriman();
+ const [states, setState] = useState([]);
+ const [cities, setCities] = useState([]);
+ const [sameAddress, setSameAddress] = useState(false);
+ const [everyWeekday, setEveryWeekday] = useState(false);
+ const [everyWeek, setEveryWeek] = useState(false);
+ const [tukarInvoice, setTukarInvoice] = useState(false);
+ const [everyWeekdayPembayaran, setEveryWeekdayPembayaran] = useState(false);
+ const [everyWeekPembayaran, setEveryWeekPembayaran] = useState(false);
+ const [tukarInvoicePembayaran, setTukarInvoicePembayaran] = useState(false);
+ const [selectedIds, setSelectedIds] = useState(
+ formPengiriman.dokumenPengiriman
+ ? formPengiriman.dokumenPengiriman.split(',').map(Number)
+ : []
+ );
+ const [selectedIdsDokumenInvoice, setSelectedIdsselectedIdsDokumenInvoice] =
+ useState(
+ formPengiriman.dokumenPengirimanInvoice
+ ? formPengiriman.dokumenPengirimanInvoice.split(',').map(Number)
+ : []
+ );
+
+ const handleCheckboxChange = (id) => {
+ const updatedSelected = selectedIds.includes(id)
+ ? selectedIds.filter((selectedId) => selectedId !== id)
+ : [...selectedIds, id];
+
+ setSelectedIds(updatedSelected);
+
+ // Jika checkbox 'Lainnya' dipilih, aktifkan input custom
+
+ updateFormPengiriman('dokumenPengiriman', updatedSelected.join(','));
+ validatePengiriman();
+ };
+ const handleCheckboxChangeDokumenPengirimanInvoice = (id) => {
+ const updatedSelected = selectedIdsDokumenInvoice.includes(id)
+ ? selectedIdsDokumenInvoice.filter((selectedId) => selectedId !== id)
+ : [...selectedIdsDokumenInvoice, id];
+
+ setSelectedIdsselectedIdsDokumenInvoice(updatedSelected);
+
+ // Jika checkbox 'Lainnya' dipilih, aktifkan input custom
+
+ updateFormPengiriman('dokumenPengirimanInvoice', updatedSelected.join(','));
+ validatePengiriman();
+ };
+
+ useEffect(() => {
+ if (formPengiriman.dokumenPengiriman) {
+ setSelectedIds(formPengiriman.dokumenPengiriman.split(',').map(Number)); // Parse string menjadi array angka
+ }
+ }, [formPengiriman.dokumenPengiriman]);
+ useEffect(() => {
+ if (formPengiriman.dokumenPengirimanInvoice) {
+ setSelectedIdsselectedIdsDokumenInvoice(
+ formPengiriman.dokumenPengirimanInvoice.split(',').map(Number)
+ ); // Parse string menjadi array angka
+ }
+ }, [formPengiriman.dokumenPengirimanInvoice]);
+
+ // Fungsi untuk memeriksa apakah item sudah dipilih
+ const isChecked = (id) => selectedIds.includes(id);
+ const isCheckedInvoice = (id) => selectedIdsDokumenInvoice.includes(id);
+
+ useEffect(() => {
+ const loadState = async () => {
+ let dataState = await stateApi();
+ dataState = dataState.map((state) => ({
+ value: state.id,
+ label: state.name,
+ }));
+ setState(dataState);
+ };
+ loadState();
+ }, []);
+
+ const watchState = watch('statePengiriman');
+ useEffect(() => {
+ updateFormPengiriman('cityPengiriman', '');
+ if (watchState) {
+ updateFormPengiriman('statePengiriman', `${watchState}`);
+ validatePengiriman();
+ const loadCities = async () => {
+ let dataCities = await cityApi({ stateId: watchState });
+ dataCities = dataCities.map((city) => ({
+ value: city.id,
+ label: city.name,
+ }));
+ setCities(dataCities);
+ };
+ loadCities();
+ }
+ }, [watchState]);
+
+ const watchCity = watch('cityPengiriman');
+ useEffect(() => {
+ if (watchCity) {
+ updateFormPengiriman('cityPengiriman', `${watchCity}`);
+ validatePengiriman();
+ }
+ }, [watchCity]);
+ const handleInputChange = (event) => {
+ const { name, value } = event.target;
+ updateFormPengiriman(name, value);
+ validatePengiriman();
+ };
+
+ const handleEveryWeekday = () => {
+ setEveryWeekday(!everyWeekday);
+ };
+ const handleEveryWeek = () => {
+ setEveryWeek(!everyWeek);
+ };
+ const handleTukarInvoice = () => {
+ setTukarInvoice(!tukarInvoice);
+ };
+ const handleEveryWeekdayPembayaran = () => {
+ setEveryWeekdayPembayaran(!everyWeekdayPembayaran);
+ };
+ const handleEveryWeekPembayaran = () => {
+ setEveryWeekPembayaran(!everyWeekPembayaran);
+ };
+ const handleTukarInvoicePembayaran = () => {
+ setTukarInvoicePembayaran(!tukarInvoicePembayaran);
+ };
+
+ useEffect(() => {
+ updateFormPengiriman('everyWeekday', everyWeekday);
+ updateFormPengiriman('everyWeek', everyWeek);
+ updateFormPengiriman('tukarInvoice', tukarInvoice);
+ updateFormPengiriman('everyWeekdayPembayaran', everyWeekdayPembayaran);
+ updateFormPengiriman('everyWeekPembayaran', everyWeekPembayaran);
+ updateFormPengiriman('tukarInvoicePembayaran', tukarInvoicePembayaran);
+ validatePengiriman();
+ }, [
+ everyWeekday,
+ everyWeek,
+ tukarInvoice,
+ everyWeekdayPembayaran,
+ everyWeekPembayaran,
+ tukarInvoicePembayaran,
+ ]);
+
+ const isFormValid = useMemo(
+ () => Object.keys(errorsPengiriman).length === 0,
+ [errorsPengiriman]
+ );
+
+ const PICNameRef = useRef(null);
+ const streetPengirimanRef = useRef(null);
+ const statePengirimanRef = useRef(null);
+ const cityPengirimanRef = useRef(null);
+ const zipRef = useRef(null);
+ const invoicePicRef = useRef(null);
+ const streetInvoiceRef = useRef(null);
+ const stateInvoiceRef = useRef(null);
+ const cityInvoiceRef = useRef(null);
+ const everyWeekdayInputRef = useRef(null);
+ const everyWeekInputRef = useRef(null);
+ const dokumenPengirimanRef = useRef(null);
+ const dokumenPengirimanInputRef = useRef(null);
+ const dokumenPengirimanInvoiceRef = useRef(null);
+ const dokumenPengirimanInvoiceInputRef = useRef(null);
+
+ useEffect(() => {
+ const loadIndustries = async () => {
+ if (!isFormValid) {
+ const options = {
+ behavior: 'smooth',
+ block: 'center',
+ };
+ if (errorsPengiriman.PICName && PICNameRef.current) {
+ PICNameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.streetPengiriman && streetPengirimanRef.current) {
+ streetPengirimanRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.statePengiriman && statePengirimanRef.current) {
+ statePengirimanRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.cityPengiriman && cityPengirimanRef.current) {
+ cityPengirimanRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.zip && zipRef.current) {
+ zipRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.invoicePic && invoicePicRef.current) {
+ invoicePicRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.streetInvoice && streetInvoiceRef.current) {
+ streetInvoiceRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.stateInvoice && stateInvoiceRef.current) {
+ stateInvoiceRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.cityInvoice && cityInvoiceRef.current) {
+ cityInvoiceRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsPengiriman.everyWeekdayInput &&
+ everyWeekdayInputRef.current
+ ) {
+ everyWeekdayInputRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.everyWeekInput && everyWeekInputRef.current) {
+ everyWeekInputRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsPengiriman.dokumenPengiriman &&
+ dokumenPengirimanRef.current
+ ) {
+ dokumenPengirimanRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ errorsPengiriman.dokumenInvoice &&
+ dokumenPengirimanInvoiceRef.current
+ ) {
+ dokumenPengirimanInvoiceRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ selectedIds &&
+ formPengiriman.dokumenPengirimanInput === '' &&
+ dokumenPengirimanInputRef.current
+ ) {
+ dokumenPengirimanInputRef.current.scrollIntoView(options);
+ return;
+ }
+ if (
+ selectedIdsDokumenInvoice &&
+ formPengiriman.dokumenPengirimanInvoiceInput === '' &&
+ dokumenPengirimanInvoiceInputRef.current
+ ) {
+ dokumenPengirimanInvoiceInputRef.current.scrollIntoView(options);
+ return;
+ }
+ }
+ };
+ loadIndustries();
+ }, [buttonSubmitClick, chekValid]);
+
+ useEffect(() => {
+ validatePengiriman();
+ if (formPengiriman.isSameAddrees) {
+ const isSame = formPengiriman.isSameAddrees;
+ if (isSame == 'true') {
+ setSameAddress(true);
+ } else {
+ setSameAddress(false);
+ }
+ }
+ }, [buttonSubmitClick]);
+ useEffect(() => {
+ if (formPengiriman.isSameAddrees) {
+ const isSame = formPengiriman.isSameAddrees;
+ if (isSame == 'true') {
+ setSameAddress(true);
+ } else {
+ setSameAddress(false);
+ }
+ }
+ }, [formPengiriman.isSameAddrees]);
+ useEffect(() => {
+ if (sameAddress) {
+ updateFormPengiriman('streetInvoice', formPengiriman.streetPengiriman);
+ updateFormPengiriman('stateInvoice', formPengiriman.statePengiriman);
+ updateFormPengiriman('cityInvoice', formPengiriman.cityPengiriman);
+ } else {
+ updateFormPengiriman('streetInvoice', '');
+ updateFormPengiriman('stateInvoice', '');
+ updateFormPengiriman('cityInvoice', '');
+ setValue('streetInvoice', '');
+ setValue('stateInvoice', '');
+ setValue('cityInvoice', '');
+ }
+ updateFormPengiriman('isSameAddrees', `${sameAddress}`);
+ validatePengiriman();
+ }, [sameAddress]);
+
+ const getFromLocalStorage = (key) => {
+ const itemStr = localStorage.getItem(key);
+ if (!itemStr) return null;
+
+ const item = JSON.parse(itemStr);
+ return item;
+ };
+
+ const cachedData = getFromLocalStorage('Pengiriman');
+ useEffect(() => {
+ if (cachedData) {
+ setValue('cityPengiriman', parseInt(cachedData?.cityPengiriman));
+ updateFormPengiriman('cityPengiriman', `${cachedData?.cityPengiriman}`);
+ }
+ if (cachedData?.statePengiriman) {
+ setValue('statePengiriman', parseInt(cachedData?.statePengiriman));
+ }
+ if (cachedData?.stateInvoice) {
+ setValue('stateInvoice', parseInt(cachedData?.stateInvoice));
+ }
+ if (cachedData?.cityInvoice) {
+ setValue('cityInvoice', parseInt(cachedData?.cityInvoice));
+ }
+ if (cachedData?.isSameAddrees) {
+ updateFormPengiriman('isSameAddrees', `${cachedData?.isSameAddrees}`);
+ }
+ validatePengiriman();
+ }, [cachedData?.cityPengiriman]);
+ useEffect(() => {
+ if (cachedData?.everyWeek) {
+ updateFormPengiriman('everyWeek', cachedData?.everyWeek);
+ setEveryWeek(cachedData?.everyWeek);
+ }
+ if (cachedData?.everyWeekday) {
+ updateFormPengiriman('everyWeekday', cachedData?.everyWeekday);
+ setEveryWeekday(cachedData?.everyWeekday);
+ }
+ if (cachedData?.tukarInvoice) {
+ updateFormPengiriman('tukarInvoice', cachedData?.tukarInvoice);
+ setTukarInvoice(cachedData?.tukarInvoice);
+ }
+ if (cachedData?.everyWeekPembayaran) {
+ updateFormPengiriman(
+ 'everyWeekPembayaran',
+ cachedData?.everyWeekPembayaran
+ );
+ setEveryWeekPembayaran(cachedData?.everyWeekPembayaran);
+ }
+ if (cachedData?.everyWeekdayPembayaran) {
+ updateFormPengiriman(
+ 'everyWeekdayPembayaran',
+ cachedData?.everyWeekdayPembayaran
+ );
+ setEveryWeekdayPembayaran(cachedData?.everyWeekdayPembayaran);
+ }
+ if (cachedData?.tukarInvoicePembayaran) {
+ updateFormPengiriman(
+ 'tukarInvoicePembayaran',
+ cachedData?.tukarInvoicePembayaran
+ );
+ setTukarInvoicePembayaran(cachedData?.tukarInvoicePembayaran);
+ }
+ validatePengiriman();
+ }, [
+ cachedData?.everyWeek,
+ cachedData?.everyWeekday,
+ cachedData?.tukarInvoice,
+ cachedData?.everyWeekdayPembayaran,
+ cachedData?.everyWeekPembayaran,
+ cachedData?.tukarInvoicePembayaran,
+ ]);
+ const handleChangeSameAddress = () => {
+ setSameAddress(!sameAddress);
+ };
+ return (
+ <>
+ {isDesktop && (
+ <div>
+ <h1 className={`font-bold ${isKonfirmasi ? 'text-xl' : ''}`}>
+ Pengiriman
+ </h1>
+ <form className='flex flex-col w-full '>
+ <div className='w-full grid grid-row-2 gap-5'>
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama PIC Penerimaan Barang
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <input
+ value={formPengiriman.PICName}
+ id='PICName'
+ name='PICName'
+ placeholder='Masukkan nama pic pengiriman disini'
+ type='text'
+ className='form-input'
+ aria-invalid={errorsPengiriman.PICName}
+ ref={PICNameRef}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.PICName}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Alamat Pengiriman Barang
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ pastikan alamat yang anda isi sesuai dengan alamat kirim
+ barang
+ </span>
+ )}
+ </div>
+ <div className='w-3/5 flex gap-3 flex-col'>
+ <div>
+ <input
+ id='streetPengiriman'
+ name='streetPengiriman'
+ ref={streetPengirimanRef}
+ placeholder='Masukkan alamat lengkap pengiriman barang'
+ type='text'
+ value={formPengiriman.streetPengiriman}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.streetPengiriman}
+ </div>
+ )}
+ </div>
+ <div className='sub-alamat flex flex-row w-full gap-3'>
+ <div className='w-2/5' ref={statePengirimanRef}>
+ <Controller
+ name='statePengiriman'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={states}
+ placeholder='Provinsi'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.statePengiriman}
+ </div>
+ )}
+ </div>
+ <div className='w-1/3' ref={cityPengirimanRef}>
+ <Controller
+ name='cityPengiriman'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={cities}
+ disabled={!watchState}
+ placeholder='Kota'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.cityPengiriman}
+ </div>
+ )}
+ </div>
+ <div className='w-1/3'>
+ <input
+ id='zipPengiriman'
+ name='zipPengiriman'
+ ref={zipRef}
+ placeholder='Kode Pos'
+ type='number'
+ value={formPengiriman.zipPengiriman}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.zipPengiriman}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama PIC Penerimaan Invoice
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <input
+ value={formPengiriman.invoicePic}
+ id='invoicePic'
+ name='invoicePic'
+ placeholder='Masukkan nama pic invoice disini'
+ type='text'
+ className='form-input'
+ aria-invalid={errorsPengiriman.invoicePic}
+ ref={invoicePicRef}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.invoicePic}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Alamat Pengiriman Invoice
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pastikan alamat yang anda isi sesuai dengan alamat kirim
+ invoice
+ </span>
+ )}
+ </div>
+ <div className='w-3/5 flex gap-3 flex-col'>
+ <div>
+ <Checkbox
+ colorScheme='red'
+ isChecked={sameAddress}
+ onChange={handleChangeSameAddress}
+ >
+ Alamat invoice sama dengan alamat pengiriman
+ </Checkbox>
+ </div>
+ {!sameAddress && (
+ <>
+ <div>
+ <input
+ id='streetInvoice'
+ name='streetInvoice'
+ ref={streetInvoiceRef}
+ placeholder='Masukkan alamat lengkap pengiriman invoice'
+ type='text'
+ value={formPengiriman.streetInvoice}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.streetInvoice}
+ </div>
+ )}
+ </div>
+ <div className='sub-alamat flex flex-row w-full gap-3'>
+ <div className='w-3/5' ref={stateInvoiceRef}>
+ <Controller
+ name='stateInvoice'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={states}
+ placeholder='Provinsi'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.stateInvoice}
+ </div>
+ )}
+ </div>
+ <div className='w-2/5' ref={cityInvoiceRef}>
+ <Controller
+ name='cityInvoice'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={cities}
+ disabled={!watchState}
+ placeholder='Kota'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.cityInvoice}
+ </div>
+ )}
+ </div>
+ </div>
+ </>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ Jadwal Penukaran Invoice{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih jika bisnis anda memiliki jadwal penukaran invoice
+ </span>
+ )}
+ </div>
+ <div className='w-3/5 flex gap-3 flex-col'>
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ colorScheme='red'
+ isChecked={everyWeekday}
+ onChange={handleEveryWeekday}
+ >
+ Setiap Minggu dihari
+ </Checkbox>
+ <input
+ id='everyWeekdayInput'
+ name='everyWeekdayInput'
+ ref={everyWeekdayInputRef}
+ placeholder='Format: Senin, Selasa, Rabu, Kamis, Jumat, Sabtu, Minggu'
+ type='text'
+ value={formPengiriman.everyWeekdayInput}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ colorScheme='red'
+ isChecked={everyWeek}
+ onChange={handleEveryWeek}
+ >
+ Setiap Bulan di minggu ke
+ </Checkbox>
+ <input
+ id='everyWeekInput'
+ name='everyWeekInput'
+ ref={everyWeekInputRef}
+ placeholder='Format: Minggu 1 & Minggu 2'
+ type='text'
+ value={formPengiriman.everyWeekInput}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ colorScheme='red'
+ isChecked={tukarInvoice}
+ onChange={handleTukarInvoice}
+ >
+ Lainnya
+ </Checkbox>
+ <textarea
+ id='tukarInvoiceInput'
+ name='tukarInvoiceInput'
+ placeholder='isi manual dokumen yang anda mau'
+ type='textarea'
+ value={formPengiriman.tukarInvoiceInput}
+ className='form-input'
+ rows={4}
+ cols={40}
+ onChange={handleInputChange}
+ />
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Jadwal Pembayaran{' '}
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih jika bisnis anda memiliki jadwal pembayaran
+ </span>
+ )}
+ </div>
+ <div className='w-3/5 flex gap-3 flex-col'>
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ colorScheme='red'
+ isChecked={everyWeekdayPembayaran}
+ onChange={handleEveryWeekdayPembayaran}
+ >
+ Setiap Minggu dihari
+ </Checkbox>
+ <input
+ id='everyWeekdayInputPembayaran'
+ name='everyWeekdayInputPembayaran'
+ placeholder='Format: Senin, Selasa, Rabu, Kamis, Jumat, Sabtu, Minggu'
+ type='text'
+ value={formPengiriman.everyWeekdayInputPembayaran}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ colorScheme='red'
+ isChecked={everyWeekPembayaran}
+ onChange={handleEveryWeekPembayaran}
+ >
+ Setiap Bulan di minggu ke
+ </Checkbox>
+ <input
+ id='everyWeekInputPembayaran'
+ name='everyWeekInputPembayaran'
+ placeholder='Format: Minggu 1 & Minggu 2'
+ type='text'
+ value={formPengiriman.everyWeekInputPembayaran}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ colorScheme='red'
+ isChecked={tukarInvoicePembayaran}
+ onChange={handleTukarInvoicePembayaran}
+ >
+ Lainnya
+ </Checkbox>
+ <textarea
+ id='tukarInvoiceInputPembayaran'
+ name='tukarInvoiceInputPembayaran'
+ placeholder='isi manual dokumen yang anda mau'
+ type='textarea'
+ value={formPengiriman.tukarInvoiceInputPembayaran}
+ className='form-input'
+ rows={4}
+ cols={40}
+ onChange={handleInputChange}
+ />
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ Dokumen saat Pengiriman Barang
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih dokumen lampiran saat pengiriman barang
+ </span>
+ )}
+ </div>
+ <div
+ className='w-3/5 flex gap-3 flex-col'
+ ref={dokumenPengirimanRef}
+ >
+ <Checkbox
+ colorScheme='red'
+ key='0'
+ isChecked={isChecked(0)}
+ onChange={() => handleCheckboxChange(0)}
+ >
+ Surat Tanda Terima Barang (STTB)
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key='1'
+ isChecked={isChecked(1)}
+ onChange={() => handleCheckboxChange(1)}
+ >
+ Good Receipt (GR)
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key='2'
+ isChecked={isChecked(2)}
+ onChange={() => handleCheckboxChange(2)}
+ >
+ Surat Terima Barang (STB)
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key='3'
+ isChecked={isChecked(3)}
+ onChange={() => handleCheckboxChange(3)}
+ >
+ Lembar Penerimaan Barang (LPB)
+ </Checkbox>
+
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ colorScheme='red'
+ key='4'
+ isChecked={isChecked(4)}
+ onChange={() => handleCheckboxChange(4)}
+ >
+ Lainnya
+ </Checkbox>
+ <textarea
+ id='dokumenPengirimanInput'
+ name='dokumenPengirimanInput'
+ placeholder='isi manual dokumen yang anda mau'
+ type='textarea'
+ ref={dokumenPengirimanInputRef}
+ value={formPengiriman.dokumenPengirimanInput}
+ className='form-input'
+ rows={4}
+ cols={40}
+ onChange={handleInputChange}
+ />
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.dokumenPengiriman}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap'>
+ Dokumen yang dilampirkan saat Pengiriman Invoice
+ </label>
+ <span className='text-xs opacity-60'>
+ Dokumen akan dikirimkan sesuai dengan yang anda pilih
+ </span>
+ </div>
+ <div
+ className='w-3/5 flex gap-3 flex-col'
+ ref={dokumenPengirimanInvoiceRef}
+ >
+ <Checkbox
+ colorScheme='red'
+ key='0'
+ isChecked={isCheckedInvoice(0)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(0)
+ }
+ >
+ Invoice Pembelian
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key='1'
+ isChecked={isCheckedInvoice(1)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(1)
+ }
+ >
+ Surat Jalan
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key='2'
+ isChecked={isCheckedInvoice(2)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(2)
+ }
+ >
+ Berita Acara Serah Terima (BAST)
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key='3'
+ isChecked={isCheckedInvoice(3)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(3)
+ }
+ >
+ Faktur Pajak
+ </Checkbox>
+ <Checkbox
+ colorScheme='red'
+ key='4'
+ isChecked={isCheckedInvoice(4)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(4)
+ }
+ >
+ Good Receipt (GR)
+ </Checkbox>
+
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ colorScheme='red'
+ key='5'
+ isChecked={isCheckedInvoice(5)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(5)
+ }
+ >
+ Lainnya
+ </Checkbox>
+ <textarea
+ id='dokumenPengirimanInvoiceInput'
+ name='dokumenPengirimanInvoiceInput'
+ placeholder='isi manual dokumen yang anda mau'
+ type='textarea'
+ ref={dokumenPengirimanInvoiceInputRef}
+ value={formPengiriman.dokumenPengirimanInvoiceInput}
+ className='form-input'
+ rows={4}
+ cols={40}
+ onChange={handleInputChange}
+ />
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.dokumenInvoicePengiriman}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+ )}
+ {isMobile && (
+ <div className='text-sm'>
+ <h1
+ className={`font-bold py-4 mt-8 ${
+ isKonfirmasi ? 'hidden' : 'text-xl'
+ }`}
+ >
+ Pengiriman
+ </h1>
+ <form className='flex flex-col w-full '>
+ <div className='w-full grid grid-row-2 gap-2'>
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Nama PIC Penerimaan Barang
+ </label>
+ <input
+ value={formPengiriman.PICName}
+ id='PICName'
+ name='PICName'
+ placeholder='Masukkan nama pic pengiriman disini'
+ type='text'
+ className='form-input'
+ aria-invalid={errorsPengiriman.PICName}
+ ref={PICNameRef}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.PICName}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Alamat Pengiriman Barang
+ </label>
+ <div className='w-full'>
+ <input
+ id='streetPengiriman'
+ name='streetPengiriman'
+ ref={streetPengirimanRef}
+ placeholder='Masukkan alamat lengkap pengiriman barang'
+ type='text'
+ value={formPengiriman.streetPengiriman}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.streetPengiriman}
+ </div>
+ )}
+ </div>
+ <div className='sub-alamat flex flex-row w-full gap-2'>
+ <div className='w-2/5' ref={statePengirimanRef}>
+ <Controller
+ name='statePengiriman'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={states}
+ placeholder='Provinsi'
+ />
+ )}
+ />
+ </div>
+ <div className='w-1/3' ref={cityPengirimanRef}>
+ <Controller
+ name='cityPengiriman'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={cities}
+ disabled={!watchState}
+ placeholder='Kota'
+ />
+ )}
+ />
+ </div>
+ <div className='w-1/3'>
+ <input
+ id='zipPengiriman'
+ name='zipPengiriman'
+ ref={zipRef}
+ placeholder='Kode Pos'
+ type='number'
+ value={formPengiriman.zipPengiriman}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.statePengiriman}
+ </div>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.cityPengiriman}
+ </div>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.zipPengiriman}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Nama PIC Penerimaan Invoice
+ </label>
+ <input
+ value={formPengiriman.invoicePic}
+ id='invoicePic'
+ name='invoicePic'
+ placeholder='Masukkan nama pic invoice disini'
+ type='text'
+ className='form-input'
+ aria-invalid={errorsPengiriman.invoicePic}
+ ref={invoicePicRef}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.invoicePic}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Alamat Pengiriman Invoice
+ </label>
+ <div>
+ <Checkbox
+ colorScheme='red'
+ isChecked={sameAddress}
+ onChange={handleChangeSameAddress}
+ size='sm'
+ >
+ Alamat invoice sama dengan alamat pengiriman
+ </Checkbox>
+ </div>
+ {!sameAddress && (
+ <>
+ <div className='w-full'>
+ <input
+ id='streetInvoice'
+ name='streetInvoice'
+ ref={streetInvoiceRef}
+ placeholder='Masukkan alamat lengkap pengiriman invoice'
+ type='text'
+ value={formPengiriman.streetInvoice}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.streetInvoice}
+ </div>
+ )}
+ </div>
+ <div className='sub-alamat flex flex-row w-full gap-3'>
+ <div className='w-3/5' ref={stateInvoiceRef}>
+ <Controller
+ name='stateInvoice'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={states}
+ placeholder='Provinsi'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.stateInvoice}
+ </div>
+ )}
+ </div>
+ <div className='w-2/5' ref={cityInvoiceRef}>
+ <Controller
+ name='cityInvoice'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={cities}
+ disabled={!watchState}
+ placeholder='Kota'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.cityInvoice}
+ </div>
+ )}
+ </div>
+ </div>
+ </>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-wrap'>
+ Jadwal Penukaran Invoice
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih jika bisnis anda memiliki jadwal penukaran invoice
+ </span>
+ )}
+ <div className='w-full flex gap-2 flex-col'>
+ <div className='flex gap-2 flex-col'>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ isChecked={everyWeekday}
+ onChange={handleEveryWeekday}
+ >
+ Setiap Minggu dihari
+ </Checkbox>
+ <input
+ id='everyWeekdayInput'
+ name='everyWeekdayInput'
+ ref={everyWeekdayInputRef}
+ placeholder='Format: Senin, Selasa, Rabu, Kamis, Jumat, Sabtu, Minggu'
+ type='text'
+ value={formPengiriman.everyWeekdayInput}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div className='flex gap-2 w-full flex-col'>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ isChecked={everyWeek}
+ onChange={handleEveryWeek}
+ >
+ Setiap Bulan di minggu ke
+ </Checkbox>
+ <input
+ id='everyWeekInput'
+ name='everyWeekInput'
+ ref={everyWeekInputRef}
+ placeholder='Format: Minggu 1 & Minggu 2'
+ type='text'
+ value={formPengiriman.everyWeekInput}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div className='flex gap-2 flex-col'>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ isChecked={tukarInvoice}
+ onChange={handleTukarInvoice}
+ >
+ Lainnya
+ </Checkbox>
+ <textarea
+ id='tukarInvoiceInput'
+ name='tukarInvoiceInput'
+ placeholder='isi manual dokumen yang anda mau'
+ type='textarea'
+ value={formPengiriman.tukarInvoiceInput}
+ className='form-input'
+ rows={4}
+ cols={40}
+ onChange={handleInputChange}
+ />
+ </div>
+ </div>
+ <div className='w-2/5'></div>
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Jadwal Pembayaran
+ <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih jika bisnis anda memiliki jadwal pembayaran
+ </span>
+ )}
+ <div className='w-full flex gap-2 flex-col'>
+ <div className='flex gap-2 flex-col'>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ isChecked={everyWeekdayPembayaran}
+ onChange={handleEveryWeekdayPembayaran}
+ >
+ Setiap Minggu dihari
+ </Checkbox>
+ <input
+ id='everyWeekdayInputPembayaran'
+ name='everyWeekdayInputPembayaran'
+ placeholder='Format: Senin, Selasa, Rabu, Kamis, Jumat, Sabtu, Minggu'
+ type='text'
+ value={formPengiriman.everyWeekdayInputPembayaran}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div className='flex gap-2 flex-col'>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ isChecked={everyWeekPembayaran}
+ onChange={handleEveryWeekPembayaran}
+ >
+ Setiap Bulan di minggu ke
+ </Checkbox>
+ <input
+ id='everyWeekInputPembayaran'
+ name='everyWeekInputPembayaran'
+ placeholder='Format: Minggu 1 & Minggu 2'
+ type='text'
+ value={formPengiriman.everyWeekInputPembayaran}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div className='flex gap-2 flex-col'>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ isChecked={tukarInvoicePembayaran}
+ onChange={handleTukarInvoicePembayaran}
+ >
+ Lainnya
+ </Checkbox>
+ <textarea
+ id='tukarInvoiceInputPembayaran'
+ name='tukarInvoiceInputPembayaran'
+ placeholder='isi manual dokumen yang anda mau'
+ type='textarea'
+ value={formPengiriman.tukarInvoiceInputPembayaran}
+ className='form-input'
+ rows={4}
+ cols={40}
+ onChange={handleInputChange}
+ />
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-wrap'>
+ Dokumen saat Pengiriman Barang
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih dokumen lampiran saat pengiriman barang
+ </span>
+ )}
+ <div
+ className='w-full flex gap-2 flex-col'
+ ref={dokumenPengirimanRef}
+ >
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='0'
+ isChecked={isChecked(0)}
+ onChange={() => handleCheckboxChange(0)}
+ >
+ Surat Tanda Terima Barang (STTB)
+ </Checkbox>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='1'
+ isChecked={isChecked(1)}
+ onChange={() => handleCheckboxChange(1)}
+ >
+ Good Receipt (GR)
+ </Checkbox>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='2'
+ isChecked={isChecked(2)}
+ onChange={() => handleCheckboxChange(2)}
+ >
+ Surat Terima Barang (STB)
+ </Checkbox>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='3'
+ isChecked={isChecked(3)}
+ onChange={() => handleCheckboxChange(3)}
+ >
+ Lembar Penerimaan Barang (LPB)
+ </Checkbox>
+
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='4'
+ isChecked={isChecked(4)}
+ onChange={() => handleCheckboxChange(4)}
+ >
+ Lainnya
+ </Checkbox>
+ <textarea
+ id='dokumenPengirimanInput'
+ name='dokumenPengirimanInput'
+ placeholder='isi manual dokumen yang anda mau'
+ type='textarea'
+ ref={dokumenPengirimanInputRef}
+ value={formPengiriman.dokumenPengirimanInput}
+ className='form-input'
+ rows={4}
+ cols={40}
+ onChange={handleInputChange}
+ />
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.dokumenPengiriman}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-wrap'>
+ Dokumen yang dilampirkan saat Pengiriman Invoice
+ </label>
+ <span className='text-xs opacity-60'>
+ Pilih dokumen lampiran saat pengiriman invoice
+ </span>
+ <div
+ className='w-full flex gap-2 flex-col'
+ ref={dokumenPengirimanInvoiceRef}
+ >
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='0'
+ isChecked={isCheckedInvoice(0)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(0)
+ }
+ >
+ Invoice Pembelian
+ </Checkbox>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='1'
+ isChecked={isCheckedInvoice(1)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(1)
+ }
+ >
+ Surat Jalan
+ </Checkbox>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='2'
+ isChecked={isCheckedInvoice(2)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(2)
+ }
+ >
+ Berita Acara Serah Terima (BAST)
+ </Checkbox>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='3'
+ isChecked={isCheckedInvoice(3)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(3)
+ }
+ >
+ Faktur Pajak
+ </Checkbox>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='4'
+ isChecked={isCheckedInvoice(4)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(4)
+ }
+ >
+ Good Receipt (GR)
+ </Checkbox>
+
+ <div className='flex gap-3 flex-col'>
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key='5'
+ isChecked={isCheckedInvoice(5)}
+ onChange={() =>
+ handleCheckboxChangeDokumenPengirimanInvoice(5)
+ }
+ >
+ Lainnya
+ </Checkbox>
+ <textarea
+ id='dokumenPengirimanInvoiceInput'
+ name='dokumenPengirimanInvoiceInput'
+ placeholder='isi manual dokumen yang anda mau'
+ type='textarea'
+ ref={dokumenPengirimanInvoiceInputRef}
+ value={formPengiriman.dokumenPengirimanInvoiceInput}
+ className='form-input'
+ rows={4}
+ cols={40}
+ onChange={handleInputChange}
+ />
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.dokumenInvoicePengiriman}
+ </div>
+ )}
+ </div>
+ <div className='w-2/5'></div>
+ </div>
+ </div>
+ </form>
+ </div>
+ )}
+ </>
+ );
+};
+
+export default Pengiriman;
diff --git a/src/lib/pengajuan-tempo/component/Referensi.jsx b/src/lib/pengajuan-tempo/component/Referensi.jsx
new file mode 100644
index 00000000..8cb3b0c3
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/Referensi.jsx
@@ -0,0 +1,548 @@
+import React, { useState, useEffect, useMemo, useRef } from 'react';
+import { useForm } from 'react-hook-form';
+import { usePengajuanTempoStoreSupplier } 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';
+const initialData = [];
+const Referensi = ({ chekValid, buttonSubmitClick }) => {
+ 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 } =
+ usePengajuanTempoStoreSupplier();
+ 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) => {
+ 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);
+ updateHasSave(false);
+ };
+
+ const handleNewSupplierChange = (e) => {
+ 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);
+ updateHasSave(false);
+ };
+
+ const handleAddNewSupplier = () => {
+ if (Object.values(newSupplier).every((val) => val.trim() !== '')) {
+ setSupplierData((prevData) => {
+ const newData = [...prevData, newSupplier];
+ return newData;
+ });
+
+ setNewSupplier({
+ supplier: '',
+ pic: '',
+ telepon: '',
+ durasiTempo: '',
+ creditLimit: '',
+ });
+ }
+ updateHasSave(false);
+ };
+
+ 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 (cachedData) {
+ setSupplierData(cachedData);
+ updateFormSupplier(cachedData);
+ }
+ }, [buttonSubmitClick]);
+
+ useEffect(() => {
+ setOpenIndexes(supplierData.map((_, index) => index));
+ }, [supplierData]);
+
+ const toggleOpen = (index) => {
+ setOpenIndexes((prev) =>
+ prev.includes(index) ? prev.filter((i) => i !== index) : [...prev, index]
+ );
+ };
+ return (
+ <>
+ {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>
+ <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'
+ />
+ </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>
+ <input
+ name='creditLimit'
+ value={formatRupiah(newSupplier.creditLimit)}
+ type='text'
+ className='form-input border px-4 py-2'
+ onChange={handleNewSupplierChange}
+ placeholder='limit kredit'
+ />
+ </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>
+ <button
+ onClick={simpanData}
+ 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'
+ >
+ 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' />
+ {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'>
+ <span className='text-xs opacity-60 text-red-500'>
+ *Klik simpan sebelum lanjut ke tahap selanjutnya
+ </span>
+ <button
+ onClick={simpanData}
+ className='bg-gray-200 border border-gray-500 rounded-md w-full text-sm text-gray-500 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;
diff --git a/src/lib/pengajuan-tempo/component/Stepper.jsx b/src/lib/pengajuan-tempo/component/Stepper.jsx
new file mode 100644
index 00000000..539fe3f3
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/Stepper.jsx
@@ -0,0 +1,65 @@
+import React from 'react';
+import useDevice from '@/core/hooks/useDevice';
+const Stepper = ({ currentStep, numberOfSteps }) => {
+ const { isDesktop, isMobile } = useDevice();
+ const stepLabels = [
+ 'Informasi Perusahaan',
+ 'Kontak Person',
+ 'Pengiriman',
+ 'Referensi',
+ 'Dokumen',
+ 'Konfirmasi',
+ ];
+ const activeColor = (index) =>
+ currentStep >= index ? 'bg-red-500' : 'bg-gray-300';
+ const activeColorBullet = (index) =>
+ currentStep >= index ? 'bg-red-500 ' : 'bg-white border-gray-300 border';
+ const isFinalStep = (index) => index === numberOfSteps - 1;
+ const isFirstStep = (index) => index === 0;
+ return (
+ <div className='flex items-center'>
+ {Array.from({ length: numberOfSteps }).map((_, index) => (
+ <React.Fragment key={index}>
+ {isFirstStep(index) ? null : (
+ <div
+ className={`${isMobile ? 'w-12' : 'w-48'} h-[0.8px] ${activeColor(
+ index
+ )}`}
+ ></div>
+ )}
+ <div
+ className={`w-6 h-6 ${
+ currentStep == index
+ ? 'border-red-500 border'
+ : `${activeColorBullet(index)} `
+ } rounded-full flex justify-center items-center text-nowrap`}
+ >
+ <div className='relative text-xs'>
+ <div
+ className={`absolute z-10 ${
+ isMobile
+ ? `w-12 h-full top-4 ${
+ isFinalStep(index) ? '-left-16' : '-left-4'
+ }`
+ : 'w-48 h-full -top-14 -left-24'
+ } `}
+ >
+ <div
+ className={`relative w-full max-w-md p-2 text-center ${
+ currentStep == index
+ ? 'text-red-500'
+ : `${isMobile ? 'hidden' : ''}`
+ } text-nowrap`}
+ >
+ {stepLabels[index]}
+ </div>
+ </div>
+ </div>
+ </div>
+ </React.Fragment>
+ ))}
+ </div>
+ );
+};
+
+export default Stepper;
diff --git a/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx
new file mode 100644
index 00000000..8a1b3508
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/informasiPerusahaan.jsx
@@ -0,0 +1,1401 @@
+import React, { useState, useEffect, useMemo, useRef } from 'react';
+import { Controller, set, useForm } from 'react-hook-form';
+import HookFormSelect from '@/core/components/elements/Select/HookFormSelect';
+import odooApi from '~/libs/odooApi';
+import stateApi from '@/lib/address/api/stateApi.js';
+import cityApi from '@/lib/address/api/cityApi';
+import { Radio, RadioGroup, Stack, Checkbox } from '@chakra-ui/react';
+import { usePengajuanTempoStore } from '../../../../src-migrate/modules/register/stores/usePengajuanTempoStore';
+import useDevice from '@/core/hooks/useDevice';
+import Divider from '@/core/components/elements/Divider/Divider';
+const InformasiPerusahaan = ({
+ chekValid,
+ buttonSubmitClick,
+ isKonfirmasi,
+}) => {
+ const { isDesktop, isMobile } = useDevice();
+ const { control, watch, setValue, getValues } = useForm();
+ const { form, errors, validate, updateForm } = usePengajuanTempoStore();
+ const [industries, setIndustries] = useState([]);
+ const [selectedCategory, setSelectedCategory] = useState('');
+ const [states, setState] = useState([]);
+ const [cities, setCities] = useState([]);
+ const [bersedia, setBersedia] = useState(null);
+ const category_produk = [
+ { id: 2040, name: 'Pengaman, Kesehatan & Keamanan' },
+ { id: 2097, name: 'Perkakas Tangan, Listrik & Pneumatic' },
+ { id: 2161, name: 'Mesin Industrial' },
+ { id: 2222, name: 'Mesin Pertanian & Perkebunan' },
+ { id: 2246, name: 'Mesin Pembersih & Janitorial' },
+ { id: 2273, name: 'Cairan Berbahan Kimia' },
+ { id: 2315, name: 'Perlengkapan Pengukuran & Pengujian' },
+ { id: 2354, name: 'Peralatan Listrik & Elektronik' },
+ { id: 2394, name: 'Perlengkapan Logistik & Gudang' },
+ { id: 2420, name: 'Peralatan Kantor & Stationery' },
+ { id: 2445, name: 'Komponen & Aksesoris' },
+ { id: 2477, name: 'Peralatan Horeca & Food Service' },
+ ];
+ const radioOptions = [
+ { label: '5.000.000', value: '5000000' },
+ { label: '10.000.000', value: '10000000' },
+ { label: '15.000.000', value: '15000000' },
+ { label: '20.000.000', value: '20000000' },
+ { label: '25.000.000', value: '25000000' },
+ { label: '30.000.000', value: '30000000' },
+ { label: '35.000.000', value: '35000000' },
+ ];
+
+ 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(() => {
+ updateForm('city', '');
+ if (watchState) {
+ updateForm('state', `${watchState}`);
+ validate();
+ const loadCities = async () => {
+ let dataCities = await cityApi({ stateId: watchState });
+ dataCities = dataCities.map((city) => ({
+ value: city.id,
+ label: city.name,
+ }));
+ setCities(dataCities);
+ };
+ loadCities();
+ }
+ }, [watchState]);
+
+ const watchCity = watch('city');
+ useEffect(() => {
+ if (watchCity) {
+ updateForm('city', `${watchCity}`);
+ validate();
+ }
+ }, [watchCity]);
+
+ useEffect(() => {
+ const loadIndustries = async () => {
+ const dataIndustries = await odooApi('GET', '/api/v1/partner/industry');
+ setIndustries(
+ dataIndustries?.map((o) => ({
+ value: o.id,
+ label: o.name,
+ category: o.category,
+ }))
+ );
+ };
+ loadIndustries();
+ }, []);
+
+ useEffect(() => {
+ const selectedIndustryType = industries.find(
+ (industry) => industry.value === watch('industry_id')
+ );
+ if (selectedIndustryType) {
+ updateForm('industry_id', `${selectedIndustryType?.value}`);
+ validate();
+ setSelectedCategory(selectedIndustryType.category);
+ }
+ }, [watch('industry_id'), industries]);
+
+ const estimasiValue = watch('estimasi');
+ const tempoLimitValue = watch('tempoLimit');
+
+ // Memformat angka menjadi format rupiah
+ const formatRupiah = (value) => {
+ if (!value) return '';
+ const numberString = value.replace(/[^0-9]/g, ''); // Menghapus karakter non-digit
+ return numberString
+ ? 'Rp ' + new Intl.NumberFormat('id-ID').format(numberString)
+ : '';
+ };
+
+ const handleChange = (e) => {
+ const value = e.target.value;
+ const formattedValue = formatRupiah(value);
+ updateForm('estimasi', formattedValue.replace(/^Rp\s*/, ''));
+ validate();
+ };
+ const onChangeTempoDuration = (e) => {
+ updateForm('tempoDuration', `${e}`);
+ validate();
+ };
+
+ const onChangeTempoLimit = (e) => {
+ updateForm('tempoLimit', `${e}`);
+ validate();
+ };
+ const [isCustom, setIsCustom] = React.useState(false);
+ const [tempoLimitValueEx, setTempoLimitValueEx] = React.useState('');
+ const handleCheckboxBersediaChange = (value) => {
+ // if (value === 'bersedia') {
+ // setBersedia(true);
+ // } else if (value === 'tidakBersedia') {
+ // setBersedia(false);
+ // }
+ // updateForm('bersedia', `${value === 'bersedia'}`);
+ updateForm('bersedia', `${value}`);
+ validate();
+ };
+ const [selectedIds, setSelectedIds] = useState(
+ form.categoryProduk ? form.categoryProduk.split(',').map(Number) : [] // 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
+ updateForm('categoryProduk', updatedSelected.join(','));
+ validate();
+ };
+
+ useEffect(() => {
+ if (form.categoryProduk) {
+ setSelectedIds(form.categoryProduk.split(',').map(Number)); // Parse string menjadi array angka
+ }
+ }, [form.categoryProduk]);
+ const isChecked = (id) => selectedIds.includes(id);
+
+ const handleInputChange = (event) => {
+ const { name, value } = event.target;
+ updateForm(name, value);
+ validate();
+ };
+
+ const midIndex = Math.ceil(category_produk.length / 2);
+ const firstColumn = category_produk.slice(0, midIndex);
+ const secondColumn = category_produk.slice(midIndex);
+ const isFormValid = useMemo(() => Object.keys(errors).length === 0, [errors]);
+
+ const nameRef = useRef(null);
+ const industry_idRef = useRef(null);
+ const streetRef = useRef(null);
+ const stateRef = useRef(null);
+ const cityRef = useRef(null);
+ const zipRef = useRef(null);
+ const mobileRef = useRef(null);
+ const bankNameRef = useRef(null);
+ const accountNameRef = useRef(null);
+ const accountNumberRef = useRef(null);
+ const estimasiRef = useRef(null);
+ const tempoDurationRef = useRef(null);
+ const bersediaRef = useRef(null);
+ const categoryProdukRef = useRef(null);
+ const tempoLimitRef = useRef(null);
+ useEffect(() => {
+ const loadIndustries = async () => {
+ if (!isFormValid) {
+ const options = {
+ behavior: 'smooth',
+ block: 'center',
+ };
+ if (errors.name && nameRef.current) {
+ nameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.industry_id && industry_idRef.current) {
+ industry_idRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.street && streetRef.current) {
+ streetRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.state && stateRef.current) {
+ stateRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.city && cityRef.current) {
+ cityRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.zip && zipRef.current) {
+ zipRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.mobile && mobileRef.current) {
+ mobileRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.bankName && bankNameRef.current) {
+ bankNameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.accountName && accountNameRef.current) {
+ accountNameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.accountNumber && accountNumberRef.current) {
+ accountNumberRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.estimasi && estimasiRef.current) {
+ estimasiRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.tempoDuration && tempoDurationRef.current) {
+ tempoDurationRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.bersedia && bersediaRef.current) {
+ bersediaRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.categoryProduk && categoryProdukRef.current) {
+ categoryProdukRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errors.tempoLimit && tempoLimitRef.current) {
+ tempoLimitRef.current.scrollIntoView(options);
+ return;
+ }
+ }
+ };
+ loadIndustries();
+ }, [buttonSubmitClick, chekValid]);
+ useEffect(() => {
+ if (form.industry_id) {
+ setValue('industry_id', parseInt(form.industry_id));
+ }
+ if (form.state) {
+ setValue('state', parseInt(form.state));
+ }
+ if (form.city) {
+ setValue('city', parseInt(form.city));
+ }
+ if (form.tempoDuration) {
+ setValue('tempoDuration', form.tempoDuration);
+ }
+ if (form.tempoLimit) {
+ setValue('tempoLimit', form.tempoLimit);
+ }
+ if (form.tempoLimit) {
+ const isValueInOptions = radioOptions.some(
+ (option) => option.value === form.tempoLimit
+ );
+
+ if (isValueInOptions) {
+ setValue('tempoLimit', form.tempoLimit); // Set value dari radio options
+ setIsCustom(false); // Pastikan custom tidak aktif
+ } else {
+ setValue('tempoLimit', 'custom'); // Set value ke custom jika tidak termasuk dalam options
+ setIsCustom(true); // Aktifkan custom input
+ setTempoLimitValueEx(form.tempoLimit); // Set nilai input custom ke form.tempoLimit
+ }
+ }
+ }, [form]);
+ return (
+ <>
+ {isDesktop && (
+ <div className=''>
+ <h1 className={`font-bold ${isKonfirmasi ? 'text-xl' : ''}`}>
+ Informasi Perusahaan
+ </h1>
+ <form className='flex flex-col w-full '>
+ <div className='w-full grid grid-row-2 gap-5'>
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>
+ Nama Perusahaan
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi detail perusahaan sesuai dengan nama yang terdaftar{' '}
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='name'
+ name='name'
+ placeholder='Masukkan nama perusahaan'
+ type='text'
+ className='form-input'
+ aria-invalid={errors.name}
+ value={form.name}
+ ref={nameRef}
+ onChange={handleInputChange}
+ />
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Format: PT. INDOTEKNIK DOTCOM GEMILANG
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.name}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5' ref={industry_idRef}>
+ <label className='form-label text-nowrap'>Industri</label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi detail perusahaan sesuai dengan nama yang terdaftar
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <Controller
+ name='industry_id'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={industries}
+ placeholder={'Pilih industri bisnis anda'}
+ />
+ )}
+ />
+ {!isKonfirmasi && selectedCategory && (
+ <span className='text-gray_r-11 text-xs opacity-60'>
+ Kategori : {selectedCategory}
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.industry_id}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5 text-nowrap'>
+ <label className='form-label '>Alamat Perusahaan</label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ alamat sesuai dengan alamat kantor pusat
+ </span>
+ )}
+ </div>
+ <div className='w-3/5 flex gap-3 flex-col'>
+ <div>
+ <input
+ id='street'
+ name='street'
+ ref={streetRef}
+ placeholder='Masukkan alamat lengkap perusahaan'
+ type='text'
+ value={form.street}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.street}
+ </div>
+ )}
+ </div>
+ <div className='sub-alamat flex flex-row w-full gap-3'>
+ <div className='w-2/5' ref={stateRef}>
+ <Controller
+ name='state'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={states}
+ placeholder='Provinsi'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.state}
+ </div>
+ )}
+ </div>
+ <div className='w-1/3' ref={cityRef}>
+ <Controller
+ name='city'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={cities}
+ disabled={!watchState}
+ placeholder='Kota'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.city}
+ </div>
+ )}
+ </div>
+ <div className='w-1/3'>
+ <input
+ id='zip'
+ name='zip'
+ ref={zipRef}
+ placeholder='Kode Pos'
+ type='number'
+ value={form.zip}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.zip}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ </div>
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5 text-nowrap'>
+ <label className='form-label '>No. Telfon Perusahaan</label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi no telfon perusahaan yang sesuai
+ </span>
+ )}
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='mobile'
+ name='mobile'
+ ref={mobileRef}
+ placeholder='Masukkan nomor telfon perusahaan'
+ type='tel'
+ value={form.mobile}
+ className='form-input'
+ aria-invalid={errors.mobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.mobile}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className=' w-2/5 text-nowrap'>
+ <label className='form-label'>Data Bank</label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Isi detail data bank perusahaan anda
+ </span>
+ )}
+ </div>
+ <div className='w-3/5 flex gap-3 flex-row'>
+ <div>
+ <input
+ id='bankName'
+ name='bankName'
+ ref={bankNameRef}
+ placeholder='Nama bank'
+ type='text'
+ value={form.bankName}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Format: BCA, Mandiri, CIMB, BNI dll
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.bankName}
+ </div>
+ )}
+ </div>
+ <div>
+ <input
+ id='accountName'
+ name='accountName'
+ ref={accountNameRef}
+ placeholder='Nama Rekening'
+ type='text'
+ value={form.accountName}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Format: John Doe
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.accountName}
+ </div>
+ )}
+ </div>
+ <div>
+ <input
+ id='accountNumber'
+ name='accountNumber'
+ ref={accountNumberRef}
+ placeholder='Nomor Rekening Bank'
+ type='text'
+ value={form.accountNumber}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Format: 01234567896
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.accountNumber}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5 text-nowrap'>
+ <label className='form-label '>
+ Website <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='website'
+ name='website'
+ placeholder='www.indoteknik.com'
+ type='text'
+ value={form.website}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5 text-nowrap'>
+ <label className='form-label '>
+ Estimasi Pembelian pertahun
+ </label>
+ </div>
+ <div className='w-3/5'>
+ <div className='relative'>
+ <input
+ id='estimasi'
+ name='estimasi'
+ ref={estimasiRef}
+ // {...register('estimasi', {
+ // setValueAs: (value) => value.replace(/^Rp\s*/, ''), // Menyimpan hanya angka
+ // })}
+ placeholder='Isi estimasi pembelian produk pertahun'
+ type='text'
+ className='form-input' // padding untuk memberi ruang untuk "RP"
+ value={formatRupiah(form.estimasi)}
+ onChange={handleChange} // Mengatur perubahan input
+ />
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.estimasi}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-center'>
+ <div className='w-2/5'>
+ <label className='form-label text-nowrap'>Durasi Tempo</label>
+ <span className='text-xs opacity-60'>
+ Pilih durasi tempo yang anda inginkan
+ </span>
+ </div>
+ <div className='w-3/5 flex flex-row items-center'>
+ <div className='w-1/5' ref={tempoDurationRef}>
+ <RadioGroup
+ onChange={onChangeTempoDuration}
+ value={form.tempoDuration}
+ >
+ <Stack direction='column' className=''>
+ <Radio colorScheme='red' value='7'>
+ 7 Hari
+ </Radio>
+ <Radio colorScheme='red' value='14' className=''>
+ 14 Hari
+ </Radio>
+ <Radio colorScheme='red' value='30' className=''>
+ 30 Hari
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoDuration}
+ </div>
+ )}
+ </div>
+ {!isKonfirmasi && (
+ <div className='w-4/5 flex flex-row justify-between items-center'>
+ <div className='w-2/5 text-nowrap'>
+ <label className='form-label '>Limit Tempo</label>
+ <span className='text-xs opacity-60'>
+ Ajukan nilai limit yang anda mau
+ </span>
+ </div>
+ <div
+ className='flex flex-col justify-start items-start'
+ ref={tempoLimitRef}
+ >
+ <RadioGroup
+ onChange={(value) => {
+ if (value === 'custom') {
+ setIsCustom(true);
+ updateForm('tempoLimit', tempoLimitValue); // Update dengan nilai input custom jika dipilih
+ } else {
+ setIsCustom(false);
+ onChangeTempoLimit(value); // Update dengan nilai radio button yang dipilih
+ }
+ }}
+ className='flex items-center justify-between'
+ value={isCustom ? 'custom' : form.tempoLimit}
+ >
+ <Stack direction='row'>
+ {/* Kolom 1 */}
+ <Stack
+ direction='column'
+ spacing={2}
+ className='mr-4'
+ >
+ {radioOptions.slice(0, 4).map((option) => (
+ <Radio
+ key={option.value}
+ colorScheme='red'
+ value={option.value}
+ >
+ {option.label}
+ </Radio>
+ ))}
+ </Stack>
+
+ {/* Kolom 2 */}
+ <Stack
+ direction='column'
+ className='ml-8'
+ spacing={2}
+ >
+ {radioOptions.slice(4).map((option) => (
+ <Radio
+ key={option.value}
+ colorScheme='red'
+ value={option.value}
+ >
+ {option.label}
+ </Radio>
+ ))}
+ <div className='flex flex-row items-center'>
+ <Radio colorScheme='red' value='custom'></Radio>
+
+ <input
+ placeholder='Isi limit yang anda inginkan'
+ type='text'
+ className='border ml-2 p-1' // padding untuk memberi ruang untuk "RP"
+ value={formatRupiah(tempoLimitValueEx)} // Menampilkan nilai terformat
+ onChange={(e) => {
+ const value = e.target.value;
+ const formattedValue = formatRupiah(value);
+ setTempoLimitValueEx(formattedValue);
+ updateForm(
+ 'tempoLimit',
+ formattedValue.replace(/^Rp\s*/, '')
+ ); // Mengupdate nilai di react-hook-form
+ }}
+ />
+ </div>
+ </Stack>
+ </Stack>
+ </RadioGroup>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoLimit}
+ </div>
+ )}
+ </div>
+ </div>
+ )}
+ </div>
+ </div>
+ {isKonfirmasi && (
+ <div className='flex flex-row justify-between items-center'>
+ <div className='w-2/5'>
+ <label className='form-label w-2/5 text-nowrap'>
+ Limit Tempo
+ </label>
+ <span className='text-xs opacity-60'>
+ Ajukan nilai limit yang anda mau
+ </span>
+ </div>
+ <div
+ className='w-3/5 flex flex-col justify-start items-start'
+ ref={tempoLimitRef}
+ >
+ <RadioGroup
+ onChange={(value) => {
+ if (value === 'custom') {
+ setIsCustom(true);
+ updateForm('tempoLimit', tempoLimitValue); // Update dengan nilai input custom jika dipilih
+ } else {
+ setIsCustom(false);
+ onChangeTempoLimit(value); // Update dengan nilai radio button yang dipilih
+ }
+ }}
+ className='flex items-center justify-between'
+ value={isCustom ? 'custom' : form.tempoLimit}
+ >
+ <Stack direction='row'>
+ {/* Kolom 1 */}
+ <Stack direction='column' spacing={2} className='mr-4'>
+ {radioOptions.slice(0, 4).map((option) => (
+ <Radio
+ key={option.value}
+ colorScheme='red'
+ value={option.value}
+ >
+ {option.label}
+ </Radio>
+ ))}
+ </Stack>
+
+ {/* Kolom 2 */}
+ <Stack direction='column' className='ml-8' spacing={2}>
+ {radioOptions.slice(4).map((option) => (
+ <Radio
+ key={option.value}
+ colorScheme='red'
+ value={option.value}
+ >
+ {option.label}
+ </Radio>
+ ))}
+ <div className='flex flex-row items-center'>
+ <Radio colorScheme='red' value='custom'></Radio>
+
+ <input
+ placeholder='Isi limit yang anda inginkan'
+ type='text'
+ className='border ml-2 p-1' // padding untuk memberi ruang untuk "RP"
+ value={formatRupiah(tempoLimitValueEx)} // Menampilkan nilai terformat
+ onChange={(e) => {
+ const value = e.target.value;
+ const formattedValue = formatRupiah(value);
+ setTempoLimitValueEx(formattedValue);
+ updateForm(
+ 'tempoLimit',
+ formattedValue.replace(/^Rp\s*/, '')
+ ); // Mengupdate nilai di react-hook-form
+ }}
+ />
+ </div>
+ </Stack>
+ </Stack>
+ </RadioGroup>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoLimit}
+ </div>
+ )}
+ </div>
+ </div>
+ )}
+
+ <div className='text-red-500'>
+ *Durasi dan limit dapat berbeda sesuai dengan verifikasi oleh
+ tim Indoteknik.com
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div className='w-2/5'>
+ <label className='form-label text-wrap '>
+ Apakah bersedia transaksi via website?
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih produk bisa lebih dari 1
+ </span>
+ )}
+ </div>
+ <div className='w-3/5 flex flex-col justify-start'>
+ <div className='flex gap-x-4' ref={bersediaRef}>
+ <RadioGroup
+ onChange={handleCheckboxBersediaChange}
+ value={form.bersedia}
+ >
+ <Stack direction='row'>
+ <Radio colorScheme='red' value='bersedia'>
+ Saya bersedia
+ </Radio>
+ <Radio colorScheme='red' value='tidakBersedia'>
+ Tidak bersedia
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ {/* <Checkbox
+ name='bersedia'
+ borderColor='gray.600'
+ colorScheme='red'
+ isChecked={bersedia === true} // Checked when bersedia is true
+ onChange={() => handleCheckboxBersediaChange('bersedia')}
+ value={true}
+ size='md'
+ >
+ Saya bersedia
+ </Checkbox>
+ <Checkbox
+ name='bersedia'
+ borderColor='gray.600'
+ colorScheme='red'
+ isChecked={bersedia === false} // Checked when bersedia is false
+ onChange={() => handleCheckboxBersediaChange('tidakBersedia')}
+ value={false}
+ size='md'
+ >
+ Tidak bersedia
+ </Checkbox> */}
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.estimasi}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div
+ className={`flex flex-row justify-between ${
+ isKonfirmasi ? 'items-center' : 'items-start'
+ }`}
+ >
+ <div className='w-2/5 text-nowrap'>
+ <label className='form-label '>
+ Kategori Produk yang Digunakan
+ </label>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Pilih produk bisa lebih dari 1
+ </span>
+ )}
+ </div>
+ <div className='w-3/5 flex flex-col'>
+ <div className='flex flex-row justify-between'>
+ <div
+ className='flex flex-col gap-2'
+ ref={categoryProdukRef}
+ >
+ {firstColumn.map((item) => (
+ <Checkbox
+ colorScheme='red'
+ key={item.id}
+ onChange={() => handleCheckboxChange(item.id)}
+ isChecked={isChecked(item.id)}
+ >
+ {item.name}
+ </Checkbox>
+ ))}
+ </div>
+ <div className='flex flex-col gap-2'>
+ {secondColumn.map((item) => (
+ <Checkbox
+ colorScheme='red'
+ key={item.id}
+ isChecked={isChecked(item.id)}
+ onChange={() => handleCheckboxChange(item.id)}
+ >
+ {item.name}
+ </Checkbox>
+ ))}
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.categoryProduk}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+ )}
+ {isMobile && (
+ <div className='text-sm'>
+ <h1
+ className={`font-bold py-4 mt-8 ${
+ isKonfirmasi ? 'hidden' : 'text-xl'
+ }`}
+ >
+ Informasi Perusahaan
+ </h1>
+ <form className='flex flex-col w-full '>
+ <div className='w-full grid grid-row-2 gap-4'>
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>
+ Nama Perusahaan
+ </label>
+ <input
+ id='name'
+ name='name'
+ placeholder='Format: PT. INDOTEKNIK DOTCOM GEMILANG'
+ type='text'
+ className='form-input'
+ aria-invalid={errors.name}
+ value={form.name}
+ ref={nameRef}
+ onChange={handleInputChange}
+ />
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ isi detail perusahaan sesuai dengan nama yang terdaftar{' '}
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.name}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label text-nowrap'>Industri</label>
+ <div className='w-full' ref={industry_idRef}>
+ <Controller
+ name='industry_id'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={industries}
+ placeholder={
+ 'Pilih Industri yang sesuai dengan perusahaan'
+ }
+ />
+ )}
+ />
+ </div>
+ {!isKonfirmasi && selectedCategory && (
+ <span className='text-gray_r-11 text-xs opacity-60'>
+ Kategori : {selectedCategory}
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.industry_id}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label '>Alamat Perusahaan</label>
+ <input
+ id='street'
+ name='street'
+ ref={streetRef}
+ placeholder='Masukkan alamat lengkap perusahaan'
+ type='text'
+ value={form.street}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ <div className='w-full text-nowrap'>
+ <div className='sub-alamat flex flex-row w-full gap-3'>
+ <div className='w-2/5' ref={stateRef}>
+ <Controller
+ name='state'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={states}
+ placeholder='Provinsi'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.state}
+ </div>
+ )}
+ </div>
+ <div className='w-1/3' ref={cityRef}>
+ <Controller
+ name='city'
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={cities}
+ disabled={!watchState}
+ placeholder='Kota'
+ />
+ )}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.city}
+ </div>
+ )}
+ </div>
+ <div className='w-1/3'>
+ <input
+ id='zip'
+ name='zip'
+ ref={zipRef}
+ placeholder='Kode Pos'
+ type='number'
+ value={form.zip}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.zip}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Isi detail alamat sesuai dengan yang terdaftar
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.street}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label '>No. Telfon Perusahaan</label>
+ <input
+ id='mobile'
+ name='mobile'
+ ref={mobileRef}
+ placeholder='Format: 08123456789 / (021) 123 4567'
+ type='tel'
+ value={form.mobile}
+ className='form-input'
+ aria-invalid={errors.mobile}
+ onChange={handleInputChange}
+ />
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Isi detail perusahaan sesuai dengan nama yang terdaftar
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.mobile}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label'>Data Bank</label>
+ <div className='flex gap-3 flex-row'>
+ <div>
+ <input
+ id='bankName'
+ name='bankName'
+ ref={bankNameRef}
+ placeholder='Nama bank'
+ type='text'
+ value={form.bankName}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+ <div>
+ <input
+ id='accountName'
+ name='accountName'
+ ref={accountNameRef}
+ placeholder='Nama Rekening'
+ type='text'
+ value={form.accountName}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.accountName}
+ </div>
+ )}
+ </div>
+ <div>
+ <input
+ id='accountNumber'
+ name='accountNumber'
+ ref={accountNumberRef}
+ placeholder='Nomor Rekening'
+ type='text'
+ value={form.accountNumber}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.accountNumber}
+ </div>
+ )}
+ </div>
+ </div>
+ {!isKonfirmasi && (
+ <span className='text-xs opacity-60'>
+ Isi data bank perusahaan sesuai dengan yang terdaftar
+ </span>
+ )}
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.bankName}
+ </div>
+ )}
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label '>
+ Website <span className=' opacity-60'>(Opsional)</span>
+ </label>
+ <input
+ id='website'
+ name='website'
+ placeholder='Format: www.indoteknik.com'
+ type='text'
+ value={form.website}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ </div>
+
+ <div className='flex flex-col gap-2 justify-between items-start'>
+ <label className='form-label '>
+ Estimasi Pembelian pertahun
+ </label>
+ <input
+ id='estimasi'
+ name='estimasi'
+ ref={estimasiRef}
+ // {...register('estimasi', {
+ // setValueAs: (value) => value.replace(/^Rp\s*/, ''), // Menyimpan hanya angka
+ // })}
+ placeholder='Isi estimasi pembelian produk pertahun'
+ type='text'
+ className='form-input' // padding untuk memberi ruang untuk "RP"
+ value={formatRupiah(form.estimasi)}
+ onChange={handleChange} // Mengatur perubahan input
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.estimasi}
+ </div>
+ )}
+ </div>
+ <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div>
+ <div className='flex flex-col gap-2 justify-start items-start'>
+ <label className='form-label text-nowrap'>Durasi Tempo</label>
+ <div className='' ref={tempoDurationRef}>
+ <RadioGroup
+ size='sm'
+ onChange={onChangeTempoDuration}
+ value={form.tempoDuration}
+ >
+ <Stack direction='row' className=''>
+ <Radio colorScheme='red' value='7'>
+ 7 Hari
+ </Radio>
+ <Radio colorScheme='red' value='14' className=''>
+ 14 Hari
+ </Radio>
+ <Radio colorScheme='red' value='30' className=''>
+ 30 Hari
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoDuration}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='flex flex-col gap-2 justify-start items-start'>
+ <label className='form-label '>Limit Tempo</label>
+ <div
+ className='flex justify-between items-center '
+ ref={tempoLimitRef}
+ >
+ <RadioGroup
+ size='sm'
+ onChange={(value) => {
+ if (value === 'custom') {
+ setIsCustom(true);
+ updateForm('tempoLimit', tempoLimitValue); // Update dengan nilai input custom jika dipilih
+ } else {
+ setIsCustom(false);
+ onChangeTempoLimit(value); // Update dengan nilai radio button yang dipilih
+ }
+ }}
+ className='flex items-center justify-between'
+ value={isCustom ? 'custom' : form.tempoLimit}
+ >
+ <Stack direction='row'>
+ {/* Kolom 1 */}
+ <Stack direction='row' spacing={2} className='mr-4'>
+ {radioOptions.slice(0, 3).map((option) => (
+ <Radio
+ key={option.value}
+ colorScheme='red'
+ value={option.value}
+ >
+ {option.label}
+ </Radio>
+ ))}
+ <Radio colorScheme='red' value='custom'></Radio>
+
+ <input
+ placeholder='Isi limit'
+ type='text'
+ className='border ml-1 p-1 w-full ' // padding untuk memberi ruang untuk "RP"
+ value={formatRupiah(tempoLimitValueEx)} // Menampilkan nilai terformat
+ onChange={(e) => {
+ const value = e.target.value;
+ const formattedValue = formatRupiah(value);
+ setTempoLimitValueEx(formattedValue);
+ updateForm(
+ 'tempoLimit',
+ formattedValue.replace(/^Rp\s*/, '')
+ ); // Mengupdate nilai di react-hook-form
+ }}
+ />
+ </Stack>
+
+ {/* Kolom 2 */}
+ {/* <Stack direction='column' className='ml-8' spacing={2}>
+ {radioOptions.slice(4).map((option) => (
+ <Radio
+ key={option.value}
+ colorScheme='red'
+ value={option.value}
+ >
+ {option.label}
+ </Radio>
+ ))}
+ <div className='flex flex-row items-center'></div>
+ </Stack> */}
+ </Stack>
+ </RadioGroup>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.tempoLimit}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='text-red-500 text-xs'>
+ **Durasi & Limit dapat berbeda dengan verifikasi oleh tim
+ indoteknik.com
+ </div>
+ <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div>
+ <div className='flex flex-col gap justify-between items-start'>
+ <label className='form-label text-wrap '>
+ Apakah bersedia transaksi via website?
+ </label>
+ <div className='flex gap-x-4' ref={bersediaRef}>
+ <RadioGroup
+ size='sm'
+ onChange={handleCheckboxBersediaChange}
+ value={form.bersedia}
+ >
+ <Stack direction='col'>
+ <Radio colorScheme='red' value='bersedia'>
+ Saya bersedia
+ </Radio>
+ <Radio colorScheme='red' value='tidakBersedia'>
+ Tidak bersedia
+ </Radio>
+ </Stack>
+ </RadioGroup>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.estimasi}
+ </div>
+ )}
+ </div>
+ <div className='h-[2px] bg-gray-300 w-[120%] inset-0 relative transform -translate-x-5'></div>
+
+ <div
+ className={`flex flex-col gap-2 justify-between ${
+ isKonfirmasi ? 'items-start' : 'items-start'
+ }`}
+ >
+ <label className='form-label '>
+ Kategori Produk yang Digunakan
+ </label>
+ <div className='flex flex-col justify-between gap-2 '>
+ <div className='flex flex-col gap-2' ref={categoryProdukRef}>
+ {firstColumn.map((item) => (
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key={item.id}
+ onChange={() => handleCheckboxChange(item.id)}
+ isChecked={isChecked(item.id)}
+ >
+ {item.name}
+ </Checkbox>
+ ))}
+ </div>
+ <div className='flex flex-col gap-2'>
+ {secondColumn.map((item) => (
+ <Checkbox
+ size='sm'
+ colorScheme='red'
+ key={item.id}
+ isChecked={isChecked(item.id)}
+ onChange={() => handleCheckboxChange(item.id)}
+ >
+ {item.name}
+ </Checkbox>
+ ))}
+ </div>
+ </div>
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errors.categoryProduk}
+ </div>
+ )}
+ </div>
+ </div>
+ </form>
+ </div>
+ )}
+ </>
+ );
+};
+
+export default InformasiPerusahaan;
diff --git a/src/pages/pengajuan-tempo/[status].jsx b/src/pages/pengajuan-tempo/[status].jsx
new file mode 100644
index 00000000..1ebf167b
--- /dev/null
+++ b/src/pages/pengajuan-tempo/[status].jsx
@@ -0,0 +1,32 @@
+import BasicLayout from '@/core/components/layouts/BasicLayout';
+import IsAuth from '@/lib/auth/components/IsAuth';
+import FinishTempoComponent from '@/lib/pengajuan-tempo/component/FinishTempo';
+import { useRouter } from 'next/router';
+import axios from 'axios';
+import Seo from '@/core/components/Seo';
+
+export async function getServerSideProps(context) {
+ const { tempo_id } = context.query;
+ // await axios.post(
+ // `${process.env.NEXT_PUBLIC_SELF_HOST}/api/pengajuan-tempo?formId=${tempo_id}`,
+ // {},
+ // { headers: context.req.headers }
+ // );
+ return { props: {} };
+}
+
+export default function Finish() {
+ const router = useRouter();
+
+ return (
+ <>
+ <Seo title='Pengajuan Tempo Indoteknik.com' />
+
+ <IsAuth>
+ <BasicLayout>
+ <FinishTempoComponent query={router.query || {}} />
+ </BasicLayout>
+ </IsAuth>
+ </>
+ );
+}
diff --git a/src/pages/pengajuan-tempo/index.jsx b/src/pages/pengajuan-tempo/index.jsx
new file mode 100644
index 00000000..23d7aaba
--- /dev/null
+++ b/src/pages/pengajuan-tempo/index.jsx
@@ -0,0 +1,29 @@
+import Seo from '@/core/components/Seo';
+import dynamic from 'next/dynamic';
+import SimpleFooter from '@/core/components/elements/Footer/SimpleFooter';
+import BasicLayout from '@/core/components/layouts/BasicLayout';
+import DesktopView from '@/core/components/views/DesktopView';
+import MobileView from '@/core/components/views/MobileView';
+const PagePengajuanTempo = dynamic(() =>
+ import('@/lib/pengajuan-tempo/component/PengajuanTempo')
+);
+
+export default function TrackingOrder() {
+ return (
+ <>
+ <Seo title='Pengajuan Tempo - Indoteknik.com' />
+
+ <DesktopView>
+ <BasicLayout>
+ <PagePengajuanTempo />
+ </BasicLayout>
+ </DesktopView>
+
+ <MobileView>
+ <BasicLayout>
+ <PagePengajuanTempo />
+ </BasicLayout>
+ </MobileView>
+ </>
+ );
+}