feat: add user groups (#376)
* feat: add user groups * wip: add unit tests * wip: add more tests and normalized name for creation and update * test: add unit tests for group router * fix: type issues, missing mysql schema, rename column creator_id to owner_id * fix: lint and format issues * fix: deepsource issues * fix: forgot to add log message * fix: build not working * chore: address pull request feedback * feat: add mysql migration and fix merge conflicts * fix: format issue and test issue
This commit is contained in:
80
packages/ui/src/components/table-pagination.tsx
Normal file
80
packages/ui/src/components/table-pagination.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback } from "react";
|
||||
import Link from "next/link";
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
||||
import type { PaginationProps } from "@mantine/core";
|
||||
import { Pagination } from "@mantine/core";
|
||||
|
||||
interface TablePaginationProps {
|
||||
total: number;
|
||||
}
|
||||
|
||||
export const TablePagination = ({ total }: TablePaginationProps) => {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const { replace } = useRouter();
|
||||
const pathName = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const current = Number(searchParams.get("page")) || 1;
|
||||
|
||||
const getItemProps = useCallback(
|
||||
(page: number) => {
|
||||
const params = new URLSearchParams(searchParams);
|
||||
params.set("page", page.toString());
|
||||
|
||||
return {
|
||||
component: Link,
|
||||
href: `?${params.toString()}`,
|
||||
};
|
||||
},
|
||||
[searchParams],
|
||||
);
|
||||
|
||||
const getControlProps = useCallback(
|
||||
(control: ControlType) => {
|
||||
return getItemProps(calculatePageFor(control, current, total));
|
||||
},
|
||||
[current],
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(page: number) => {
|
||||
const params = new URLSearchParams(searchParams);
|
||||
params.set("page", page.toString());
|
||||
replace(`${pathName}?${params.toString()}`);
|
||||
},
|
||||
[pathName, searchParams],
|
||||
);
|
||||
|
||||
return (
|
||||
<Pagination
|
||||
total={total}
|
||||
getItemProps={getItemProps}
|
||||
getControlProps={getControlProps}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type ControlType = Parameters<
|
||||
Exclude<PaginationProps["getControlProps"], undefined>
|
||||
>[0];
|
||||
const calculatePageFor = (
|
||||
type: ControlType,
|
||||
current: number,
|
||||
total: number,
|
||||
) => {
|
||||
switch (type) {
|
||||
case "first":
|
||||
return 1;
|
||||
case "previous":
|
||||
return Math.max(current - 1, 1);
|
||||
case "next":
|
||||
return current + 1;
|
||||
case "last":
|
||||
return total;
|
||||
default:
|
||||
console.error(`Unknown pagination control type: ${type as string}`);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user