"use server"; import { revalidatePath } from "next/cache"; import { requireStaff } from "@/lib/admin/guard"; import { prisma } from "@/lib/prisma"; import type { ActionResult } from "@/lib/safe-action-shared"; import { rcon } from "@/lib/services/rcon"; import { logStaffActivity } from "@/lib/services/staff-activity"; export async function updateCatalogPage({ id, ...fields }: { id: number } & Record): Promise { const staff = await requireStaff(); await prisma.catalogPages.update({ where: { id }, data: fields as any }); await rcon.updateCatalog(); await logStaffActivity({ staffId: staff.id, action: "catalog_page_update", description: `Updated catalog page #${id}`, targetType: "catalog_page", targetId: id, }); revalidatePath("/admin/catalog"); return { ok: true as const, data: {} }; } export async function deleteCatalogPage({ id }: { id: number }) { const staff = await requireStaff(); await prisma.catalogPages.delete({ where: { id } }); await rcon.updateCatalog(); await logStaffActivity({ staffId: staff.id, action: "catalog_page_delete", description: `Deleted catalog page #${id}`, targetType: "catalog_page", targetId: id, }); revalidatePath("/admin/catalog"); return { ok: true as const, data: {} }; } export async function toggleCatalogPage({ id, action, }: { id: number; action: "toggleEnabled" | "toggleVisible"; }) { await requireStaff(); const page = await prisma.catalogPages.findUnique({ where: { id }, select: { enabled: true, visible: true }, }); if (!page) return { ok: false as const, error: "Catalog page not found" }; const field = action === "toggleEnabled" ? "enabled" : "visible"; const current = action === "toggleEnabled" ? page.enabled : page.visible; await prisma.catalogPages.update({ where: { id }, data: { [field]: current === "1" ? "0" : "1" }, }); revalidatePath("/admin/catalog"); return { ok: true as const, data: {} }; } export async function createCatalogPage(input: { caption: string; parentId: number; pageLayout?: string; iconImage?: number; iconColor?: number; enabled?: "0" | "1"; visible?: "0" | "1"; minRank?: number; orderNum?: number; }): Promise> { const staff = await requireStaff(); const created = await prisma.catalogPages.create({ data: { caption: input.caption, parentId: input.parentId, pageLayout: input.pageLayout ?? "default_3x3", captionSave: input.caption.slice(0, 25), iconColor: input.iconColor ?? 0, iconImage: input.iconImage ?? 0, minRank: input.minRank ?? 1, orderNum: input.orderNum ?? 0, visible: input.visible ?? "1", enabled: input.enabled ?? "1", clubOnly: "0", vipOnly: "0", pageHeadline: "", pageTeaser: "", includes: "", }, }); await logStaffActivity({ staffId: staff.id, action: "catalog_page_create", description: `Created catalog page "${input.caption}"`, targetType: "catalog_page", targetId: created.id, }); revalidatePath("/admin/catalog"); return { ok: true as const, data: { id: created.id } }; } export async function reorderTreePage(input: { pageId: number; newParentId?: number; newOrderNum: number; }) { await requireStaff(); await prisma.catalogPages.update({ where: { id: input.pageId }, data: { orderNum: input.newOrderNum, ...(input.newParentId === undefined ? {} : { parentId: input.newParentId }), }, }); await rcon.updateCatalog(); revalidatePath("/admin/catalog"); return { ok: true as const, data: {} }; } export async function deleteTreePage(input: { pageId: number; mode: "reparent" | "cascade"; }) { await requireStaff(); if (input.mode === "cascade") { const children = await prisma.catalogPages.findMany({ where: { parentId: input.pageId }, select: { id: true }, }); const pageIds = [input.pageId, ...children.map((child) => child.id)]; await prisma.$transaction([ prisma.catalogItems.deleteMany({ where: { pageId: { in: pageIds } } }), prisma.catalogPages.deleteMany({ where: { id: { in: pageIds } } }), ]); } else { const page = await prisma.catalogPages.findUnique({ where: { id: input.pageId }, select: { parentId: true }, }); if (!page) return { ok: false as const, error: "Catalog page not found" }; await prisma.$transaction([ prisma.catalogPages.updateMany({ where: { parentId: input.pageId }, data: { parentId: page.parentId }, }), prisma.catalogItems.deleteMany({ where: { pageId: input.pageId } }), prisma.catalogPages.delete({ where: { id: input.pageId } }), ]); } await rcon.updateCatalog(); revalidatePath("/admin/catalog"); return { ok: true as const, data: {} }; }