export function BlockchainTable()

in src/components/graphs/table.tsx [142:458]


export function BlockchainTable({
  total,
  cb,
}: {
  total: number;
  cb: (state: unknown) => void;
}) {
  const [loading, setLoading] = React.useState(false);
  const [data, setData] = React.useState<Block[]>([]);
  const [pageIndex, setPageIndex] = React.useState(0);
  const [pageSize, setPageSize] = React.useState(10);

  // Fetch blocks data
  const fetchBlocksData = React.useCallback(async () => {
    console.log("Page Idx", pageIndex);
    try {
      setLoading(true);

      const start = pageIndex * pageSize + 1;
      const end = Math.min(total, start + pageSize - 1);
      cb((prev: { start: number; end: number }) => ({
        ...prev,
        start,
        end,
      }));

      const response = await middlewareApi.get(`/explorer/getBlocks`, {
        params: { start, end },
      });
      console.log("Response is: ", response?.data);
      setData(response?.data as Block[]);
      setLoading(false);
    } catch (error) {
      console.error(error);
      setLoading(false);
    }
  }, [pageIndex, pageSize, total]);

  // Run fetchBlocksData when pageIndex or pageSize changes
  React.useEffect(() => {
    fetchBlocksData();
  }, [fetchBlocksData]); // Direct dependencies

  const totalPages = Math.ceil(total / pageSize);

  const handlePageChange = (newPageIndex: number) => {
    if (newPageIndex >= 0 && newPageIndex < totalPages) {
      console.log("Changing page from", pageIndex, "to", newPageIndex);
      setPageIndex(newPageIndex);
    }
  };

  const visiblePages = 5;
  const startPage = Math.max(
    0,
    Math.min(
      pageIndex - Math.floor(visiblePages / 2),
      totalPages - visiblePages
    )
  );
  const endPage = Math.min(startPage + visiblePages, totalPages);

  const [sorting, setSorting] = React.useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
    []
  );
  const [columnVisibility, setColumnVisibility] =
    React.useState<VisibilityState>({});

  const table = useReactTable({
    data,
    columns,
    manualPagination: true,
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    onColumnVisibilityChange: setColumnVisibility,
    state: {
      sorting,
      columnFilters,
      columnVisibility,
      pagination: { pageIndex, pageSize },
    },
    pageCount: totalPages,
  });

  if (loading) {
    return (
      <div className="w-full">
        <div className="flex items-center py-4">
          <Skeleton className="h-8 w-[250px]" />
          <Skeleton className="ml-auto h-8 w-[100px]" />
        </div>
        <div className="rounded-md border">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>
                  <Skeleton className="h-4 w-[100px]" />
                </TableHead>
                <TableHead>
                  <Skeleton className="h-4 w-[100px]" />
                </TableHead>
                <TableHead>
                  <Skeleton className="h-4 w-[100px]" />
                </TableHead>
                <TableHead>
                  <Skeleton className="h-4 w-[100px]" />
                </TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {[...Array(10)].map((_, index) => (
                <TableRow key={index}>
                  <TableCell>
                    <Skeleton className="h-4 w-[50px]" />
                  </TableCell>
                  <TableCell>
                    <Skeleton className="h-4 w-[100px]" />
                  </TableCell>
                  <TableCell>
                    <Skeleton className="h-4 w-[50px]" />
                  </TableCell>
                  <TableCell>
                    <Skeleton className="h-4 w-[150px]" />
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
        <div className="flex items-center justify-end space-x-2 py-4">
          <Skeleton className="h-8 w-[80px]" />
          <Skeleton className="h-8 w-[80px]" />
        </div>
      </div>
    );
  } else {
    return (
      <div className="w-full">
        <div className="flex items-center py-4">
          <Input
            placeholder="Filter blocks..."
            value={
              (table.getColumn("number")?.getFilterValue() as string) ?? ""
            }
            onChange={(event) =>
              table.getColumn("number")?.setFilterValue(event.target.value)
            }
            className="max-w-sm"
          />
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="outline" className="ml-auto">
                Columns <ChevronDown className="ml-2 h-4 w-4" />
              </Button>
            </DropdownMenuTrigger>
            <Select
              value={String(pageSize)}
              onValueChange={(value) => {
                setPageSize(Number(value));
                setPageIndex(0);
              }}
            >
              <SelectTrigger className="w-[150px]">
                <span>Page Size {pageSize}</span>
              </SelectTrigger>
              <SelectContent>
                {[5, 10, 20, 50, 100, 200].map((size) => (
                  <SelectItem key={size} value={String(size)}>
                    Page Size {size}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Button
              variant="outline"
              className="ml-4"
              onClick={fetchBlocksData}
            >
              Refresh
            </Button>

            <DropdownMenuContent align="end">
              {table
                .getAllColumns()
                .filter((column) => column.getCanHide())
                .map((column) => {
                  return (
                    <DropdownMenuCheckboxItem
                      key={column.id}
                      className="capitalize"
                      checked={column.getIsVisible()}
                      onCheckedChange={(value) =>
                        column.toggleVisibility(!!value)
                      }
                    >
                      {column.id}
                    </DropdownMenuCheckboxItem>
                  );
                })}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
        <div className="rounded-md border">
          <Table>
            <TableHeader>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id}>
                  {headerGroup.headers.map((header) => {
                    return (
                      <TableHead key={header.id}>
                        {header.isPlaceholder
                          ? null
                          : flexRender(
                              header.column.columnDef.header,
                              header.getContext()
                            )}
                      </TableHead>
                    );
                  })}
                </TableRow>
              ))}
            </TableHeader>
            <TableBody>
              {table.getRowModel().rows?.length ? (
                table.getRowModel().rows.map((row) => (
                  <TableRow
                    key={row.id}
                    data-state={row.getIsSelected() && "selected"}
                  >
                    {row.getVisibleCells().map((cell) => (
                      <TableCell key={cell.id}>
                        {flexRender(
                          cell.column.columnDef.cell,
                          cell.getContext()
                        )}
                      </TableCell>
                    ))}
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell
                    colSpan={columns.length}
                    className="h-24 text-center"
                  >
                    No results...
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
        <div className="flex items-center justify-end space-x-2 py-4">
          {/* Go to Start Button */}
          <Button
            variant="outline"
            size="sm"
            onClick={() => handlePageChange(0)}
            disabled={pageIndex === 0}
          >
            Go to Start
          </Button>

          {/* Previous Button */}
          <Button
            variant="outline"
            size="sm"
            onClick={() => handlePageChange(pageIndex - 1)}
            disabled={pageIndex === 0}
          >
            Previous
          </Button>

          {/* Page Numbers */}
          {Array.from(
            { length: endPage - startPage },
            (_, i) => startPage + i
          ).map((page) => (
            <Button
              key={page}
              variant={page === pageIndex ? "default" : "outline"}
              size="sm"
              onClick={() => handlePageChange(page)}
            >
              {page + 1}
            </Button>
          ))}

          {/* Next Button */}
          <Button
            variant="outline"
            size="sm"
            onClick={() => handlePageChange(pageIndex + 1)}
            disabled={pageIndex === totalPages - 1}
          >
            Next
          </Button>

          {/* Go to End Button */}
          <Button
            variant="outline"
            size="sm"
            onClick={() => handlePageChange(totalPages - 1)}
            disabled={pageIndex === totalPages - 1}
          >
            Go to End
          </Button>
        </div>
      </div>
    );
  }
}