Inquiries: completed and rejected inquiries move to an "Archiv" tab; resetting the status brings them back. Reviews: new "Ablehnen" action (Review.rejectedAt) instead of only deleting; the archive shows decided reviews in two columns, accepted and rejected, and either decision can be reversed. Pending counters in the sidebar and dashboard exclude rejected reviews, and the product page tells the author their review was not published instead of "still being checked". Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { logAdminAction } from "@/lib/audit-log";
|
|
import { requireAdmin, str } from "./_shared";
|
|
import { setFlash } from "@/lib/flash";
|
|
|
|
export async function approveReviewAction(formData: FormData): Promise<void> {
|
|
const admin = await requireAdmin();
|
|
const id = str(formData, "id");
|
|
|
|
const review = await prisma.review.update({
|
|
where: { id },
|
|
data: { isApproved: true, rejectedAt: null },
|
|
select: { product: { select: { slug: true, name: true } } },
|
|
});
|
|
|
|
await logAdminAction(admin, {
|
|
action: "review.approve",
|
|
entityType: "Review",
|
|
entityId: id,
|
|
detail: review.product.name,
|
|
});
|
|
|
|
revalidatePath("/admin/bewertungen");
|
|
revalidatePath(`/honig/${review.product.slug}`);
|
|
await setFlash("success", "Bewertung freigegeben — sie ist jetzt im Shop sichtbar.");
|
|
}
|
|
|
|
/**
|
|
* Lehnt eine Bewertung ab, statt sie zu loeschen: sie verschwindet aus dem
|
|
* Shop (falls sie dort war) und steht im Archiv unter "Abgelehnt", damit die
|
|
* Entscheidung nachvollziehbar bleibt und sich rueckgaengig machen laesst.
|
|
*/
|
|
export async function rejectReviewAction(formData: FormData): Promise<void> {
|
|
const admin = await requireAdmin();
|
|
const id = str(formData, "id");
|
|
|
|
const review = await prisma.review.update({
|
|
where: { id },
|
|
data: { isApproved: false, rejectedAt: new Date() },
|
|
select: { product: { select: { slug: true, name: true } } },
|
|
});
|
|
|
|
await logAdminAction(admin, {
|
|
action: "review.reject",
|
|
entityType: "Review",
|
|
entityId: id,
|
|
detail: review.product.name,
|
|
});
|
|
|
|
revalidatePath("/admin/bewertungen");
|
|
revalidatePath(`/honig/${review.product.slug}`);
|
|
await setFlash("success", "Bewertung abgelehnt — sie steht jetzt im Archiv.");
|
|
}
|
|
|
|
export async function deleteReviewAction(formData: FormData): Promise<void> {
|
|
const admin = await requireAdmin();
|
|
const id = str(formData, "id");
|
|
|
|
const review = await prisma.review.delete({
|
|
where: { id },
|
|
select: { product: { select: { slug: true, name: true } } },
|
|
});
|
|
|
|
await logAdminAction(admin, {
|
|
action: "review.delete",
|
|
entityType: "Review",
|
|
entityId: id,
|
|
detail: review.product.name,
|
|
});
|
|
|
|
revalidatePath("/admin/bewertungen");
|
|
revalidatePath(`/honig/${review.product.slug}`);
|
|
await setFlash("success", "Bewertung gelöscht.");
|
|
}
|