import React, { useEffect, useRef, useState } from "react"; import Link from "next/link"; import MiniSearch from "minisearch"; import ReactPaginate from "react-paginate"; import styles from "../styles/CellList.module.css"; import type { CellCoord } from "./ModData"; const PAGE_SIZE = 100; type Props = { cells: CellCoord[]; }; const CellList: React.FC = ({ cells }) => { const cellSearch = useRef | null>( null ) as React.MutableRefObject>; useEffect(() => { cellSearch.current = new MiniSearch({ fields: ["id"], storeFields: ["id", "x", "y"], tokenize: (s) => [s.replace(/cell\s?|\s/gi, "")], searchOptions: { fields: ["id"], prefix: true, fuzzy: false, }, }); cellSearch.current.addAll( cells.map((cell) => ({ ...cell, id: `${cell.x},${cell.y}` })) ); }, [cells]); const [filter, setFilter] = useState(""); const [filterResults, setFilterResults] = useState>(new Set()); const [page, setPage] = useState(0); const filteredCells = cells .filter((cell) => !filter || filterResults.has(`${cell.x},${cell.y}`)) .sort((a, b) => (a.x - b.x) * 1000 + a.y - b.y); useEffect(() => { if (cellSearch.current) { setFilterResults( new Set(cellSearch.current.search(filter).map((result) => result.id)) ); } }, [filter]); useEffect(() => { setPage(0); }, [filterResults]); const renderPagination = () => ( { setPage(event.selected); document.getElementById("exterior-cells")?.scrollIntoView(); }} pageRangeDisplayed={3} marginPagesDisplayed={2} pageCount={Math.ceil(filteredCells.length / PAGE_SIZE)} previousLabel="<" renderOnZeroPageCount={() => null} className={styles.pagination} activeClassName={styles["active-page"]} hrefBuilder={() => "#"} /> ); return ( filteredCells && ( <>

Exterior Cells ({filteredCells.length})


setFilter(event.target.value)} />

{renderPagination()}
    {filteredCells .slice(page * PAGE_SIZE, page * PAGE_SIZE + PAGE_SIZE) .map((cell) => (
  • ))}
{renderPagination()} ) ); }; export default CellList;