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 (

{title}

{children}
); } 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.previewAlt(beeName, ) : (

{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, }))} />
); }