Added some more pagination
This commit is contained in:
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) => (
|
||||||
|
|||||||
@@ -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")}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user