mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
refactor(FE): Refactor table components to improve styling and structure
This commit is contained in:
@@ -82,7 +82,7 @@ const FinanceClosingTable = ({
|
|||||||
}, [finance]);
|
}, [finance]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col gap-4'>
|
<div className='flex flex-col gap-4 p-0 sm:p-3'>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<FinanceClosingSkeleton />
|
<FinanceClosingSkeleton />
|
||||||
) : !isResponseSuccess(finance) ? (
|
) : !isResponseSuccess(finance) ? (
|
||||||
@@ -96,10 +96,13 @@ const FinanceClosingTable = ({
|
|||||||
<Card
|
<Card
|
||||||
variant='bordered'
|
variant='bordered'
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='grid grid-cols-2 gap-6'>
|
<div className='p-4 grid grid-cols-2 gap-6'>
|
||||||
<div className='flex flex-col gap-1'>
|
<div className='flex flex-col gap-1'>
|
||||||
<div>Laba Rugi Brutto</div>
|
<div>Laba Rugi Brutto</div>
|
||||||
<div className='text-lg font-bold'>
|
<div className='text-lg font-bold'>
|
||||||
@@ -127,10 +130,13 @@ const FinanceClosingTable = ({
|
|||||||
variant='bordered'
|
variant='bordered'
|
||||||
collapsible
|
collapsible
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='mt-6 p-0 mb-0'>
|
<div className='p-0'>
|
||||||
<Table<HppItem>
|
<Table<HppItem>
|
||||||
data={hppTableData}
|
data={hppTableData}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
@@ -263,6 +269,24 @@ const FinanceClosingTable = ({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
className={{
|
||||||
|
containerClassName: 'w-full mb-0!',
|
||||||
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
tableFooterClassName:
|
||||||
|
'bg-gray-100 font-semibold border border-gray-200',
|
||||||
|
footerRowClassName: 'border-t-2 border-gray-300',
|
||||||
|
footerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
}}
|
||||||
renderCustomRow={(row) => {
|
renderCustomRow={(row) => {
|
||||||
const rowData = row.original;
|
const rowData = row.original;
|
||||||
if (rowData.code === 'custom_row') {
|
if (rowData.code === 'custom_row') {
|
||||||
@@ -296,10 +320,13 @@ const FinanceClosingTable = ({
|
|||||||
variant='bordered'
|
variant='bordered'
|
||||||
collapsible
|
collapsible
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='mt-6 p-0 mb-0'>
|
<div className='p-0'>
|
||||||
<Table<ProfitLossItem>
|
<Table<ProfitLossItem>
|
||||||
data={profitLossTableData}
|
data={profitLossTableData}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
@@ -363,6 +390,25 @@ const FinanceClosingTable = ({
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
className={{
|
||||||
|
containerClassName: 'w-full mb-0!',
|
||||||
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
tableFooterClassName:
|
||||||
|
'bg-gray-100 font-semibold border border-gray-200',
|
||||||
|
footerRowClassName: 'border-t-2 border-gray-300',
|
||||||
|
footerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
paginationClassName: 'hidden',
|
||||||
|
}}
|
||||||
renderCustomRow={(row) => {
|
renderCustomRow={(row) => {
|
||||||
const rowData = row.original;
|
const rowData = row.original;
|
||||||
if (rowData.code === 'custom_row') {
|
if (rowData.code === 'custom_row') {
|
||||||
@@ -404,9 +450,6 @@ const FinanceClosingTable = ({
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}}
|
}}
|
||||||
className={{
|
|
||||||
paginationClassName: 'hidden',
|
|
||||||
}}
|
|
||||||
renderFooter={isResponseSuccess(finance)}
|
renderFooter={isResponseSuccess(finance)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -91,53 +91,56 @@ const HppExpeditionClosingTable = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className='w-full p-0 sm:p-3'>
|
||||||
<section className='w-full'>
|
<Card
|
||||||
<div className='p-4'>
|
className={{
|
||||||
<h2 className='text-xl font-semibold mb-4'>HPP Ekspedisi</h2>
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
<Card
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
|
}}
|
||||||
|
variant='bordered'
|
||||||
|
title='HPP Ekspedisi'
|
||||||
|
collapsible
|
||||||
|
defaultCollapsed={false}
|
||||||
|
>
|
||||||
|
{isLoading ? (
|
||||||
|
<HppExpeditionClosingSkeleton
|
||||||
|
columns={costOfRevenueExpeditionColumns}
|
||||||
|
/>
|
||||||
|
) : costOfRevenueExpeditionData.length === 0 ? (
|
||||||
|
<HppExpeditionClosingSkeleton
|
||||||
|
columns={costOfRevenueExpeditionColumns}
|
||||||
|
iconName='heroicons:chart-bar'
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Table
|
||||||
|
data={costOfRevenueExpeditionData}
|
||||||
|
columns={costOfRevenueExpeditionColumns}
|
||||||
|
isLoading={isLoading}
|
||||||
|
renderFooter={costOfRevenueExpeditionData.length > 0}
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full bg-base-100',
|
containerClassName: 'w-full mb-0!',
|
||||||
body: 'p-0',
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
tableFooterClassName:
|
||||||
|
'bg-gray-100 font-semibold border border-gray-200',
|
||||||
|
footerRowClassName: 'border-t-2 border-gray-300',
|
||||||
|
footerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
{isLoading ? (
|
)}
|
||||||
<HppExpeditionClosingSkeleton
|
</Card>
|
||||||
columns={costOfRevenueExpeditionColumns}
|
</div>
|
||||||
/>
|
|
||||||
) : costOfRevenueExpeditionData.length === 0 ? (
|
|
||||||
<HppExpeditionClosingSkeleton
|
|
||||||
columns={costOfRevenueExpeditionColumns}
|
|
||||||
iconName='heroicons:chart-bar'
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Table
|
|
||||||
data={costOfRevenueExpeditionData}
|
|
||||||
columns={costOfRevenueExpeditionColumns}
|
|
||||||
isLoading={isLoading}
|
|
||||||
renderFooter={costOfRevenueExpeditionData.length > 0}
|
|
||||||
className={{
|
|
||||||
tableWrapperClassName: 'overflow-x-auto',
|
|
||||||
tableClassName: 'w-full table-auto text-sm',
|
|
||||||
headerRowClassName: 'border-b border-b-gray-200',
|
|
||||||
headerColumnClassName:
|
|
||||||
'px-4 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end whitespace-nowrap',
|
|
||||||
bodyRowClassName:
|
|
||||||
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
|
||||||
bodyColumnClassName:
|
|
||||||
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
|
||||||
tableFooterClassName:
|
|
||||||
'bg-gray-100 font-semibold border border-gray-200',
|
|
||||||
footerRowClassName: 'border-t-2 border-gray-300',
|
|
||||||
footerColumnClassName:
|
|
||||||
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -209,15 +209,18 @@ const OverheadClosingTable = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className='w-full p-0 sm:p-3'>
|
||||||
<Card
|
<Card
|
||||||
|
className={{
|
||||||
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
|
}}
|
||||||
|
variant='bordered'
|
||||||
title='Pengeluaran Overhead'
|
title='Pengeluaran Overhead'
|
||||||
collapsible
|
collapsible
|
||||||
defaultCollapsed={false}
|
defaultCollapsed={false}
|
||||||
className={{
|
|
||||||
wrapper: 'w-full',
|
|
||||||
body: 'p-4 shadow',
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{isLoadingOverhead ? (
|
{isLoadingOverhead ? (
|
||||||
<OverheadClosingSkeleton columns={columns} />
|
<OverheadClosingSkeleton columns={columns} />
|
||||||
@@ -243,11 +246,24 @@ const OverheadClosingTable = ({
|
|||||||
}
|
}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
className={{
|
className={{
|
||||||
containerClassName: 'my-4',
|
containerClassName: 'w-full mb-0!',
|
||||||
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
headerColumnClassName: cn(
|
headerColumnClassName: cn(
|
||||||
TABLE_DEFAULT_STYLING.headerColumnClassName,
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
'whitespace-nowrap'
|
'whitespace-nowrap'
|
||||||
),
|
),
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
tableFooterClassName:
|
||||||
|
'bg-gray-100 font-semibold border border-gray-200',
|
||||||
|
footerRowClassName: 'border-t-2 border-gray-300',
|
||||||
|
footerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
}}
|
}}
|
||||||
isLoading={isLoadingOverhead}
|
isLoading={isLoadingOverhead}
|
||||||
renderFooter={
|
renderFooter={
|
||||||
@@ -312,7 +328,7 @@ const OverheadClosingTable = ({
|
|||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -316,50 +316,54 @@ const SalesClosingTable = ({ projectFlockId }: SalesClosingTableProps) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className='w-full p-0 sm:p-3'>
|
||||||
<section className='w-full'>
|
<Card
|
||||||
<div className='p-4'>
|
className={{
|
||||||
<h2 className='text-xl font-semibold mb-4'>Penjualan</h2>
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
<Card
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
|
}}
|
||||||
|
variant='bordered'
|
||||||
|
title='Penjualan'
|
||||||
|
collapsible
|
||||||
|
defaultCollapsed={false}
|
||||||
|
>
|
||||||
|
{isLoading ? (
|
||||||
|
<SalesClosingSkeleton columns={salesColumns} />
|
||||||
|
) : salesData.length === 0 ? (
|
||||||
|
<SalesClosingSkeleton
|
||||||
|
columns={salesColumns}
|
||||||
|
iconName='heroicons:chart-bar'
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Table
|
||||||
|
data={salesData}
|
||||||
|
columns={salesColumns}
|
||||||
|
isLoading={isLoading}
|
||||||
|
renderFooter={salesData.length > 0}
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full bg-base-100',
|
containerClassName: 'w-full mb-0!',
|
||||||
body: 'p-0',
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
tableFooterClassName:
|
||||||
|
'bg-gray-100 font-semibold border border-gray-200',
|
||||||
|
footerRowClassName: 'border-t-2 border-gray-300',
|
||||||
|
footerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
{isLoading ? (
|
)}
|
||||||
<SalesClosingSkeleton columns={salesColumns} />
|
</Card>
|
||||||
) : salesData.length === 0 ? (
|
</div>
|
||||||
<SalesClosingSkeleton
|
|
||||||
columns={salesColumns}
|
|
||||||
iconName='heroicons:chart-bar'
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Table
|
|
||||||
data={salesData}
|
|
||||||
columns={salesColumns}
|
|
||||||
isLoading={isLoading}
|
|
||||||
renderFooter={salesData.length > 0}
|
|
||||||
className={{
|
|
||||||
tableWrapperClassName: 'overflow-x-auto',
|
|
||||||
tableClassName: 'w-full table-auto text-sm',
|
|
||||||
headerColumnClassName:
|
|
||||||
'px-4 py-3 text-xs font-semibold text-gray-500 whitespace-nowrap border-l border-l-gray-200 border-r border-r-gray-200 border-t border-t-gray-200 border-gray-200 border-b-0',
|
|
||||||
bodyRowClassName:
|
|
||||||
'hover:bg-gray-50 transition-colors border-b border-gray-200 first:border-t first:border-t-gray-200 border-l border-l-gray-200 border-r border-r-gray-200',
|
|
||||||
bodyColumnClassName:
|
|
||||||
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
|
||||||
tableFooterClassName:
|
|
||||||
'bg-gray-100 font-semibold border border-gray-200',
|
|
||||||
footerRowClassName: 'border-t-2 border-gray-300',
|
|
||||||
footerColumnClassName:
|
|
||||||
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ const SapronakCalculationClosingTable = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col gap-4'>
|
<div className='flex flex-col gap-4 p-0 sm:p-3'>
|
||||||
{/* Table DOC jika kategori Project Flock Growing */}
|
{/* Table DOC jika kategori Project Flock Growing */}
|
||||||
<Card
|
<Card
|
||||||
title={
|
title={
|
||||||
@@ -190,9 +190,12 @@ const SapronakCalculationClosingTable = ({
|
|||||||
collapsible
|
collapsible
|
||||||
defaultCollapsed={false}
|
defaultCollapsed={false}
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
body: 'p-4 shadow',
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
}}
|
}}
|
||||||
|
variant='bordered'
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<SapronakCalculationClosingSkeleton columns={docColumns} />
|
<SapronakCalculationClosingSkeleton columns={docColumns} />
|
||||||
@@ -213,7 +216,22 @@ const SapronakCalculationClosingTable = ({
|
|||||||
}
|
}
|
||||||
columns={docColumns}
|
columns={docColumns}
|
||||||
className={{
|
className={{
|
||||||
containerClassName: 'my-4',
|
containerClassName: 'w-full mb-0!',
|
||||||
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
tableFooterClassName:
|
||||||
|
'bg-gray-100 font-semibold border border-gray-200',
|
||||||
|
footerRowClassName: 'border-t-2 border-gray-300',
|
||||||
|
footerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
}}
|
}}
|
||||||
renderFooter={
|
renderFooter={
|
||||||
isResponseSuccess(sapronakCalculation) &&
|
isResponseSuccess(sapronakCalculation) &&
|
||||||
@@ -229,7 +247,10 @@ const SapronakCalculationClosingTable = ({
|
|||||||
collapsible
|
collapsible
|
||||||
defaultCollapsed={true}
|
defaultCollapsed={true}
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
@@ -251,7 +272,22 @@ const SapronakCalculationClosingTable = ({
|
|||||||
}
|
}
|
||||||
columns={ovkColumns}
|
columns={ovkColumns}
|
||||||
className={{
|
className={{
|
||||||
containerClassName: 'my-4',
|
containerClassName: 'w-full mb-0!',
|
||||||
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
tableFooterClassName:
|
||||||
|
'bg-gray-100 font-semibold border border-gray-200',
|
||||||
|
footerRowClassName: 'border-t-2 border-gray-300',
|
||||||
|
footerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
}}
|
}}
|
||||||
renderFooter={
|
renderFooter={
|
||||||
isResponseSuccess(sapronakCalculation) &&
|
isResponseSuccess(sapronakCalculation) &&
|
||||||
@@ -267,7 +303,10 @@ const SapronakCalculationClosingTable = ({
|
|||||||
collapsible
|
collapsible
|
||||||
defaultCollapsed={true}
|
defaultCollapsed={true}
|
||||||
className={{
|
className={{
|
||||||
wrapper: 'w-full',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
@@ -289,7 +328,22 @@ const SapronakCalculationClosingTable = ({
|
|||||||
}
|
}
|
||||||
columns={pakanColumns}
|
columns={pakanColumns}
|
||||||
className={{
|
className={{
|
||||||
containerClassName: 'my-4',
|
containerClassName: 'w-full mb-0!',
|
||||||
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
tableFooterClassName:
|
||||||
|
'bg-gray-100 font-semibold border border-gray-200',
|
||||||
|
footerRowClassName: 'border-t-2 border-gray-300',
|
||||||
|
footerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
}}
|
}}
|
||||||
renderFooter={
|
renderFooter={
|
||||||
isResponseSuccess(sapronakCalculation) &&
|
isResponseSuccess(sapronakCalculation) &&
|
||||||
|
|||||||
@@ -5,12 +5,10 @@ import { useSearchParams } from 'next/navigation';
|
|||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||||
|
|
||||||
import { Icon } from '@iconify/react';
|
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
import Collapse from '@/components/Collapse';
|
|
||||||
|
|
||||||
import { cn, formatNumber } from '@/lib/helper';
|
import { formatNumber } from '@/lib/helper';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
import { ClosingApi } from '@/services/api/closing';
|
import { ClosingApi } from '@/services/api/closing';
|
||||||
@@ -56,8 +54,6 @@ const ClosingIncomingSapronaksSummaryTable = ({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const [open, setOpen] = useState(true);
|
|
||||||
|
|
||||||
const [sorting, setSorting] = useState<SortingState>([]);
|
const [sorting, setSorting] = useState<SortingState>([]);
|
||||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||||
|
|
||||||
@@ -94,97 +90,78 @@ const ClosingIncomingSapronaksSummaryTable = ({
|
|||||||
}
|
}
|
||||||
}, [sorting, updateFilter]);
|
}, [sorting, updateFilter]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!open) {
|
|
||||||
setOpen(
|
|
||||||
isResponseSuccess(incomingSapronakSummaries)
|
|
||||||
? incomingSapronakSummaries.data.length > 0
|
|
||||||
: false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [incomingSapronakSummaries, isResponseSuccess]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<div className='w-full p-0 sm:p-3'>
|
||||||
className={{
|
<Card
|
||||||
wrapper: 'w-full',
|
className={{
|
||||||
body: 'p-4 shadow',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
}}
|
body: 'p-0',
|
||||||
>
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
<Collapse
|
collapsible: 'rounded-lg',
|
||||||
open={open}
|
}}
|
||||||
onOpenChange={setOpen}
|
variant='bordered'
|
||||||
title={
|
title='Ringkasan Sapronak Masuk'
|
||||||
<div className='card-actions p-4 justify-between items-center w-full'>
|
collapsible
|
||||||
<div className='card-title'>Ringkasan Sapronak Masuk</div>
|
defaultCollapsed={false}
|
||||||
|
|
||||||
<Icon
|
|
||||||
icon='material-symbols:keyboard-arrow-down'
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
className={cn('text-primary transition-transform', {
|
|
||||||
'-rotate-180': open,
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
className='w-full!'
|
|
||||||
titleClassName='w-full p-0!'
|
|
||||||
>
|
>
|
||||||
<div className='w-full p-0'>
|
{isLoadingIncomingSapronakSummaries ? (
|
||||||
{isLoadingIncomingSapronakSummaries ? (
|
<SapronakClosingSkeleton
|
||||||
<SapronakClosingSkeleton
|
type='incoming'
|
||||||
type='incoming'
|
columns={incomingSapronaksColumns}
|
||||||
columns={incomingSapronaksColumns}
|
/>
|
||||||
/>
|
) : isResponseSuccess(incomingSapronakSummaries) &&
|
||||||
) : isResponseSuccess(incomingSapronakSummaries) &&
|
incomingSapronakSummaries.data.length === 0 ? (
|
||||||
incomingSapronakSummaries.data.length === 0 ? (
|
<SapronakClosingSkeleton
|
||||||
<SapronakClosingSkeleton
|
type='incoming'
|
||||||
type='incoming'
|
columns={incomingSapronaksColumns}
|
||||||
columns={incomingSapronaksColumns}
|
iconName='heroicons:chart-bar'
|
||||||
iconName='heroicons:chart-bar'
|
title='Ringkasan Sapronak Masuk Tidak Ditemukan'
|
||||||
title='Ringkasan Sapronak Masuk Tidak Ditemukan'
|
subtitle='Tidak ada ringkasan sapronak masuk untuk periode ini.'
|
||||||
subtitle='Tidak ada ringkasan sapronak masuk untuk periode ini.'
|
/>
|
||||||
/>
|
) : (
|
||||||
) : (
|
<Table<ClosingIncomingSapronakSummary>
|
||||||
<Table<ClosingIncomingSapronakSummary>
|
data={
|
||||||
data={
|
isResponseSuccess(incomingSapronakSummaries)
|
||||||
isResponseSuccess(incomingSapronakSummaries)
|
? incomingSapronakSummaries?.data
|
||||||
? incomingSapronakSummaries?.data
|
: []
|
||||||
: []
|
}
|
||||||
}
|
columns={incomingSapronaksColumns}
|
||||||
columns={incomingSapronaksColumns}
|
pageSize={tableFilterState.pageSize}
|
||||||
pageSize={tableFilterState.pageSize}
|
onPageSizeChange={setPageSize}
|
||||||
onPageSizeChange={setPageSize}
|
rowOptions={[10, 20, 50, 100]}
|
||||||
rowOptions={[10, 20, 50, 100]}
|
page={
|
||||||
page={
|
isResponseSuccess(incomingSapronakSummaries)
|
||||||
isResponseSuccess(incomingSapronakSummaries)
|
? incomingSapronakSummaries?.meta?.page
|
||||||
? incomingSapronakSummaries?.meta?.page
|
: 0
|
||||||
: 0
|
}
|
||||||
}
|
totalItems={
|
||||||
totalItems={
|
isResponseSuccess(incomingSapronakSummaries)
|
||||||
isResponseSuccess(incomingSapronakSummaries)
|
? incomingSapronakSummaries?.meta?.total_results
|
||||||
? incomingSapronakSummaries?.meta?.total_results
|
: 0
|
||||||
: 0
|
}
|
||||||
}
|
onPageChange={setPage}
|
||||||
onPageChange={setPage}
|
isLoading={isLoadingIncomingSapronakSummaries}
|
||||||
isLoading={isLoadingIncomingSapronakSummaries}
|
sorting={sorting}
|
||||||
sorting={sorting}
|
setSorting={setSorting}
|
||||||
setSorting={setSorting}
|
rowSelection={rowSelection}
|
||||||
rowSelection={rowSelection}
|
setRowSelection={setRowSelection}
|
||||||
setRowSelection={setRowSelection}
|
className={{
|
||||||
className={{
|
containerClassName: 'w-full mb-0!',
|
||||||
containerClassName: cn({
|
tableWrapperClassName:
|
||||||
'w-full mb-20':
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
isResponseSuccess(incomingSapronakSummaries) &&
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
incomingSapronakSummaries?.data?.length === 0,
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
}),
|
headerColumnClassName:
|
||||||
}}
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
/>
|
bodyRowClassName:
|
||||||
)}
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
</div>
|
bodyColumnClassName:
|
||||||
</Collapse>
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
</Card>
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,11 @@ import { useSearchParams } from 'next/navigation';
|
|||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||||
|
|
||||||
import { Icon } from '@iconify/react';
|
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
import Collapse from '@/components/Collapse';
|
|
||||||
|
|
||||||
import { cn, formatDate, formatNumber } from '@/lib/helper';
|
import { formatDate, formatNumber } from '@/lib/helper';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
import { ClosingApi } from '@/services/api/closing';
|
import { ClosingApi } from '@/services/api/closing';
|
||||||
@@ -52,8 +50,6 @@ const ClosingIncomingSapronaksTable = ({
|
|||||||
ClosingApi.getAllIncomingSapronakFetcher
|
ClosingApi.getAllIncomingSapronakFetcher
|
||||||
);
|
);
|
||||||
|
|
||||||
const [open, setOpen] = useState(true);
|
|
||||||
|
|
||||||
const [sorting, setSorting] = useState<SortingState>([]);
|
const [sorting, setSorting] = useState<SortingState>([]);
|
||||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||||
|
|
||||||
@@ -118,109 +114,90 @@ const ClosingIncomingSapronaksTable = ({
|
|||||||
}
|
}
|
||||||
}, [sorting, updateFilter]);
|
}, [sorting, updateFilter]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!open) {
|
|
||||||
setOpen(
|
|
||||||
isResponseSuccess(incomingSapronaks)
|
|
||||||
? incomingSapronaks.data.length > 0
|
|
||||||
: false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [incomingSapronaks, isResponseSuccess]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<div className='w-full p-0 sm:p-3'>
|
||||||
className={{
|
<Card
|
||||||
wrapper: 'w-full',
|
className={{
|
||||||
body: 'p-4 shadow',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
}}
|
body: 'p-0',
|
||||||
>
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
<Collapse
|
collapsible: 'rounded-lg',
|
||||||
open={open}
|
}}
|
||||||
onOpenChange={setOpen}
|
variant='bordered'
|
||||||
title={
|
title='Sapronak Masuk'
|
||||||
<div className='card-actions p-4 justify-between items-center w-full'>
|
collapsible
|
||||||
<div className='card-title'>Sapronak Masuk</div>
|
defaultCollapsed={false}
|
||||||
|
|
||||||
<Icon
|
|
||||||
icon='material-symbols:keyboard-arrow-down'
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
className={cn('text-primary transition-transform', {
|
|
||||||
'-rotate-180': open,
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
className='w-full!'
|
|
||||||
titleClassName='w-full p-0!'
|
|
||||||
>
|
>
|
||||||
<div className='w-full p-0'>
|
<div className='flex flex-col gap-2 mb-4'>
|
||||||
<div className='flex flex-col gap-2 mb-4'>
|
<div className='w-full flex flex-col sm:flex-row justify-start items-end sm:items-center gap-4'>
|
||||||
<div className='w-full flex flex-col sm:flex-row justify-start items-end sm:items-center gap-4'>
|
<DebouncedTextInput
|
||||||
<DebouncedTextInput
|
name='search'
|
||||||
name='search'
|
placeholder='Cari Sapronak Masuk'
|
||||||
placeholder='Cari Sapronak Masuk'
|
value={tableFilterState.search}
|
||||||
value={tableFilterState.search}
|
onChange={searchChangeHandler}
|
||||||
onChange={searchChangeHandler}
|
className={{ wrapper: 'sm:max-w-3xs' }}
|
||||||
className={{ wrapper: 'sm:max-w-3xs' }}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isLoadingIncomingSapronaks ? (
|
|
||||||
<SapronakClosingSkeleton
|
|
||||||
type='incoming'
|
|
||||||
columns={incomingSapronaksColumns}
|
|
||||||
/>
|
|
||||||
) : isResponseSuccess(incomingSapronaks) &&
|
|
||||||
incomingSapronaks.data.length === 0 ? (
|
|
||||||
<SapronakClosingSkeleton
|
|
||||||
type='incoming'
|
|
||||||
columns={incomingSapronaksColumns}
|
|
||||||
iconName='heroicons:chart-bar'
|
|
||||||
title='Data Sapronak Masuk Tidak Ditemukan'
|
|
||||||
subtitle='Tidak ada data sapronak masuk untuk periode ini.'
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Table<ClosingIncomingSapronak>
|
|
||||||
data={
|
|
||||||
isResponseSuccess(incomingSapronaks)
|
|
||||||
? incomingSapronaks?.data
|
|
||||||
: []
|
|
||||||
}
|
|
||||||
columns={incomingSapronaksColumns}
|
|
||||||
pageSize={tableFilterState.pageSize}
|
|
||||||
onPageSizeChange={setPageSize}
|
|
||||||
rowOptions={[10, 20, 50, 100]}
|
|
||||||
page={
|
|
||||||
isResponseSuccess(incomingSapronaks)
|
|
||||||
? incomingSapronaks?.meta?.page
|
|
||||||
: 0
|
|
||||||
}
|
|
||||||
totalItems={
|
|
||||||
isResponseSuccess(incomingSapronaks)
|
|
||||||
? incomingSapronaks?.meta?.total_results
|
|
||||||
: 0
|
|
||||||
}
|
|
||||||
onPageChange={setPage}
|
|
||||||
isLoading={isLoadingIncomingSapronaks}
|
|
||||||
sorting={sorting}
|
|
||||||
setSorting={setSorting}
|
|
||||||
rowSelection={rowSelection}
|
|
||||||
setRowSelection={setRowSelection}
|
|
||||||
className={{
|
|
||||||
containerClassName: cn({
|
|
||||||
'w-full mb-20':
|
|
||||||
isResponseSuccess(incomingSapronaks) &&
|
|
||||||
incomingSapronaks?.data?.length === 0,
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</Collapse>
|
|
||||||
</Card>
|
{isLoadingIncomingSapronaks ? (
|
||||||
|
<SapronakClosingSkeleton
|
||||||
|
type='incoming'
|
||||||
|
columns={incomingSapronaksColumns}
|
||||||
|
/>
|
||||||
|
) : isResponseSuccess(incomingSapronaks) &&
|
||||||
|
incomingSapronaks.data.length === 0 ? (
|
||||||
|
<SapronakClosingSkeleton
|
||||||
|
type='incoming'
|
||||||
|
columns={incomingSapronaksColumns}
|
||||||
|
iconName='heroicons:chart-bar'
|
||||||
|
title='Data Sapronak Masuk Tidak Ditemukan'
|
||||||
|
subtitle='Tidak ada data sapronak masuk untuk periode ini.'
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Table<ClosingIncomingSapronak>
|
||||||
|
data={
|
||||||
|
isResponseSuccess(incomingSapronaks)
|
||||||
|
? incomingSapronaks?.data
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
columns={incomingSapronaksColumns}
|
||||||
|
pageSize={tableFilterState.pageSize}
|
||||||
|
onPageSizeChange={setPageSize}
|
||||||
|
rowOptions={[10, 20, 50, 100]}
|
||||||
|
page={
|
||||||
|
isResponseSuccess(incomingSapronaks)
|
||||||
|
? incomingSapronaks?.meta?.page
|
||||||
|
: 0
|
||||||
|
}
|
||||||
|
totalItems={
|
||||||
|
isResponseSuccess(incomingSapronaks)
|
||||||
|
? incomingSapronaks?.meta?.total_results
|
||||||
|
: 0
|
||||||
|
}
|
||||||
|
onPageChange={setPage}
|
||||||
|
isLoading={isLoadingIncomingSapronaks}
|
||||||
|
sorting={sorting}
|
||||||
|
setSorting={setSorting}
|
||||||
|
rowSelection={rowSelection}
|
||||||
|
setRowSelection={setRowSelection}
|
||||||
|
className={{
|
||||||
|
containerClassName: 'w-full mb-0!',
|
||||||
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName: 'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,10 @@ import { useSearchParams } from 'next/navigation';
|
|||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||||
|
|
||||||
import { Icon } from '@iconify/react';
|
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
import Collapse from '@/components/Collapse';
|
|
||||||
|
|
||||||
import { cn, formatNumber } from '@/lib/helper';
|
import { formatNumber } from '@/lib/helper';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
import { ClosingApi } from '@/services/api/closing';
|
import { ClosingApi } from '@/services/api/closing';
|
||||||
@@ -56,8 +54,6 @@ const ClosingOutgoingSapronaksSummaryTable = ({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const [open, setOpen] = useState(true);
|
|
||||||
|
|
||||||
const [sorting, setSorting] = useState<SortingState>([]);
|
const [sorting, setSorting] = useState<SortingState>([]);
|
||||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||||
|
|
||||||
@@ -94,97 +90,79 @@ const ClosingOutgoingSapronaksSummaryTable = ({
|
|||||||
}
|
}
|
||||||
}, [sorting, updateFilter]);
|
}, [sorting, updateFilter]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!open) {
|
|
||||||
setOpen(
|
|
||||||
isResponseSuccess(outgoingSapronakSummaries)
|
|
||||||
? outgoingSapronakSummaries.data.length > 0
|
|
||||||
: false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [outgoingSapronakSummaries, isResponseSuccess]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<div className='w-full p-0 sm:p-3'>
|
||||||
className={{
|
<Card
|
||||||
wrapper: 'w-full',
|
className={{
|
||||||
body: 'p-4 shadow',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
}}
|
body: 'p-0',
|
||||||
>
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
<Collapse
|
collapsible: 'rounded-lg',
|
||||||
open={open}
|
}}
|
||||||
onOpenChange={setOpen}
|
variant='bordered'
|
||||||
title={
|
title='Ringkasan Sapronak Keluar'
|
||||||
<div className='card-actions p-4 justify-between items-center w-full'>
|
collapsible
|
||||||
<div className='card-title'>Ringkasan Sapronak Keluar</div>
|
defaultCollapsed={false}
|
||||||
|
|
||||||
<Icon
|
|
||||||
icon='material-symbols:keyboard-arrow-down'
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
className={cn('text-primary transition-transform', {
|
|
||||||
'-rotate-180': open,
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
className='w-full!'
|
|
||||||
titleClassName='w-full p-0!'
|
|
||||||
>
|
>
|
||||||
<div className='w-full p-0'>
|
{isLoadingOutgoingSapronakSummaries ? (
|
||||||
{isLoadingOutgoingSapronakSummaries ? (
|
<SapronakClosingSkeleton
|
||||||
<SapronakClosingSkeleton
|
type='outgoing'
|
||||||
type='outgoing'
|
columns={outgoingSapronaksColumns}
|
||||||
columns={outgoingSapronaksColumns}
|
/>
|
||||||
/>
|
) : isResponseSuccess(outgoingSapronakSummaries) &&
|
||||||
) : isResponseSuccess(outgoingSapronakSummaries) &&
|
outgoingSapronakSummaries.data.length === 0 ? (
|
||||||
outgoingSapronakSummaries.data.length === 0 ? (
|
<SapronakClosingSkeleton
|
||||||
<SapronakClosingSkeleton
|
type='outgoing'
|
||||||
type='outgoing'
|
columns={outgoingSapronaksColumns}
|
||||||
columns={outgoingSapronaksColumns}
|
iconName='heroicons:chart-bar'
|
||||||
iconName='heroicons:chart-bar'
|
title='Ringkasan Sapronak Keluar Tidak Ditemukan'
|
||||||
title='Ringkasan Sapronak Keluar Tidak Ditemukan'
|
subtitle='Tidak ada ringkasan sapronak keluar untuk periode ini.'
|
||||||
subtitle='Tidak ada ringkasan sapronak keluar untuk periode ini.'
|
/>
|
||||||
/>
|
) : (
|
||||||
) : (
|
<Table<ClosingOutgoingSapronakSummary>
|
||||||
<Table<ClosingOutgoingSapronakSummary>
|
data={
|
||||||
data={
|
isResponseSuccess(outgoingSapronakSummaries)
|
||||||
isResponseSuccess(outgoingSapronakSummaries)
|
? outgoingSapronakSummaries?.data
|
||||||
? outgoingSapronakSummaries?.data
|
: []
|
||||||
: []
|
}
|
||||||
}
|
columns={outgoingSapronaksColumns}
|
||||||
columns={outgoingSapronaksColumns}
|
pageSize={tableFilterState.pageSize}
|
||||||
pageSize={tableFilterState.pageSize}
|
onPageSizeChange={setPageSize}
|
||||||
onPageSizeChange={setPageSize}
|
rowOptions={[10, 20, 50, 100]}
|
||||||
rowOptions={[10, 20, 50, 100]}
|
page={
|
||||||
page={
|
isResponseSuccess(outgoingSapronakSummaries)
|
||||||
isResponseSuccess(outgoingSapronakSummaries)
|
? outgoingSapronakSummaries?.meta?.page
|
||||||
? outgoingSapronakSummaries?.meta?.page
|
: 0
|
||||||
: 0
|
}
|
||||||
}
|
totalItems={
|
||||||
totalItems={
|
isResponseSuccess(outgoingSapronakSummaries)
|
||||||
isResponseSuccess(outgoingSapronakSummaries)
|
? outgoingSapronakSummaries?.meta?.total_results
|
||||||
? outgoingSapronakSummaries?.meta?.total_results
|
: 0
|
||||||
: 0
|
}
|
||||||
}
|
onPageChange={setPage}
|
||||||
onPageChange={setPage}
|
isLoading={isLoadingOutgoingSapronakSummaries}
|
||||||
isLoading={isLoadingOutgoingSapronakSummaries}
|
sorting={sorting}
|
||||||
sorting={sorting}
|
setSorting={setSorting}
|
||||||
setSorting={setSorting}
|
rowSelection={rowSelection}
|
||||||
rowSelection={rowSelection}
|
setRowSelection={setRowSelection}
|
||||||
setRowSelection={setRowSelection}
|
className={{
|
||||||
className={{
|
containerClassName: 'w-full mb-0!',
|
||||||
containerClassName: cn({
|
tableWrapperClassName:
|
||||||
'w-full mb-20':
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
isResponseSuccess(outgoingSapronakSummaries) &&
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
outgoingSapronakSummaries?.data?.length === 0,
|
headerRowClassName:
|
||||||
}),
|
'border-b border-b-gray-200 bg-gray-50',
|
||||||
}}
|
headerColumnClassName:
|
||||||
/>
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
)}
|
bodyRowClassName:
|
||||||
</div>
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
</Collapse>
|
bodyColumnClassName:
|
||||||
</Card>
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,11 @@ import { useSearchParams } from 'next/navigation';
|
|||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||||
|
|
||||||
import { Icon } from '@iconify/react';
|
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
import Collapse from '@/components/Collapse';
|
|
||||||
|
|
||||||
import { cn, formatDate, formatNumber } from '@/lib/helper';
|
import { formatDate, formatNumber } from '@/lib/helper';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
import { ClosingApi } from '@/services/api/closing';
|
import { ClosingApi } from '@/services/api/closing';
|
||||||
@@ -52,8 +50,6 @@ const ClosingOutgoingSapronaksTable = ({
|
|||||||
ClosingApi.getAllOutgoingSapronakFetcher
|
ClosingApi.getAllOutgoingSapronakFetcher
|
||||||
);
|
);
|
||||||
|
|
||||||
const [open, setOpen] = useState(true);
|
|
||||||
|
|
||||||
const [sorting, setSorting] = useState<SortingState>([]);
|
const [sorting, setSorting] = useState<SortingState>([]);
|
||||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||||
|
|
||||||
@@ -118,109 +114,91 @@ const ClosingOutgoingSapronaksTable = ({
|
|||||||
}
|
}
|
||||||
}, [sorting, updateFilter]);
|
}, [sorting, updateFilter]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!open) {
|
|
||||||
setOpen(
|
|
||||||
isResponseSuccess(outgoingSapronaks)
|
|
||||||
? outgoingSapronaks.data.length > 0
|
|
||||||
: false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [outgoingSapronaks, isResponseSuccess]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<div className='w-full p-0 sm:p-3'>
|
||||||
className={{
|
<Card
|
||||||
wrapper: 'w-full',
|
className={{
|
||||||
body: 'p-4 shadow',
|
wrapper: 'w-full rounded-lg border-none',
|
||||||
}}
|
body: 'p-0',
|
||||||
>
|
title: 'px-2 py-1.5 font-normal text-sm bg-primary text-white',
|
||||||
<Collapse
|
collapsible: 'rounded-lg',
|
||||||
open={open}
|
}}
|
||||||
onOpenChange={setOpen}
|
variant='bordered'
|
||||||
title={
|
title='Sapronak Keluar'
|
||||||
<div className='card-actions p-4 justify-between items-center w-full'>
|
collapsible
|
||||||
<div className='card-title'>Sapronak Keluar</div>
|
defaultCollapsed={false}
|
||||||
|
|
||||||
<Icon
|
|
||||||
icon='material-symbols:keyboard-arrow-down'
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
className={cn('text-primary transition-transform', {
|
|
||||||
'-rotate-180': open,
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
className='w-full!'
|
|
||||||
titleClassName='w-full p-0!'
|
|
||||||
>
|
>
|
||||||
<div className='w-full p-0'>
|
<div className='flex flex-col gap-2 mb-4'>
|
||||||
<div className='flex flex-col gap-2 mb-4'>
|
<div className='w-full flex flex-col sm:flex-row justify-start items-end sm:items-center gap-4'>
|
||||||
<div className='w-full flex flex-col sm:flex-row justify-start items-end sm:items-center gap-4'>
|
<DebouncedTextInput
|
||||||
<DebouncedTextInput
|
name='search'
|
||||||
name='search'
|
placeholder='Cari Sapronak Keluar'
|
||||||
placeholder='Cari Sapronak Keluar'
|
value={tableFilterState.search}
|
||||||
value={tableFilterState.search}
|
onChange={searchChangeHandler}
|
||||||
onChange={searchChangeHandler}
|
className={{ wrapper: 'sm:max-w-3xs' }}
|
||||||
className={{ wrapper: 'sm:max-w-3xs' }}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isLoadingOutgoingSapronaks ? (
|
|
||||||
<SapronakClosingSkeleton
|
|
||||||
type='outgoing'
|
|
||||||
columns={outgoingSapronaksColumns}
|
|
||||||
/>
|
|
||||||
) : isResponseSuccess(outgoingSapronaks) &&
|
|
||||||
outgoingSapronaks.data.length === 0 ? (
|
|
||||||
<SapronakClosingSkeleton
|
|
||||||
type='outgoing'
|
|
||||||
columns={outgoingSapronaksColumns}
|
|
||||||
iconName='heroicons:chart-bar'
|
|
||||||
title='Data Sapronak Keluar Tidak Ditemukan'
|
|
||||||
subtitle='Tidak ada data sapronak keluar untuk periode ini.'
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Table<ClosingOutgoingSapronak>
|
|
||||||
data={
|
|
||||||
isResponseSuccess(outgoingSapronaks)
|
|
||||||
? outgoingSapronaks?.data
|
|
||||||
: []
|
|
||||||
}
|
|
||||||
columns={outgoingSapronaksColumns}
|
|
||||||
pageSize={tableFilterState.pageSize}
|
|
||||||
onPageSizeChange={setPageSize}
|
|
||||||
rowOptions={[10, 20, 50, 100]}
|
|
||||||
page={
|
|
||||||
isResponseSuccess(outgoingSapronaks)
|
|
||||||
? outgoingSapronaks?.meta?.page
|
|
||||||
: 0
|
|
||||||
}
|
|
||||||
totalItems={
|
|
||||||
isResponseSuccess(outgoingSapronaks)
|
|
||||||
? outgoingSapronaks?.meta?.total_results
|
|
||||||
: 0
|
|
||||||
}
|
|
||||||
onPageChange={setPage}
|
|
||||||
isLoading={isLoadingOutgoingSapronaks}
|
|
||||||
sorting={sorting}
|
|
||||||
setSorting={setSorting}
|
|
||||||
rowSelection={rowSelection}
|
|
||||||
setRowSelection={setRowSelection}
|
|
||||||
className={{
|
|
||||||
containerClassName: cn({
|
|
||||||
'w-full mb-20':
|
|
||||||
isResponseSuccess(outgoingSapronaks) &&
|
|
||||||
outgoingSapronaks?.data?.length === 0,
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</Collapse>
|
|
||||||
</Card>
|
{isLoadingOutgoingSapronaks ? (
|
||||||
|
<SapronakClosingSkeleton
|
||||||
|
type='outgoing'
|
||||||
|
columns={outgoingSapronaksColumns}
|
||||||
|
/>
|
||||||
|
) : isResponseSuccess(outgoingSapronaks) &&
|
||||||
|
outgoingSapronaks.data.length === 0 ? (
|
||||||
|
<SapronakClosingSkeleton
|
||||||
|
type='outgoing'
|
||||||
|
columns={outgoingSapronaksColumns}
|
||||||
|
iconName='heroicons:chart-bar'
|
||||||
|
title='Data Sapronak Keluar Tidak Ditemukan'
|
||||||
|
subtitle='Tidak ada data sapronak keluar untuk periode ini.'
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Table<ClosingOutgoingSapronak>
|
||||||
|
data={
|
||||||
|
isResponseSuccess(outgoingSapronaks)
|
||||||
|
? outgoingSapronaks?.data
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
columns={outgoingSapronaksColumns}
|
||||||
|
pageSize={tableFilterState.pageSize}
|
||||||
|
onPageSizeChange={setPageSize}
|
||||||
|
rowOptions={[10, 20, 50, 100]}
|
||||||
|
page={
|
||||||
|
isResponseSuccess(outgoingSapronaks)
|
||||||
|
? outgoingSapronaks?.meta?.page
|
||||||
|
: 0
|
||||||
|
}
|
||||||
|
totalItems={
|
||||||
|
isResponseSuccess(outgoingSapronaks)
|
||||||
|
? outgoingSapronaks?.meta?.total_results
|
||||||
|
: 0
|
||||||
|
}
|
||||||
|
onPageChange={setPage}
|
||||||
|
isLoading={isLoadingOutgoingSapronaks}
|
||||||
|
sorting={sorting}
|
||||||
|
setSorting={setSorting}
|
||||||
|
rowSelection={rowSelection}
|
||||||
|
setRowSelection={setRowSelection}
|
||||||
|
className={{
|
||||||
|
containerClassName: 'w-full mb-0!',
|
||||||
|
tableWrapperClassName:
|
||||||
|
'overflow-x-auto rounded-tr-none rounded-tl-none',
|
||||||
|
tableClassName: 'w-full table-auto text-sm',
|
||||||
|
headerRowClassName:
|
||||||
|
'border-b border-b-gray-200 bg-gray-50',
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||||
|
bodyRowClassName:
|
||||||
|
'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200',
|
||||||
|
bodyColumnClassName:
|
||||||
|
'px-4 py-3 text-xs text-gray-900 whitespace-nowrap',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user