All checks were successful
Container-Image bauen und veröffentlichen / build-and-push (push) Successful in 5m15s
114 lines
4.0 KiB
TypeScript
114 lines
4.0 KiB
TypeScript
import { notFound } from "next/navigation"
|
||
|
||
import { PublicHeader } from "@/components/public-header"
|
||
import { SiteFooter } from "@/components/site-footer"
|
||
import { markdownToHtml } from "@/lib/markdown"
|
||
import {
|
||
SITE_PAGE_META,
|
||
SitePageKey,
|
||
hasSitePageContent,
|
||
isAllowedEmbedUrl,
|
||
isSafeMediaUrl,
|
||
} from "@/lib/site-pages"
|
||
import { readSitePages } from "@/lib/site-pages.server"
|
||
|
||
/**
|
||
* Rendert eine der rechtlichen Seiten aus dem im Admin gepflegten Markdown.
|
||
*
|
||
* Serverseitig gerendert: Der Text steht ohne JavaScript im Dokument und ist
|
||
* damit auch für Screenreader, Suchmaschinen und Archivierung erreichbar.
|
||
* Ist nichts gepflegt, gibt es die Seite nicht – ein leeres Impressum wäre
|
||
* irreführender als ein 404.
|
||
*/
|
||
export async function LegalPage({ page }: { page: SitePageKey }) {
|
||
const pages = await readSitePages()
|
||
const content = pages[page].trim()
|
||
const meta = SITE_PAGE_META[page]
|
||
|
||
// Auf der Gebärdensprach-Seite ist das Video der eigentliche Inhalt. Sie
|
||
// erscheint deshalb auch dann, wenn nur eine Videoadresse hinterlegt ist –
|
||
// ein zusätzlicher Text ist willkommen, aber keine Bedingung.
|
||
const video =
|
||
page === "signLanguage" && isSafeMediaUrl(pages.signLanguageVideo)
|
||
? pages.signLanguageVideo.trim()
|
||
: ""
|
||
|
||
if (!hasSitePageContent(pages, page)) notFound()
|
||
|
||
const html = content ? await markdownToHtml(content) : ""
|
||
|
||
const captions = isSafeMediaUrl(pages.signLanguageCaptions)
|
||
? pages.signLanguageCaptions.trim()
|
||
: ""
|
||
|
||
return (
|
||
<div className="flex min-h-screen flex-col bg-background">
|
||
<PublicHeader subtitle={meta.title} />
|
||
|
||
<main id="inhalt" tabIndex={-1} className="mx-auto w-full max-w-3xl flex-1 px-4 py-6 sm:px-6 sm:py-8">
|
||
<h1 className="mb-6 text-2xl font-semibold tracking-tight">
|
||
{meta.title}
|
||
</h1>
|
||
|
||
{/* Erläuterungen in Deutscher Gebärdensprache nach § 4 BITV 2.0.
|
||
Der native Player ist mit der Tastatur bedienbar; Untertitel
|
||
werden eingebunden, sobald eine WebVTT-Datei hinterlegt ist. */}
|
||
{page === "signLanguage" && video && (
|
||
<figure className="mb-8">
|
||
{isAllowedEmbedUrl(video) ? (
|
||
// Player eines zugelassenen Anbieters. Die Attribute setzt die
|
||
// Anwendung, nicht der Text im Admin – so lässt sich über das
|
||
// Adressfeld nichts anderes einschleusen.
|
||
<div className="aspect-video w-full overflow-hidden rounded-lg border bg-muted">
|
||
<iframe
|
||
src={video}
|
||
title="Gebärdensprach-Video des Amts Leezen"
|
||
referrerPolicy="no-referrer"
|
||
allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
|
||
allowFullScreen
|
||
className="size-full border-0"
|
||
/>
|
||
</div>
|
||
) : (
|
||
<video
|
||
controls
|
||
preload="metadata"
|
||
className="w-full rounded-lg border bg-muted"
|
||
>
|
||
<source src={video} />
|
||
{captions && (
|
||
<track
|
||
src={captions}
|
||
kind="captions"
|
||
srcLang="de"
|
||
label="Deutsch"
|
||
default
|
||
/>
|
||
)}
|
||
Ihr Browser kann dieses Video nicht abspielen.{" "}
|
||
<a href={video}>Video herunterladen</a>
|
||
</video>
|
||
)}
|
||
<figcaption className="mt-2 text-sm text-muted-foreground">
|
||
Video in Deutscher Gebärdensprache.{" "}
|
||
<a className="underline" href={video}>Video direkt öffnen</a>
|
||
</figcaption>
|
||
</figure>
|
||
)}
|
||
|
||
<div
|
||
className="markdown-content"
|
||
dangerouslySetInnerHTML={{ __html: html }}
|
||
/>
|
||
</main>
|
||
|
||
<SiteFooter />
|
||
</div>
|
||
)
|
||
}
|
||
|
||
/** Seitentitel für den Browser-Tab. */
|
||
export function legalPageMetadata(page: SitePageKey) {
|
||
return { title: SITE_PAGE_META[page].title }
|
||
}
|