refactor(FE-114): streamline cost field validation messages and enhance layout with FieldMessage component

This commit is contained in:
rstubryan
2025-10-20 18:54:31 +07:00
parent 1bcfd9bbb4
commit e0ce571000
2 changed files with 85 additions and 79 deletions
@@ -61,32 +61,24 @@ const DeliveryObjectSchema: Yup.ObjectSchema<DeliverySchema> = Yup.object({
.transform((value) => (isNaN(value) || value === 0 ? undefined : value))
.min(1, 'Biaya minimal 1!')
.typeError('Biaya harus berupa angka!')
.test(
'one-of-cost-fields',
'Biaya pengiriman atau biaya per item wajib diisi!',
function (value) {
.test('one-of-cost-fields', 'Wajib diisi salah satu!', function (value) {
const { delivery_cost_per_item } = this.parent;
return (
(value !== undefined && value > 0) ||
(delivery_cost_per_item !== undefined && delivery_cost_per_item > 0)
);
}
),
}),
delivery_cost_per_item: Yup.number()
.transform((value) => (isNaN(value) || value === 0 ? undefined : value))
.min(1, 'Biaya per item minimal 1!')
.typeError('Biaya per item harus berupa angka!')
.test(
'one-of-cost-fields',
'Biaya pengiriman atau biaya per item wajib diisi!',
function (value) {
.test('one-of-cost-fields', 'Wajib diisi salah satu!', function (value) {
const { delivery_cost } = this.parent;
return (
(value !== undefined && value > 0) ||
(delivery_cost !== undefined && delivery_cost > 0)
);
}
),
}),
document_path: Yup.string().optional(),
document_index: Yup.number().optional(),
document: Yup.mixed<File | string>()
@@ -8,7 +8,6 @@ import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import TextInput from '@/components/input/TextInput';
import SelectInput, { OptionType } from '@/components/input/SelectInput';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import { FormHeader } from '@/components/helper/form/FormHeader';
import { FormActions } from '@/components/helper/form/FormActions';
import {
@@ -29,6 +28,7 @@ import { SupplierApi, WarehouseApi } from '@/services/api/master-data';
import { ProductWarehouseApi } from '@/services/api/inventory';
import { toast } from 'react-hot-toast';
import FileInput from '@/components/input/FileInput';
import FieldMessage from '@/components/helper/FieldMessage';
interface MovementFormProps {
type?: 'add' | 'edit' | 'detail';
@@ -863,6 +863,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
<tr key={`product-row-${idx}-${product.product_id}`}>
{type !== 'detail' && (
<td>
<div className='flex flex-col items-start gap-2'>
<input
type='checkbox'
className='checkbox'
@@ -880,6 +881,8 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
}
}}
/>
<FieldMessage message={null} isVisible={false} />
</div>
</td>
)}
<td>
@@ -954,6 +957,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
</td>
{type !== 'detail' && (
<td>
<div className='flex flex-col items-start gap-2'>
<Button
type='button'
color='error'
@@ -965,6 +969,8 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
height={24}
/>
</Button>
<FieldMessage message={null} isVisible={false} />
</div>
</td>
)}
</tr>
@@ -1051,6 +1057,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
<tr key={`delivery-row-${idx}`}>
{type !== 'detail' && (
<td>
<div className='flex flex-col items-start gap-2'>
<input
type='checkbox'
className='checkbox'
@@ -1063,11 +1070,15 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
]);
} else {
setSelectedDeliveries(
selectedDeliveries.filter((i) => i !== idx)
selectedDeliveries.filter(
(i) => i !== idx
)
);
}
}}
/>
<FieldMessage message={null} isVisible={false} />
</div>
</td>
)}
<td>
@@ -1267,6 +1278,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
</td>
{type !== 'detail' && (
<td>
<div className='flex flex-col items-start gap-2'>
<Button
type='button'
color='error'
@@ -1278,6 +1290,8 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
height={24}
/>
</Button>
<FieldMessage message={null} isVisible={false} />
</div>
</td>
)}
</tr>