46ddc018a6
- Added TableSortProvider to manage sorting state in AdminsTable, CmsTable, CompaniesTable, CustomersTable, TendersTable, and CompanyCategoriesTable. - Enhanced TableHead component to support sortable columns with visual indicators for sort direction. - Introduced columnSortKeys and columnDefaultOrder mappings in respective table presenters to define sortable fields and default sorting behavior. - Updated useCompanyListPresenter, useCmsTablePresenter, useCustomerListPresenter, useTenderListPresenter, and useCompanyCategoriesPresenter to handle sorting logic and state management. - Improved user experience by allowing dynamic sorting of table data based on user interactions.
195 lines
6.6 KiB
TypeScript
195 lines
6.6 KiB
TypeScript
"use client";
|
|
|
|
import { ExclamationIcon, EyeIcon } from "@/assets/icons";
|
|
import EmptyListWrapper from "@/components/HOC/EmptyListWrapper";
|
|
import Status from "@/components/ui/Status";
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
TableSortProvider,
|
|
} from "@/components/ui/table";
|
|
import IsVisible from "@/components/ui/IsVisible";
|
|
import ListHeader from "@/components/ui/ListHeader";
|
|
import ListWrapper from "@/components/ui/ListWrapper";
|
|
import Pagination from "@/components/ui/pagination";
|
|
import TableSkeleton from "@/components/ui/TableSkeleton";
|
|
import { _TooltipDefaultParams } from "@/constants/tooltip";
|
|
import { cn } from "@/lib/utils";
|
|
import { Tooltip } from "react-tooltip";
|
|
import TenderListFilters from "./TenderListFilters";
|
|
import useTenderListPresenter from "./useTenderListPresenter";
|
|
|
|
const TendersTable = () => {
|
|
const {
|
|
columns,
|
|
columnSortKeys,
|
|
columnDefaultOrder,
|
|
sortBy,
|
|
sortOrder,
|
|
handleSortChange,
|
|
filterRegister,
|
|
handleFilterSubmit,
|
|
search,
|
|
watch,
|
|
setFilterValue,
|
|
control,
|
|
isMutating,
|
|
shouldShowPagination,
|
|
clearAllFilters,
|
|
tableSectionRef,
|
|
skeletonTbodyRef,
|
|
dataTbodyRef,
|
|
tendersList,
|
|
isPending,
|
|
navigateToTenderDetails,
|
|
navigateToTenderFeedback,
|
|
handlePaginationChange,
|
|
buildWindowedPageLabel,
|
|
getRowNumber,
|
|
formatDateTimeCell,
|
|
pagination,
|
|
absoluteCurrentPage,
|
|
} = useTenderListPresenter();
|
|
|
|
return (
|
|
<ListWrapper>
|
|
<ListHeader
|
|
hasFilter={false}
|
|
createButtonText="Create Tender"
|
|
hasCreate={false}
|
|
/>
|
|
<TenderListFilters
|
|
setValue={setFilterValue}
|
|
filterRegister={filterRegister}
|
|
control={control}
|
|
handleFilterSubmit={handleFilterSubmit}
|
|
isMutating={isMutating as number}
|
|
search={search}
|
|
watch={watch}
|
|
onClearAll={clearAllFilters}
|
|
/>
|
|
<div ref={tableSectionRef}>
|
|
<TableSortProvider
|
|
sortKey={sortBy}
|
|
sortOrder={sortOrder}
|
|
onSortChange={handleSortChange}
|
|
>
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow className="border-none uppercase [&>th]:text-start">
|
|
{columns.map((column) => {
|
|
const sortKey = columnSortKeys[column];
|
|
return (
|
|
<TableHead
|
|
key={column}
|
|
colSpan={100}
|
|
sortable={Boolean(sortKey)}
|
|
sortKey={sortKey}
|
|
defaultSortOrder={columnDefaultOrder[column]}
|
|
>
|
|
{column}
|
|
</TableHead>
|
|
);
|
|
})}
|
|
</TableRow>
|
|
</TableHeader>
|
|
|
|
{isPending ? (
|
|
<TableSkeleton ref={skeletonTbodyRef} column={columns.length} />
|
|
) : (
|
|
<TableBody ref={dataTbodyRef}>
|
|
<EmptyListWrapper
|
|
list={tendersList}
|
|
columns={columns}
|
|
emptyMessage="No tenders were found"
|
|
isLoading={false}
|
|
>
|
|
{tendersList.map((item, index) => (
|
|
<TableRow
|
|
key={item.id}
|
|
className="odd:bg-gray-2 dark:odd:bg-gray-7"
|
|
>
|
|
<TableCell className="text-start" colSpan={100}>
|
|
{getRowNumber(index)}
|
|
</TableCell>
|
|
<TableCell className="text-start" colSpan={100}>
|
|
{item.title}
|
|
</TableCell>
|
|
<TableCell className="text-start" colSpan={100}>
|
|
{item.country_code}
|
|
</TableCell>
|
|
<TableCell className="text-start" colSpan={100}>
|
|
{formatDateTimeCell(item.publication_date)}
|
|
</TableCell>
|
|
<TableCell className="text-start" colSpan={100}>
|
|
{formatDateTimeCell(item.submission_deadline)}
|
|
</TableCell>
|
|
<TableCell className="text-start" colSpan={100}>
|
|
{formatDateTimeCell(item.tender_deadline)}
|
|
</TableCell>
|
|
<TableCell className="text-start" colSpan={100}>
|
|
{formatDateTimeCell(item?.created_at ?? 0)}
|
|
</TableCell>
|
|
|
|
<TableCell className={cn(`text capitalize`)} colSpan={100}>
|
|
<Status status={item.status}>{item.status}</Status>
|
|
</TableCell>
|
|
<TableCell className="capitalize" colSpan={100}>
|
|
<div className="flex items-center gap-2">
|
|
<button
|
|
type="button"
|
|
data-tooltip-id="details"
|
|
data-tooltip-content="Details"
|
|
data-tooltip-place="top"
|
|
onClick={() => navigateToTenderDetails(item.id)}
|
|
>
|
|
<Tooltip
|
|
{..._TooltipDefaultParams({
|
|
id: "details",
|
|
})}
|
|
/>
|
|
<EyeIcon />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
data-tooltip-id="feedback"
|
|
data-tooltip-content="Feedback"
|
|
data-tooltip-place="top"
|
|
className="text-gray-40 rounded-full bg-gray-dark bg-opacity-5 hover:text-green-dark dark:bg-gray dark:bg-opacity-5"
|
|
onClick={() => navigateToTenderFeedback(item.id)}
|
|
>
|
|
<Tooltip {..._TooltipDefaultParams({ id: "feedback" })} />
|
|
<ExclamationIcon />
|
|
</button>
|
|
</div>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</EmptyListWrapper>
|
|
</TableBody>
|
|
)}
|
|
</Table>
|
|
</TableSortProvider>
|
|
</div>
|
|
<IsVisible condition={shouldShowPagination}>
|
|
<Pagination
|
|
key={`pagination-tenders-${absoluteCurrentPage}`}
|
|
currentPage={pagination.currentPage}
|
|
totalPages={pagination.totalPages}
|
|
onPageChange={handlePaginationChange}
|
|
pageRangeDisplayed={3}
|
|
marginPagesDisplayed={1}
|
|
pageLabelBuilder={buildWindowedPageLabel}
|
|
variant="tenders"
|
|
/>
|
|
</IsVisible>
|
|
</ListWrapper>
|
|
);
|
|
};
|
|
|
|
export default TendersTable;
|