mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE): Display form error list in purchase forms
This commit is contained in:
@@ -14,6 +14,7 @@ import SelectInput, {
|
|||||||
useSelect,
|
useSelect,
|
||||||
} from '@/components/input/SelectInput';
|
} from '@/components/input/SelectInput';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
import AlertErrorList from '@/components/helper/form/FormErrors';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PurchaseRequestAcceptApprovalFormDefaultValues,
|
PurchaseRequestAcceptApprovalFormDefaultValues,
|
||||||
@@ -28,6 +29,7 @@ import {
|
|||||||
} from '@/types/api/purchase/purchase';
|
} from '@/types/api/purchase/purchase';
|
||||||
import DateInput from '@/components/input/DateInput';
|
import DateInput from '@/components/input/DateInput';
|
||||||
import { formatNumber } from '@/lib/helper';
|
import { formatNumber } from '@/lib/helper';
|
||||||
|
import { getUniqueFormikErrors } from '@/lib/formik-helper';
|
||||||
import { Supplier } from '@/types/api/master-data/supplier';
|
import { Supplier } from '@/types/api/master-data/supplier';
|
||||||
import { SupplierApi } from '@/services/api/master-data';
|
import { SupplierApi } from '@/services/api/master-data';
|
||||||
|
|
||||||
@@ -52,6 +54,7 @@ const PurchaseOrderAcceptApprovalForm = ({
|
|||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const [purchaseOrderFormErrorMessage, setPurchaseOrderFormErrorMessage] =
|
const [purchaseOrderFormErrorMessage, setPurchaseOrderFormErrorMessage] =
|
||||||
useState('');
|
useState('');
|
||||||
|
const [formErrorList, setFormErrorList] = useState<string[]>([]);
|
||||||
const [key, setKey] = useState(0);
|
const [key, setKey] = useState(0);
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
@@ -209,6 +212,22 @@ const PurchaseOrderAcceptApprovalForm = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleValidateForm = async () => {
|
||||||
|
const errors = await formik.validateForm();
|
||||||
|
|
||||||
|
if (Object.keys(errors).length > 0) {
|
||||||
|
const errorMessages = getUniqueFormikErrors(errors);
|
||||||
|
setFormErrorList(errorMessages);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleValidateForm();
|
||||||
|
formik.handleSubmit(e);
|
||||||
|
};
|
||||||
|
|
||||||
// ===== API DATA FETCHING =====
|
// ===== API DATA FETCHING =====
|
||||||
const purchaseItems = useMemo(() => {
|
const purchaseItems = useMemo(() => {
|
||||||
if (initialValues?.items) {
|
if (initialValues?.items) {
|
||||||
@@ -336,7 +355,7 @@ const PurchaseOrderAcceptApprovalForm = ({
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
key={key}
|
key={key}
|
||||||
onSubmit={formik.handleSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
className='w-full flex flex-col gap-6'
|
className='w-full flex flex-col gap-6'
|
||||||
>
|
>
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
@@ -355,6 +374,15 @@ const PurchaseOrderAcceptApprovalForm = ({
|
|||||||
<span>{purchaseOrderFormErrorMessage}</span>
|
<span>{purchaseOrderFormErrorMessage}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Error List Alert */}
|
||||||
|
{formErrorList.length > 0 && (
|
||||||
|
<AlertErrorList
|
||||||
|
formErrorList={formErrorList}
|
||||||
|
onClose={() => setFormErrorList([])}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className='overflow-x-auto'>
|
<div className='overflow-x-auto'>
|
||||||
<table className='table'>
|
<table className='table'>
|
||||||
<thead>
|
<thead>
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ import NumberInput from '@/components/input/NumberInput';
|
|||||||
import SelectInput, { OptionType } from '@/components/input/SelectInput';
|
import SelectInput, { OptionType } from '@/components/input/SelectInput';
|
||||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||||
import { useModal } from '@/components/Modal';
|
import { useModal } from '@/components/Modal';
|
||||||
|
import AlertErrorList from '@/components/helper/form/FormErrors';
|
||||||
import { SupplierApi } from '@/services/api/master-data';
|
import { SupplierApi } from '@/services/api/master-data';
|
||||||
import { SupplierProducts } from '@/types/api/master-data/supplier';
|
import { SupplierProducts } from '@/types/api/master-data/supplier';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
|
|
||||||
|
import { getUniqueFormikErrors } from '@/lib/formik-helper';
|
||||||
import {
|
import {
|
||||||
PurchaseRequestStaffApprovalFormDefaultValues,
|
PurchaseRequestStaffApprovalFormDefaultValues,
|
||||||
PurchaseRequestStaffApprovalFormInitialValues,
|
PurchaseRequestStaffApprovalFormInitialValues,
|
||||||
@@ -87,6 +89,7 @@ const PurchaseOrderStaffApprovalForm = ({
|
|||||||
const deleteModal = useModal();
|
const deleteModal = useModal();
|
||||||
const [purchaseOrderFormErrorMessage, setPurchaseOrderFormErrorMessage] =
|
const [purchaseOrderFormErrorMessage, setPurchaseOrderFormErrorMessage] =
|
||||||
useState('');
|
useState('');
|
||||||
|
const [formErrorList, setFormErrorList] = useState<string[]>([]);
|
||||||
const [selectedItemForDelete, setSelectedItemForDelete] = useState<
|
const [selectedItemForDelete, setSelectedItemForDelete] = useState<
|
||||||
number | null
|
number | null
|
||||||
>(null);
|
>(null);
|
||||||
@@ -415,6 +418,22 @@ const PurchaseOrderStaffApprovalForm = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleValidateForm = async () => {
|
||||||
|
const errors = await formik.validateForm();
|
||||||
|
|
||||||
|
if (Object.keys(errors).length > 0) {
|
||||||
|
const errorMessages = getUniqueFormikErrors(errors);
|
||||||
|
setFormErrorList(errorMessages);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleValidateForm();
|
||||||
|
formik.handleSubmit(e);
|
||||||
|
};
|
||||||
|
|
||||||
const supplierProductOptions = baseSupplierProductOptions;
|
const supplierProductOptions = baseSupplierProductOptions;
|
||||||
|
|
||||||
// ===== API DATA FETCHING =====
|
// ===== API DATA FETCHING =====
|
||||||
@@ -652,10 +671,7 @@ const PurchaseOrderStaffApprovalForm = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<form
|
<form onSubmit={handleFormSubmit} className='w-full flex flex-col gap-6'>
|
||||||
onSubmit={formik.handleSubmit}
|
|
||||||
className='w-full flex flex-col gap-6'
|
|
||||||
>
|
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
<h2 className='text-lg font-semibold mb-4'>
|
<h2 className='text-lg font-semibold mb-4'>
|
||||||
{type === 'add'
|
{type === 'add'
|
||||||
@@ -672,6 +688,15 @@ const PurchaseOrderStaffApprovalForm = ({
|
|||||||
<span>{purchaseOrderFormErrorMessage}</span>
|
<span>{purchaseOrderFormErrorMessage}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Error List Alert */}
|
||||||
|
{formErrorList.length > 0 && (
|
||||||
|
<AlertErrorList
|
||||||
|
formErrorList={formErrorList}
|
||||||
|
onClose={() => setFormErrorList([])}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className='overflow-x-auto'>
|
<div className='overflow-x-auto'>
|
||||||
{groupedPurchaseItems.length > 0 ? (
|
{groupedPurchaseItems.length > 0 ? (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import SelectInput, {
|
|||||||
} from '@/components/input/SelectInput';
|
} from '@/components/input/SelectInput';
|
||||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||||
import { useModal } from '@/components/Modal';
|
import { useModal } from '@/components/Modal';
|
||||||
|
import AlertErrorList from '@/components/helper/form/FormErrors';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PurchaseRequestFormSchema,
|
PurchaseRequestFormSchema,
|
||||||
@@ -32,6 +33,7 @@ import {
|
|||||||
import { Supplier, SupplierProducts } from '@/types/api/master-data/supplier';
|
import { Supplier, SupplierProducts } from '@/types/api/master-data/supplier';
|
||||||
import { isResponseSuccess, isResponseError } from '@/lib/api-helper';
|
import { isResponseSuccess, isResponseError } from '@/lib/api-helper';
|
||||||
import { formatNumber } from '@/lib/helper';
|
import { formatNumber } from '@/lib/helper';
|
||||||
|
import { getUniqueFormikErrors } from '@/lib/formik-helper';
|
||||||
import { PurchaseApi } from '@/services/api/purchase';
|
import { PurchaseApi } from '@/services/api/purchase';
|
||||||
|
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
@@ -59,6 +61,7 @@ const PurchaseRequestForm = ({
|
|||||||
);
|
);
|
||||||
const [purchaseRequestFormErrorMessage, setPurchaseRequestFormErrorMessage] =
|
const [purchaseRequestFormErrorMessage, setPurchaseRequestFormErrorMessage] =
|
||||||
useState('');
|
useState('');
|
||||||
|
const [formErrorList, setFormErrorList] = useState<string[]>([]);
|
||||||
|
|
||||||
// ===== TYPE DEFINITIONS =====
|
// ===== TYPE DEFINITIONS =====
|
||||||
interface ProductOptionType {
|
interface ProductOptionType {
|
||||||
@@ -211,6 +214,22 @@ const PurchaseRequestForm = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleValidateForm = async () => {
|
||||||
|
const errors = await formik.validateForm();
|
||||||
|
|
||||||
|
if (Object.keys(errors).length > 0) {
|
||||||
|
const errorMessages = getUniqueFormikErrors(errors);
|
||||||
|
setFormErrorList(errorMessages);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
handleValidateForm();
|
||||||
|
formik.handleSubmit(e);
|
||||||
|
};
|
||||||
|
|
||||||
// ===== API DATA FETCHING =====
|
// ===== API DATA FETCHING =====
|
||||||
const { data: supplierData, isLoading: isLoadingProducts } = useSWR(
|
const { data: supplierData, isLoading: isLoadingProducts } = useSWR(
|
||||||
formik.values.supplier_id && Number(formik.values.supplier_id) > 0
|
formik.values.supplier_id && Number(formik.values.supplier_id) > 0
|
||||||
@@ -487,7 +506,7 @@ const PurchaseRequestForm = ({
|
|||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
<form
|
<form
|
||||||
onSubmit={formik.handleSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
onReset={formik.handleReset}
|
onReset={formik.handleReset}
|
||||||
className='w-full mt-8 flex flex-col gap-6'
|
className='w-full mt-8 flex flex-col gap-6'
|
||||||
>
|
>
|
||||||
@@ -501,6 +520,15 @@ const PurchaseRequestForm = ({
|
|||||||
<span>{purchaseRequestFormErrorMessage}</span>
|
<span>{purchaseRequestFormErrorMessage}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Error List Alert */}
|
||||||
|
{formErrorList.length > 0 && (
|
||||||
|
<AlertErrorList
|
||||||
|
formErrorList={formErrorList}
|
||||||
|
onClose={() => setFormErrorList([])}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Basic Info Card */}
|
{/* Basic Info Card */}
|
||||||
<Card
|
<Card
|
||||||
title='Informasi Purchase Request'
|
title='Informasi Purchase Request'
|
||||||
|
|||||||
Reference in New Issue
Block a user