mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE-Storyless): streamline RecordingForm component by native card and optimizing layout for better usability
This commit is contained in:
@@ -32,6 +32,7 @@ import { MovementApi } from '@/services/api/inventory';
|
||||
import FileInput from '@/components/input/FileInput';
|
||||
import CheckboxInput from '@/components/input/CheckboxInput';
|
||||
import Badge from '@/components/Badge';
|
||||
import Card from '@/components/Card';
|
||||
|
||||
interface MovementFormProps {
|
||||
type?: 'add' | 'edit' | 'detail';
|
||||
@@ -768,8 +769,13 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
className='w-full mt-8 flex flex-col gap-6'
|
||||
>
|
||||
{/* Top card - Movement details */}
|
||||
<div className='card bg-base-100 shadow mb-4'>
|
||||
<div className='card-body'>
|
||||
<Card
|
||||
title='Detail Movement'
|
||||
className={{
|
||||
wrapper: 'w-full mb-4 shadow',
|
||||
body: 'flex flex-col gap-6',
|
||||
}}
|
||||
>
|
||||
<div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
|
||||
<TextInput
|
||||
required
|
||||
@@ -802,14 +808,17 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
readOnly={type === 'detail'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Warehouse cards */}
|
||||
<div className='grid grid-cols-1 md:grid-cols-2 gap-4 mb-4'>
|
||||
<div className='card bg-base-100 shadow'>
|
||||
<div className='card-body space-y-4'>
|
||||
<h3 className='card-title text-lg'>Gudang Asal</h3>
|
||||
<Card
|
||||
title='Gudang Asal'
|
||||
className={{
|
||||
wrapper: 'w-full shadow',
|
||||
body: 'space-y-4',
|
||||
}}
|
||||
>
|
||||
<SelectInput
|
||||
required
|
||||
label='Gudang'
|
||||
@@ -872,12 +881,15 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<div className='card bg-base-100 shadow'>
|
||||
<div className='card-body space-y-4'>
|
||||
<h3 className='card-title text-lg'>Gudang Tujuan</h3>
|
||||
<Card
|
||||
title='Gudang Tujuan'
|
||||
className={{
|
||||
wrapper: 'w-full shadow',
|
||||
body: 'space-y-4',
|
||||
}}
|
||||
>
|
||||
<SelectInput
|
||||
required
|
||||
label='Gudang'
|
||||
@@ -899,9 +911,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
formik.touched.destination_warehouse_id &&
|
||||
Boolean(formik.errors.destination_warehouse_id)
|
||||
}
|
||||
errorMessage={
|
||||
formik.errors.destination_warehouse_id as string
|
||||
}
|
||||
errorMessage={formik.errors.destination_warehouse_id as string}
|
||||
isDisabled={type === 'detail'}
|
||||
isClearable
|
||||
startAdornment={
|
||||
@@ -919,10 +929,8 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
label='Area'
|
||||
name='destination_warehouse_area'
|
||||
value={
|
||||
(
|
||||
formik.values
|
||||
.destination_warehouse as WarehouseOptionType
|
||||
)?.area || '-'
|
||||
(formik.values.destination_warehouse as WarehouseOptionType)
|
||||
?.area || '-'
|
||||
}
|
||||
readOnly
|
||||
disabled
|
||||
@@ -934,10 +942,8 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
label='Lokasi'
|
||||
name='destination_warehouse_location'
|
||||
value={
|
||||
(
|
||||
formik.values
|
||||
.destination_warehouse as WarehouseOptionType
|
||||
)?.location || '-'
|
||||
(formik.values.destination_warehouse as WarehouseOptionType)
|
||||
?.location || '-'
|
||||
}
|
||||
readOnly
|
||||
disabled
|
||||
@@ -946,14 +952,17 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Products table */}
|
||||
<div className='card bg-base-100 shadow mb-4'>
|
||||
<div className='card-body'>
|
||||
<h2 className='card-title mb-4'>Produk</h2>
|
||||
<Card
|
||||
title='Produk'
|
||||
className={{
|
||||
wrapper: 'w-full mb-4 shadow',
|
||||
title: 'mb-4',
|
||||
}}
|
||||
>
|
||||
<div className='overflow-x-auto'>
|
||||
<table className='table'>
|
||||
<thead>
|
||||
@@ -972,9 +981,8 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
) => {
|
||||
if (e.target.checked) {
|
||||
setSelectedProducts(
|
||||
formik.values.products?.map(
|
||||
(_, idx) => idx
|
||||
) ?? []
|
||||
formik.values.products?.map((_, idx) => idx) ??
|
||||
[]
|
||||
);
|
||||
} else {
|
||||
setSelectedProducts([]);
|
||||
@@ -1020,10 +1028,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
e: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
if (e.target.checked) {
|
||||
setSelectedProducts([
|
||||
...selectedProducts,
|
||||
idx,
|
||||
]);
|
||||
setSelectedProducts([...selectedProducts, idx]);
|
||||
} else {
|
||||
setSelectedProducts(
|
||||
selectedProducts.filter((i) => i !== idx)
|
||||
@@ -1078,8 +1083,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
idx
|
||||
)}
|
||||
className={{
|
||||
wrapper:
|
||||
'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
@@ -1097,25 +1101,18 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
decimalSeparator='.'
|
||||
bottomLabel={getProductQtyBottomLabel(idx)}
|
||||
isError={
|
||||
isRepeaterInputError(
|
||||
'products',
|
||||
'product_qty',
|
||||
idx
|
||||
).isError || Boolean(getProductQtyError(idx))
|
||||
isRepeaterInputError('products', 'product_qty', idx)
|
||||
.isError || Boolean(getProductQtyError(idx))
|
||||
}
|
||||
errorMessage={
|
||||
isRepeaterInputError(
|
||||
'products',
|
||||
'product_qty',
|
||||
idx
|
||||
).errorMessage ||
|
||||
isRepeaterInputError('products', 'product_qty', idx)
|
||||
.errorMessage ||
|
||||
getProductQtyError(idx) ||
|
||||
undefined
|
||||
}
|
||||
readOnly={type === 'detail'}
|
||||
className={{
|
||||
wrapper:
|
||||
'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
@@ -1169,13 +1166,16 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Deliveries table */}
|
||||
<div className='card bg-base-100 shadow mb-4'>
|
||||
<div className='card-body'>
|
||||
<h2 className='card-title mb-8'>Pengiriman</h2>
|
||||
<Card
|
||||
title='Pengiriman'
|
||||
className={{
|
||||
wrapper: 'w-full mb-4 shadow',
|
||||
title: 'mb-8',
|
||||
}}
|
||||
>
|
||||
<div className='overflow-x-auto'>
|
||||
<table className='table'>
|
||||
<thead>
|
||||
@@ -1340,8 +1340,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
.errorMessage
|
||||
}
|
||||
className={{
|
||||
wrapper:
|
||||
'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
@@ -1367,10 +1366,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
getDeliveryQtyError(idx, 0) ||
|
||||
undefined
|
||||
}
|
||||
bottomLabel={getDeliveryProductQtyBottomLabel(
|
||||
idx,
|
||||
0
|
||||
)}
|
||||
bottomLabel={getDeliveryProductQtyBottomLabel(idx, 0)}
|
||||
readOnly={type === 'detail'}
|
||||
className={{
|
||||
wrapper: 'w-full min-w-48',
|
||||
@@ -1411,8 +1407,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
idx
|
||||
)}
|
||||
className={{
|
||||
wrapper:
|
||||
'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
@@ -1431,8 +1426,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
)}
|
||||
readOnly={type === 'detail'}
|
||||
className={{
|
||||
wrapper:
|
||||
'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
@@ -1470,9 +1464,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (file) {
|
||||
if (file.size > 2 * 1024 * 1024) {
|
||||
toast.error(
|
||||
'Ukuran dokumen maksimal 2 MB!'
|
||||
);
|
||||
toast.error('Ukuran dokumen maksimal 2 MB!');
|
||||
e.target.value = '';
|
||||
return;
|
||||
}
|
||||
@@ -1514,8 +1506,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
)}
|
||||
readOnly={type === 'detail'}
|
||||
className={{
|
||||
wrapper:
|
||||
'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
@@ -1525,9 +1516,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
name={`deliveries.${idx}.delivery_cost_per_item`}
|
||||
placeholder='Masukkan biaya per item...'
|
||||
value={delivery.delivery_cost_per_item || ''}
|
||||
onChange={handleDeliveryCostPerItemChangeWrapper(
|
||||
idx
|
||||
)}
|
||||
onChange={handleDeliveryCostPerItemChangeWrapper(idx)}
|
||||
onBlur={formik.handleBlur}
|
||||
decimalScale={0}
|
||||
allowNegative={false}
|
||||
@@ -1541,8 +1530,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
)}
|
||||
readOnly={type === 'detail'}
|
||||
className={{
|
||||
wrapper:
|
||||
'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
@@ -1561,8 +1549,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
)}
|
||||
readOnly={type === 'detail'}
|
||||
className={{
|
||||
wrapper:
|
||||
'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
wrapper: 'w-full min-w-52 md:min-w-72 lg:min-w-80',
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
@@ -1616,8 +1603,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Action buttons */}
|
||||
<div className='flex flex-row justify-between gap-2 flex-wrap'>
|
||||
|
||||
Reference in New Issue
Block a user