first commit
Docker-Images bauen und veroeffentlichen / build-and-push (push) Failing after 1m32s

This commit is contained in:
Nick Szaunig committed 2026-09-27 06:06:56 +02:00
commit 59bb5a38a3
132 files changed
+19435

No files matched your search

@@ -0,0 +1,93 @@
import { site } from "@/content/site";
import { MediaFrame } from "../MediaFrame";
import { Reveal } from "../Reveal";
import { VideoSlot } from "../VideoSlot";
export function TeachersSection({ showDrafts }: { showDrafts: boolean }) {
const { teachers } = site;
return (
<section id="dozentinnen" aria-labelledby="dozentinnen-title" className="bg-paper py-20 md:py-32">
<div className="container-edge">
<h2 id="dozentinnen-title" className="section-title">{teachers.title}</h2>
<div className="mt-14 grid gap-16 md:grid-cols-12 md:gap-10">
{teachers.people.map((person, index) => (
<article
key={index}
aria-label={person.name ?? `Dozentin ${index + 1}`}
className={index === 0 ? "md:col-span-5" : "md:col-span-5 md:col-start-8 md:mt-40"}
>
<Reveal>
<MediaFrame media={person.portrait} aspect="aspect-[3/4]" sizes="(min-width: 768px) 40vw, 100vw" showLabel={showDrafts} />
</Reveal>
<h3 className="display mt-6 text-3xl">
{person.name ?? (showDrafts ? `Dozentin ${index + 1}: Name folgt` : "Wird in Kürze vorgestellt")}
</h3>
{person.role && <p className="mt-1 text-stone">{person.role}</p>}
{person.bio ? (
<p className="mt-4 max-w-md">{person.bio}</p>
) : (
showDrafts && <p className="mt-4"><span className="draft-flag">Kurzbeschreibung folgt</span></p>
)}
</article>
))}
</div>
</div>
</section>
);
}
export function AboutSection({ showDrafts }: { showDrafts: boolean }) {
const { about } = site;
return (
<section id="artista" aria-labelledby="artista-title" className="py-20 md:py-32">
<div className="container-edge grid gap-8 md:grid-cols-12">
<h2 id="artista-title" className="section-title md:col-span-5">{about.title}</h2>
<div className="prose-body md:col-span-6 md:col-start-7">
{about.paragraphs.length > 0 ? (
about.paragraphs.map((p) => <p key={p}>{p}</p>)
) : (
<p className="text-stone">
{showDrafts ? (
<>
<span className="draft-flag">Inhalt folgt</span> Grundlage wird die ARTISTA-Stammmodel-Seite (Link folgt).
</>
) : (
"Mehr über ARTISTA erfährst du in Kürze hier."
)}
</p>
)}
{about.sourceUrl && (
<p className="mt-6">
<a href={about.sourceUrl} target="_blank" rel="noopener noreferrer" className="font-semibold underline underline-offset-4">
Zur ARTISTA-Stammmodel-Seite
</a>
</p>
)}
</div>
</div>
</section>
);
}
export function VoicesSection({ showDrafts, provider }: { showDrafts: boolean; provider: "none" | "youtube-nocookie" | "vimeo" }) {
const { videos } = site;
const filled = videos.slots.filter((s) => s.src || s.externalId);
// Leere Slots nur in Entwicklung/Staging zeigen; oeffentlich nie ein
// erfundenes Testimonial als Ersatz.
const slots = showDrafts ? videos.slots : filled;
if (slots.length === 0) return null;
return (
<section id="stimmen" aria-labelledby="stimmen-title" className="border-t border-line py-20 md:py-28">
<div className="container-edge">
<h2 id="stimmen-title" className="section-title">{videos.title}</h2>
<ul className="mt-12 grid gap-10 md:grid-cols-3">
{slots.map((slot, index) => (
<li key={index}>
<VideoSlot slot={slot} index={index} provider={provider} showDrafts={showDrafts} />
</li>
))}
</ul>
</div>
</section>
);
}