From 6814e9e2c81630023918b93c659f2c311bf90d55 Mon Sep 17 00:00:00 2001 From: Nick Szaunig Date: Fri, 11 Sep 2026 14:53:14 +0200 Subject: [PATCH] feat: Hero-Hintergrundvideo im Admin, ScrollReveal + Bild-Perf auf Unterseiten Neues admin-editierbares Hintergrundvideo fuer den Startseiten-Hero (home.hero.video, MP4/WebM) mit eigenem, magic-byte-validiertem Upload-Endpunkt (app/api/admin/upload-video) analog zur bestehenden Bild-Upload-Pipeline. Ausserdem: ScrollReveal-Animation von der Startseite auf Imkerei, Herkunft, Unternehmen, Ernten, Wissen, Kontakt, Shop sowie die Produkt-/Ernte-/Chargen-Detailseiten ausgerollt (bisher nur Startseite), priority auf bislang lazy geladene Above-the-fold-Bilder (Herkunft/Unternehmen) gesetzt, und passende sizes-Hints auf Grid-Bilder (Produktkarten, Origin/Regional/Business-Teaser, Ernten-Liste) ergaenzt statt voller Viewport-Breite. Co-Authored-By: Claude Sonnet 5 --- src/app/admin/actions/content.ts | 7 +- src/app/admin/inhalte/page.tsx | 18 ++++- src/app/api/admin/upload-video/route.ts | 88 ++++++++++++++++++++++++ src/app/charge/[code]/page.tsx | 65 ++++++++++-------- src/app/ernten/[year]/[type]/page.tsx | 22 +++--- src/app/ernten/page.tsx | 43 +++++++----- src/app/herkunft/page.tsx | 22 +++--- src/app/honig/[slug]/page.tsx | 9 ++- src/app/imkerei/page.tsx | 22 +++--- src/app/kontakt/page.tsx | 13 ++-- src/app/page.tsx | 6 +- src/app/shop/page.tsx | 15 +++-- src/app/unternehmen/page.tsx | 26 ++++--- src/app/wissen/page.tsx | 17 +++-- src/components/admin-video-field.tsx | 90 +++++++++++++++++++++++++ src/components/hero.tsx | 35 +++++++--- src/components/home-sections-a.tsx | 2 + src/components/home-sections-b.tsx | 2 + src/components/product-card.tsx | 1 + src/i18n/dictionaries/de.ts | 6 ++ src/i18n/dictionaries/en.ts | 6 ++ src/i18n/dictionary-type.ts | 8 +++ src/lib/content-registry.ts | 8 ++- src/lib/uploads.test.ts | 61 +++++++++++++++++ src/lib/uploads.ts | 51 +++++++++++++- 25 files changed, 524 insertions(+), 119 deletions(-) create mode 100644 src/app/api/admin/upload-video/route.ts create mode 100644 src/components/admin-video-field.tsx diff --git a/src/app/admin/actions/content.ts b/src/app/admin/actions/content.ts index dbce963..158a25a 100644 --- a/src/app/admin/actions/content.ts +++ b/src/app/admin/actions/content.ts @@ -5,7 +5,7 @@ import { revalidatePath } from "next/cache"; import { prisma } from "@/lib/prisma"; import { logAdminAction } from "@/lib/audit-log"; import { CONTENT_REGISTRY } from "@/lib/content-registry"; -import { isValidUploadPath } from "@/lib/uploads"; +import { isValidUploadPath, isValidVideoUploadPath } from "@/lib/uploads"; import { requireAdmin } from "./_shared"; /** @@ -43,6 +43,11 @@ export async function updateSiteContentAction(formData: FormData): Promise if (def.type === "image" && valueDe !== "" && !isValidUploadPath(valueDe)) { continue; } + // Analog zum Bild-Feld: ein Video-Feld darf nur einen Pfad enthalten, + // den app/api/admin/upload-video/route.ts tatsaechlich erzeugt hat. + if (def.type === "video" && valueDe !== "" && !isValidVideoUploadPath(valueDe)) { + continue; + } updates.push({ key: def.key, valueDe, valueEn: null }); } } diff --git a/src/app/admin/inhalte/page.tsx b/src/app/admin/inhalte/page.tsx index c808e2e..39adb93 100644 --- a/src/app/admin/inhalte/page.tsx +++ b/src/app/admin/inhalte/page.tsx @@ -1,6 +1,7 @@ import { prisma } from "@/lib/prisma"; import { BackLink } from "@/components/back-link"; import { AdminImageField } from "@/components/admin-image-field"; +import { AdminVideoField } from "@/components/admin-video-field"; import { CONTENT_REGISTRY, type ContentFieldDef } from "@/lib/content-registry"; import { updateSiteContentAction } from "../actions"; import { getLocale } from "@/i18n/locale"; @@ -13,10 +14,11 @@ const ROWS_BY_TYPE: Record = { "list-titled": 5, "list-numbered": 6, "richtext-sections": 14, - // Bild-Feld hat kein