refactor(FE): Refactor FinanceTable and simplify Finance page structure

This commit is contained in:
rstubryan
2026-02-27 11:14:13 +07:00
parent b14bc00af4
commit d3ce60d3ba
2 changed files with 446 additions and 265 deletions
+1 -6
View File
@@ -3,12 +3,7 @@
import FinanceTable from '@/components/pages/finance/FinanceTable'; import FinanceTable from '@/components/pages/finance/FinanceTable';
const Finance = () => { const Finance = () => {
return ( return <FinanceTable />;
<section className='size-full p-6'>
<div className='flex flex-row gap-4'></div>
<FinanceTable />
</section>
);
}; };
export default Finance; export default Finance;
+445 -259
View File
@@ -1,10 +1,19 @@
import { useEffect, useMemo, useRef, useState } from 'react'; 'use client';
import { CellContext } from '@tanstack/react-table';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { CellContext, ColumnDef } from '@tanstack/react-table';
import useSWR from 'swr'; import useSWR from 'swr';
import { Icon } from '@iconify/react';
import { useFormik } from 'formik'; import { useFormik } from 'formik';
import { cn, formatCurrency, formatDate, formatTitleCase } from '@/lib/helper';
import Button from '@/components/Button'; import Button from '@/components/Button';
import Card from '@/components/Card';
import DateInput from '@/components/input/DateInput'; import DateInput from '@/components/input/DateInput';
import DebouncedTextInput from '@/components/input/DebouncedTextInput'; import DebouncedTextInput from '@/components/input/DebouncedTextInput';
import SelectInput, { import SelectInput, {
@@ -12,7 +21,6 @@ import SelectInput, {
useSelect, useSelect,
} from '@/components/input/SelectInput'; } from '@/components/input/SelectInput';
import Table from '@/components/Table'; import Table from '@/components/Table';
import { formatCurrency, formatDate, formatTitleCase } from '@/lib/helper';
import { useTableFilter } from '@/services/hooks/useTableFilter'; import { useTableFilter } from '@/services/hooks/useTableFilter';
import { Finance } from '@/types/api/finance/finance'; import { Finance } from '@/types/api/finance/finance';
import { import {
@@ -25,115 +33,149 @@ import { FinanceApi } from '@/services/api/finance';
import { isResponseSuccess } from '@/lib/api-helper'; import { isResponseSuccess } from '@/lib/api-helper';
import { BankApi, CustomerApi, SupplierApi } from '@/services/api/master-data'; import { BankApi, CustomerApi, SupplierApi } from '@/services/api/master-data';
import { Bank } from '@/types/api/master-data/bank'; import { Bank } from '@/types/api/master-data/bank';
import { useModal } from '@/components/Modal'; import Modal, { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal'; import ConfirmationModal from '@/components/modal/ConfirmationModal';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import RowOptionsMenuWrapper from '@/components/table/RowOptionsMenuWrapper';
import RequirePermission from '@/components/helper/RequirePermission'; import RequirePermission from '@/components/helper/RequirePermission';
import { Icon } from '@iconify/react';
import RowDropdownOptions from '@/components/table/RowDropdownOptions';
import RowCollapseOptions from '@/components/table/RowCollapseOptions';
import { useUiStore } from '@/stores/ui/ui.store'; import { useUiStore } from '@/stores/ui/ui.store';
import { import {
FinanceTableFilterSchema, FinanceTableFilterSchema,
FinanceTableFilterValues, FinanceTableFilterValues,
} from './FinanceTableFilter.schema'; } from './FinanceTableFilter.schema';
import SelectInputRadio from '@/components/input/SelectInputRadio';
const RowOptionsMenu = ({ const RowOptionsMenu = ({
type = 'dropdown', popoverPosition = 'bottom',
props, props,
deleteClickHandler, deleteClickHandler,
}: { }: {
type: 'dropdown' | 'collapse'; popoverPosition: 'bottom' | 'top';
props: CellContext<Finance, unknown>; props: CellContext<Finance, unknown>;
deleteClickHandler: () => void; deleteClickHandler: () => void;
}) => { }) => {
const popoverId = `finance#${props.row.original.id}`;
const popoverAnchorName = `--anchor-finance#${props.row.original.id}`;
const closePopover = () => {
const popover = document.getElementById(popoverId) as
| HTMLDivElement
| undefined;
popover?.hidePopover?.();
};
return ( return (
<RowOptionsMenuWrapper type={type}> <div className='relative'>
<RequirePermission <Button
permissions={[ tabIndex={0}
'lti.finance.transactions.detail', variant='ghost'
'lti.finance.initial_balances.detail', color='none'
'lti.finance.injections.detail', className='p-2'
'lti.finance.payments.detail', popoverTarget={popoverId}
]} style={{ anchorName: popoverAnchorName } as React.CSSProperties}
> >
<Button <Icon icon='material-symbols:more-vert' width={20} height={20} />
href={`/finance/detail?financeId=${props.row.original.id}`} </Button>
variant='ghost'
color='primary'
className='justify-start text-sm'
>
<Icon icon='mdi:eye-outline' width={16} height={16} />
Detail
</Button>
</RequirePermission>
{FINANCE_TRANSACTION_STATUS.includes( <div
props.row.original.transaction_type id={popoverId}
) && ( popover='auto'
<RequirePermission permissions='lti.finance.payments.update'> style={{ positionAnchor: popoverAnchorName } as React.CSSProperties}
<Button className={cn(
href={`/finance/detail/edit?financeId=${props.row.original.id}`} 'fixed inset-auto bg-base-100 rounded-xl border border-base-content/5 shadow-sm w-full max-w-40 z-[100]',
variant='ghost' popoverPosition === 'bottom'
color='warning' ? 'top-[anchor(bottom)] left-[anchor(left)] mt-1'
className='justify-start text-sm' : 'bottom-[anchor(top)] left-[anchor(left)] mb-1'
)}
>
<div className='flex flex-col bg-base-100 rounded-xl'>
<RequirePermission
permissions={[
'lti.finance.transactions.detail',
'lti.finance.initial_balances.detail',
'lti.finance.injections.detail',
'lti.finance.payments.detail',
]}
> >
<Icon icon='material-symbols:edit-outline' width={16} height={16} /> <Button
Edit href={`/finance/detail?financeId=${props.row.original.id}`}
</Button> variant='ghost'
</RequirePermission> color='none'
)} className='p-3 justify-start text-sm font-semibold w-full'
onClick={closePopover}
>
<Icon icon='heroicons:eye' width={20} height={20} />
Detail
</Button>
</RequirePermission>
{FINANCE_INITIAL_BALANCE_STATUS.includes( {FINANCE_TRANSACTION_STATUS.includes(
props.row.original.transaction_type props.row.original.transaction_type
) && ( ) && (
<RequirePermission permissions='lti.finance.initial_balances.update'> <RequirePermission permissions='lti.finance.payments.update'>
<Button <Button
href={`/finance/detail/edit/initial-balance?financeId=${props.row.original.id}`} href={`/finance/detail/edit?financeId=${props.row.original.id}`}
variant='ghost' variant='ghost'
color='warning' color='none'
className='justify-start text-sm' className='p-3 justify-start text-sm font-semibold w-full'
> onClick={closePopover}
<Icon icon='material-symbols:edit-outline' width={16} height={16} /> >
Edit <Icon icon='mdi:pencil-outline' width={20} height={20} />
</Button> Edit
</RequirePermission> </Button>
)} </RequirePermission>
)}
{FINANCE_INJECTION_STATUS.includes( {FINANCE_INITIAL_BALANCE_STATUS.includes(
props.row.original.transaction_type props.row.original.transaction_type
) && ( ) && (
<RequirePermission permissions='lti.finance.injections.update'> <RequirePermission permissions='lti.finance.initial_balances.update'>
<Button <Button
href={`/finance/detail/edit/injection?financeId=${props.row.original.id}`} href={`/finance/detail/edit/initial-balance?financeId=${props.row.original.id}`}
variant='ghost' variant='ghost'
color='warning' color='none'
className='justify-start text-sm' className='p-3 justify-start text-sm font-semibold w-full'
> onClick={closePopover}
<Icon icon='material-symbols:edit-outline' width={16} height={16} /> >
Edit <Icon icon='mdi:pencil-outline' width={20} height={20} />
</Button> Edit
</RequirePermission> </Button>
)} </RequirePermission>
)}
<RequirePermission permissions='lti.finance.transactions.delete'> {FINANCE_INJECTION_STATUS.includes(
<Button props.row.original.transaction_type
onClick={deleteClickHandler} ) && (
variant='ghost' <RequirePermission permissions='lti.finance.injections.update'>
color='error' <Button
className='text-error hover:text-inherit' href={`/finance/detail/edit/injection?financeId=${props.row.original.id}`}
> variant='ghost'
<Icon color='none'
icon='material-symbols:delete-outline-rounded' className='p-3 justify-start text-sm font-semibold w-full'
width={16} onClick={closePopover}
height={16} >
className='justify-start text-sm' <Icon icon='mdi:pencil-outline' width={20} height={20} />
/> Edit
Delete </Button>
</Button> </RequirePermission>
</RequirePermission> )}
</RowOptionsMenuWrapper>
<RequirePermission permissions='lti.finance.transactions.delete'>
<Button
onClick={() => {
deleteClickHandler();
closePopover();
}}
variant='ghost'
color='error'
className='p-3 justify-start text-sm font-semibold w-full focus-visible:text-error-content hover:text-error-content'
>
<Icon icon='mdi:delete-outline' width={20} height={20} />
Delete
</Button>
</RequirePermission>
</div>
</div>
</div>
); );
}; };
@@ -171,6 +213,9 @@ const FinanceTable = () => {
}, },
}); });
// ===== FILTER MODAL STATE =====
const filterModal = useModal();
// ===== State ===== // ===== State =====
const deleteModal = useModal(); const deleteModal = useModal();
const [selectedTransactionType, setSelectedTransactionType] = useState< const [selectedTransactionType, setSelectedTransactionType] = useState<
@@ -214,6 +259,18 @@ const FinanceTable = () => {
updateFilter('sortBy', values.sort_by); updateFilter('sortBy', values.sort_by);
updateFilter('startDate', values.start_date); updateFilter('startDate', values.start_date);
updateFilter('endDate', values.end_date); updateFilter('endDate', values.end_date);
filterModal.closeModal();
},
onReset: () => {
updateFilter('search', '');
resetSearchValue();
updateFilter('transactionTypes', '');
updateFilter('bankIds', '');
updateFilter('customerIds', '');
updateFilter('supplierIds', '');
updateFilter('sortBy', '');
updateFilter('startDate', '');
updateFilter('endDate', '');
}, },
}); });
@@ -266,10 +323,41 @@ const FinanceTable = () => {
}); });
}, [bankOptions, bankRawData]); }, [bankOptions, bankRawData]);
// ===== ACTIVE FILTERS COUNT =====
const activeFiltersCount = useMemo(() => {
let count = 0;
if (tableFilterState.transactionTypes) count += 1;
if (tableFilterState.bankIds) count += 1;
if (tableFilterState.customerIds) count += 1;
if (tableFilterState.supplierIds) count += 1;
if (tableFilterState.sortBy) count += 1;
if (tableFilterState.startDate) count += 1;
if (tableFilterState.endDate) count += 1;
return count;
}, [
tableFilterState.transactionTypes,
tableFilterState.bankIds,
tableFilterState.customerIds,
tableFilterState.supplierIds,
tableFilterState.sortBy,
tableFilterState.startDate,
tableFilterState.endDate,
]);
const hasFilters = activeFiltersCount > 0;
// ===== Handler ===== // ===== Handler =====
const searchChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => { const searchChangeHandler = useCallback(
filterFormik.setFieldValue('search', e.target.value); (e: React.ChangeEvent<HTMLInputElement>) => {
}; updateFilter('search', e.target.value);
setSearchValue(e.target.value);
setPage(1);
},
[updateFilter, setSearchValue, setPage]
);
const transactionTypeChangeHandler = ( const transactionTypeChangeHandler = (
val: OptionType | OptionType[] | null val: OptionType | OptionType[] | null
) => { ) => {
@@ -387,6 +475,11 @@ const FinanceTable = () => {
} }
}; };
const handleFilterModalOpen = () => {
filterModal.openModal();
filterFormik.validateForm();
};
const resetFilterHandler = () => { const resetFilterHandler = () => {
setSelectedTransactionType(null); setSelectedTransactionType(null);
setSelectedBank(null); setSelectedBank(null);
@@ -406,6 +499,7 @@ const FinanceTable = () => {
updateFilter('startDate', ''); updateFilter('startDate', '');
updateFilter('endDate', ''); updateFilter('endDate', '');
}; };
const confirmationModalDeleteClickHandler = async () => { const confirmationModalDeleteClickHandler = async () => {
setIsDeleteLoading(true); setIsDeleteLoading(true);
@@ -417,8 +511,8 @@ const FinanceTable = () => {
setIsDeleteLoading(false); setIsDeleteLoading(false);
}; };
const columns = useMemo(() => { const columns: ColumnDef<Finance>[] = useMemo(
return [ () => [
{ {
header: 'ID', header: 'ID',
accessorKey: 'payment_code', accessorKey: 'payment_code',
@@ -498,32 +592,17 @@ const FinanceTable = () => {
}; };
return ( return (
<> <RowOptionsMenu
{currentPageSize > 2 && ( props={props}
<RowDropdownOptions isLast2Rows={isLast2Rows}> deleteClickHandler={deleteClickHandler}
<RowOptionsMenu popoverPosition={isLast2Rows ? 'top' : 'bottom'}
type='dropdown' />
props={props}
deleteClickHandler={deleteClickHandler}
/>
</RowDropdownOptions>
)}
{currentPageSize <= 2 && (
<RowCollapseOptions>
<RowOptionsMenu
type='collapse'
props={props}
deleteClickHandler={deleteClickHandler}
/>
</RowCollapseOptions>
)}
</>
); );
}, },
}, },
]; ],
}, []); []
);
useEffect(() => { useEffect(() => {
return () => { return () => {
@@ -555,151 +634,258 @@ const FinanceTable = () => {
}, [resetSearchValue, dateErrorShown]); }, [resetSearchValue, dateErrorShown]);
return ( return (
<section className='size-full flex flex-col gap-6'> <>
<div className='flex justify-end gap-2'> <div className='w-full'>
<RequirePermission permissions='lti.finance.injections.create'> {/* Header Section */}
<Button <div className='w-full p-3 flex flex-row justify-between gap-3 flex-wrap border-b border-base-content/10'>
color='warning' {/* Action Buttons */}
className='min-w-24' <div className='w-fit flex flex-row gap-3 flex-wrap'>
href='/finance/add/injection' <RequirePermission permissions='lti.finance.injections.create'>
> <Button
Injection Saldo Bank href='/finance/add/injection'
</Button> color='warning'
</RequirePermission> className='px-3 py-2.5 w-fit text-sm text-base-100 rounded-lg shadow-sm'
<RequirePermission permissions='lti.finance.initial_balances.create'> >
<Button <Icon icon='mdi:bank-transfer-in' width={20} height={20} />
color='info' Add Injection (Saldo Bank)
className='text-white min-w-24' </Button>
href='/finance/add/initial-balance' </RequirePermission>
> <RequirePermission permissions='lti.finance.initial_balances.create'>
Saldo Awal <Button
</Button> href='/finance/add/initial-balance'
</RequirePermission> color='info'
<RequirePermission permissions='lti.finance.payments.create'> className='px-3 py-2.5 w-fit text-sm text-base-100 rounded-lg shadow-sm'
<Button color='primary' className='min-w-24' href='/finance/add'> >
Tambah <Icon icon='mdi:cash-register' width={20} height={20} />
</Button> Add Initial Balance
</RequirePermission> </Button>
</div> </RequirePermission>
<Card <RequirePermission permissions='lti.finance.payments.create'>
variant='bordered' <Button
className={{ href='/finance/add'
wrapper: 'w-full', color='primary'
}} className='px-3 py-2.5 w-fit text-sm text-base-100 rounded-lg shadow-sm'
footer={ >
<div className='flex justify-end gap-2'> <Icon icon='heroicons:plus' width={20} height={20} />
Add Finance
</Button>
</RequirePermission>
</div>
{/* Search and Filter */}
<div className='flex flex-1 flex-row justify-start sm:justify-end items-center gap-3 flex-wrap'>
<DebouncedTextInput
name='search'
placeholder='Search'
value={tableFilterState.search ?? ''}
onChange={searchChangeHandler}
startAdornment={
<Icon
icon='heroicons:magnifying-glass'
width={20}
height={20}
/>
}
className={{
wrapper: 'w-full min-w-24 max-w-3xs',
inputWrapper: 'rounded-xl! shadow-button-soft',
input:
'placeholder:font-semibold placeholder:text-base-content/50',
}}
/>
<Button <Button
color='warning' variant='outline'
className='min-w-24' color='none'
onClick={resetFilterHandler} onClick={handleFilterModalOpen}
className={cn(
'px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft transition-all',
{
'border-primary-gradient text-primary': hasFilters,
}
)}
> >
Reset <Icon icon='heroicons:funnel' width={20} height={20} />
</Button> Filter
<Button {hasFilters && (
color='primary' <span className='w-5 h-5 text-white bg-[#FF3535] rounded-lg border border-base-300 flex items-center justify-center text-xs'>
className='min-w-24' {activeFiltersCount}
onClick={() => filterFormik.handleSubmit()} </span>
> )}
Cari
</Button> </Button>
</div> </div>
}
>
<div className='grid grid-cols-4 gap-6'>
<SelectInput
options={FINANCE_TRANSACTION_TYPE_OPTIONS}
label='Jenis Transaksi'
value={selectedTransactionType}
onChange={transactionTypeChangeHandler}
closeMenuOnSelect={false}
isClearable
isMulti
/>
<SelectInput
options={customerOptions}
label={'Customer'}
value={selectedCustomerId}
onChange={customerIdChangeHandler}
onInputChange={customerInputValue}
onMenuScrollToBottom={customerLoadMore}
isLoading={customerIsLoadingOptions}
closeMenuOnSelect={false}
isClearable
isMulti
/>
<SelectInput
options={supplierOptions}
label={'Supplier'}
value={selectedSupplierId}
onChange={supplierIdChangeHandler}
onInputChange={supplierInputValue}
onMenuScrollToBottom={supplierLoadMore}
isLoading={supplierIsLoadingOptions}
closeMenuOnSelect={false}
isClearable
isMulti
/>
<SelectInput
options={bankSelectOptions}
label='Bank'
value={selectedBank}
onChange={bankChangeHandler}
onInputChange={bankInputValue}
onMenuScrollToBottom={bankLoadMore}
closeMenuOnSelect={false}
isClearable
isMulti
/>
<SelectInput
options={sortByOptions}
label='Urutkan Berdasarkan'
value={selectedSortBy}
onChange={sortByChangeHandler}
isClearable
/>
<DateInput
name='start_date'
label='Periode Tanggal (Mulai)'
value={filterFormik.values.start_date}
onChange={startDateChangeHandler}
errorMessage={
filterFormik.errors.end_date
? filterFormik.errors.end_date
: undefined
}
/>
<DateInput
name='end_date'
label='Periode Tanggal (Akhir)'
value={filterFormik.values.end_date}
onChange={endDateChangeHandler}
errorMessage={
filterFormik.errors.end_date
? filterFormik.errors.end_date
: undefined
}
/>
<DebouncedTextInput
name='search'
label='Cari'
placeholder='Cari'
value={filterFormik.values.search}
onChange={searchChangeHandler}
/>
</div> </div>
</Card>
<Table<Finance> {/* Table Section */}
data={isResponseSuccess(finances) ? finances.data : []} <div className='flex flex-col mb-4 -mx-4 px-4'>
columns={columns} {isLoading ? (
pageSize={tableFilterState.pageSize} <div className='w-full flex flex-row justify-center items-center p-4'>
page={tableFilterState.page} <span className='loading loading-spinner loading-xl' />
onPageChange={setPage} </div>
onPageSizeChange={setPageSize} ) : (
totalItems={ <Table<Finance>
isResponseSuccess(finances) ? finances.meta?.total_results : 0 data={isResponseSuccess(finances) ? finances.data : []}
} columns={columns}
isLoading={isLoading} pageSize={tableFilterState.pageSize}
/> page={tableFilterState.page}
totalItems={
isResponseSuccess(finances) ? finances.meta?.total_results : 0
}
onPageChange={setPage}
onPageSizeChange={setPageSize}
isLoading={isLoading}
className={{
containerClassName: 'p-3 mb-0',
headerColumnClassName: 'text-nowrap',
}}
/>
)}
</div>
</div>
{/* Filter Modal */}
<Modal
ref={filterModal.ref}
className={{
modal: 'p-0',
modalBox: 'p-0 rounded-[0.875rem] xl:max-w-4/12 max-w-sm',
}}
>
{/* Modal Header */}
<div className='flex items-center justify-between gap-2 border-b border-base-content/10 p-4'>
<div className='flex items-center gap-2 text-primary'>
<Icon icon='heroicons:funnel' width={20} height={20} />
<h3 className='font-medium text-sm'>Filter Data</h3>
</div>
<Button
variant='link'
onClick={filterModal.closeModal}
className='text-base-content/50 hover:text-base-content transition-colors cursor-pointer'
>
<Icon icon='heroicons:x-mark' width={20} height={20} />
</Button>
</div>
<form
onSubmit={filterFormik.handleSubmit}
onReset={filterFormik.handleReset}
>
<div className='p-4 flex flex-col gap-1.5'>
<SelectInput
options={FINANCE_TRANSACTION_TYPE_OPTIONS}
label='Jenis Transaksi'
placeholder='Pilih Jenis Transaksi'
value={selectedTransactionType}
onChange={transactionTypeChangeHandler}
onInputChange={() => {}}
closeMenuOnSelect={false}
isClearable
isMulti
className={{ wrapper: 'w-full' }}
/>
<SelectInput
options={customerOptions}
label='Customer'
placeholder='Pilih Customer'
value={selectedCustomerId}
onChange={customerIdChangeHandler}
onInputChange={customerInputValue}
onMenuScrollToBottom={customerLoadMore}
isLoading={customerIsLoadingOptions}
closeMenuOnSelect={false}
isClearable
isMulti
className={{ wrapper: 'w-full' }}
/>
<SelectInput
options={supplierOptions}
label='Supplier'
placeholder='Pilih Supplier'
value={selectedSupplierId}
onChange={supplierIdChangeHandler}
onInputChange={supplierInputValue}
onMenuScrollToBottom={supplierLoadMore}
isLoading={supplierIsLoadingOptions}
closeMenuOnSelect={false}
isClearable
isMulti
className={{ wrapper: 'w-full' }}
/>
<SelectInput
options={bankSelectOptions}
label='Bank'
placeholder='Pilih Bank'
value={selectedBank}
onChange={bankChangeHandler}
onInputChange={bankInputValue}
onMenuScrollToBottom={bankLoadMore}
closeMenuOnSelect={false}
isClearable
isMulti
className={{ wrapper: 'w-full' }}
/>
<SelectInputRadio
options={sortByOptions}
label='Urutkan Berdasarkan'
placeholder='Pilih Urutan'
value={selectedSortBy}
onChange={sortByChangeHandler}
isClearable
className={{ wrapper: 'w-full' }}
/>
<DateInput
name='start_date'
label='Periode Tanggal (Mulai)'
value={filterFormik.values.start_date}
onChange={startDateChangeHandler}
errorMessage={
filterFormik.errors.end_date
? filterFormik.errors.end_date
: undefined
}
/>
<DateInput
name='end_date'
label='Periode Tanggal (Akhir)'
value={filterFormik.values.end_date}
onChange={endDateChangeHandler}
errorMessage={
filterFormik.errors.end_date
? filterFormik.errors.end_date
: undefined
}
/>
</div>
{/* Modal Footer */}
<div className='flex justify-between items-center gap-4 p-4 border-t border-base-content/10 bg-gray-50'>
<Button
type='button'
variant='soft'
className='rounded-lg text-base-content/65 bg-transparent border-none hover:bg-base-content/10 hover:text-base-content/65 transition-colors px-3 py-2'
onClick={() => {
filterFormik.resetForm();
setSelectedTransactionType(null);
setSelectedBank(null);
setSelectedCustomerId(null);
setSelectedSupplierId(null);
setSelectedSortBy(null);
resetFilterHandler();
filterModal.closeModal();
}}
>
Reset Filter
</Button>
<Button
type='submit'
className='min-w-40 text-sm rounded-lg py-3 text-white font-semibold'
disabled={!filterFormik.isValid || filterFormik.isSubmitting}
>
Apply Filter
</Button>
</div>
</form>
</Modal>
<ConfirmationModal <ConfirmationModal
ref={deleteModal.ref} ref={deleteModal.ref}
type='error' type='error'
@@ -714,7 +900,7 @@ const FinanceTable = () => {
onClick: confirmationModalDeleteClickHandler, onClick: confirmationModalDeleteClickHandler,
}} }}
/> />
</section> </>
); );
}; };