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,14 +1,37 @@
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 (
<div className="w-full h-full flex flex-col gap-2">
<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 > data.length ? data.length : (page + 1) * SIZE} / {data.length}
</span>
<Button className="w-[200px]" disabled={(page + 1) * SIZE >= data.length} onClick={() => setPage((prev) => prev + 1)}>
Next Page
</Button>
</div>
</div>
<table className="rounded-xl bg-mti-purple-ultralight/40 w-full"> <table className="rounded-xl bg-mti-purple-ultralight/40 w-full">
<thead> <thead>
{table.getHeaderGroups().map((headerGroup) => ( {table.getHeaderGroups().map((headerGroup) => (
@@ -19,7 +42,9 @@ export default function List<T>({data, columns}: {data: T[]; columns: any[]}) {
<> <>
<div <div
{...{ {...{
className: header.column.getCanSort() ? "cursor-pointer select-none py-4 text-left first:pl-4" : "", className: header.column.getCanSort()
? "cursor-pointer select-none py-4 text-left first:pl-4"
: "",
onClick: header.column.getToggleSortingHandler(), onClick: header.column.getToggleSortingHandler(),
}}> }}>
{flexRender(header.column.columnDef.header, header.getContext())} {flexRender(header.column.columnDef.header, header.getContext())}
@@ -47,5 +72,6 @@ export default function List<T>({data, columns}: {data: T[]; columns: any[]}) {
))} ))}
</tbody> </tbody>
</table> </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>