Skip to content
Snippets Groups Projects
PublicationsTable.component.tsx 4.64 KiB
Newer Older
import { ONE, ZERO } from '@/constants/common';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import {
  totalSizeSelector,
  paginationSelector,
  isLoadingSelector,
} from '@/redux/publications/publications.selectors';
import { getPublications } from '@/redux/publications/publications.thunks';
import { Button } from '@/shared/Button';
import { Publication } from '@/types/models';
import {
  createColumnHelper,
  flexRender,
  getCoreRowModel,
  useReactTable,
} from '@tanstack/react-table';
import { useEffect, useState } from 'react';

const columnHelper = createColumnHelper<Publication>();

const columns = [
  columnHelper.accessor(row => row.publication.article.pubmedId, { header: 'Pubmed ID' }),
  columnHelper.accessor(row => row.publication.article.title, { header: 'Title' }),
  columnHelper.accessor(row => row.publication.article.authors, { header: 'Authors' }),
  columnHelper.accessor(row => row.publication.article.journal, { header: 'Journal' }),
  columnHelper.accessor(row => row.publication.article.year, { header: 'Year' }),
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  columnHelper.accessor(row => '{link to element on map}', { header: 'Elements on map' }),
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  columnHelper.accessor(row => '{link to submap}', { header: 'Submaps' }),
];

type PublicationsTableProps = {
  data: Publication[];
};

export const PublicationsTable = ({ data }: PublicationsTableProps): JSX.Element => {
  const dispatch = useAppDispatch();
  const pagesCount = useAppSelector(totalSizeSelector);
  const isPublicationsLoading = useAppSelector(isLoadingSelector);

  const reduxPagination = useAppSelector(paginationSelector);
  const [pagination, setPagination] = useState(reduxPagination);
  useEffect(() => {
    dispatch(getPublications({ page: pagination.pageIndex, length: pagination.pageSize }));
  }, [pagination, dispatch]);

  const table = useReactTable({
    state: {
      pagination,
    },
    columns,
    data,
    getCoreRowModel: getCoreRowModel(),
    manualPagination: true,
    pageCount: pagesCount,
    onPaginationChange: setPagination,
  });

  return (
    <div className="flex max-h-full w-full flex-col items-center justify-center bg-white p-6">
      <div className="overflow-y-auto">
        <table className="table-auto overflow-auto text-sm">
          <thead className="sticky top-0 bg-white-pearl">
            {table.getHeaderGroups().map(headerGroup => (
              <tr key={headerGroup.id} className="border-y ">
                {headerGroup.headers.map(header => (
                  <th key={header.id} className="whitespace-nowrap py-2.5">
                    {header.isPlaceholder
                      ? null
                      : flexRender(header.column.columnDef.header, header.getContext())}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody>
            {data &&
              table.getRowModel().rows.map(row => (
                <tr key={row.id} className="even:bg-lotion">
                  {row.getVisibleCells().map(cell => (
                    <td key={cell.id} className="p-3">
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </td>
                  ))}
                </tr>
              ))}
          </tbody>
        </table>
      </div>
      <div className="flex w-full flex-row justify-end border-t">
        <div className="mt-6 flex flex-row items-center">
          <Button
            variantStyles="quiet"
            className="text-primary-500"
            onClick={() => table.setPageIndex(ZERO)}
            disabled={isPublicationsLoading}
          >
            First page
          </Button>
          <Button
            variantStyles="secondary"
            onClick={() => table.previousPage()}
            disabled={isPublicationsLoading}
          >
            Previous page
          </Button>

          <div className="mx-4 text-sm font-semibold">
            Page {table.getState().pagination.pageIndex + ONE} out of {table.getPageCount()}
          </div>

          <Button
            variantStyles="secondary"
            onClick={() => table.nextPage()}
            disabled={isPublicationsLoading}
          >
            Next page
          </Button>
          <Button
            variantStyles="quiet"
            className="text-primary-500"
            onClick={() => table.setPageIndex(table.getPageCount() - ONE)}
            disabled={isPublicationsLoading}
          >
            Last page
          </Button>
        </div>
      </div>
    </div>
  );
};