diff --git a/src/app/admin/(bereich)/gutscheine/[id]/page.tsx b/src/app/admin/(bereich)/gutscheine/[id]/page.tsx
index 22076ae..2385a32 100644
--- a/src/app/admin/(bereich)/gutscheine/[id]/page.tsx
+++ b/src/app/admin/(bereich)/gutscheine/[id]/page.tsx
@@ -3,11 +3,33 @@ import { notFound } from "next/navigation";
import { connection } from "next/server";
import { Flash, PageTitle } from "@/components/admin/AdminUi";
import { VoucherForm } from "@/components/admin/VoucherForm";
+import { getCamp, salesStateFor } from "@/lib/camp";
import { getDb } from "@/lib/db";
+import { stripeModeOrNull } from "@/lib/env";
import { BOOKING_STATUS_LABEL, REDEMPTION_STATUS_LABEL } from "@/lib/labels";
+import { evaluateVoucher, VOUCHER_REJECTION_ADMIN_TEXT } from "@/lib/vouchers";
export const metadata = { title: "Gutschein" };
+/**
+ * Prueft wie der Buchungsdialog, ob der Code gerade einloesbar ist, und nennt
+ * den Grund, den Kundinnen bewusst nicht sehen (neutrale Ablehnung).
+ * Eine E-Mail-Bindung prueft erst der Checkout.
+ */
+async function redeemability(code: string): Promise<{ ok: boolean; text: string }> {
+ const mode = stripeModeOrNull();
+ if (!mode) return { ok: false, text: "Nicht prüfbar: STRIPE_SECRET_KEY fehlt oder ist ungültig." };
+ const db = getDb();
+ const now = new Date();
+ const camp = await getCamp(db);
+ const evaluation = await evaluateVoucher(db, { code, email: null, now, livemode: mode === "live", quota: camp.stammmodelQuota, lock: false });
+ if (!evaluation.ok) return { ok: false, text: `Derzeit nicht einlösbar: ${VOUCHER_REJECTION_ADMIN_TEXT[evaluation.reason]}.` };
+ if (!salesStateFor(camp, mode, now).checkoutOpen) {
+ return { ok: false, text: "Code ist gültig, aber die Buchung ist noch nicht geöffnet. Der Dialog zeigt deshalb keinen Preis und keinen Rabatt." };
+ }
+ return { ok: true, text: "Derzeit einlösbar (10 % auf den gültigen Preis)." };
+}
+
export default async function VoucherPage({ params, searchParams }: { params: Promise<{ id: string }>; searchParams: Promise<{ ok?: string; fehler?: string }> }) {
await connection();
const { id } = await params;
@@ -17,11 +39,13 @@ export default async function VoucherPage({ params, searchParams }: { params: Pr
include: { redemptions: { orderBy: { createdAt: "desc" }, include: { booking: { select: { id: true, reference: true, status: true, livemode: true } } } } },
});
if (!voucher) notFound();
+ const check = await redeemability(voucher.code);
return (
<>
Alle Gutscheine
{check.text}