import type { ReactNode } from "react";
import Image from "next/image";
import Link from "next/link";
import { notFound } from "next/navigation";
import { prisma } from "@/lib/prisma";
import { BackLink } from "@/components/back-link";
import { AdminBadge } from "@/components/admin-list";
import { formatDate, formatDateTime } from "@/lib/format";
import { MAX_ISSUE_ATTEMPTS } from "@/lib/sponsorship/issue";
import { getLocale } from "@/i18n/locale";
import { getSponsorshipAdminStrings } from "@/i18n/sponsorship/admin";
import { SponsorshipStatusBadge } from "../_components/status-badge";
import { SponsorshipActions } from "../_components/sponsorship-actions";
import { RevisionTable, TransferTable } from "../_components/history-tables";
import { beeNameFromJson } from "../_lib/revision-data";
// A4 hochkant: 595.28 × 841.89 pt — die Vorschau wird in 900 px Breite gerendert.
const PREVIEW_WIDTH = 900;
const PREVIEW_HEIGHT = Math.round((PREVIEW_WIDTH * 841.89) / 595.28);
function Panel({ title, children }: { title: string; children: ReactNode }) {
return (
);
}
export default async function AdminSponsorshipDetailPage(props: PageProps<"/admin/patenschaften/[id]">) {
const locale = await getLocale();
const t = getSponsorshipAdminStrings(locale);
const td = t.detail;
const { id } = await props.params;
const sponsorship = await prisma.sponsorship.findUnique({
where: { id },
include: {
owner: { select: { id: true, email: true, firstName: true, lastName: true } },
offer: { select: { id: true, name: true, kind: true, isPhysical: true } },
orderItem: { select: { order: { select: { id: true, orderNumber: true } } } },
subscription: { select: { id: true, status: true } },
revisions: { orderBy: { revision: "desc" } },
transfers: { orderBy: { createdAt: "desc" } },
},
});
if (!sponsorship) notFound();
const accountIds = [...new Set(sponsorship.transfers.flatMap((row) => [row.createdById, row.claimedById ?? ""]).filter(Boolean))];
const accounts =
accountIds.length > 0
? await prisma.customer.findMany({ where: { id: { in: accountIds } }, select: { id: true, email: true } })
: [];
const emailOf = new Map(accounts.map((account) => [account.id, account.email]));
const current = sponsorship.revisions.find((row) => row.revision === sponsorship.currentRevision) ?? null;
const beeName = beeNameFromJson(current?.personalization) ?? "—";
const start = formatDate(sponsorship.startDate, locale);
const order = sponsorship.orderItem?.order ?? null;
return (
{sponsorship.number}
{beeName}
{t.kinds[sponsorship.offer.kind]}
{sponsorship.owner.firstName} {sponsorship.owner.lastName}
{sponsorship.owner.email}
{td.openAccount}
{order ? (
{td.order(order.orderNumber)}
) : sponsorship.subscription ? (
{td.subscription} · {t.subscriptionStatuses[sponsorship.subscription.status]}
) : (
{td.noSource}
)}
{sponsorship.offer.name}
{sponsorship.offer.isPhysical ? td.physical : td.digital}
{sponsorship.endDate ? t.common.range(start, formatDate(sponsorship.endDate, locale)) : td.termOpen(start)}
{td.previewHeading}
{current ? (
) : (
{td.noRevision}
)}
- {td.attempts(sponsorship.pdfAttempts, MAX_ISSUE_ATTEMPTS)}
{sponsorship.nextAttemptAt ? - {td.nextAttempt(formatDateTime(sponsorship.nextAttemptAt, locale))}
: null}
- {sponsorship.mailSentAt ? td.mailSent(formatDateTime(sponsorship.mailSentAt, locale)) : td.mailNotSent}
{sponsorship.offer.isPhysical ? (
- {sponsorship.printedAt ? td.printed(formatDateTime(sponsorship.printedAt, locale)) : td.notPrinted}
) : null}
{sponsorship.lastError ? (
{td.lastError}
{sponsorship.lastError}
) : null}
({
id: row.id,
createdAt: row.createdAt,
expiresAt: row.expiresAt,
createdBy: emailOf.get(row.createdById) ?? row.createdById,
claimedBy: row.claimedById ? (emailOf.get(row.claimedById) ?? row.claimedById) : null,
claimedAt: row.claimedAt,
revokedAt: row.revokedAt,
}))}
/>
);
}