mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE-114): enhance form UI by adding required field indicators for multiple inputs
This commit is contained in:
@@ -864,8 +864,24 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
)}
|
)}
|
||||||
<th>Produk</th>
|
<th>
|
||||||
<th>Qty</th>
|
Produk
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Qty
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
{type !== 'detail' && <th>Aksi</th>}
|
{type !== 'detail' && <th>Aksi</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -1032,7 +1048,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
|||||||
{/* Deliveries table */}
|
{/* Deliveries table */}
|
||||||
<div className='card bg-base-100 shadow mb-4'>
|
<div className='card bg-base-100 shadow mb-4'>
|
||||||
<div className='card-body'>
|
<div className='card-body'>
|
||||||
<h2 className='card-title mb-4'>Pengiriman</h2>
|
<h2 className='card-title mb-8'>Pengiriman</h2>
|
||||||
<div className='overflow-x-auto'>
|
<div className='overflow-x-auto'>
|
||||||
<table className='table'>
|
<table className='table'>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -1064,14 +1080,70 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
)}
|
)}
|
||||||
<th>Produk</th>
|
<th>
|
||||||
<th>Qty</th>
|
Produk
|
||||||
<th>Supplier</th>
|
<span
|
||||||
<th>Plat Nomor</th>
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Qty
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Supplier
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Plat Nomor
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
<th>Dokumen</th>
|
<th>Dokumen</th>
|
||||||
<th>Biaya Pengiriman (Rp.)</th>
|
<th>
|
||||||
<th>Biaya Per Item (Rp.)</th>
|
Biaya Pengiriman (Rp.)
|
||||||
<th>Nama Sopir</th>
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Biaya Per Item (Rp.)
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Nama Sopir
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
{type !== 'detail' && <th>Aksi</th>}
|
{type !== 'detail' && <th>Aksi</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
@@ -418,27 +418,96 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
formik.setFieldValue('body_weight', newBodyWeight);
|
formik.setFieldValue('body_weight', newBodyWeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBodyWeightChange =
|
// Handle calculation when chicken_weight changes
|
||||||
(fieldName: string, idx: number) =>
|
const handleChickenWeightChange = useCallback(
|
||||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
(idx: number, value: number) => {
|
||||||
formik.handleChange(e);
|
formik.setFieldValue(`body_weight.${idx}.chicken_weight`, value);
|
||||||
setTimeout(() => {
|
|
||||||
const currentWeight = formik.values.body_weight?.[idx];
|
const currentWeight = formik.values.body_weight?.[idx];
|
||||||
if (currentWeight) {
|
if (currentWeight) {
|
||||||
const newAverage =
|
const chickenCount = currentWeight.chicken_count;
|
||||||
currentWeight.chicken_count > 0
|
if (chickenCount > 0 && value > 0) {
|
||||||
? Math.round(
|
const averageWeight = Math.round(value / chickenCount);
|
||||||
currentWeight.chicken_weight / currentWeight.chicken_count
|
|
||||||
)
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
`body_weight.${idx}.average_chicken_weight`,
|
`body_weight.${idx}.average_chicken_weight`,
|
||||||
newAverage
|
averageWeight
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
formik.setFieldValue(`body_weight.${idx}.average_chicken_weight`, '');
|
||||||
}
|
}
|
||||||
}, 0);
|
}
|
||||||
};
|
},
|
||||||
|
[formik]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handle calculation when chicken_count changes
|
||||||
|
const handleChickenCountChange = useCallback(
|
||||||
|
(idx: number, value: number) => {
|
||||||
|
formik.setFieldValue(`body_weight.${idx}.chicken_count`, value);
|
||||||
|
|
||||||
|
const currentWeight = formik.values.body_weight?.[idx];
|
||||||
|
if (currentWeight) {
|
||||||
|
const chickenWeight = currentWeight.chicken_weight;
|
||||||
|
if (chickenWeight > 0 && value > 0) {
|
||||||
|
const averageWeight = Math.round(chickenWeight / value);
|
||||||
|
formik.setFieldValue(
|
||||||
|
`body_weight.${idx}.average_chicken_weight`,
|
||||||
|
averageWeight
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
formik.setFieldValue(`body_weight.${idx}.average_chicken_weight`, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[formik]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handle calculation when average_weight changes
|
||||||
|
const handleAverageWeightChange = useCallback(
|
||||||
|
(idx: number, value: number) => {
|
||||||
|
formik.setFieldValue(`body_weight.${idx}.average_chicken_weight`, value);
|
||||||
|
|
||||||
|
const currentWeight = formik.values.body_weight?.[idx];
|
||||||
|
if (currentWeight) {
|
||||||
|
const chickenCount = currentWeight.chicken_count;
|
||||||
|
if (chickenCount > 0 && value > 0) {
|
||||||
|
const totalWeight = value * chickenCount;
|
||||||
|
formik.setFieldValue(
|
||||||
|
`body_weight.${idx}.chicken_weight`,
|
||||||
|
totalWeight
|
||||||
|
);
|
||||||
|
} else if (value === 0) {
|
||||||
|
formik.setFieldValue(`body_weight.${idx}.chicken_weight`, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[formik]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create wrapper handlers that match NumberInput's onChange signature
|
||||||
|
const handleChickenWeightChangeWrapper = useCallback(
|
||||||
|
(idx: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const value = parseFloat(e.target.value) || 0;
|
||||||
|
handleChickenWeightChange(idx, value);
|
||||||
|
},
|
||||||
|
[handleChickenWeightChange]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleChickenCountChangeWrapper = useCallback(
|
||||||
|
(idx: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const value = parseFloat(e.target.value) || 0;
|
||||||
|
handleChickenCountChange(idx, value);
|
||||||
|
},
|
||||||
|
[handleChickenCountChange]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleAverageWeightChangeWrapper = useCallback(
|
||||||
|
(idx: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const value = parseFloat(e.target.value) || 0;
|
||||||
|
handleAverageWeightChange(idx, value);
|
||||||
|
},
|
||||||
|
[handleAverageWeightChange]
|
||||||
|
);
|
||||||
|
|
||||||
const removeBodyWeight = (idx: number) => {
|
const removeBodyWeight = (idx: number) => {
|
||||||
const updatedBodyWeight = formik.values.body_weight?.filter(
|
const updatedBodyWeight = formik.values.body_weight?.filter(
|
||||||
@@ -712,9 +781,25 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
)}
|
)}
|
||||||
<th>Nama Pakan</th>
|
<th>
|
||||||
|
Nama Pakan
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
<th>Total Stock pada saat ini</th>
|
<th>Total Stock pada saat ini</th>
|
||||||
<th>Jumlah Stock yang digunakan</th>
|
<th>
|
||||||
|
Jumlah Stock yang digunakan
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
{type !== 'detail' && <th>Action</th>}
|
{type !== 'detail' && <th>Action</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -945,9 +1030,33 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
)}
|
)}
|
||||||
<th>Berat (Gram)</th>
|
<th>
|
||||||
<th>Jumlah Ayam</th>
|
Berat (Gram)
|
||||||
<th>Rata-rata berat Ayam</th>
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Jumlah Ayam
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Rata-rata berat Ayam
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
{type !== 'detail' && <th>Action</th>}
|
{type !== 'detail' && <th>Action</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -981,10 +1090,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
required
|
required
|
||||||
name={`body_weight.${idx}.chicken_weight`}
|
name={`body_weight.${idx}.chicken_weight`}
|
||||||
value={weight.chicken_weight}
|
value={weight.chicken_weight}
|
||||||
onChange={handleBodyWeightChange(
|
onChange={handleChickenWeightChangeWrapper(idx)}
|
||||||
'chicken_weight',
|
|
||||||
idx
|
|
||||||
)}
|
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
maskType='weight'
|
maskType='weight'
|
||||||
weightUnit='gram'
|
weightUnit='gram'
|
||||||
@@ -1015,10 +1121,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
required
|
required
|
||||||
name={`body_weight.${idx}.chicken_count`}
|
name={`body_weight.${idx}.chicken_count`}
|
||||||
value={weight.chicken_count}
|
value={weight.chicken_count}
|
||||||
onChange={handleBodyWeightChange(
|
onChange={handleChickenCountChangeWrapper(idx)}
|
||||||
'chicken_count',
|
|
||||||
idx
|
|
||||||
)}
|
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
maskType='number'
|
maskType='number'
|
||||||
decimals={0}
|
decimals={0}
|
||||||
@@ -1048,15 +1151,8 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
<NumberInput
|
<NumberInput
|
||||||
required
|
required
|
||||||
name={`body_weight.${idx}.average_chicken_weight`}
|
name={`body_weight.${idx}.average_chicken_weight`}
|
||||||
value={
|
value={weight.average_chicken_weight || ''}
|
||||||
weight.chicken_count > 0
|
onChange={handleAverageWeightChangeWrapper(idx)}
|
||||||
? Math.round(
|
|
||||||
weight.chicken_weight /
|
|
||||||
weight.chicken_count
|
|
||||||
)
|
|
||||||
: 0
|
|
||||||
}
|
|
||||||
onChange={formik.handleChange}
|
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
maskType='weight'
|
maskType='weight'
|
||||||
weightUnit='gram'
|
weightUnit='gram'
|
||||||
@@ -1076,12 +1172,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
idx
|
idx
|
||||||
).errorMessage
|
).errorMessage
|
||||||
}
|
}
|
||||||
readOnly={true}
|
readOnly={type === 'detail'}
|
||||||
disabled={true}
|
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full min-w-24',
|
wrapper: 'w-full min-w-24',
|
||||||
}}
|
}}
|
||||||
placeholder='0'
|
placeholder=''
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@@ -1175,9 +1270,25 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
)}
|
)}
|
||||||
<th>Name Vaksin</th>
|
<th>
|
||||||
|
Name Vaksin
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
<th>Total Stock pada saat ini</th>
|
<th>Total Stock pada saat ini</th>
|
||||||
<th>Jumlah Stock yang digunakan</th>
|
<th>
|
||||||
|
Jumlah Stock yang digunakan
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
{type !== 'detail' && <th>Action</th>}
|
{type !== 'detail' && <th>Action</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -1418,8 +1529,24 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
)}
|
)}
|
||||||
<th>Kondisi/Alasan Mortalitas</th>
|
<th>
|
||||||
<th>Jumlah</th>
|
Kondisi/Alasan Mortalitas
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Jumlah
|
||||||
|
<span
|
||||||
|
className='tooltip tooltip-error tooltip-bottom z-[9999]'
|
||||||
|
data-tip='required'
|
||||||
|
>
|
||||||
|
<span className='text-error'>*</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
{type !== 'detail' && <th>Action</th>}
|
{type !== 'detail' && <th>Action</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user