124 lines
3.6 KiB
TypeScript
124 lines
3.6 KiB
TypeScript
import { format } from 'date-fns';
|
|
import { ChangeEvent, useEffect, useState } from 'react';
|
|
|
|
import TableLoadingOverlay from '@/shared/components/table-loading-overlay';
|
|
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHeader,
|
|
TableRow,
|
|
} from '@/shared/shadcn-ui/table';
|
|
|
|
import { TransactionsTablePagination } from './table-pagination';
|
|
import { TransactionsTableHeader } from './transactions-table-header';
|
|
|
|
export interface TransactionRequest {
|
|
start_date?: string;
|
|
end_date?: string;
|
|
page: number;
|
|
limit: number;
|
|
}
|
|
|
|
export interface TransactionsTableProps<T> {
|
|
data: {
|
|
transactions: T[];
|
|
total_pages: number;
|
|
total_records: number;
|
|
};
|
|
isLoading: boolean;
|
|
onChange: (request: TransactionRequest) => void;
|
|
renderHeaders: () => React.ReactNode;
|
|
renderRow: (transaction: T, index: number) => React.ReactNode;
|
|
itemsPerPageOptions?: number[];
|
|
}
|
|
|
|
export const TransactionsTable = <T,>({
|
|
data,
|
|
isLoading,
|
|
onChange,
|
|
renderHeaders,
|
|
renderRow,
|
|
itemsPerPageOptions = [5, 10, 20, 50],
|
|
}: TransactionsTableProps<T>) => {
|
|
const [startDate, setStartDate] = useState<Date | undefined>(
|
|
new Date(new Date().setMonth(new Date().getMonth() - 1)),
|
|
);
|
|
const [endDate, setEndDate] = useState<Date | undefined>(new Date());
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const [itemsPerPage, setItemsPerPage] = useState(itemsPerPageOptions[0]);
|
|
|
|
const handlePageChange = (page: number) => {
|
|
if (page < 1 || page > data.total_pages) return;
|
|
setCurrentPage(page);
|
|
};
|
|
|
|
const handleItemsPerPageChange = (e: ChangeEvent<HTMLSelectElement>) => {
|
|
setItemsPerPage(Number(e.target.value));
|
|
setCurrentPage(1); // Reset to first page when changing items per page
|
|
};
|
|
|
|
const filterTransactions = () => {
|
|
if (!startDate || !endDate) return;
|
|
setCurrentPage(1); // Reset to the first page when applying filters
|
|
};
|
|
|
|
const { t } = useTextController();
|
|
|
|
useEffect(() => {
|
|
onChange({
|
|
limit: itemsPerPage,
|
|
page: currentPage,
|
|
...(startDate ? { start_date: format(startDate, 'yyyy-MM-dd') } : {}),
|
|
...(endDate ? { end_date: format(endDate, 'yyyy-MM-dd') } : {}),
|
|
});
|
|
}, [startDate, endDate, itemsPerPage, currentPage]);
|
|
|
|
if (!data) return null;
|
|
|
|
return (
|
|
<div className='relative space-y-6'>
|
|
<TableLoadingOverlay isLoading={isLoading} />
|
|
<TransactionsTableHeader
|
|
startDate={startDate}
|
|
setStartDate={setStartDate}
|
|
endDate={endDate}
|
|
setEndDate={setEndDate}
|
|
/>
|
|
|
|
<div className='relative rounded-md border'>
|
|
<Table>
|
|
<TableHeader>{renderHeaders()}</TableHeader>
|
|
<TableBody>
|
|
{data.transactions.length > 0 ? (
|
|
data.transactions.map((transaction, index) =>
|
|
renderRow(transaction, index),
|
|
)
|
|
) : (
|
|
<TableRow>
|
|
<TableCell
|
|
colSpan={6}
|
|
className='py-6 text-center text-gray-500'
|
|
>
|
|
{t('corporate.transactions.no-data')}
|
|
</TableCell>
|
|
</TableRow>
|
|
)}
|
|
</TableBody>
|
|
</Table>
|
|
</div>
|
|
<TransactionsTablePagination
|
|
currentPage={currentPage}
|
|
itemsPerPage={itemsPerPage}
|
|
itemsPerPageOptions={itemsPerPageOptions}
|
|
totalPages={data.total_pages}
|
|
transactionsQuantity={data.transactions.length}
|
|
totalOperations={data.total_records}
|
|
onPageChange={handlePageChange}
|
|
onItemsPerPageChange={handleItemsPerPageChange}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|