"use client"
import { motion, useScroll } from "motion/react"
import { Fragment, useRef, useState } from "react"
import { ArrowDownRightIcon, ArrowRightIcon, CheckIcon, PauseIcon, PlayIcon, QuoteIcon, XIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import type { TemplateProps } from "../../lib/types"
import { DemoForm } from "../shared/demo-form"
import { TField } from "../shared/fields"
import { TImage } from "../shared/media"
import { Reveal, RevealWords, ease, parseRich, useScrollNav } from "../shared/motion"
import { TemplateShell } from "../shared/shell"
import { coach, type CoachData } from "./definition"
import { fonts, script } from "./fonts"
const em = "italic text-t-accent"
const container = "mx-auto w-full max-w-[1280px] px-5 md:px-8"
const heading = "font-t-display font-normal tracking-[-0.02em]"
function Eyebrow({ children }: { children: string }) {
return
{children}
}
// Wörter gleiten herein, hervorgehobene Wörter bekommen eine handgezeichnete Linie
function MarkedTitle({ text }: { text: string }) {
const lines: { word: string; em: boolean; index: number }[][] = []
let count = 0
for (const tokens of parseRich(text)) {
const line = []
for (const token of tokens) {
line.push({ ...token, index: count })
count += 1
}
lines.push(line)
}
return (
{lines.map((tokens, l) => (
{tokens.map((token, t) => (
{t > 0 && " "}
{token.word}
{token.em && (
)}
))}
))}
)
}
export function CoachTemplate({ content }: TemplateProps) {
const { brand, hero, press, pains, story, offers, results, podcast, leadmagnet, contact } = content.data
const show = (key: string) => !content.hidden.includes(key)
const links = [
{ href: "#ueber-mich", label: "Über mich", visible: show("story") },
{ href: "#angebote", label: "Angebote", visible: show("offers") },
{ href: "#podcast", label: "Podcast", visible: show("podcast") },
].filter((link) => link.visible)
return (
{hero.eyebrow}
{hero.text}
{hero.quote}
{hero.badge}
{show("press") && (
{press.title}
{press.items.map((item, i) => (
{item.name}
))}
)}
{show("pains") && (
)}
{show("story") && }
{show("offers") && (
{offers.eyebrow}
{offers.items.map((offer, i) => {
const featured = Boolean(offer.highlight.trim())
return (
0{i + 1}
{offer.title}
{offer.text}
{offer.price}
{offer.cta}
)
})}
)}
{show("results") && (
{results.eyebrow}
{results.items.map((item, i) => (
„{item.quote}“
{item.author}
{item.role}
))}
)}
{show("podcast") && }
{show("leadmagnet") && (
Workbook
{leadmagnet.book}
{brand.name}
{leadmagnet.text}
Ist unterwegs – schau in dein Postfach!
}
>
)}
)
}
function Nav({ name, cta, links }: { name: string; cta: string; links: { href: string; label: string }[] }) {
const { scrolled, hidden } = useScrollNav()
return (
)
}
function Story({ story }: { story: CoachData["story"] }) {
const ref = useRef(null)
const { scrollYProgress } = useScroll({ target: ref, offset: ["start 0.8", "end 0.6"] })
return (
{story.eyebrow}
{story.text}
{story.milestones.map((milestone, i) => (
-
{milestone.year}
{milestone.text}
))}
{story.signature}
)
}
function Podcast({ podcast }: { podcast: CoachData["podcast"] }) {
const [playing, setPlaying] = useState(null)
return (
{podcast.eyebrow}
{podcast.items.map((episode, i) => {
const active = playing === i
return (
-
Folge {episode.number} · {episode.duration}
{episode.title}
{active && (
{[0, 1, 2, 3, 4, 5].map((bar) => (
))}
)}
{active && (
)}
)
})}
)
}