Add functions to commission form

This commit is contained in:
2026-01-01 09:47:04 +01:00
parent 61421aa487
commit 42f23dddcf
12 changed files with 982 additions and 3 deletions

View File

@ -0,0 +1,14 @@
"use server";
import { prisma } from "@/lib/prisma";
import { z } from "zod";
export async function deleteCommissionRequest(id: string) {
const parsed = z.string().min(1).parse(id);
await prisma.commissionRequest.delete({
where: { id: parsed },
});
return { ok: true };
}

View File

@ -0,0 +1,110 @@
"use server";
import { prisma } from "@/lib/prisma";
import {
commissionRequestTableRowSchema,
commissionStatusSchema,
} from "@/schemas/commissions/tableSchema";
import { z } from "zod";
export type CursorPagination = { pageIndex: number; pageSize: number };
export type SortDir = "asc" | "desc";
const triStateSchema = z.enum(["any", "true", "false"]);
type TriState = z.infer<typeof triStateSchema>;
const sortingSchema = z.array(
z.object({
id: z.string(),
desc: z.boolean(),
})
);
const filtersSchema = z.object({
q: z.string().optional(),
email: z.string().optional(),
status: z.union([z.literal("any"), commissionStatusSchema]).default("any"),
hasFiles: triStateSchema.default("any"),
});
export async function getCommissionRequestsTablePage(input: {
pagination: CursorPagination;
sorting: z.infer<typeof sortingSchema>;
filters: z.infer<typeof filtersSchema>;
}) {
const { pagination, sorting, filters } = input;
const where: any = {};
if (filters.q) {
const q = filters.q.trim();
if (q) {
where.OR = [
{ customerName: { contains: q, mode: "insensitive" } },
{ customerEmail: { contains: q, mode: "insensitive" } },
{ message: { 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: any =
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,
createdAt: true,
status: true,
customerName: true,
customerEmail: true,
customerSocials: true,
message: true,
_count: { select: { files: true } },
},
}),
]);
const mapped = rows.map((r) => ({
id: r.id,
createdAt: r.createdAt.toISOString(),
status: r.status as any,
customerName: r.customerName,
customerEmail: r.customerEmail,
customerSocials: r.customerSocials ?? null,
messagePreview: r.message.slice(0, 140),
filesCount: 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 };
}

View File

@ -0,0 +1,20 @@
"use server";
import { prisma } from "@/lib/prisma";
import { commissionStatusSchema } from "@/schemas/commissions/tableSchema";
import { z } from "zod";
export async function setCommissionRequestStatus(input: {
id: string;
status: z.infer<typeof commissionStatusSchema>;
}) {
const id = z.string().min(1).parse(input.id);
const status = commissionStatusSchema.parse(input.status);
await prisma.commissionRequest.update({
where: { id },
data: { status },
});
return { ok: true };
}