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:
Meier Lukas
2024-04-29 21:46:30 +02:00
committed by GitHub
parent 621f6c81ae
commit 036925bf78
50 changed files with 3333 additions and 132 deletions

View 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;
}
};