summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2024-10-18 17:08:55 +0700
committerit-fixcomart <it@fixcomart.co.id>2024-10-18 17:08:55 +0700
commit548e2b48b1c2f6521037765f96083a8d79f611d6 (patch)
treeb2b1d8d924ec973d683e8fb0157b302bc7b037de
parent87ffd2fa7edc240693ddd81401ef23c5cd1bbb3e (diff)
<iman> add pengiriman section
-rw-r--r--src-migrate/modules/register/stores/usePengajuanTempoStore.ts71
-rw-r--r--src-migrate/types/tempo.ts13
-rw-r--r--src-migrate/validations/tempo.ts9
-rw-r--r--src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx4
-rw-r--r--src/lib/pengajuan-tempo/component/PengajuanTempo.jsx6
-rw-r--r--src/lib/pengajuan-tempo/component/Pengiriman.jsx604
6 files changed, 701 insertions, 6 deletions
diff --git a/src-migrate/modules/register/stores/usePengajuanTempoStore.ts b/src-migrate/modules/register/stores/usePengajuanTempoStore.ts
index 7f1bcbb0..0d397c78 100644
--- a/src-migrate/modules/register/stores/usePengajuanTempoStore.ts
+++ b/src-migrate/modules/register/stores/usePengajuanTempoStore.ts
@@ -1,6 +1,14 @@
import { create } from 'zustand';
-import { TempoProps, TempoPropsKontakPerson } from '~/types/tempo';
-import { TempoSchema, TempoSchemaKontakPerson } from '~/validations/tempo';
+import {
+ TempoProps,
+ TempoPropsKontakPerson,
+ TempoPropsPengiriman,
+} from '~/types/tempo';
+import {
+ TempoSchema,
+ TempoSchemaKontakPerson,
+ TempoSchemaPengiriman,
+} from '~/validations/tempo';
import { boolean, ZodError } from 'zod';
type State = {
@@ -156,3 +164,62 @@ export const usePengajuanTempoStoreKontakPerson = create<
},
}),
}));
+
+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: '',
+ zip: '',
+ invoicePic: '',
+ },
+ 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: '',
+ zip: '',
+ invoicePic: '',
+ },
+ }),
+}));
diff --git a/src-migrate/types/tempo.ts b/src-migrate/types/tempo.ts
index 85680cba..6e3f2502 100644
--- a/src-migrate/types/tempo.ts
+++ b/src-migrate/types/tempo.ts
@@ -1,4 +1,8 @@
-import { TempoSchema, TempoSchemaKontakPerson } from '~/validations/tempo';
+import {
+ TempoSchema,
+ TempoSchemaKontakPerson,
+ TempoSchemaPengiriman,
+} from '~/validations/tempo';
import { OdooApiRes } from './odoo';
import { z } from 'zod';
@@ -29,11 +33,18 @@ export type tempoPropsKontakPerson = {
financeName: string;
purchasingMobile: string;
};
+export type tempoPropsPengiriman = {
+ PICName: string;
+ streetPengiriman: string;
+ statePengiriman: string;
+ cityPengiriman: 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 TempoResApiProps = {
Tempo: boolean;
diff --git a/src-migrate/validations/tempo.ts b/src-migrate/validations/tempo.ts
index 756bb722..7adfa780 100644
--- a/src-migrate/validations/tempo.ts
+++ b/src-migrate/validations/tempo.ts
@@ -26,6 +26,7 @@ export const TempoSchema = z.object({
.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' }),
@@ -61,3 +62,11 @@ export const TempoSchemaKontakPerson = z.object({
.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' }),
+ zip: z.string().min(1, { message: 'Kode pos harus diisi' }),
+ invoicePic: z.string().min(1, { message: 'Nama pic invoice harus diisi' }),
+});
diff --git a/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx b/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx
index 861a75ba..c09aaf57 100644
--- a/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx
+++ b/src/lib/pengajuan-tempo/component/KontakPerusahaan.jsx
@@ -86,6 +86,10 @@ const KontakPerusahaan = ({ chekValid, buttonSubmitClick }) => {
};
loadIndustries();
}, [buttonSubmitClick, chekValid]);
+
+ useEffect(() => {
+ validateKontakPerson();
+ }, [buttonSubmitClick]);
return (
<>
<div className='flex justify-start'>
diff --git a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx
index 14ea1805..257648ca 100644
--- a/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx
+++ b/src/lib/pengajuan-tempo/component/PengajuanTempo.jsx
@@ -3,6 +3,7 @@ import { useMemo, useState, useEffect, useRef } from 'react';
import Stepper from './Stepper';
import InformasiPerusahaan from './informasiPerusahaan';
import KontakPerusahaan from './KontakPerusahaan';
+import Pengiriman from './Pengiriman';
import { Controller, useForm } from 'react-hook-form';
import {
usePengajuanTempoStore,
@@ -31,8 +32,7 @@ const PengajuanTempo = () => {
chekValid={notValid}
buttonSubmitClick={buttonSubmitClick}
/>,
- <div>Kontak Person</div>,
- <div>Pengiriman</div>,
+ <Pengiriman chekValid={notValid} buttonSubmitClick={buttonSubmitClick} />,
<div>Referensi</div>,
<div>Dokumen</div>,
<div>Konfirmasi</div>,
@@ -85,7 +85,7 @@ const PengajuanTempo = () => {
top: 0,
behavior: 'smooth',
});
- }, [currentStep]);
+ }, [currentStep, buttonSubmitClick]);
useEffect(() => {
const cachedData = getFromLocalStorage(stepLabels[currentStep]);
diff --git a/src/lib/pengajuan-tempo/component/Pengiriman.jsx b/src/lib/pengajuan-tempo/component/Pengiriman.jsx
new file mode 100644
index 00000000..91772c7f
--- /dev/null
+++ b/src/lib/pengajuan-tempo/component/Pengiriman.jsx
@@ -0,0 +1,604 @@
+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';
+const Pengiriman = ({ chekValid, buttonSubmitClick }) => {
+ const { control, watch } = useForm();
+ const {
+ formPengiriman,
+ errorsPengiriman,
+ validatePengiriman,
+ updateFormPengiriman,
+ } = usePengajuanTempoStorePengiriman();
+ const [states, setState] = useState([]);
+ const [cities, setCities] = useState([]);
+ const [sameAddress, setSameAddress] = useState(false);
+
+ 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(() => {
+ updateFormPengiriman('city', '');
+ if (watchState) {
+ updateFormPengiriman('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 handleInputChange = (event) => {
+ const { name, value } = event.target;
+ updateFormPengiriman(name, value);
+ validatePengiriman();
+ };
+
+ 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 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 (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.direkturEmail && direkturEmailRef.current) {
+ direkturEmailRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.purchasingName && purchasingNameRef.current) {
+ purchasingNameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.purchasingMobile && purchasingMobileRef.current) {
+ purchasingMobileRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.purchasingEmail && purchasingEmailRef.current) {
+ purchasingEmailRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.financeName && financeNameRef.current) {
+ financeNameRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.financeMobile && financeMobileRef.current) {
+ financeMobileRef.current.scrollIntoView(options);
+ return;
+ }
+ if (errorsPengiriman.financeEmail && financeEmailRef.current) {
+ financeEmailRef.current.scrollIntoView(options);
+ return;
+ }
+ }
+ };
+ loadIndustries();
+ }, [buttonSubmitClick, chekValid]);
+
+ useEffect(() => {
+ validatePengiriman();
+ }, [buttonSubmitClick]);
+ useEffect(() => {
+ if (sameAddress) {
+ updateFormPengiriman('streetPengiriman', formPengiriman.streetPengiriman);
+ updateFormPengiriman('statePengiriman', formPengiriman.statePengiriman);
+ updateFormPengiriman('cityPengiriman', formPengiriman.cityPengiriman);
+ updateFormPengiriman('zip', formPengiriman.zip);
+ }
+ }, [sameAddress]);
+ return (
+ <>
+ <div className='flex justify-start'>
+ <h1 className='font-bold'>Pengiriman</h1>
+ </div>
+ <form className='flex mt-4 flex-col w-full '>
+ <div className='w-full grid grid-row-2 gap-5'>
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 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>
+ <label className='form-label w-2/5 text-nowrap'>
+ Alamat Pengiriman Barang
+ </label>
+ <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='zip'
+ name='zip'
+ ref={zipRef}
+ placeholder='Kode Pos'
+ type='number'
+ value={formPengiriman.zip}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.zip}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 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>
+ <label className='form-label w-2/5 text-nowrap'>
+ Alamat Pengiriman Invoice
+ </label>
+ <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={() => setSameAddress(!sameAddress)}
+ >
+ Alamat invoice sama dengan alamat pengiriman
+ </Checkbox>
+ </div>
+ {!sameAddress && (
+ <>
+ <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='zip'
+ name='zip'
+ ref={zipRef}
+ placeholder='Kode Pos'
+ type='number'
+ value={formPengiriman.zip}
+ className='form-input'
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.zip}
+ </div>
+ )}
+ </div>
+ </div>
+ </>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 text-nowrap'>
+ Email Direktur
+ </label>
+ <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={formPengiriman.direkturEmail}
+ className='form-input'
+ aria-invalid={errorsPengiriman.direkturEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.direkturEmail}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 text-nowrap'>
+ Nama Purchasing
+ </label>
+ <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={formPengiriman.purchasingName}
+ type='text'
+ className='form-input'
+ aria-invalid={errorsPengiriman.purchasingName}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.purchasingName}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 text-nowrap'>
+ No. Telpon Purchasing
+ </label>
+ <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={formPengiriman.purchasingMobile}
+ type='tel'
+ className='form-input'
+ aria-invalid={errorsPengiriman.purchasingMobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.purchasingMobile}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 text-nowrap'>
+ Email Purchasing
+ </label>
+ <span className='text-xs opacity-60'>
+ isi email purchasing benar
+ </span>
+ </div>
+ <div className='w-3/5'>
+ <input
+ id='purchasingEmail'
+ name='purchasingEmail'
+ ref={purchasingEmailRef}
+ placeholder='contoh@email.com'
+ value={formPengiriman.purchasingEmail}
+ type='email'
+ className='form-input'
+ aria-invalid={errorsPengiriman.purchasingEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.purchasingEmail}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 text-nowrap'>
+ Nama Finance
+ </label>
+ <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={formPengiriman.financeName}
+ type='text'
+ className='form-input'
+ aria-invalid={errorsPengiriman.financeName}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.financeName}
+ </div>
+ )}
+ </div>
+ </div>
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 text-nowrap'>
+ No. Telpon Finance
+ </label>
+ <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={formPengiriman.financeMobile}
+ type='tel'
+ className='form-input'
+ aria-invalid={errorsPengiriman.financeMobile}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.financeMobile}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div className='flex flex-row justify-between items-start'>
+ <div>
+ <label className='form-label w-2/5 text-nowrap'>
+ Email Finance
+ </label>
+ <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={formPengiriman.financeEmail}
+ className='form-input'
+ aria-invalid={errorsPengiriman.financeEmail}
+ onChange={handleInputChange}
+ />
+ {chekValid && (
+ <div className='text-caption-2 text-danger-500 mt-1'>
+ {errorsPengiriman.financeEmail}
+ </div>
+ )}
+ </div>
+ </div>
+ </div>
+ </form>
+ </>
+ );
+};
+
+export default Pengiriman;