continued the kita-planer
This commit is contained in:
+394
-72
@@ -1,104 +1,426 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { redirect } from "next/navigation";
|
||||
import { CalendarCheck2, ShieldCheck, Users } from "lucide-react";
|
||||
import {
|
||||
ArrowRight,
|
||||
CalendarDays,
|
||||
CheckCircle2,
|
||||
DatabaseZap,
|
||||
Fingerprint,
|
||||
LockKeyhole,
|
||||
Mail,
|
||||
Megaphone,
|
||||
MessageSquareText,
|
||||
ShieldAlert,
|
||||
ShieldCheck,
|
||||
Stethoscope,
|
||||
Trash2,
|
||||
UsersRound,
|
||||
} from "lucide-react";
|
||||
|
||||
import { auth } from "@/auth";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { ContactForm } from "./contact-form";
|
||||
|
||||
// Eingeloggte User von der Landingpage direkt weiterleiten — die Routing-
|
||||
// Logik selbst (Onboarding vs. Dashboard) übernimmt `requireKitaSession`.
|
||||
export const metadata: Metadata = {
|
||||
title: "Kita-Planer für Elternvereine",
|
||||
description:
|
||||
"Die einfache Plattform für Elternvereine, Dienste und Kommunikation: plant Dienste, teilt Neuigkeiten und behaltet Termine gemeinsam im Blick.",
|
||||
openGraph: {
|
||||
title: "Kita-Planer für Elternvereine",
|
||||
description:
|
||||
"Plant Dienste, teilt Neuigkeiten und behaltet Termine gemeinsam im Blick.",
|
||||
type: "website",
|
||||
locale: "de_DE",
|
||||
images: [
|
||||
{
|
||||
url: "/og-image.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "Ein Kind spielt mit bunten Holzklötzen.",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Kita-Planer für Elternvereine",
|
||||
description:
|
||||
"Plant Dienste, teilt Neuigkeiten und behaltet Termine gemeinsam im Blick.",
|
||||
images: ["/og-image.png"],
|
||||
},
|
||||
};
|
||||
|
||||
const heroImage =
|
||||
"https://images.unsplash.com/photo-1503454537195-1dcabb73ffb9?auto=format&fit=crop&w=2400&q=86";
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: ShieldAlert,
|
||||
title: "Fairer Notdienst-Planer",
|
||||
description:
|
||||
"Automatische Generierung, gerechte Verteilung und 1-Klick-Alarmierung, wenn morgens Ersatz gebraucht wird.",
|
||||
accent: "bg-red-50 text-red-700 ring-red-100",
|
||||
},
|
||||
{
|
||||
icon: CalendarDays,
|
||||
title: "Smarter Kalender",
|
||||
description:
|
||||
"Feste, Termine, Raumbuchungen und digitale Mitbring-Listen in einem verbindlichen Kalender für alle Familien.",
|
||||
accent: "bg-sky-50 text-sky-700 ring-sky-100",
|
||||
},
|
||||
{
|
||||
icon: UsersRound,
|
||||
title: "Sicheres Adressbuch",
|
||||
description:
|
||||
"Haushaltsbasiert, DSGVO-konform und mit strengem Opt-In: Kontaktdaten werden nur sichtbar, wenn Eltern zustimmen.",
|
||||
accent: "bg-emerald-50 text-emerald-700 ring-emerald-100",
|
||||
},
|
||||
{
|
||||
icon: Stethoscope,
|
||||
title: "Digitale Krankmeldung",
|
||||
description:
|
||||
"Ein Klick statt Dauerläuten am Morgen. Eltern melden Kinder digital ab, ErzieherInnen sehen auf dem Tablet sofort den Überblick für den Morgenkreis.",
|
||||
accent: "bg-amber-50 text-amber-700 ring-amber-100",
|
||||
badge: "Neu",
|
||||
},
|
||||
{
|
||||
icon: Megaphone,
|
||||
title: "Schwarzes Brett",
|
||||
description:
|
||||
"Der WhatsApp-Killer für Vorstände: offizielle Ankündigungen mit Dateianhängen, Lesebestätigung und optionalem E-Mail-Push.",
|
||||
accent: "bg-indigo-50 text-indigo-700 ring-indigo-100",
|
||||
badge: "Neu",
|
||||
},
|
||||
];
|
||||
|
||||
const privacyPoints = [
|
||||
{
|
||||
icon: DatabaseZap,
|
||||
title: "Strikt isolierte Mandanten",
|
||||
text: "Jede Kita arbeitet innerhalb ihrer eigenen kitaId-Grenze. Datenabfragen sind konsequent tenant-isoliert.",
|
||||
},
|
||||
{
|
||||
icon: Fingerprint,
|
||||
title: "Privacy by Design",
|
||||
text: "Adressbuchdaten erscheinen nur nach aktivem Opt-In pro Elternteil. Nicht freigegebene Kontaktdaten verlassen den Server nicht.",
|
||||
},
|
||||
{
|
||||
icon: Trash2,
|
||||
title: "Recht auf Vergessenwerden",
|
||||
text: "Eltern können ihren Account selbst löschen. Wenn sie der letzte Haushaltspartner sind, werden die Familiendaten sauber entfernt.",
|
||||
},
|
||||
{
|
||||
icon: LockKeyhole,
|
||||
title: "Geschützte Anhänge",
|
||||
text: "Dokumente vom Schwarzen Brett liegen nicht öffentlich und werden nur nach Session- und Kita-Prüfung ausgeliefert.",
|
||||
},
|
||||
];
|
||||
|
||||
const proofPoints = [
|
||||
"Notdienst, Kalender und Abwesenheiten in einem System",
|
||||
"Gebaut für Vorstände, Eltern und ErzieherInnen",
|
||||
"Klare Rollenrechte statt Chat-Chaos",
|
||||
];
|
||||
|
||||
// Eingeloggte User von der Landingpage direkt weiterleiten.
|
||||
export default async function LandingPage() {
|
||||
const session = await auth();
|
||||
if (session?.user) {
|
||||
if (session?.user?.id) {
|
||||
redirect(session.user.kitaId ? "/dashboard" : "/onboarding");
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col">
|
||||
<header className="border-b">
|
||||
<div className="mx-auto flex h-16 w-full max-w-6xl items-center justify-between px-6">
|
||||
<span className="text-lg font-semibold">Kita-Planer</span>
|
||||
<nav className="flex items-center gap-3">
|
||||
<Button asChild variant="ghost">
|
||||
<Link href="/login">Anmelden</Link>
|
||||
<div className="min-h-screen bg-[#f8faf8] text-slate-950">
|
||||
<header className="absolute left-0 right-0 top-0 z-20">
|
||||
<div className="mx-auto flex h-20 w-full max-w-7xl items-center justify-between px-5 sm:px-6">
|
||||
<Link href="/" className="flex items-center gap-3 text-white">
|
||||
<span className="flex h-9 w-9 items-center justify-center rounded-lg bg-white/12 ring-1 ring-white/30">
|
||||
<ShieldCheck className="h-5 w-5" />
|
||||
</span>
|
||||
<span className="text-base font-semibold tracking-tight">
|
||||
Kita-Planer
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<nav className="flex items-center gap-2">
|
||||
<Button
|
||||
asChild
|
||||
variant="ghost"
|
||||
className="text-white hover:bg-white/10 hover:text-white"
|
||||
>
|
||||
<Link href="/login">Login</Link>
|
||||
</Button>
|
||||
<Button asChild>
|
||||
<Button
|
||||
asChild
|
||||
className="bg-white text-slate-950 shadow-sm hover:bg-white/90"
|
||||
>
|
||||
<Link href="/register">Kita registrieren</Link>
|
||||
</Button>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex-1">
|
||||
<section className="mx-auto w-full max-w-6xl px-6 py-24">
|
||||
<div className="max-w-3xl">
|
||||
<p className="mb-4 inline-block rounded-full bg-secondary px-3 py-1 text-xs font-medium text-secondary-foreground">
|
||||
Für Elterninitiativen & Elternvereine
|
||||
</p>
|
||||
<h1 className="text-balance text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
Der digitale Kita-Planer für Elterninitiativen.
|
||||
</h1>
|
||||
<p className="mt-6 text-lg text-muted-foreground">
|
||||
Notdienst-Planung, Terminkalender und Stammdaten — endlich
|
||||
an einem Ort. Schluss mit Excel-Tabellen, WhatsApp-Listen und
|
||||
vergessenen Geburtstagen.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-wrap gap-3">
|
||||
<Button asChild size="lg">
|
||||
<Link href="/register">Kita kostenlos registrieren</Link>
|
||||
</Button>
|
||||
<Button asChild size="lg" variant="outline">
|
||||
<Link href="/login">Bereits Mitglied? Anmelden</Link>
|
||||
</Button>
|
||||
<main>
|
||||
<section
|
||||
className="relative min-h-[calc(100svh-56px)] overflow-hidden bg-slate-950"
|
||||
style={{
|
||||
backgroundImage: `linear-gradient(90deg, rgba(2, 6, 23, 0.9), rgba(15, 23, 42, 0.68), rgba(15, 23, 42, 0.18)), url(${heroImage})`,
|
||||
backgroundPosition: "center",
|
||||
backgroundSize: "cover",
|
||||
}}
|
||||
>
|
||||
<div className="absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-[#f8faf8] to-transparent" />
|
||||
|
||||
<div className="relative z-10 mx-auto flex min-h-[calc(100svh-56px)] w-full max-w-7xl items-center px-5 pb-20 pt-28 sm:px-6">
|
||||
<div className="max-w-4xl text-white">
|
||||
<Badge className="mb-6 border-white/20 bg-white/12 text-white hover:bg-white/12">
|
||||
Kita-Betriebssystem für Elternvereine
|
||||
</Badge>
|
||||
<h1 className="max-w-4xl text-balance text-5xl font-semibold leading-[1.02] sm:text-6xl lg:text-7xl">
|
||||
Die einfache Plattform für Elternvereine, Dienste und
|
||||
Kommunikation.
|
||||
</h1>
|
||||
<p className="mt-6 max-w-2xl text-lg leading-8 text-white/82 sm:text-xl">
|
||||
Organisiert Notdienste, Termine, Krankmeldungen und offizielle
|
||||
Kommunikation an einem Ort. Schluss mit Zettelwirtschaft und
|
||||
WhatsApp-Chaos.
|
||||
</p>
|
||||
|
||||
<div className="mt-9 flex flex-col gap-3 sm:flex-row">
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
className="h-12 bg-white px-6 text-slate-950 hover:bg-white/90"
|
||||
>
|
||||
<Link href="/register">
|
||||
Kita registrieren
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="h-12 border-white/35 bg-white/10 px-6 text-white hover:bg-white/20 hover:text-white"
|
||||
>
|
||||
<Link href="/login">Login</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 grid max-w-3xl gap-3 text-sm text-white/78 md:grid-cols-3">
|
||||
{proofPoints.map((item) => (
|
||||
<div key={item} className="flex items-center gap-2">
|
||||
<CheckCircle2 className="h-4 w-4 shrink-0 text-emerald-300" />
|
||||
<span>{item}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="mt-20 grid gap-8 sm:grid-cols-3">
|
||||
<FeatureCard
|
||||
icon={<ShieldCheck className="h-6 w-6" />}
|
||||
title="Notdienst-Planung"
|
||||
description="Verfügbarkeiten erfassen, fairen Plan automatisch generieren, Eltern bei Krankheitsausfall sofort alarmieren."
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={<CalendarCheck2 className="h-6 w-6" />}
|
||||
title="Terminkalender"
|
||||
description="Kita-Feste, Schließtage und private Anfragen mit Mitbringsel-Listen — übersichtlich für alle Eltern."
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={<Users className="h-6 w-6" />}
|
||||
title="Eltern-Adressbuch"
|
||||
description="Spielverabredungen leichter machen — auf Opt-In-Basis und DSGVO-konform."
|
||||
/>
|
||||
<section className="mx-auto w-full max-w-7xl px-5 py-24 sm:px-6">
|
||||
<div className="mb-12 flex flex-col gap-5 lg:flex-row lg:items-end lg:justify-between">
|
||||
<div className="max-w-3xl">
|
||||
<p className="mb-3 text-sm font-semibold uppercase tracking-wide text-emerald-700">
|
||||
Die 5 Säulen
|
||||
</p>
|
||||
<h2 className="text-balance text-3xl font-semibold leading-tight sm:text-4xl">
|
||||
Plant Dienste, teilt Neuigkeiten und behaltet Termine gemeinsam
|
||||
im Blick.
|
||||
</h2>
|
||||
</div>
|
||||
<p className="max-w-md text-sm leading-6 text-slate-600">
|
||||
Kita-Planer bündelt operative Aufgaben, sensible Familiendaten und
|
||||
offizielle Kommunikation in einer Oberfläche, die Vorstände
|
||||
kontrollieren und Eltern verstehen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-5 md:grid-cols-2 xl:grid-cols-6">
|
||||
{features.map((feature, index) => {
|
||||
const Icon = feature.icon;
|
||||
const isWide = index > 2;
|
||||
return (
|
||||
<Card
|
||||
key={feature.title}
|
||||
className={`group border-slate-200 bg-white/90 shadow-sm transition duration-200 hover:-translate-y-1 hover:border-slate-300 hover:shadow-lg ${
|
||||
isWide ? "xl:col-span-3" : "xl:col-span-2"
|
||||
}`}
|
||||
>
|
||||
<CardHeader className="space-y-5">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div
|
||||
className={`flex h-11 w-11 items-center justify-center rounded-lg ring-1 ${feature.accent}`}
|
||||
>
|
||||
<Icon className="h-5 w-5" />
|
||||
</div>
|
||||
{feature.badge && (
|
||||
<Badge className="bg-slate-950 text-white hover:bg-slate-950">
|
||||
{feature.badge}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<CardTitle className="text-xl tracking-tight">
|
||||
{feature.title}
|
||||
</CardTitle>
|
||||
<CardDescription className="mt-3 text-sm leading-6 text-slate-600">
|
||||
{feature.description}
|
||||
</CardDescription>
|
||||
</div>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="bg-slate-950 px-5 py-24 text-white sm:px-6">
|
||||
<div className="mx-auto grid w-full max-w-7xl gap-12 lg:grid-cols-[0.92fr_1.08fr] lg:items-start">
|
||||
<div>
|
||||
<div className="mb-7 flex h-16 w-16 items-center justify-center rounded-lg bg-emerald-400/12 text-emerald-200 ring-1 ring-emerald-300/20">
|
||||
<ShieldCheck className="h-8 w-8" />
|
||||
</div>
|
||||
<Badge className="mb-5 border-emerald-300/20 bg-emerald-300/10 text-emerald-100 hover:bg-emerald-300/10">
|
||||
Das Vorstands-Argument
|
||||
</Badge>
|
||||
<h2 className="text-balance text-3xl font-semibold leading-tight sm:text-4xl">
|
||||
Datenschutz ist nicht die Fußnote. Er ist die Architektur.
|
||||
</h2>
|
||||
<p className="mt-5 max-w-xl text-base leading-7 text-slate-300">
|
||||
Elternvereine verwalten besonders sensible Daten. Deshalb ist
|
||||
Kita-Planer so gebaut, dass Sichtbarkeit, Löschung und
|
||||
Mandantentrennung nicht vom guten Willen einzelner Chats
|
||||
abhängen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
{privacyPoints.map((point) => {
|
||||
const Icon = point.icon;
|
||||
return (
|
||||
<div
|
||||
key={point.title}
|
||||
className="rounded-lg border border-white/10 bg-white/[0.06] p-5 shadow-sm transition hover:bg-white/[0.09]"
|
||||
>
|
||||
<div className="mb-4 flex h-10 w-10 items-center justify-center rounded-lg bg-white/10 text-emerald-100">
|
||||
<Icon className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className="font-semibold">{point.title}</h3>
|
||||
<p className="mt-2 text-sm leading-6 text-slate-300">
|
||||
{point.text}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="mx-auto w-full max-w-7xl px-5 py-20 sm:px-6">
|
||||
<div className="rounded-lg border border-slate-200 bg-white p-8 shadow-sm sm:p-10">
|
||||
<div className="flex flex-col gap-6 md:flex-row md:items-center md:justify-between">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="text-2xl font-semibold tracking-tight">
|
||||
Bereit für eine Kita-Organisation ohne Nebenkanäle?
|
||||
</h2>
|
||||
<p className="mt-3 text-sm leading-6 text-slate-600">
|
||||
Registriere eure Kita, lade den Vorstand ein und starte mit
|
||||
einem System, das für Elternvereine und Datenschutz gebaut ist.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-3 sm:flex-row">
|
||||
<Button asChild size="lg">
|
||||
<Link href="/register">Kita registrieren</Link>
|
||||
</Button>
|
||||
<Button asChild size="lg" variant="outline">
|
||||
<Link href="/login">Login</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="kontakt" className="px-5 pb-24 sm:px-6">
|
||||
<div className="mx-auto grid w-full max-w-7xl gap-6 rounded-lg border border-slate-200 bg-[#eef6f1] p-5 shadow-sm lg:grid-cols-[0.9fr_1.1fr] lg:p-8">
|
||||
<div className="flex flex-col justify-between rounded-lg bg-slate-950 p-8 text-white">
|
||||
<div>
|
||||
<div className="mb-6 flex h-12 w-12 items-center justify-center rounded-lg bg-emerald-300/12 text-emerald-200 ring-1 ring-emerald-300/20">
|
||||
<MessageSquareText className="h-6 w-6" />
|
||||
</div>
|
||||
<Badge className="mb-5 border-white/15 bg-white/10 text-white hover:bg-white/10">
|
||||
Kontakt & Demo
|
||||
</Badge>
|
||||
<h2 className="text-balance text-3xl font-semibold leading-tight sm:text-4xl">
|
||||
Ihr wollt sehen, ob Kita-Planer zu eurem Verein passt?
|
||||
</h2>
|
||||
<p className="mt-5 text-sm leading-6 text-slate-300">
|
||||
Schreibt uns kurz, wie ihr aktuell organisiert seid. Wir
|
||||
melden uns mit einer passenden Demo, beantworten
|
||||
Datenschutzfragen oder sprechen über ein individuelles Setup.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 grid gap-3 text-sm text-slate-200">
|
||||
{[
|
||||
"Demo für Vorstand und ErzieherInnen",
|
||||
"Einordnung eurer bestehenden Abläufe",
|
||||
"Antworten auf Datenschutz- und Hosting-Fragen",
|
||||
].map((item) => (
|
||||
<div key={item} className="flex items-center gap-2">
|
||||
<CheckCircle2 className="h-4 w-4 shrink-0 text-emerald-300" />
|
||||
<span>{item}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="border-white/70 bg-white shadow-sm">
|
||||
<CardHeader>
|
||||
<div className="mb-2 flex h-10 w-10 items-center justify-center rounded-lg bg-emerald-50 text-emerald-700 ring-1 ring-emerald-100">
|
||||
<Mail className="h-5 w-5" />
|
||||
</div>
|
||||
<CardTitle className="text-2xl tracking-tight">
|
||||
Anfrage senden
|
||||
</CardTitle>
|
||||
<CardDescription className="text-sm leading-6">
|
||||
Seriös, unverbindlich und ohne Sales-Theater. Wir melden uns
|
||||
in der Regel zeitnah mit einem konkreten Vorschlag.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ContactForm />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer className="border-t">
|
||||
<div className="mx-auto flex h-16 w-full max-w-6xl items-center justify-between px-6 text-sm text-muted-foreground">
|
||||
<footer className="border-t border-slate-200 bg-white">
|
||||
<div className="mx-auto flex w-full max-w-7xl flex-col gap-4 px-5 py-8 text-sm text-slate-500 sm:flex-row sm:items-center sm:justify-between sm:px-6">
|
||||
<span>© {new Date().getFullYear()} Kita-Planer</span>
|
||||
<span>Made with ❤️ für Elternvereine</span>
|
||||
<nav className="flex gap-5">
|
||||
<Link href="/impressum" className="hover:text-slate-950">
|
||||
Impressum
|
||||
</Link>
|
||||
<Link href="/datenschutz" className="hover:text-slate-950">
|
||||
Datenschutz
|
||||
</Link>
|
||||
<Link href="#kontakt" className="hover:text-slate-950">
|
||||
Kontakt
|
||||
</Link>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function FeatureCard({
|
||||
icon,
|
||||
title,
|
||||
description,
|
||||
}: {
|
||||
icon: React.ReactNode;
|
||||
title: string;
|
||||
description: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="rounded-lg border bg-card p-6">
|
||||
<div className="mb-4 inline-flex h-10 w-10 items-center justify-center rounded-md bg-secondary text-secondary-foreground">
|
||||
{icon}
|
||||
</div>
|
||||
<h3 className="mb-2 text-lg font-semibold">{title}</h3>
|
||||
<p className="text-sm text-muted-foreground">{description}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user