oriyo_next/src/widgets/transactions-table/ui/transactions-table.tsx

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>
);
};