Added some more pagination

This commit is contained in:
Tiago Ribeiro
2024-09-08 23:02:48 +01:00
parent eab6ab03b7
commit 745eef981f
4 changed files with 102 additions and 47 deletions

View File

@@ -1,51 +1,77 @@
import {Column, flexRender, getCoreRowModel, getSortedRowModel, useReactTable} from "@tanstack/react-table"; import {Column, flexRender, getCoreRowModel, getSortedRowModel, useReactTable} from "@tanstack/react-table";
import {useMemo, useState} from "react";
import Button from "./Low/Button";
const SIZE = 25;
export default function List<T>({data, columns}: {data: T[]; columns: any[]}) { export default function List<T>({data, columns}: {data: T[]; columns: any[]}) {
const [page, setPage] = useState(0);
const items = useMemo(() => data.slice(page * SIZE, (page + 1) * SIZE > data.length ? data.length : (page + 1) * SIZE), [data, page]);
const table = useReactTable({ const table = useReactTable({
data, data: items,
columns: columns, columns: columns,
getCoreRowModel: getCoreRowModel(), getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(), getSortedRowModel: getSortedRowModel(),
}); });
return ( return (
<table className="rounded-xl bg-mti-purple-ultralight/40 w-full"> <div className="w-full h-full flex flex-col gap-2">
<thead> <div className="w-full flex gap-2 justify-between">
{table.getHeaderGroups().map((headerGroup) => ( <Button className="w-full max-w-[200px]" disabled={page === 0} onClick={() => setPage((prev) => prev - 1)}>
<tr key={headerGroup.id}> Previous Page
{headerGroup.headers.map((header) => ( </Button>
<th key={header.id} colSpan={header.colSpan}> <div className="flex items-center gap-4 w-fit">
{header.isPlaceholder ? null : ( <span className="opacity-80">
<> {page * SIZE + 1} - {(page + 1) * SIZE > data.length ? data.length : (page + 1) * SIZE} / {data.length}
<div </span>
{...{ <Button className="w-[200px]" disabled={(page + 1) * SIZE >= data.length} onClick={() => setPage((prev) => prev + 1)}>
className: header.column.getCanSort() ? "cursor-pointer select-none py-4 text-left first:pl-4" : "", Next Page
onClick: header.column.getToggleSortingHandler(), </Button>
}}> </div>
{flexRender(header.column.columnDef.header, header.getContext())} </div>
{{
asc: " 🔼", <table className="rounded-xl bg-mti-purple-ultralight/40 w-full">
desc: " 🔽", <thead>
}[header.column.getIsSorted() as string] ?? null} {table.getHeaderGroups().map((headerGroup) => (
</div> <tr key={headerGroup.id}>
</> {headerGroup.headers.map((header) => (
)} <th key={header.id} colSpan={header.colSpan}>
</th> {header.isPlaceholder ? null : (
))} <>
</tr> <div
))} {...{
</thead> className: header.column.getCanSort()
<tbody className="px-2"> ? "cursor-pointer select-none py-4 text-left first:pl-4"
{table.getRowModel().rows.map((row) => ( : "",
<tr className="odd:bg-white even:bg-mti-purple-ultralight/40 rounded-lg py-2" key={row.id}> onClick: header.column.getToggleSortingHandler(),
{row.getVisibleCells().map((cell) => ( }}>
<td className="px-4 py-2" key={cell.id}> {flexRender(header.column.columnDef.header, header.getContext())}
{flexRender(cell.column.columnDef.cell, cell.getContext())} {{
</td> asc: " 🔼",
))} desc: " 🔽",
</tr> }[header.column.getIsSorted() as string] ?? null}
))} </div>
</tbody> </>
</table> )}
</th>
))}
</tr>
))}
</thead>
<tbody className="px-2">
{table.getRowModel().rows.map((row) => (
<tr className="odd:bg-white even:bg-mti-purple-ultralight/40 rounded-lg py-2" key={row.id}>
{row.getVisibleCells().map((cell) => (
<td className="px-4 py-2" key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
); );
} }

View File

@@ -1,4 +1,4 @@
import React from "react"; import React, {useEffect, useMemo, useState} from "react";
import {CorporateUser, User} from "@/interfaces/user"; import {CorporateUser, User} from "@/interfaces/user";
import {BsFileExcel, BsBank, BsPersonFill} from "react-icons/bs"; import {BsFileExcel, BsBank, BsPersonFill} from "react-icons/bs";
import IconCard from "../IconCard"; import IconCard from "../IconCard";
@@ -44,8 +44,11 @@ interface UserCount {
const searchFilters = [["email"], ["user"], ["userId"]]; const searchFilters = [["email"], ["user"], ["userId"]];
const SIZE = 16;
const MasterStatistical = (props: Props) => { const MasterStatistical = (props: Props) => {
const {users, corporateUsers, displaySelection = true} = props; const {users, corporateUsers, displaySelection = true} = props;
const [page, setPage] = useState(0);
// const corporateRelevantUsers = React.useMemo( // const corporateRelevantUsers = React.useMemo(
// () => corporateUsers.filter((x) => x.type !== "student") as CorporateUser[], // () => corporateUsers.filter((x) => x.type !== "student") as CorporateUser[],
@@ -215,8 +218,14 @@ const MasterStatistical = (props: Props) => {
const {rows: filteredRows, renderSearch, text: searchText} = useListSearch(searchFilters, tableResults); const {rows: filteredRows, renderSearch, text: searchText} = useListSearch(searchFilters, tableResults);
useEffect(() => setPage(0), [searchText]);
const rows = useMemo(
() => filteredRows.slice(page * SIZE, (page + 1) * SIZE > filteredRows.length ? filteredRows.length : (page + 1) * SIZE),
[filteredRows, page],
);
const table = useReactTable({ const table = useReactTable({
data: filteredRows, data: rows,
columns: defaultColumns, columns: defaultColumns,
getCoreRowModel: getCoreRowModel(), getCoreRowModel: getCoreRowModel(),
}); });
@@ -345,7 +354,22 @@ const MasterStatistical = (props: Props) => {
</div> </div>
</div> </div>
<div> <div className="w-full h-full flex flex-col gap-4">
<div className="w-full flex gap-2 justify-between">
<Button className="w-full max-w-[200px]" disabled={page === 0} onClick={() => setPage((prev) => prev - 1)}>
Previous Page
</Button>
<div className="flex items-center gap-4 w-fit">
<span className="opacity-80">
{page * SIZE + 1} - {(page + 1) * SIZE > filteredRows.length ? filteredRows.length : (page + 1) * SIZE} /{" "}
{filteredRows.length}
</span>
<Button className="w-[200px]" disabled={(page + 1) * SIZE >= rows.length} onClick={() => setPage((prev) => prev + 1)}>
Next Page
</Button>
</div>
</div>
<table className="rounded-xl h-full bg-mti-purple-ultralight/40 w-full"> <table className="rounded-xl h-full bg-mti-purple-ultralight/40 w-full">
<thead> <thead>
{table.getHeaderGroups().map((headerGroup) => ( {table.getHeaderGroups().map((headerGroup) => (

View File

@@ -131,7 +131,6 @@ export default function MasterCorporateDashboard({user}: Props) {
const {users} = useUsers(); const {users} = useUsers();
const groupedByNameCorporates = useMemo( const groupedByNameCorporates = useMemo(
() => () =>
groupBy( groupBy(
@@ -374,12 +373,18 @@ export default function MasterCorporateDashboard({user}: Props) {
color="purple" color="purple"
onClick={() => router.push("/#corporate")} onClick={() => router.push("/#corporate")}
/> />
<IconCard Icon={BsBank} label="Corporate" value={groupedByNameCorporatesKeys.length} isLoading={isCorporatesLoading} color="purple" /> <IconCard
Icon={BsBank}
label="Corporate"
value={groupedByNameCorporatesKeys.length}
isLoading={isCorporatesLoading}
color="purple"
/>
<IconCard <IconCard
Icon={BsPersonFillGear} Icon={BsPersonFillGear}
isLoading={isStudentsLoading} isLoading={isStudentsLoading}
label="Student Performance" label="Student Performance"
value={students.length} value={totalStudents}
color="purple" color="purple"
onClick={() => router.push("/#studentsPerformance")} onClick={() => router.push("/#studentsPerformance")}
/> />

View File

@@ -642,12 +642,12 @@ export default function UserList({
</Button> </Button>
<div className="flex items-center gap-4 w-fit"> <div className="flex items-center gap-4 w-fit">
<span className="opacity-80"> <span className="opacity-80">
{page * 16 + 1} - {(page + 1) * 16 > total ? total : (page + 1) * 16} / {total} {page * userHash.size + 1} - {(page + 1) * userHash.size > total ? total : (page + 1) * userHash.size} / {total}
</span> </span>
<Button <Button
isLoading={isLoading} isLoading={isLoading}
className="w-[200px]" className="w-[200px]"
disabled={page * 16 >= total} disabled={(page + 1) * userHash.size >= total}
onClick={() => setPage((prev) => prev + 1)}> onClick={() => setPage((prev) => prev + 1)}>
Next Page Next Page
</Button> </Button>