Files
EpicNext-Cms/src/actions/admin-ads.ts
T

70 lines
2.5 KiB
TypeScript

"use server";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { z } from "zod";
import {
contentMutationService,
createContentMutationInvocation,
} from "@/features/housekeeping/domains/content/services/mutations";
import { createCorrelationId } from "@/features/housekeeping/foundation/contracts";
import { requirePermission } from "@/lib/admin/guard";
import { logger } from "@/lib/logger";
import { PERMS } from "@/lib/permissions";
import { adminAction } from "@/lib/safe-action";
import { ActionError, actionOk } from "@/lib/safe-action-shared";
export async function createAd(formData: FormData): Promise<void> {
const staff = await requirePermission(PERMS.PAGES_EDIT);
const image = String(formData.get("image") ?? "").normalize("NFC").trim().slice(0, 255);
if (!image) return;
const result = await contentMutationService.execute(
createContentMutationInvocation(staff, createCorrelationId()),
"ad.change",
{ action: "create", image },
);
if (!result.ok) {
logger.error("Action failed: createAd", { action: "createAd", error: result.error.messageKey });
revalidatePath("/admin/ads");
return;
}
redirect("/admin/ads");
}
export async function updateAd(formData: FormData): Promise<void> {
const staff = await requirePermission(PERMS.PAGES_EDIT);
const raw = String(formData.get("id") ?? "").normalize("NFC");
if (!/^\d+$/u.test(raw)) return;
const image = String(formData.get("image") ?? "").normalize("NFC").trim().slice(0, 255);
if (!image) return;
const result = await contentMutationService.execute(
createContentMutationInvocation(staff, createCorrelationId()),
"ad.change",
{ action: "update", id: raw, image },
);
if (!result.ok) {
logger.error("Action failed: updateAd", { action: "updateAd", id: Number(raw), error: result.error.messageKey });
revalidatePath("/admin/ads/" + raw);
return;
}
redirect("/admin/ads");
}
const deleteAdInput = z.object({
id: z.union([z.string(), z.number(), z.bigint()]).transform((value) => BigInt(String(value))),
});
export const deleteAd = adminAction(
{ permission: PERMS.PAGES_EDIT, schema: deleteAdInput },
async (ctx) => {
const result = await contentMutationService.execute(
{ correlationId: String(ctx.requestId), expectedActorId: Number(ctx.session.user.id), legacy: true },
"ad.change",
{ action: "delete", id: ctx.data.id.toString() },
);
if (!result.ok) throw new ActionError("Advertisement not found");
revalidatePath("/admin/ads");
return actionOk();
},
);