added category infinite grid and fixed missing items at useInfiniteQuery
This commit is contained in:
@@ -6,10 +6,58 @@ import {
|
||||
} from "@/server/api/trpc";
|
||||
import { categories, Category } from "@/server/db/schema";
|
||||
|
||||
import { count, eq, like } from "drizzle-orm";
|
||||
import {
|
||||
and,
|
||||
asc,
|
||||
count,
|
||||
desc,
|
||||
eq,
|
||||
gt,
|
||||
gte,
|
||||
ilike,
|
||||
like,
|
||||
lte,
|
||||
} from "drizzle-orm";
|
||||
import { hasPermission, Role } from "@/lib/validation/permissions";
|
||||
import { categorySchema } from "@/lib/validation/zod/category";
|
||||
import {
|
||||
categoryFilterSchema,
|
||||
categorySchema,
|
||||
} from "@/lib/validation/zod/category";
|
||||
import { generateSlug } from "@/lib/utils";
|
||||
import SuperJSON from "superjson";
|
||||
|
||||
type CategoryCursor = Pick<Category, "slug" | "createdAt" | "name">;
|
||||
const getCategorySorting = (sort: string, cursor?: CategoryCursor) => {
|
||||
// Default to newest
|
||||
const baseCase = {
|
||||
orderBy: [desc(categories.createdAt), asc(categories.slug)],
|
||||
cursor: cursor ? lte(categories.createdAt, cursor.createdAt) : undefined,
|
||||
};
|
||||
|
||||
switch (sort) {
|
||||
case "newest":
|
||||
return baseCase;
|
||||
case "oldest":
|
||||
return {
|
||||
orderBy: [asc(categories.createdAt), asc(categories.slug)],
|
||||
cursor: cursor
|
||||
? gte(categories.createdAt, cursor.createdAt)
|
||||
: undefined,
|
||||
};
|
||||
case "abc":
|
||||
return {
|
||||
orderBy: [asc(categories.name), asc(categories.slug)],
|
||||
cursor: cursor ? gte(categories.name, cursor.name) : undefined,
|
||||
};
|
||||
case "cba":
|
||||
return {
|
||||
orderBy: [desc(categories.name), asc(categories.slug)],
|
||||
cursor: cursor ? lte(categories.name, cursor.name) : undefined,
|
||||
};
|
||||
default:
|
||||
return baseCase;
|
||||
}
|
||||
};
|
||||
|
||||
export const categoryRouter = createTRPCRouter({
|
||||
search: publicProcedure
|
||||
@@ -42,6 +90,71 @@ export const categoryRouter = createTRPCRouter({
|
||||
});
|
||||
}),
|
||||
|
||||
getByCursor: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
limit: z.number().optional(),
|
||||
cursor: z.string().optional(),
|
||||
filter: categoryFilterSchema.optional(),
|
||||
}),
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
const { cursor } = input!;
|
||||
const limit = input?.limit ?? 50;
|
||||
|
||||
// Decode cursor if using it
|
||||
let cursorObj: CategoryCursor | undefined;
|
||||
if (cursor) {
|
||||
try {
|
||||
cursorObj = SuperJSON.parse(Buffer.from(cursor, "base64").toString());
|
||||
} catch (e) {
|
||||
// Handle invalid cursor
|
||||
cursorObj = undefined;
|
||||
}
|
||||
}
|
||||
const queryFilterArg = input?.filter?.query?.length
|
||||
? ilike(categories.name, "%" + input.filter.query + "%")
|
||||
: undefined;
|
||||
|
||||
const sortConfig = input?.filter?.sort ?? "newest";
|
||||
const { orderBy, cursor: cursorArg } = getCategorySorting(
|
||||
sortConfig,
|
||||
cursorObj,
|
||||
);
|
||||
|
||||
const items = (await ctx.db.query.categories.findMany({
|
||||
where: and(cursorArg, queryFilterArg),
|
||||
limit: limit + 1,
|
||||
orderBy,
|
||||
columns: {
|
||||
name: true,
|
||||
slug: true,
|
||||
createdAt: true,
|
||||
},
|
||||
})) as Category[];
|
||||
|
||||
let nextCursor: string | undefined = undefined;
|
||||
if (items.length > limit) {
|
||||
console.log("Configure next cursor");
|
||||
const cursorItem = items.pop();
|
||||
// Create a cursor object with the relevant fields for sorting
|
||||
const cursorData: CategoryCursor = {
|
||||
slug: cursorItem!.slug,
|
||||
createdAt: cursorItem!.createdAt,
|
||||
name: cursorItem!.name,
|
||||
};
|
||||
// Encode the cursor as base64
|
||||
nextCursor = Buffer.from(SuperJSON.stringify(cursorData)).toString(
|
||||
"base64",
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
items,
|
||||
nextCursor,
|
||||
};
|
||||
}),
|
||||
|
||||
getCount: publicProcedure.query(async ({ ctx }) => {
|
||||
return (await ctx.db.select({ count: count() }).from(categories))[0]?.count;
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user