Typen Social Media und Video

Social Media buendelt Profile auf einer Seite. Wer „@firma" eintippt, meint
das Profil beim gewaehlten Netzwerk — daraus wird die volle Adresse. Statt
nachgezeichneter Markenlogos steht ein Kreis in der Hausfarbe mit Monogramm;
ein schlecht nachgebautes Logo sieht schlechter aus als ein sauberes Zeichen.

Video erkennt YouTube, Vimeo und direkte Dateien. Der Rahmen zum Anbieter
laedt erst auf Klick, und davor steht, dass dabei Daten uebertragen werden —
diese Seite bekommen Fremde nach einem Scan zu sehen, ungefragt einen
Drittanbieter einzubinden waere nicht in Ordnung. Videodateien laden mit
preload="none": wer unterwegs scannt, zahlt das Volumen.
This commit is contained in:
Florian Wilde
2026-08-14 22:44:23 +02:00
parent e627f7c372
commit fdf6452b35
11 changed files with 859 additions and 12 deletions
+67
View File
@@ -0,0 +1,67 @@
import { Icon } from "@/components/icons";
import { LandingShell } from "@/components/landing/shell";
import type { LandingProps } from "@/components/landing/types";
import { EmbeddedVideo } from "@/components/landing/video-player";
import { resolveVideoSource, videoDataSchema } from "@/lib/qr/types/video";
export function VideoLanding({ data }: LandingProps) {
const { url, title, description } = videoDataSchema.parse(data);
const quelle = resolveVideoSource(url);
return (
<LandingShell
title={title || "Video"}
subtitle={description || null}
footer={
quelle.kind === "youtube" || quelle.kind === "vimeo" ? (
<a
href={url}
rel="noopener noreferrer"
className="underline underline-offset-2 hover:text-slate-600"
>
Bei {quelle.label} öffnen
</a>
) : null
}
>
{quelle.kind === "youtube" || quelle.kind === "vimeo" ? (
<EmbeddedVideo
embedUrl={quelle.embedUrl}
provider={quelle.label}
title={title || "Video"}
/>
) : quelle.kind === "file" ? (
<video
controls
// Nicht von allein laden: Wer unterwegs scannt, zahlt das Volumen.
preload="none"
className="aspect-video w-full rounded-2xl bg-black shadow-sm"
>
<source src={url} />
Dein Browser kann dieses Video nicht abspielen.
</video>
) : (
<a
href={url}
rel="noopener noreferrer"
className="flex items-center gap-3 rounded-2xl border border-slate-200 bg-white px-5 py-4 text-slate-900 shadow-sm transition-colors hover:border-indigo-300 hover:bg-indigo-50/60"
>
<span className="flex size-10 shrink-0 items-center justify-center rounded-full bg-slate-100 text-slate-600">
<Icon name="video" className="size-5" />
</span>
<span className="min-w-0 flex-1">
<span className="block font-medium">Video ansehen</span>
<span className="block truncate text-sm text-slate-500">
{quelle.label}
</span>
</span>
<Icon
name="external"
className="size-4 shrink-0 text-slate-400"
aria-hidden="true"
/>
</a>
)}
</LandingShell>
);
}