mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE): Refactor table components to improve styling and structure
This commit is contained in:
@@ -82,7 +82,7 @@ const FinanceClosingTable = ({
|
||||
}, [finance]);
|
||||
|
||||
return (
|
||||
<div className='flex flex-col gap-4'>
|
||||
<div className='flex flex-col gap-4 p-0 sm:p-3'>
|
||||
{isLoading ? (
|
||||
<FinanceClosingSkeleton />
|
||||
) : !isResponseSuccess(finance) ? (
|
||||
@@ -96,10 +96,13 @@ const FinanceClosingTable = ({
|
||||
<Card
|
||||
variant='bordered'
|
||||
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>Laba Rugi Brutto</div>
|
||||
<div className='text-lg font-bold'>
|
||||
@@ -127,10 +130,13 @@ const FinanceClosingTable = ({
|
||||
variant='bordered'
|
||||
collapsible
|
||||
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>
|
||||
data={hppTableData}
|
||||
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) => {
|
||||
const rowData = row.original;
|
||||
if (rowData.code === 'custom_row') {
|
||||
@@ -296,10 +320,13 @@ const FinanceClosingTable = ({
|
||||
variant='bordered'
|
||||
collapsible
|
||||
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>
|
||||
data={profitLossTableData}
|
||||
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) => {
|
||||
const rowData = row.original;
|
||||
if (rowData.code === 'custom_row') {
|
||||
@@ -404,9 +450,6 @@ const FinanceClosingTable = ({
|
||||
}
|
||||
return null;
|
||||
}}
|
||||
className={{
|
||||
paginationClassName: 'hidden',
|
||||
}}
|
||||
renderFooter={isResponseSuccess(finance)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -91,53 +91,56 @@ const HppExpeditionClosingTable = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className='w-full'>
|
||||
<div className='p-4'>
|
||||
<h2 className='text-xl font-semibold mb-4'>HPP Ekspedisi</h2>
|
||||
<Card
|
||||
<div className='w-full p-0 sm:p-3'>
|
||||
<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='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={{
|
||||
wrapper: 'w-full bg-base-100',
|
||||
body: 'p-0',
|
||||
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',
|
||||
}}
|
||||
>
|
||||
{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={{
|
||||
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>
|
||||
</>
|
||||
/>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -209,15 +209,18 @@ const OverheadClosingTable = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='w-full p-0 sm:p-3'>
|
||||
<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'
|
||||
collapsible
|
||||
defaultCollapsed={false}
|
||||
className={{
|
||||
wrapper: 'w-full',
|
||||
body: 'p-4 shadow',
|
||||
}}
|
||||
>
|
||||
{isLoadingOverhead ? (
|
||||
<OverheadClosingSkeleton columns={columns} />
|
||||
@@ -243,11 +246,24 @@ const OverheadClosingTable = ({
|
||||
}
|
||||
columns={columns}
|
||||
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(
|
||||
TABLE_DEFAULT_STYLING.headerColumnClassName,
|
||||
'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200',
|
||||
'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}
|
||||
renderFooter={
|
||||
@@ -312,7 +328,7 @@ const OverheadClosingTable = ({
|
||||
</Card>
|
||||
)}
|
||||
</Card>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -316,50 +316,54 @@ const SalesClosingTable = ({ projectFlockId }: SalesClosingTableProps) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className='w-full'>
|
||||
<div className='p-4'>
|
||||
<h2 className='text-xl font-semibold mb-4'>Penjualan</h2>
|
||||
<Card
|
||||
<div className='w-full p-0 sm:p-3'>
|
||||
<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='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={{
|
||||
wrapper: 'w-full bg-base-100',
|
||||
body: 'p-0',
|
||||
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',
|
||||
}}
|
||||
>
|
||||
{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={{
|
||||
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>
|
||||
</>
|
||||
/>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ const SapronakCalculationClosingTable = ({
|
||||
);
|
||||
|
||||
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 */}
|
||||
<Card
|
||||
title={
|
||||
@@ -190,9 +190,12 @@ const SapronakCalculationClosingTable = ({
|
||||
collapsible
|
||||
defaultCollapsed={false}
|
||||
className={{
|
||||
wrapper: 'w-full',
|
||||
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',
|
||||
collapsible: 'rounded-lg',
|
||||
}}
|
||||
variant='bordered'
|
||||
>
|
||||
{isLoading ? (
|
||||
<SapronakCalculationClosingSkeleton columns={docColumns} />
|
||||
@@ -213,7 +216,22 @@ const SapronakCalculationClosingTable = ({
|
||||
}
|
||||
columns={docColumns}
|
||||
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={
|
||||
isResponseSuccess(sapronakCalculation) &&
|
||||
@@ -229,7 +247,10 @@ const SapronakCalculationClosingTable = ({
|
||||
collapsible
|
||||
defaultCollapsed={true}
|
||||
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 ? (
|
||||
@@ -251,7 +272,22 @@ const SapronakCalculationClosingTable = ({
|
||||
}
|
||||
columns={ovkColumns}
|
||||
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={
|
||||
isResponseSuccess(sapronakCalculation) &&
|
||||
@@ -267,7 +303,10 @@ const SapronakCalculationClosingTable = ({
|
||||
collapsible
|
||||
defaultCollapsed={true}
|
||||
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 ? (
|
||||
@@ -289,7 +328,22 @@ const SapronakCalculationClosingTable = ({
|
||||
}
|
||||
columns={pakanColumns}
|
||||
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={
|
||||
isResponseSuccess(sapronakCalculation) &&
|
||||
|
||||
@@ -5,12 +5,10 @@ import { useSearchParams } from 'next/navigation';
|
||||
import useSWR from 'swr';
|
||||
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||
|
||||
import { Icon } from '@iconify/react';
|
||||
import Table from '@/components/Table';
|
||||
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 { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import { ClosingApi } from '@/services/api/closing';
|
||||
@@ -56,8 +54,6 @@ const ClosingIncomingSapronaksSummaryTable = ({
|
||||
}
|
||||
);
|
||||
|
||||
const [open, setOpen] = useState(true);
|
||||
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||
|
||||
@@ -94,97 +90,78 @@ const ClosingIncomingSapronaksSummaryTable = ({
|
||||
}
|
||||
}, [sorting, updateFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
setOpen(
|
||||
isResponseSuccess(incomingSapronakSummaries)
|
||||
? incomingSapronakSummaries.data.length > 0
|
||||
: false
|
||||
);
|
||||
}
|
||||
}, [incomingSapronakSummaries, isResponseSuccess]);
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={{
|
||||
wrapper: 'w-full',
|
||||
body: 'p-4 shadow',
|
||||
}}
|
||||
>
|
||||
<Collapse
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
title={
|
||||
<div className='card-actions p-4 justify-between items-center w-full'>
|
||||
<div className='card-title'>Ringkasan Sapronak Masuk</div>
|
||||
|
||||
<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 sm:p-3'>
|
||||
<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='Ringkasan Sapronak Masuk'
|
||||
collapsible
|
||||
defaultCollapsed={false}
|
||||
>
|
||||
<div className='w-full p-0'>
|
||||
{isLoadingIncomingSapronakSummaries ? (
|
||||
<SapronakClosingSkeleton
|
||||
type='incoming'
|
||||
columns={incomingSapronaksColumns}
|
||||
/>
|
||||
) : isResponseSuccess(incomingSapronakSummaries) &&
|
||||
incomingSapronakSummaries.data.length === 0 ? (
|
||||
<SapronakClosingSkeleton
|
||||
type='incoming'
|
||||
columns={incomingSapronaksColumns}
|
||||
iconName='heroicons:chart-bar'
|
||||
title='Ringkasan Sapronak Masuk Tidak Ditemukan'
|
||||
subtitle='Tidak ada ringkasan sapronak masuk untuk periode ini.'
|
||||
/>
|
||||
) : (
|
||||
<Table<ClosingIncomingSapronakSummary>
|
||||
data={
|
||||
isResponseSuccess(incomingSapronakSummaries)
|
||||
? incomingSapronakSummaries?.data
|
||||
: []
|
||||
}
|
||||
columns={incomingSapronaksColumns}
|
||||
pageSize={tableFilterState.pageSize}
|
||||
onPageSizeChange={setPageSize}
|
||||
rowOptions={[10, 20, 50, 100]}
|
||||
page={
|
||||
isResponseSuccess(incomingSapronakSummaries)
|
||||
? incomingSapronakSummaries?.meta?.page
|
||||
: 0
|
||||
}
|
||||
totalItems={
|
||||
isResponseSuccess(incomingSapronakSummaries)
|
||||
? incomingSapronakSummaries?.meta?.total_results
|
||||
: 0
|
||||
}
|
||||
onPageChange={setPage}
|
||||
isLoading={isLoadingIncomingSapronakSummaries}
|
||||
sorting={sorting}
|
||||
setSorting={setSorting}
|
||||
rowSelection={rowSelection}
|
||||
setRowSelection={setRowSelection}
|
||||
className={{
|
||||
containerClassName: cn({
|
||||
'w-full mb-20':
|
||||
isResponseSuccess(incomingSapronakSummaries) &&
|
||||
incomingSapronakSummaries?.data?.length === 0,
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Collapse>
|
||||
</Card>
|
||||
{isLoadingIncomingSapronakSummaries ? (
|
||||
<SapronakClosingSkeleton
|
||||
type='incoming'
|
||||
columns={incomingSapronaksColumns}
|
||||
/>
|
||||
) : isResponseSuccess(incomingSapronakSummaries) &&
|
||||
incomingSapronakSummaries.data.length === 0 ? (
|
||||
<SapronakClosingSkeleton
|
||||
type='incoming'
|
||||
columns={incomingSapronaksColumns}
|
||||
iconName='heroicons:chart-bar'
|
||||
title='Ringkasan Sapronak Masuk Tidak Ditemukan'
|
||||
subtitle='Tidak ada ringkasan sapronak masuk untuk periode ini.'
|
||||
/>
|
||||
) : (
|
||||
<Table<ClosingIncomingSapronakSummary>
|
||||
data={
|
||||
isResponseSuccess(incomingSapronakSummaries)
|
||||
? incomingSapronakSummaries?.data
|
||||
: []
|
||||
}
|
||||
columns={incomingSapronaksColumns}
|
||||
pageSize={tableFilterState.pageSize}
|
||||
onPageSizeChange={setPageSize}
|
||||
rowOptions={[10, 20, 50, 100]}
|
||||
page={
|
||||
isResponseSuccess(incomingSapronakSummaries)
|
||||
? incomingSapronakSummaries?.meta?.page
|
||||
: 0
|
||||
}
|
||||
totalItems={
|
||||
isResponseSuccess(incomingSapronakSummaries)
|
||||
? incomingSapronakSummaries?.meta?.total_results
|
||||
: 0
|
||||
}
|
||||
onPageChange={setPage}
|
||||
isLoading={isLoadingIncomingSapronakSummaries}
|
||||
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,13 +5,11 @@ import { useSearchParams } from 'next/navigation';
|
||||
import useSWR from 'swr';
|
||||
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||
|
||||
import { Icon } from '@iconify/react';
|
||||
import Table from '@/components/Table';
|
||||
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
||||
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 { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import { ClosingApi } from '@/services/api/closing';
|
||||
@@ -52,8 +50,6 @@ const ClosingIncomingSapronaksTable = ({
|
||||
ClosingApi.getAllIncomingSapronakFetcher
|
||||
);
|
||||
|
||||
const [open, setOpen] = useState(true);
|
||||
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||
|
||||
@@ -118,109 +114,90 @@ const ClosingIncomingSapronaksTable = ({
|
||||
}
|
||||
}, [sorting, updateFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
setOpen(
|
||||
isResponseSuccess(incomingSapronaks)
|
||||
? incomingSapronaks.data.length > 0
|
||||
: false
|
||||
);
|
||||
}
|
||||
}, [incomingSapronaks, isResponseSuccess]);
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={{
|
||||
wrapper: 'w-full',
|
||||
body: 'p-4 shadow',
|
||||
}}
|
||||
>
|
||||
<Collapse
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
title={
|
||||
<div className='card-actions p-4 justify-between items-center w-full'>
|
||||
<div className='card-title'>Sapronak Masuk</div>
|
||||
|
||||
<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 sm:p-3'>
|
||||
<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='Sapronak Masuk'
|
||||
collapsible
|
||||
defaultCollapsed={false}
|
||||
>
|
||||
<div className='w-full p-0'>
|
||||
<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'>
|
||||
<DebouncedTextInput
|
||||
name='search'
|
||||
placeholder='Cari Sapronak Masuk'
|
||||
value={tableFilterState.search}
|
||||
onChange={searchChangeHandler}
|
||||
className={{ wrapper: 'sm:max-w-3xs' }}
|
||||
/>
|
||||
</div>
|
||||
<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'>
|
||||
<DebouncedTextInput
|
||||
name='search'
|
||||
placeholder='Cari Sapronak Masuk'
|
||||
value={tableFilterState.search}
|
||||
onChange={searchChangeHandler}
|
||||
className={{ wrapper: 'sm:max-w-3xs' }}
|
||||
/>
|
||||
</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>
|
||||
</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 { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||
|
||||
import { Icon } from '@iconify/react';
|
||||
import Table from '@/components/Table';
|
||||
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 { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import { ClosingApi } from '@/services/api/closing';
|
||||
@@ -56,8 +54,6 @@ const ClosingOutgoingSapronaksSummaryTable = ({
|
||||
}
|
||||
);
|
||||
|
||||
const [open, setOpen] = useState(true);
|
||||
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||
|
||||
@@ -94,97 +90,79 @@ const ClosingOutgoingSapronaksSummaryTable = ({
|
||||
}
|
||||
}, [sorting, updateFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
setOpen(
|
||||
isResponseSuccess(outgoingSapronakSummaries)
|
||||
? outgoingSapronakSummaries.data.length > 0
|
||||
: false
|
||||
);
|
||||
}
|
||||
}, [outgoingSapronakSummaries, isResponseSuccess]);
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={{
|
||||
wrapper: 'w-full',
|
||||
body: 'p-4 shadow',
|
||||
}}
|
||||
>
|
||||
<Collapse
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
title={
|
||||
<div className='card-actions p-4 justify-between items-center w-full'>
|
||||
<div className='card-title'>Ringkasan Sapronak Keluar</div>
|
||||
|
||||
<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 sm:p-3'>
|
||||
<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='Ringkasan Sapronak Keluar'
|
||||
collapsible
|
||||
defaultCollapsed={false}
|
||||
>
|
||||
<div className='w-full p-0'>
|
||||
{isLoadingOutgoingSapronakSummaries ? (
|
||||
<SapronakClosingSkeleton
|
||||
type='outgoing'
|
||||
columns={outgoingSapronaksColumns}
|
||||
/>
|
||||
) : isResponseSuccess(outgoingSapronakSummaries) &&
|
||||
outgoingSapronakSummaries.data.length === 0 ? (
|
||||
<SapronakClosingSkeleton
|
||||
type='outgoing'
|
||||
columns={outgoingSapronaksColumns}
|
||||
iconName='heroicons:chart-bar'
|
||||
title='Ringkasan Sapronak Keluar Tidak Ditemukan'
|
||||
subtitle='Tidak ada ringkasan sapronak keluar untuk periode ini.'
|
||||
/>
|
||||
) : (
|
||||
<Table<ClosingOutgoingSapronakSummary>
|
||||
data={
|
||||
isResponseSuccess(outgoingSapronakSummaries)
|
||||
? outgoingSapronakSummaries?.data
|
||||
: []
|
||||
}
|
||||
columns={outgoingSapronaksColumns}
|
||||
pageSize={tableFilterState.pageSize}
|
||||
onPageSizeChange={setPageSize}
|
||||
rowOptions={[10, 20, 50, 100]}
|
||||
page={
|
||||
isResponseSuccess(outgoingSapronakSummaries)
|
||||
? outgoingSapronakSummaries?.meta?.page
|
||||
: 0
|
||||
}
|
||||
totalItems={
|
||||
isResponseSuccess(outgoingSapronakSummaries)
|
||||
? outgoingSapronakSummaries?.meta?.total_results
|
||||
: 0
|
||||
}
|
||||
onPageChange={setPage}
|
||||
isLoading={isLoadingOutgoingSapronakSummaries}
|
||||
sorting={sorting}
|
||||
setSorting={setSorting}
|
||||
rowSelection={rowSelection}
|
||||
setRowSelection={setRowSelection}
|
||||
className={{
|
||||
containerClassName: cn({
|
||||
'w-full mb-20':
|
||||
isResponseSuccess(outgoingSapronakSummaries) &&
|
||||
outgoingSapronakSummaries?.data?.length === 0,
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Collapse>
|
||||
</Card>
|
||||
{isLoadingOutgoingSapronakSummaries ? (
|
||||
<SapronakClosingSkeleton
|
||||
type='outgoing'
|
||||
columns={outgoingSapronaksColumns}
|
||||
/>
|
||||
) : isResponseSuccess(outgoingSapronakSummaries) &&
|
||||
outgoingSapronakSummaries.data.length === 0 ? (
|
||||
<SapronakClosingSkeleton
|
||||
type='outgoing'
|
||||
columns={outgoingSapronaksColumns}
|
||||
iconName='heroicons:chart-bar'
|
||||
title='Ringkasan Sapronak Keluar Tidak Ditemukan'
|
||||
subtitle='Tidak ada ringkasan sapronak keluar untuk periode ini.'
|
||||
/>
|
||||
) : (
|
||||
<Table<ClosingOutgoingSapronakSummary>
|
||||
data={
|
||||
isResponseSuccess(outgoingSapronakSummaries)
|
||||
? outgoingSapronakSummaries?.data
|
||||
: []
|
||||
}
|
||||
columns={outgoingSapronaksColumns}
|
||||
pageSize={tableFilterState.pageSize}
|
||||
onPageSizeChange={setPageSize}
|
||||
rowOptions={[10, 20, 50, 100]}
|
||||
page={
|
||||
isResponseSuccess(outgoingSapronakSummaries)
|
||||
? outgoingSapronakSummaries?.meta?.page
|
||||
: 0
|
||||
}
|
||||
totalItems={
|
||||
isResponseSuccess(outgoingSapronakSummaries)
|
||||
? outgoingSapronakSummaries?.meta?.total_results
|
||||
: 0
|
||||
}
|
||||
onPageChange={setPage}
|
||||
isLoading={isLoadingOutgoingSapronakSummaries}
|
||||
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,13 +5,11 @@ import { useSearchParams } from 'next/navigation';
|
||||
import useSWR from 'swr';
|
||||
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||
|
||||
import { Icon } from '@iconify/react';
|
||||
import Table from '@/components/Table';
|
||||
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
||||
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 { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import { ClosingApi } from '@/services/api/closing';
|
||||
@@ -52,8 +50,6 @@ const ClosingOutgoingSapronaksTable = ({
|
||||
ClosingApi.getAllOutgoingSapronakFetcher
|
||||
);
|
||||
|
||||
const [open, setOpen] = useState(true);
|
||||
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
|
||||
|
||||
@@ -118,109 +114,91 @@ const ClosingOutgoingSapronaksTable = ({
|
||||
}
|
||||
}, [sorting, updateFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
setOpen(
|
||||
isResponseSuccess(outgoingSapronaks)
|
||||
? outgoingSapronaks.data.length > 0
|
||||
: false
|
||||
);
|
||||
}
|
||||
}, [outgoingSapronaks, isResponseSuccess]);
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={{
|
||||
wrapper: 'w-full',
|
||||
body: 'p-4 shadow',
|
||||
}}
|
||||
>
|
||||
<Collapse
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
title={
|
||||
<div className='card-actions p-4 justify-between items-center w-full'>
|
||||
<div className='card-title'>Sapronak Keluar</div>
|
||||
|
||||
<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 sm:p-3'>
|
||||
<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='Sapronak Keluar'
|
||||
collapsible
|
||||
defaultCollapsed={false}
|
||||
>
|
||||
<div className='w-full p-0'>
|
||||
<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'>
|
||||
<DebouncedTextInput
|
||||
name='search'
|
||||
placeholder='Cari Sapronak Keluar'
|
||||
value={tableFilterState.search}
|
||||
onChange={searchChangeHandler}
|
||||
className={{ wrapper: 'sm:max-w-3xs' }}
|
||||
/>
|
||||
</div>
|
||||
<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'>
|
||||
<DebouncedTextInput
|
||||
name='search'
|
||||
placeholder='Cari Sapronak Keluar'
|
||||
value={tableFilterState.search}
|
||||
onChange={searchChangeHandler}
|
||||
className={{ wrapper: 'sm:max-w-3xs' }}
|
||||
/>
|
||||
</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>
|
||||
</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