This repository has been archived on 2026-06-19. You can view files and clone it, but cannot push or open issues or pull requests.
gso-landingpage/src/app/components/WeekTimeline.tsx
Athena 580cad5b25 Neue Wochenstruktur: Woche 2 Startangebot + Woche 3/4 angepasst
- Woche 2 neu: "Was verkaufst du — und womit fängst du an?"
- Woche 3: Angebot ausbauen + Positionierungsformel (war Woche 2)
- Woche 4: Verkaufsseite + Kanal-Strategie + 90-Tage-Plan (merged)
- Manuela Ludewig in Woche 7 (statt TBA)
- Coach-Sektion: Einstiegsangebot in Katjas Themenbereich

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 20:31:28 +02:00

252 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useEffect, useRef } from "react";
import { ClipboardIcon, CheckIcon } from "./Icons";
interface Week {
week: string;
expert?: string;
title: string;
body: string;
vorlagen: string;
result: string;
}
interface Module {
label: string;
headline: string;
weeks: Week[];
}
const MODULES: Module[] = [
{
label: "Modul 1 — Wochen 1 & 2",
headline: "Wunschkunde, Markt + dein erstes klares Angebot",
weeks: [
{
week: "Woche 1",
title: "Dein Wunschkunde + dein Markt",
body: "Erst weißt du für wen — dann weißt du womit du anfängst. Du schaust konkret hin: Wer ist dein Wunschkunde wirklich? Welches Problem hat er — und was hat er schon alles versucht? Was kostet ihn das jeden Monat? Du machst einen ehrlichen Marketing-Audit: Was läuft, was nicht — und warum. Diese Woche ist die Grundlage für dein Einstiegsangebot in Woche 2.",
vorlagen: "Marketing-Audit-Vorlage · Wunschkunden-Persona-Vorlage",
result: "Klarheit über deinen Wunschkunden — konkret, nicht allgemein. Basis für Woche 2.",
},
{
week: "Woche 2",
title: "Was verkaufst du — und womit fängst du an?",
body: "Schluss mit 'Ich habe so viel anzubieten — wo fange ich an?' Du schaust auf alles was du anbietest und wählst EIN klares Startangebot aus: konkret, klar, sofort buchbar. Welches Problem löst es? Für wen? Was macht es wert? Ab jetzt weißt du genau: das ist mein erstes Produkt.",
vorlagen: "Startangebot-Vorlage · Angebotsportfolio-Canvas",
result: "EIN klares Startangebot — definiert, priorisiert, bereit zum Verkauf.",
},
],
},
{
label: "Modul 2 — Wochen 3 & 4",
headline: "Dein System steht.",
weeks: [
{
week: "Woche 3",
title: "Angebot ausbauen + deine Positionierungsformel",
body: "Du baust dein Startangebot weiter aus: Was sind die Extras die es unwiderstehlich machen? Dann entwickelst du deine Positionierungsformel — für wen, welches Problem, was macht dich anders. In einem Satz. Du übst ihn live in der Gruppe.",
vorlagen: "Positionierungsformel-Vorlage · Kurztext für Website, Instagram und LinkedIn",
result: "Angebot vollständig ausgebaut — Positionierung in einem Satz, für alle Kanäle.",
},
{
week: "Woche 4",
title: "Verkaufsseite + Kanal-Strategie + 90-Tage-Marketingplan",
body: "Du bekommst die Struktur für deine Verkaufsseite — 7 Pflicht-Elemente, Vorlage, direkt einsetzbar. Dann entscheidest du: Welche 2 Kanäle fokussierst du auf Basis deiner Zielgruppe? Du baust deine Marketing-Systemkarte und startest deinen 90-Tage-Plan.",
vorlagen: "Verkaufsseiten-Vorlage · Kanal-Entscheidungsmatrix · Marketing-Systemkarte · 90-Tage-Marketingplan",
result: "Verkaufsseite strukturiert + 2 Kanäle entschieden + 90-Tage-Plan begonnen.",
},
],
},
{
label: "Modul 3 — Wochen 58",
headline: "Sichtbarkeit. Anfragen. Und du weißt wie es weitergeht.",
weeks: [
{
week: "Woche 5",
expert: "Can Turkdogan · Social Media",
title: "Dein Content-System",
body: "Deine 34 Content-Themen die zeigen wofür du stehst. Du erstellst live deinen 4-Wochen-Redaktionsplan, schreibst deinen ersten Hook und weißt ab dieser Woche genau: was du postest, wann, und warum.",
vorlagen: "Content-Säulen-Template · 4-Wochen-Redaktionsplan · 10 bewährte Hook-Formeln",
result: "Content-Plan für 4 Wochen — weißt genau was und wie du postest.",
},
{
week: "Woche 6",
expert: "Stefan & Philipp · Onlinewerbevideo",
title: "Social Media Verkauf + Video-Setup",
body: "Du lernst wie du dein Angebot aktiv über Social Media verkaufst — mit Strategie, nicht mit Druck. Die Video-Experten zeigen live: professionelle Videos mit dem Handy.",
vorlagen: "Launch-Checkliste · Equipment-Checkliste · Filming-Guide",
result: "Plan für Social Media Verkauf + professionell auf Video.",
},
{
week: "Woche 7",
expert: "Manuela Ludewig · Vertrieb",
title: "Verkauf + Direktansprache",
body: "Dein persönliches Verkaufsskript für die Direktansprache — angepasst auf deine Positionierung. Du übst es live in der Gruppe mit konkretem Plan für deine nächsten Kontakte.",
vorlagen: "Persönliches Verkaufsskript · Follow-up-Template · Event-Recherche-Guide",
result: "Dein Verkaufsskript für die Direktansprache — einmal geübt.",
},
{
week: "Woche 8",
expert: "Katja Pestereva · Market Compass",
title: "Sichtbarkeit auf Google + Abschluss",
body: "Du optimierst dein Google Business Profil Schritt für Schritt in der Gruppe. Du bringst deine Website auf die Grundlagen die Google belohnt. Abschlussrunde: Was hat sich in 8 Wochen verändert?",
vorlagen: "SEO-Checkliste · Keyword-Recherche-Vorlage · Website-Leitfaden",
result: "Google Business vollständig optimiert + Seite für dein Haupt-Keyword.",
},
],
},
];
/* Running week counter so odd/even alternates across all modules */
let globalWeekIndex = 0;
function WeekCard({ week, isLeft }: { week: Week; isLeft: boolean }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const obs = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
el.classList.add("tl-visible");
obs.disconnect();
}
},
{ threshold: 0.15 }
);
obs.observe(el);
return () => obs.disconnect();
}, []);
return (
<div
ref={ref}
className={`tl-card ${isLeft ? "tl-from-left" : "tl-from-right"} w-full md:w-[46%] ${
isLeft ? "md:mr-auto md:pr-10" : "md:ml-auto md:pl-10"
}`}
>
<div className="mc-card p-6 space-y-3 hover:shadow-lg hover:shadow-indigo-100 transition-shadow">
{/* Header */}
<div className="flex flex-wrap items-center gap-2">
<span className="bg-gradient-to-r from-indigo-500 to-violet-500 text-white text-xs font-bold px-3 py-1 rounded-full uppercase tracking-wide">
{week.week}
</span>
{week.expert && (
<span className="bg-indigo-50 text-indigo-700 text-xs font-medium px-3 py-1 rounded-full border border-indigo-100">
{week.expert}
</span>
)}
</div>
{/* Title */}
<h4 className="font-extrabold text-slate-900 text-lg leading-snug">{week.title}</h4>
{/* Body */}
<p className="text-slate-500 text-sm leading-relaxed">{week.body}</p>
{/* Vorlagen */}
<p className="text-xs text-slate-400 italic border-t border-slate-100 pt-3 flex items-start gap-1.5">
<ClipboardIcon className="w-3.5 h-3.5 flex-shrink-0 mt-0.5" />
{week.vorlagen}
</p>
{/* Result */}
<p className="text-sm font-semibold text-slate-700 flex items-start gap-1.5">
<CheckIcon className="w-4 h-4 flex-shrink-0 mt-0.5 text-indigo-500" />
{week.result}
</p>
</div>
</div>
);
}
export default function WeekTimeline() {
/* Reset global counter each render (SSR-safe: only matters client-side) */
globalWeekIndex = 0;
return (
<section className="py-20">
<div className="max-w-5xl mx-auto px-6">
{/* Section header */}
<div className="text-center mb-16">
<span className="inline-flex items-center gap-2 bg-indigo-50 text-indigo-700 text-xs font-bold uppercase tracking-widest rounded-full px-4 py-2 border border-indigo-100">
<span className="w-2 h-2 rounded-full bg-indigo-500 animate-pulse" />
8 Wochen · Schritt für Schritt
</span>
<h2 className="mt-4 text-3xl md:text-4xl font-extrabold text-slate-900">
Dein Programm Woche für Woche
</h2>
<p className="mt-3 text-slate-500 max-w-xl mx-auto">
Jede Woche baut auf der nächsten auf. Am Ende hast du kein Zertifikat sondern ein fertiges System.
</p>
</div>
{MODULES.map((mod) => (
<div key={mod.label} className="mb-6">
{/* Module divider */}
<ModuleDivider label={mod.label} headline={mod.headline} />
{/* Weeks */}
<div className="relative">
{/* Vertical timeline line */}
<div className="hidden md:block absolute left-1/2 top-0 bottom-0 w-0.5 bg-gradient-to-b from-indigo-300 via-violet-300 to-indigo-200 -translate-x-1/2" />
<div className="flex flex-col gap-10 py-6">
{mod.weeks.map((week) => {
const isLeft = globalWeekIndex % 2 === 0;
globalWeekIndex++;
return (
<div key={week.week} className="relative flex items-start">
{/* Timeline dot — centered */}
<div className="hidden md:flex absolute left-1/2 -translate-x-1/2 top-7 w-8 h-8 rounded-full bg-gradient-to-br from-indigo-500 to-violet-500 items-center justify-center shadow-lg shadow-indigo-200 z-10 flex-shrink-0">
<span className="text-white text-xs font-bold">
{week.week.replace("Woche ", "")}
</span>
</div>
<WeekCard week={week} isLeft={isLeft} />
</div>
);
})}
</div>
</div>
</div>
))}
</div>
</section>
);
}
function ModuleDivider({ label, headline }: { label: string; headline: string }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const obs = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
el.classList.add("tl-visible");
obs.disconnect();
}
},
{ threshold: 0.2 }
);
obs.observe(el);
return () => obs.disconnect();
}, []);
return (
<div
ref={ref}
className="tl-card tl-from-bottom text-center py-8 mb-2"
>
<div className="inline-flex items-center gap-3">
<div className="h-px w-12 bg-gradient-to-r from-transparent to-indigo-300" />
<span className="bg-gradient-to-r from-indigo-600 to-violet-600 bg-clip-text text-transparent text-xs font-extrabold uppercase tracking-widest">
{label}
</span>
<div className="h-px w-12 bg-gradient-to-l from-transparent to-indigo-300" />
</div>
<h3 className="mt-2 text-xl md:text-2xl font-extrabold text-slate-900">{headline}</h3>
</div>
);
}