feat: make /imkerei and /herkunft hero images admin-editable

Both pages are the ones most directly meant to give customers "ein
gutes Bild von der Imkerei" (per the active /goal), but their hero
images were still hardcoded PlaceholderImage tiles with no way to
ever swap in a real photo — unlike every homepage section, which
already went through this exact upload flow.

Added imkerei.image / herkunft.image to the content registry (new
"pages" group, since neither belongs under "Homepage") and switched
both pages from PlaceholderImage to ContentImage + getContentValue,
the same pattern already proven on the homepage sections. Falls back
to the identical placeholder tile until a photo is uploaded, so this
is a pure addition with no visual change until the owner uploads one.

Verified: tsc clean, 151/151 tests pass, both pages still render
correctly (curl 200 + screenshot) with the placeholder fallback.
Could not verify the admin upload UI end-to-end live — the local
admin account has 2FA enabled and I don't have the second factor;
confidence instead comes from reusing the identical, already-verified
AdminImageField/ContentImage wiring used for the four home.*.image
fields, plus generic (group-agnostic) admin field loading confirmed
by reading admin/inhalte/page.tsx.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Sonnet 5 committed 2026-09-08 22:32:00 +02:00
1 parent 3627f4e5c1
commit 8d988515f3
7 files changed
+29 -7

No files matched your search

+1
View File
@@ -33,6 +33,7 @@ export default async function AdminInhaltePage(props: PageProps<"/admin/inhalte"
const groups: { key: ContentFieldDef["group"]; heading: string }[] = [
{ key: "company", heading: t.adminContentPage.groupCompany },
{ key: "home", heading: t.adminContentPage.groupHome },
{ key: "pages", heading: t.adminContentPage.groupPages },
{ key: "social", heading: t.adminContentPage.groupSocial },
{ key: "legal", heading: t.adminContentPage.groupLegal },
];
+8 -3
View File
@@ -1,8 +1,9 @@
import type { Metadata } from "next";
import { Container, SectionHeading } from "@/components/ui";
import { PlaceholderImage } from "@/components/placeholder-image";
import { ContentImage } from "@/components/content-image";
import { getLocale } from "@/i18n/locale";
import { getDictionary } from "@/i18n/get-dictionary";
import { getContentValue } from "@/lib/content";
export async function generateMetadata(): Promise<Metadata> {
const t = getDictionary(await getLocale());
@@ -14,10 +15,14 @@ export async function generateMetadata(): Promise<Metadata> {
}
export default async function HerkunftPage() {
const t = getDictionary(await getLocale());
const locale = await getLocale();
const t = getDictionary(locale);
const image = await getContentValue("herkunft.image", locale);
return (
<div className="py-20">
<PlaceholderImage
<ContentImage
src={image || null}
alt={t.herkunftPage.eyebrow}
tone="forest"
className="h-[50vh] min-h-[360px] w-full mb-20"
label={t.herkunftPage.eyebrow}
+12 -3
View File
@@ -1,8 +1,9 @@
import type { Metadata } from "next";
import { Container, SectionHeading } from "@/components/ui";
import { PlaceholderImage } from "@/components/placeholder-image";
import { ContentImage } from "@/components/content-image";
import { getLocale } from "@/i18n/locale";
import { getDictionary } from "@/i18n/get-dictionary";
import { getContentValue } from "@/lib/content";
export async function generateMetadata(): Promise<Metadata> {
const t = getDictionary(await getLocale());
@@ -14,7 +15,9 @@ export async function generateMetadata(): Promise<Metadata> {
}
export default async function ImkereiPage() {
const t = getDictionary(await getLocale());
const locale = await getLocale();
const t = getDictionary(locale);
const image = await getContentValue("imkerei.image", locale);
return (
<div className="py-20">
<Container className="grid md:grid-cols-2 gap-14 items-center">
@@ -30,7 +33,13 @@ export default async function ImkereiPage() {
))}
</div>
</div>
<PlaceholderImage tone="honey" className="aspect-[4/5] w-full" label={t.imkereiPage.imageLabel} />
<ContentImage
src={image || null}
alt={t.imkereiPage.imageLabel}
tone="honey"
className="aspect-[4/5] w-full"
label={t.imkereiPage.imageLabel}
/>
</Container>
</div>
);