refactor(FE-208,213): enhance PurchaseOrderDetail and PurchaseOrderStaffApprovalForm components with initialValues prop and clean up unused code

This commit is contained in:
rstubryan
2025-11-18 18:22:10 +07:00
parent 75e7b9a6de
commit 8c3cd3bc53
3 changed files with 85 additions and 172 deletions
+81 -120
View File
@@ -91,7 +91,6 @@ const PurchaseTable = () => {
null
);
const [sorting, setSorting] = useState<SortingState>([]);
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
// ===== TABLE FILTER STATE =====
const {
@@ -134,104 +133,94 @@ const PurchaseTable = () => {
PurchaseRequestApi.getAllFetcher
);
// ===== COMPUTED VALUES =====
const selectedRowIds = useMemo(
() => Object.keys(rowSelection).map((item) => parseInt(item)),
[rowSelection]
);
// ===== TABLE COLUMNS DEFINITION =====
const purchaseColumns: ColumnDef<Purchase>[] = useMemo(
() => [
{
header: 'No. PR/PO',
cell: (props) => {
const { pr_number, po_number } = props.row.original;
return po_number ? po_number : pr_number;
},
const purchaseColumns: ColumnDef<Purchase>[] = [
{
header: 'No. PR/PO',
cell: (props) => {
const { pr_number, po_number } = props.row.original;
return po_number ? po_number : pr_number;
},
{
accessorKey: 'supplier',
header: 'Vendor',
cell: (props) => props.row.original.supplier.name,
},
{
accessorKey: 'supplier',
header: 'Vendor',
cell: (props) => props.row.original.supplier.name,
},
{
accessorKey: 'po_date',
header: 'Tgl. PO',
cell: (props) =>
props.row.original.po_date
? formatDate(props.row.original.po_date, 'DD MMM YYYY')
: '-',
},
{
accessorKey: 'due_date',
header: 'Jatuh Tempo',
cell: (props) =>
props.row.original.due_date
? formatDate(props.row.original.due_date, 'DD MMM YYYY')
: '-',
},
{
header: 'Aging',
cell: (props) => {
const purchase = props.row.original;
if (!purchase.po_date) return '-';
const poDate = new Date(purchase.po_date);
const today = new Date();
const diffTime = Math.abs(today.getTime() - poDate.getTime());
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return `${diffDays} hari`;
},
{
accessorKey: 'po_date',
header: 'Tgl. PO',
cell: (props) =>
props.row.original.po_date
? formatDate(props.row.original.po_date, 'DD MMM YYYY')
: '-',
},
{
accessorKey: 'due_date',
header: 'Jatuh Tempo',
cell: (props) =>
props.row.original.due_date
? formatDate(props.row.original.due_date, 'DD MMM YYYY')
: '-',
},
{
header: 'Aging',
cell: (props) => {
const purchase = props.row.original;
if (!purchase.po_date) return '-';
const poDate = new Date(purchase.po_date);
const today = new Date();
const diffTime = Math.abs(today.getTime() - poDate.getTime());
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return `${diffDays} hari`;
},
},
{
accessorKey: 'grand_total',
header: 'Total (Rp.)',
cell: (props) => formatCurrency(props.row.original.grand_total),
},
{
header: 'Aksi',
cell: (props) => {
const currentPageSize =
props.table.getPaginationRowModel().rows.length;
const currentPageRows = props.table.getPaginationRowModel().flatRows;
const currentRowRelativeIndex =
currentPageRows.findIndex((r) => r.id === props.row.id) + 1;
},
{
accessorKey: 'grand_total',
header: 'Total (Rp.)',
cell: (props) => formatCurrency(props.row.original.grand_total),
},
{
header: 'Aksi',
cell: (props) => {
const currentPageSize = props.table.getPaginationRowModel().rows.length;
const currentPageRows = props.table.getPaginationRowModel().flatRows;
const currentRowRelativeIndex =
currentPageRows.findIndex((r) => r.id === props.row.id) + 1;
const isLast2Rows = currentRowRelativeIndex > currentPageSize - 2;
const isLast2Rows = currentRowRelativeIndex > currentPageSize - 2;
const deleteClickHandler = () => {
setSelectedPurchase(props.row.original);
deleteModal.openModal();
};
const deleteClickHandler = () => {
setSelectedPurchase(props.row.original);
deleteModal.openModal();
};
return (
<>
{currentPageSize > 2 && (
<RowDropdownOptions isLast2Rows={isLast2Rows}>
<RowOptionsMenu
type='dropdown'
props={props}
deleteClickHandler={deleteClickHandler}
/>
</RowDropdownOptions>
)}
return (
<>
{currentPageSize > 2 && (
<RowDropdownOptions isLast2Rows={isLast2Rows}>
<RowOptionsMenu
type='dropdown'
props={props}
deleteClickHandler={deleteClickHandler}
/>
</RowDropdownOptions>
)}
{currentPageSize <= 2 && (
<RowCollapseOptions>
<RowOptionsMenu
type='collapse'
props={props}
deleteClickHandler={deleteClickHandler}
/>
</RowCollapseOptions>
)}
</>
);
},
{currentPageSize <= 2 && (
<RowCollapseOptions>
<RowOptionsMenu
type='collapse'
props={props}
deleteClickHandler={deleteClickHandler}
/>
</RowCollapseOptions>
)}
</>
);
},
],
[]
);
},
];
// ===== EVENT HANDLERS =====
const confirmationModalDeleteClickHandler = useCallback(async () => {
@@ -287,7 +276,7 @@ const PurchaseTable = () => {
<div className='w-full p-0 sm:p-4'>
<div className='flex flex-col gap-2 mb-4'>
<div className='w-full flex flex-col xl:flex-row justify-between items-end xl:items-center gap-2'>
<div className='w-full sm:w-fit flex flex-col sm:flex-row self-start gap-2'>
<div className='w-full flex flex-row gap-2'>
<Button
href='/purchase/add'
variant='outline'
@@ -297,32 +286,6 @@ const PurchaseTable = () => {
<Icon icon='ic:round-plus' width={24} height={24} />
Tambah
</Button>
{selectedRowIds.length > 0 && (
<Button
variant='outline'
color='error'
onClick={() => {
setSelectedPurchase(
isResponseSuccess(purchaseRequests)
? purchaseRequests?.data?.find((p: Purchase) =>
selectedRowIds.includes(p.id)
) || null
: null
);
deleteModal.openModal();
}}
disabled={selectedRowIds.length === 0}
className='w-full sm:w-fit'
>
<Icon
icon='material-symbols:delete-outline-rounded'
width={24}
height={24}
/>
Hapus ({selectedRowIds.length})
</Button>
)}
</div>
<DebouncedTextInput
@@ -400,8 +363,6 @@ const PurchaseTable = () => {
isLoading={isLoading}
sorting={sorting}
setSorting={setSorting}
rowSelection={rowSelection}
setRowSelection={setRowSelection}
className={{
containerClassName: cn({
'mb-20':
@@ -170,7 +170,7 @@ const PurchaseOrderStaffApprovalForm = ({
if (initialValues?.items) {
return initialValues.items.map((item) => ({
value: item.id,
label: `${item.product.name} (${item.quantity} ${item.product.uom?.name || 'unit'})`,
label: `${item.product.name} ${item.quantity}`,
id: item.id,
quantity: item.quantity,
product: {
@@ -184,57 +184,8 @@ const PurchaseOrderStaffApprovalForm = ({
}));
}
return [
{
value: 1,
label: 'SEALYTE SPARK 1 x 87 gr (14 SACHET)',
id: 1,
quantity: 14,
product: {
name: 'SEALYTE SPARK 1 x 87 gr',
product_category: 'Bahan Baku',
uom: {
name: 'SACHET',
},
},
warehouse: {
name: 'GUDANG CIANGSANA 1 (ARCA P15)',
},
},
{
value: 2,
label: 'CID-2000 @ 5 KG (2 KILOGRAM)',
id: 2,
quantity: 2,
product: {
name: 'CID-2000 @ 5 KG',
product_category: 'Bahan Baku',
uom: {
name: 'Kilogram',
},
},
warehouse: {
name: 'GUDANG CIANGSANA 2 (ARCA P15)',
},
},
{
value: 3,
label: 'VITAMIN AYAM (10 DOSIS)',
id: 3,
quantity: 10,
product: {
name: 'VITAMIN AYAM',
product_category: 'Bahan Baku',
uom: {
name: 'DOSIS',
},
},
warehouse: {
name: 'GUDANG CIANGSANA 3 (ARCA P15)',
},
},
];
}, [initialValues?.items, searchParams]);
return [];
}, [initialValues?.items]);
const getPurchaseItemOptions = useCallback(() => {
return purchaseItems;
@@ -758,6 +758,7 @@ const PurchaseOrderDetail = ({
>
<PurchaseOrderStaffApprovalForm
type='add'
initialValues={purchaseData}
onCancel={staffApprovalModal.closeModal}
/>
</Modal>