feat: Wabenhain Honig-Shop Anwendung

Vollstaendige Next.js/Prisma-E-Commerce-Anwendung fuer eine Imkerei:
Shop, Warenkorb, Stripe-Checkout, Kundenkonto mit 2FA, Admin-Bereich
(Produkte, Ernten, Chargen, Bestellungen, Gutscheine, admin-editierbare
Website-Inhalte), i18n (DE/EN), Rate-Limiting/CSP/Audit-Log-Haertung,
PostgreSQL- und MySQL-Unterstuetzung ueber austauschbare Prisma-
Treiber-Adapter, Unit-/Komponenten-/E2E-Tests.
This commit is contained in:
Nick Szaunig
2026-08-17 14:30:28 +02:00
parent 5c76fcc266
commit c7927f2883
240 changed files with 26096 additions and 137 deletions
+90
View File
@@ -0,0 +1,90 @@
import { ImageResponse } from "next/og";
import { getProductBySlug } from "@/lib/data";
import { formatPrice } from "@/lib/format";
export const alt = "Wabenhain Produkt";
export const size = { width: 1200, height: 630 };
export const contentType = "image/png";
/**
* Produktspezifisches Social-Preview-Bild statt des generischen
* Seiten-Fallbacks (app/opengraph-image.tsx) — wer einen Honig-Link teilt,
* soll den tatsaechlichen Produktnamen und Preis in der Vorschau sehen statt
* nur des Wabenhain-Markenbilds.
*/
export default async function Image({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const product = await getProductBySlug(slug);
const title = product?.name ?? "Wabenhain";
const tags = product?.tasteTags.slice(0, 3).join(" · ") ?? "";
const price = product ? formatPrice(product.priceCents, product.currency) : "";
return new ImageResponse(
(
<div
style={{
width: "100%",
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
background: "linear-gradient(135deg, #1a271f 0%, #24352b 55%, #3a4d3f 100%)",
padding: "80px",
}}
>
<div
style={{
display: "flex",
fontSize: 20,
letterSpacing: 6,
color: "#b88a44",
marginBottom: 24,
}}
>
WABENHAIN
</div>
<div
style={{
display: "flex",
fontSize: 76,
letterSpacing: 1,
color: "#f4efe5",
textAlign: "center",
lineHeight: 1.1,
}}
>
{title}
</div>
{tags ? (
<div
style={{
display: "flex",
fontSize: 26,
color: "#f4efe5",
opacity: 0.7,
marginTop: 28,
letterSpacing: 1,
}}
>
{tags}
</div>
) : null}
{price ? (
<div
style={{
display: "flex",
fontSize: 34,
color: "#b88a44",
marginTop: 36,
}}
>
{price}
</div>
) : null}
</div>
),
{ ...size }
);
}