mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 07:45:47 +00:00
feat(FE): Add 5MB file size check and show form errors
This commit is contained in:
@@ -75,7 +75,16 @@ export const ExpenseRequestFormSchema: Yup.ObjectSchema<ExpenseFormSchemaType> =
|
|||||||
|
|
||||||
deleted_documents: Yup.array().of(Yup.number().required()).optional(),
|
deleted_documents: Yup.array().of(Yup.number().required()).optional(),
|
||||||
|
|
||||||
documents: Yup.array().of(Yup.mixed<File>().required()).optional(),
|
documents: Yup.array()
|
||||||
|
.of(
|
||||||
|
Yup.mixed<File>()
|
||||||
|
.required()
|
||||||
|
.test('fileSize', 'Ukuran dokumen maksimal 5 MB', (value) => {
|
||||||
|
if (!value || !(value instanceof File)) return true;
|
||||||
|
return value.size <= 5 * 1024 * 1024;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
|
|
||||||
expense_nonstocks: Yup.array()
|
expense_nonstocks: Yup.array()
|
||||||
.of(
|
.of(
|
||||||
@@ -104,7 +113,16 @@ export const ExpenseRequestFormSchema: Yup.ObjectSchema<ExpenseFormSchemaType> =
|
|||||||
export const UpdateExpenseRequestFormSchema = ExpenseRequestFormSchema;
|
export const UpdateExpenseRequestFormSchema = ExpenseRequestFormSchema;
|
||||||
|
|
||||||
export const UploadRequestDocumentsFormSchema = Yup.object({
|
export const UploadRequestDocumentsFormSchema = Yup.object({
|
||||||
documents: Yup.array().of(Yup.mixed<File>().required()).required(),
|
documents: Yup.array()
|
||||||
|
.of(
|
||||||
|
Yup.mixed<File>()
|
||||||
|
.required()
|
||||||
|
.test('fileSize', 'Ukuran dokumen maksimal 5 MB', (value) => {
|
||||||
|
if (!value || !(value instanceof File)) return true;
|
||||||
|
return value.size <= 5 * 1024 * 1024;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.required(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ExpenseRequestFormValues = Yup.InferType<
|
export type ExpenseRequestFormValues = Yup.InferType<
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ import { cn, sleep } from '@/lib/helper';
|
|||||||
import { LocationApi, SupplierApi } from '@/services/api/master-data';
|
import { LocationApi, SupplierApi } from '@/services/api/master-data';
|
||||||
import { ACCEPTED_FILE_TYPE } from '@/config/constant';
|
import { ACCEPTED_FILE_TYPE } from '@/config/constant';
|
||||||
import { Supplier } from '@/types/api/master-data/supplier';
|
import { Supplier } from '@/types/api/master-data/supplier';
|
||||||
|
import { getUniqueFormikErrors } from '@/lib/formik-helper';
|
||||||
|
import AlertErrorList from '@/components/helper/form/FormErrors';
|
||||||
|
|
||||||
interface ExpenseFormProps {
|
interface ExpenseFormProps {
|
||||||
type?: 'add' | 'edit' | 'detail';
|
type?: 'add' | 'edit' | 'detail';
|
||||||
@@ -55,6 +57,7 @@ const ExpenseRequestForm = ({
|
|||||||
const rejectModal = useModal();
|
const rejectModal = useModal();
|
||||||
|
|
||||||
const [expenseFormErrorMessage, setExpenseFormErrorMessage] = useState('');
|
const [expenseFormErrorMessage, setExpenseFormErrorMessage] = useState('');
|
||||||
|
const [formErrorList, setFormErrorList] = useState<string[]>([]);
|
||||||
|
|
||||||
const createExpenseHandler = useCallback(
|
const createExpenseHandler = useCallback(
|
||||||
async (payload: CreateExpensePayload) => {
|
async (payload: CreateExpensePayload) => {
|
||||||
@@ -322,6 +325,22 @@ const ExpenseRequestForm = ({
|
|||||||
router.push('/expense');
|
router.push('/expense');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
formikSetValues(getExpenseFormInitialValues(initialValues));
|
formikSetValues(getExpenseFormInitialValues(initialValues));
|
||||||
}, [formikSetValues, getExpenseFormInitialValues, initialValues]);
|
}, [formikSetValues, getExpenseFormInitialValues, initialValues]);
|
||||||
@@ -347,10 +366,27 @@ const ExpenseRequestForm = ({
|
|||||||
</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'
|
||||||
>
|
>
|
||||||
|
{expenseFormErrorMessage && (
|
||||||
|
<div role='alert' className='alert alert-error'>
|
||||||
|
<Icon
|
||||||
|
icon='material-symbols:error-outline'
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
<span>{expenseFormErrorMessage}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{formErrorList.length > 0 && (
|
||||||
|
<AlertErrorList
|
||||||
|
formErrorList={formErrorList}
|
||||||
|
onClose={() => setFormErrorList([])}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<div className='grid grid-cols-12 gap-4'>
|
<div className='grid grid-cols-12 gap-4'>
|
||||||
<SelectInput
|
<SelectInput
|
||||||
label='Kategori'
|
label='Kategori'
|
||||||
@@ -535,17 +571,6 @@ const ExpenseRequestForm = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{expenseFormErrorMessage && (
|
|
||||||
<div role='alert' className='alert alert-error w-full'>
|
|
||||||
<Icon
|
|
||||||
icon='material-symbols:error-outline'
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
/>
|
|
||||||
<span>{expenseFormErrorMessage}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{type !== 'detail' && (
|
{type !== 'detail' && (
|
||||||
<div
|
<div
|
||||||
className={cn('flex flex-row justify-end gap-2', {
|
className={cn('flex flex-row justify-end gap-2', {
|
||||||
|
|||||||
Reference in New Issue
Block a user