Untitled - MARKUP 5.95 KB
                                
                                    import {
  Paper,
  Skeleton,
  Table as MuiTable,
  TablePagination,
  TableSortLabel,
} from "@mui/material";
import { styled } from "@mui/material/styles";
import TableBody from "@mui/material/TableBody";
import TableCell, { tableCellClasses } from "@mui/material/TableCell";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import {
  ColumnDef,
  flexRender,
  getCoreRowModel,
  getSortedRowModel,
  useReactTable,
} from "@tanstack/react-table";
import React, { memo, useState } from "react";
import { BaseEntity } from "../types/users";

interface TableProps<T> {
  data: T[];
  columns: ColumnDef<T, unknown>[];
  isFetching?: boolean;
  rowsPerPage: number;
  setRowsPerPage: React.Dispatch<React.SetStateAction<number>>;
  setLastRowId: React.Dispatch<React.SetStateAction<number | undefined>>;
  rowCount: number;
  setDirection: React.Dispatch<React.SetStateAction<string>>;
}

const StyledTableCell = styled(TableCell)(({ theme }) => ({
  [`&.${tableCellClasses.head}`]: {
    backgroundColor: "lightgray",
    fontWeight: "bold",
  },
  [`&.${tableCellClasses.body}`]: {
    fontSize: 14,
  },
}));

function Table<T extends BaseEntity>(props: TableProps<T>) {
  const {
    data,
    columns,
    isFetching,
    rowsPerPage,
    setRowsPerPage,
    setLastRowId,
    rowCount,
    setDirection,
  } = props;

  const { getHeaderGroups, getRowModel, getAllColumns } = useReactTable<T>({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    manualPagination: true,
    getSortedRowModel: getSortedRowModel(),
  });

  const handleChangePage = (
    event: React.MouseEvent<HTMLButtonElement> | null,
    newPage: number
  ) => {
    if (newPage >= page) {
      const id = data[data.length - 1].id;
      setLastRowId(id);
      setDirection("desc");
    } else {
      const id = data[0].id;
      setLastRowId(id);
      setDirection("asc");
    }

    setPage(newPage);
  };

  const handleChangeRowsPerPage = (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    setRowsPerPage(parseInt(event.target.value, 10));

    setLastRowId(undefined);
    setDirection("desc");
    setPage(0);
  };

  const skeletons = Array.from({ length: data.length }, (x, i) => i);
  const columnCount = getAllColumns().length;

  const [page, setPage] = useState(0);

  return (
    <Paper sx={{ overflowX: "auto" }}>
      <MuiTable
        style={{
          whiteSpace: "nowrap",
          overflow: "hidden",
          textOverflow: "ellipsis",
        }}
      >
        <TableHead>
          {getHeaderGroups().map((headerGroup) => (
            <TableRow key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <StyledTableCell key={header.id}>
                  <>
                    {header.isPlaceholder
                      ? null
                      : flexRender(
                          header.column.columnDef.header,
                          header.getContext()
                        )}

                    {header.column.getCanSort() ? (
                      <TableSortLabel
                        active={header.column.getIsSorted() ? true : false}
                        onClick={header.column.getToggleSortingHandler()}
                        direction={
                          header.column.getIsSorted() === "asc"
                            ? "asc"
                            : header.column.getIsSorted() === "desc"
                            ? "desc"
                            : undefined
                        }
                      />
                    ) : null}
                  </>
                </StyledTableCell>
              ))}
            </TableRow>
          ))}
        </TableHead>

        <TableBody>
          {!isFetching ? (
            getRowModel().rows.map((row) => (
              <TableRow key={row.id}>
                {row.getVisibleCells().map((cell) => (
                  <TableCell key={cell.id}>
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </TableCell>
                ))}
              </TableRow>
            ))
          ) : (
            <>
              {skeletons.map((skeleton) => (
                <TableRow key={skeleton}>
                  {Array.from({ length: columnCount }, (x, i) => i).map(
                    (elm) => (
                      <TableCell key={elm}>
                        <Skeleton />
                      </TableCell>
                    )
                  )}
                </TableRow>
              ))}
            </>
          )}
        </TableBody>
      </MuiTable>

      <TablePagination
        component="div"
        count={-1}
        page={page}
        onPageChange={handleChangePage}
        rowsPerPageOptions={[3, 5, 10, 25, 50, 100]}
        rowsPerPage={rowsPerPage}
        onRowsPerPageChange={handleChangeRowsPerPage}
        labelRowsPerPage="Wiersze na stronę"
        labelDisplayedRows={({ from, to }) => `${from}-${to} elementów`}
        nextIconButtonProps={{
          disabled: data.length >= rowCount && page !== 0,
        }}
      />
    </Paper>
  );
}

export default memo(Table);
                                
                            

Paste Hosted With By Wklejamy.pl