Finished Hub ESLINT rule enforcement
This commit is contained in:
@@ -11,10 +11,10 @@ export const CustomErrorBoundary = ({ children }: { children?: React.ReactNode }
|
||||
let errorTest;
|
||||
let errorCode = 500;
|
||||
if ("statusCode" in error) {
|
||||
errorCode = (error as any).statusCode;
|
||||
errorCode = error.statusCode;
|
||||
}
|
||||
if ("message" in error || error instanceof Error) {
|
||||
errorTest = (error as any).message;
|
||||
errorTest = error.message;
|
||||
} else if (typeof error === "string") {
|
||||
errorTest = error;
|
||||
} else {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
import { useEffect, useState, useCallback, Ref, useImperativeHandle } from "react";
|
||||
import { useState, Ref, useImperativeHandle } from "react";
|
||||
import SortableTable, { Pagination, SortableTableProps } from "./Table";
|
||||
import { PrismaClient } from "@repo/db";
|
||||
import { getData } from "./pagiantedTableActions";
|
||||
import { useDebounce } from "@repo/shared-components";
|
||||
|
||||
export interface PaginatedTableRef {
|
||||
refresh: () => void;
|
||||
@@ -10,9 +11,8 @@ export interface PaginatedTableRef {
|
||||
|
||||
interface PaginatedTableProps<TData> extends Omit<SortableTableProps<TData>, "data"> {
|
||||
prismaModel: keyof PrismaClient;
|
||||
filter?: Record<string, any>;
|
||||
filter?: Record<string, unknown>;
|
||||
rowsPerPage?: number;
|
||||
showEditButton?: boolean;
|
||||
searchFields?: string[];
|
||||
include?: Record<string, boolean>;
|
||||
strictQuery?: boolean;
|
||||
@@ -26,7 +26,6 @@ interface PaginatedTableProps<TData> extends Omit<SortableTableProps<TData>, "da
|
||||
export function PaginatedTable<TData>({
|
||||
prismaModel,
|
||||
rowsPerPage = 10,
|
||||
showEditButton = false,
|
||||
searchFields = [],
|
||||
filter,
|
||||
include,
|
||||
@@ -42,7 +41,6 @@ export function PaginatedTable<TData>({
|
||||
const [page, setPage] = useState(0);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(searchTerm);
|
||||
const [orderBy, setOrderBy] = useState<Record<string, "asc" | "desc">>(
|
||||
restProps.initialOrderBy
|
||||
? restProps.initialOrderBy.reduce(
|
||||
@@ -60,16 +58,19 @@ export function PaginatedTable<TData>({
|
||||
prismaModel,
|
||||
rowsPerPage,
|
||||
page * rowsPerPage,
|
||||
debouncedSearchTerm,
|
||||
searchTerm,
|
||||
searchFields,
|
||||
filter,
|
||||
include,
|
||||
orderBy,
|
||||
strictQuery
|
||||
? restProps.columns
|
||||
.filter((col: any) => "accessorKey" in col)
|
||||
.map((col: any) => col.accessorKey)
|
||||
.reduce((acc: Record<string, any>, key: string) => {
|
||||
.filter(
|
||||
(col): col is { accessorKey: string } =>
|
||||
typeof (col as { accessorKey?: unknown }).accessorKey === "string",
|
||||
)
|
||||
.map((col) => col.accessorKey)
|
||||
.reduce<Record<string, boolean>>((acc, key) => {
|
||||
acc[key] = true;
|
||||
return acc;
|
||||
}, {})
|
||||
@@ -82,35 +83,20 @@ export function PaginatedTable<TData>({
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
RefreshTableData();
|
||||
}, [filter, orderBy]);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
refresh: () => {
|
||||
RefreshTableData();
|
||||
},
|
||||
}));
|
||||
|
||||
const debounce = (func: Function, delay: number) => {
|
||||
let timer: NodeJS.Timeout;
|
||||
return (...args: any[]) => {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => func(...args), delay);
|
||||
};
|
||||
};
|
||||
|
||||
const handleSearchChange = useCallback(
|
||||
debounce((value: string) => {
|
||||
setDebouncedSearchTerm(value);
|
||||
}, 500),
|
||||
[],
|
||||
useDebounce(
|
||||
() => {
|
||||
RefreshTableData();
|
||||
},
|
||||
500,
|
||||
[searchTerm, page, rowsPerPage, orderBy, filter],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
RefreshTableData();
|
||||
}, [page, debouncedSearchTerm]);
|
||||
|
||||
return (
|
||||
<div className="space-y-4 m-4">
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -122,7 +108,6 @@ export function PaginatedTable<TData>({
|
||||
value={searchTerm}
|
||||
onChange={(e) => {
|
||||
setSearchTerm(e.target.value);
|
||||
handleSearchChange(e.target.value);
|
||||
setPage(0); // Reset to first page on search
|
||||
}}
|
||||
className="input input-bordered w-full max-w-xs justify-end"
|
||||
@@ -134,7 +119,6 @@ export function PaginatedTable<TData>({
|
||||
<SortableTable
|
||||
data={data}
|
||||
prismaModel={prismaModel}
|
||||
showEditButton={showEditButton}
|
||||
setOrderBy={setOrderBy}
|
||||
{...restProps}
|
||||
/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import { toast } from "react-hot-toast";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { ReactNode, useEffect, useState } from "react";
|
||||
import { ReactNode, useState } from "react";
|
||||
|
||||
export function QueryProvider({ children }: { children: ReactNode }) {
|
||||
const [queryClient] = useState(
|
||||
|
||||
@@ -9,13 +9,11 @@ import {
|
||||
flexRender,
|
||||
} from "@tanstack/react-table";
|
||||
import { ArrowLeft, ArrowRight, ChevronDown, ChevronUp } from "lucide-react"; // Icons for sorting
|
||||
import Link from "next/link";
|
||||
import { PrismaClient } from "@repo/db";
|
||||
|
||||
export interface SortableTableProps<TData> {
|
||||
data: TData[];
|
||||
columns: ColumnDef<TData>[];
|
||||
showEditButton?: boolean;
|
||||
prismaModel?: keyof PrismaClient;
|
||||
setOrderBy?: (orderBy: Record<string, "asc" | "desc">) => void;
|
||||
initialOrderBy?: SortingState;
|
||||
@@ -26,28 +24,13 @@ export default function SortableTable<TData>({
|
||||
columns,
|
||||
initialOrderBy = [],
|
||||
prismaModel,
|
||||
showEditButton,
|
||||
setOrderBy,
|
||||
}: SortableTableProps<TData>) {
|
||||
const [sorting, setSorting] = useState<SortingState>(initialOrderBy);
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
columns: showEditButton
|
||||
? [
|
||||
...columns,
|
||||
{
|
||||
header: "Actions",
|
||||
cell: ({ row }) => (
|
||||
<div className="flex items-center gap-1">
|
||||
<Link href={`/admin/${prismaModel as string}/${(row.original as any).id}`}>
|
||||
<button className="btn btn-sm">Edit</button>
|
||||
</Link>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: columns,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
onSortingChange: setSorting,
|
||||
|
||||
@@ -15,7 +15,7 @@ export const Button = ({
|
||||
|
||||
return (
|
||||
<button
|
||||
{...(props as any)}
|
||||
{...props}
|
||||
className={cn("btn", props.className)}
|
||||
disabled={isLoadingState || props.disabled}
|
||||
onClick={async (e) => {
|
||||
@@ -27,7 +27,7 @@ export const Button = ({
|
||||
}}
|
||||
>
|
||||
{isLoadingState && <span className="loading loading-spinner loading-sm"></span>}
|
||||
{props.children as any}
|
||||
{props.children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,32 +1,24 @@
|
||||
import DatePicker, { DatePickerProps, registerLocale } from "react-datepicker";
|
||||
import { Control, Controller, FieldValues, Path } from "react-hook-form";
|
||||
import { de } from "date-fns/locale";
|
||||
registerLocale("de", de);
|
||||
import { formatDate } from "date-fns";
|
||||
|
||||
interface DateInputProps<T extends FieldValues>
|
||||
extends Omit<DatePickerProps, "onChange" | "selected"> {
|
||||
control: Control<T>;
|
||||
name: Path<T>;
|
||||
}
|
||||
|
||||
export const DateInput = <T extends FieldValues>({
|
||||
control,
|
||||
name,
|
||||
export const DateInput = ({
|
||||
value,
|
||||
onChange,
|
||||
...props
|
||||
}: DateInputProps<T>) => {
|
||||
}: Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange"> & {
|
||||
value?: Date | null;
|
||||
onChange?: (date: Date) => void;
|
||||
}) => {
|
||||
return (
|
||||
<Controller
|
||||
control={control}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
<DatePicker
|
||||
className="input input-bordered mt-2"
|
||||
locale={"de"}
|
||||
onChange={(date) => field.onChange(date)}
|
||||
selected={field.value}
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
<input
|
||||
type="datetime-local"
|
||||
className="input"
|
||||
value={formatDate(value || new Date(), "yyyy-MM-dd hh:mm")}
|
||||
onChange={(e) => {
|
||||
const date = e.target.value ? new Date(e.target.value) : null;
|
||||
if (!date) return;
|
||||
onChange?.(date);
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user