import Image from "next/image"; import { PlaceholderImage } from "@/components/placeholder-image"; interface ContentImageProps { /** Hochgeladener Bildpfad (z.B. "/uploads/.webp") oder null/leer -> Platzhalter. */ src: string | null | undefined; alt: string; /** Groessen-/Seitenverhaeltnis-Klassen (z.B. "aspect-[4/5] w-full") — gilt fuer Platzhalter UND Bild-Wrapper gleichermassen. */ className: string; tone?: "forest" | "cream" | "honey"; label?: string; sizes?: string; /** Fuer das wahrscheinlichste LCP-Bild einer Seite (z.B. Startseiten-Hero) * true setzen — laedt das Bild mit hoher Prioritaet ohne Lazy-Loading, * statt es erst beim Scannen weiter unten im Dokument zu entdecken. */ priority?: boolean; /** Leicht abgerundete Ecken. Standard true — passt fuer Karten, Teaser * und Inhaltsbilder, die als eigene Flaeche auf dem Seitenhintergrund * liegen. Fuer randlose Flaechen (Hero ueber die volle Fensterbreite) * bewusst false: dort saesse die Rundung direkt an der Fensterkante und * wirkte wie ein Darstellungsfehler. */ rounded?: boolean; } /** * Zeigt ein hochgeladenes Bild an, sobald eines gepflegt ist, sonst denselben * PlaceholderImage-Platzhalter wie zuvor an dieser Stelle — nie ein kaputtes * . Uploads liegen same-origin unter /uploads/... (siehe * app/uploads/[...path]/route.ts) und brauchen deshalb KEINEN * next.config.ts-remotePatterns-Eintrag: remotePatterns/domains werden nur * fuer externe (cross-origin) Bildquellen benoetigt, next/image behandelt * einen mit "/" beginnenden src immer als lokal und ruft dafuer intern die * eigene Optimierungsroute auf. */ export function ContentImage({ src, alt, className, tone = "forest", label, sizes = "100vw", priority = false, rounded = true, }: ContentImageProps) { // Dieselbe Rundung fuer Platzhalter UND echtes Bild — sonst spraenge die // Form in dem Moment um, in dem ein Bild gepflegt wird. const roundedClass = rounded ? "rounded-lg" : ""; if (!src) { return ( ); } // "label" traegt bereits eine kurze inhaltliche Einordnung (Ernte-Jahr/Typ, // Kategorie, Ort — siehe Aufrufer), die bisher nur auf der Platzhalterkachel // sichtbar war und bei echten Fotos verworfen wurde. Fuer echte Bilder in // den Alt-Text uebernommen: aussagekraeftiger fuer Screenreader UND // Bildersuche als der Produkt-/Ernteame allein. const descriptiveAlt = label ? `${alt} – ${label}` : alt; return (
{descriptiveAlt}, setzt // am selbst aber weder fetchpriority noch loading. Gemessen kam // das Hero-Bild damit trotz "priority" mit niedriger Netzwerk- // Prioritaet an. Die Dokumentation nennt fuer diesen Fall // ausdruecklich loading="eager" und fetchPriority="high" als Ersatz. loading={priority ? "eager" : "lazy"} fetchPriority={priority ? "high" : "auto"} className="object-cover" />
); }