Files
v2.admin.gaertan.art/src/actions/commissions/requests/getCommissionRequestsTablePage.ts
2026-02-03 12:17:47 +01:00

94 lines
2.7 KiB
TypeScript

"use server";
import type { Prisma } from "@/generated/prisma/client";
import { prisma } from "@/lib/prisma";
import { commissionRequestTableRowSchema } from "@/schemas/commissions/requests";
import type {
CommissionRequestsTableFilters,
CommissionRequestsTableSorting,
} from "@/schemas/commissions/requestsTable";
import type { CursorPagination } from "@/types/pagination";
import { z } from "zod/v4";
// Builds a paginated, filtered, and sorted commission-requests table payload for the admin UI.
export async function getCommissionRequestsTablePage(input: {
pagination: CursorPagination;
sorting: CommissionRequestsTableSorting;
filters: CommissionRequestsTableFilters;
}) {
const { pagination, sorting, filters } = input;
const where: Prisma.CommissionRequestWhereInput = {};
if (filters.q) {
const q = filters.q.trim();
if (q) {
where.OR = [
{ customerName: { contains: q, mode: "insensitive" } },
{ customerEmail: { contains: q, mode: "insensitive" } },
];
}
}
if (filters.email) {
const e = filters.email.trim();
if (e) where.customerEmail = { contains: e, mode: "insensitive" };
}
if (filters.status !== "any") {
where.status = filters.status;
}
if (filters.hasFiles !== "any") {
where.files = filters.hasFiles === "true" ? { some: {} } : { none: {} };
}
// sorting
const sort = sorting?.[0] ?? { id: "createdAt", desc: true };
const orderBy: Prisma.CommissionRequestOrderByWithRelationInput =
sort.id === "createdAt"
? { createdAt: sort.desc ? "desc" : "asc" }
: sort.id === "status"
? { status: sort.desc ? "desc" : "asc" }
: { createdAt: "desc" };
const [total, rows] = await prisma.$transaction([
prisma.commissionRequest.count({ where }),
prisma.commissionRequest.findMany({
where,
orderBy,
skip: pagination.pageIndex * pagination.pageSize,
take: pagination.pageSize,
select: {
id: true,
index: true,
createdAt: true,
status: true,
customerName: true,
customerEmail: true,
customerSocials: true,
_count: { select: { files: true } },
},
}),
]);
const mapped = rows.map((r) => ({
id: r.id,
index: r.index,
createdAt: r.createdAt.toISOString(),
customerName: r.customerName,
customerEmail: r.customerEmail,
customerSocials: r.customerSocials ?? null,
status: r.status,
fileCount: r._count.files,
}));
// Validate output once (helps catch schema drift)
const parsed = z.array(commissionRequestTableRowSchema).safeParse(mapped);
if (!parsed.success) {
throw new Error("Commission table row shape mismatch");
}
return { total, rows: parsed.data };
}