Removed sorting in exchange for filtering
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import {useState, useMemo} from "react";
|
import {useState, useMemo} from "react";
|
||||||
import Input from "@/components/Low/Input";
|
import Input from "@/components/Low/Input";
|
||||||
import { search } from "@/utils/search";
|
import {search} from "@/utils/search";
|
||||||
|
|
||||||
export function useListSearch<T>(fields: string[][], rows: T[]) {
|
export function useListSearch<T>(fields: string[][], rows: T[]) {
|
||||||
const [text, setText] = useState("");
|
const [text, setText] = useState("");
|
||||||
@@ -8,7 +8,8 @@ export function useListSearch<T>(fields: string[][], rows: T[]) {
|
|||||||
const renderSearch = () => <Input label="Search" type="text" name="search" onChange={setText} placeholder="Enter search text" value={text} />;
|
const renderSearch = () => <Input label="Search" type="text" name="search" onChange={setText} placeholder="Enter search text" value={text} />;
|
||||||
|
|
||||||
const updatedRows = useMemo(() => {
|
const updatedRows = useMemo(() => {
|
||||||
return search(text, fields, rows);
|
if (text.length > 0) return search(text, fields, rows);
|
||||||
|
return rows;
|
||||||
}, [fields, rows, text]);
|
}, [fields, rows, text]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
28
src/hooks/usePagination.tsx
Normal file
28
src/hooks/usePagination.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import Button from "@/components/Low/Button";
|
||||||
|
import {useMemo, useState} from "react";
|
||||||
|
|
||||||
|
export default function usePagination<T>(list: T[], size = 25) {
|
||||||
|
const [page, setPage] = useState(0);
|
||||||
|
|
||||||
|
const items = useMemo(() => list.slice(page * size, (page + 1) * size), [page, size, list]);
|
||||||
|
|
||||||
|
const render = () => (
|
||||||
|
<div className="w-full flex gap-2 justify-between items-center">
|
||||||
|
<div className="flex items-center gap-4 w-fit">
|
||||||
|
<Button className="w-[200px] h-fit" disabled={page === 0} onClick={() => setPage((prev) => prev - 1)}>
|
||||||
|
Previous Page
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-4 w-fit">
|
||||||
|
<span className="opacity-80">
|
||||||
|
{page * size + 1} - {(page + 1) * size > list.length ? list.length : (page + 1) * size} / {list.length}
|
||||||
|
</span>
|
||||||
|
<Button className="w-[200px]" disabled={(page + 1) * size >= list.length} onClick={() => setPage((prev) => prev + 1)}>
|
||||||
|
Next Page
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return {page, items, setPage, render};
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ import {checkAccess} from "@/utils/permissions";
|
|||||||
import {PermissionType} from "@/interfaces/permissions";
|
import {PermissionType} from "@/interfaces/permissions";
|
||||||
import usePermissions from "@/hooks/usePermissions";
|
import usePermissions from "@/hooks/usePermissions";
|
||||||
import useUserBalance from "@/hooks/useUserBalance";
|
import useUserBalance from "@/hooks/useUserBalance";
|
||||||
|
import usePagination from "@/hooks/usePagination";
|
||||||
const columnHelper = createColumnHelper<User>();
|
const columnHelper = createColumnHelper<User>();
|
||||||
const searchFields = [["name"], ["email"], ["corporateInformation", "companyInformation", "name"]];
|
const searchFields = [["name"], ["email"], ["corporateInformation", "companyInformation", "name"]];
|
||||||
|
|
||||||
@@ -62,15 +63,12 @@ export default function UserList({
|
|||||||
const [sorter, setSorter] = useState<string>();
|
const [sorter, setSorter] = useState<string>();
|
||||||
const [displayUsers, setDisplayUsers] = useState<User[]>([]);
|
const [displayUsers, setDisplayUsers] = useState<User[]>([]);
|
||||||
const [selectedUser, setSelectedUser] = useState<User>();
|
const [selectedUser, setSelectedUser] = useState<User>();
|
||||||
const [page, setPage] = useState(0);
|
|
||||||
|
|
||||||
const userHash = useMemo(
|
const userHash = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
type,
|
type,
|
||||||
size: 16,
|
|
||||||
page,
|
|
||||||
}),
|
}),
|
||||||
[type, page],
|
[type],
|
||||||
);
|
);
|
||||||
|
|
||||||
const {users, total, isLoading, reload} = useUsers(userHash);
|
const {users, total, isLoading, reload} = useUsers(userHash);
|
||||||
@@ -102,9 +100,9 @@ export default function UserList({
|
|||||||
(async () => {
|
(async () => {
|
||||||
if (users && users.length > 0) {
|
if (users && users.length > 0) {
|
||||||
const filteredUsers = filters.reduce((d, f) => d.filter(f), users);
|
const filteredUsers = filters.reduce((d, f) => d.filter(f), users);
|
||||||
const sortedUsers = await asyncSorter<User>(filteredUsers, sortFunction);
|
// const sortedUsers = await asyncSorter<User>(filteredUsers, sortFunction);
|
||||||
|
|
||||||
setDisplayUsers([...sortedUsers]);
|
setDisplayUsers([...filteredUsers]);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
@@ -513,10 +511,14 @@ export default function UserList({
|
|||||||
return a.id.localeCompare(b.id);
|
return a.id.localeCompare(b.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const {rows: filteredRows, renderSearch} = useListSearch<User>(searchFields, displayUsers);
|
const {rows: filteredRows, renderSearch, text: searchText} = useListSearch<User>(searchFields, displayUsers);
|
||||||
|
const {items, setPage, render: renderPagination} = usePagination<User>(filteredRows, 16);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
useEffect(() => setPage(0), [searchText]);
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data: filteredRows,
|
data: items,
|
||||||
columns: (!showDemographicInformation ? defaultColumns : demographicColumns) as any,
|
columns: (!showDemographicInformation ? defaultColumns : demographicColumns) as any,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
});
|
});
|
||||||
@@ -632,27 +634,7 @@ export default function UserList({
|
|||||||
Download List
|
Download List
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex gap-2 justify-between">
|
{renderPagination()}
|
||||||
<Button
|
|
||||||
isLoading={isLoading}
|
|
||||||
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 * userHash.size + 1} - {(page + 1) * userHash.size > total ? total : (page + 1) * userHash.size} / {total}
|
|
||||||
</span>
|
|
||||||
<Button
|
|
||||||
isLoading={isLoading}
|
|
||||||
className="w-[200px]"
|
|
||||||
disabled={(page + 1) * userHash.size >= total}
|
|
||||||
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) => (
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
direction,
|
direction,
|
||||||
);
|
);
|
||||||
|
|
||||||
res.status(200).json({users: uniqBy([...users, req.session.user], "id"), total});
|
res.status(200).json({users: uniqBy([...users], "id"), total});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user