Auth fertig erstellt. Aktuell läuft review durch KI
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import { Check, Sparkles } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button.tsx";
|
||||
import { BookingDialog } from "@/components/booking-dialog.tsx";
|
||||
|
||||
type PricingPlan = {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
price: number;
|
||||
features: string[];
|
||||
priceNote: string;
|
||||
highlighted?: boolean;
|
||||
};
|
||||
|
||||
const offerlist: PricingPlan[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Das Kompakt-Paket",
|
||||
description:
|
||||
"Perfekt für die schnelle, moderne Präsentation. Ideal für Therapeuten, Berater und regionale Handwerker.",
|
||||
price: 900,
|
||||
features: [
|
||||
"Alle wichtigen Infos auf einer Seite",
|
||||
"Kontaktformular & Anfahrt",
|
||||
"Für Smartphone optimiert",
|
||||
"SSL-Verschlüsselung inklusive",
|
||||
"SEO-Grundlagen (Meta-Tags, schnelle Ladezeit)",
|
||||
],
|
||||
priceNote: "Aufpreise z. B. für mehrsprachige Seiten oder Terminbuchung.",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Das Klassik-Paket",
|
||||
description:
|
||||
"Für Praxen und Betriebe mit breitem Angebot. Maximale Übersicht für Ihre Besucher.",
|
||||
price: 1700,
|
||||
features: [
|
||||
"Separate Leistungs- und Teamseiten",
|
||||
"Bildergalerie & Referenzen",
|
||||
"Erweiterte SEO-Optimierung",
|
||||
"Rechtstexte-Assistenz",
|
||||
"3 Monate kostenloser Support",
|
||||
],
|
||||
priceNote: "Aufpreise z. B. für zusätzliche Sprachen oder Shop-Anbindung.",
|
||||
highlighted: true,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Ihre neue Webapp",
|
||||
description:
|
||||
"Für digitale Lösungen mit echtem Mehrwert. Ideal für Unternehmen, die mehr als eine Website brauchen.",
|
||||
price: 2500,
|
||||
features: [
|
||||
"Login- und Nutzerbereich",
|
||||
"Individuelle Funktionen",
|
||||
"Terminbuchung oder Kundenportal",
|
||||
"SEO-Grundlagen (Meta-Tags, schnelle Ladezeit)",
|
||||
"Skalierbare Infrastruktur",
|
||||
],
|
||||
priceNote: "Endpreis abhängig vom Funktionsumfang - Details im Erstgespräch.",
|
||||
},
|
||||
];
|
||||
|
||||
const priceFormatter = new Intl.NumberFormat("de-DE");
|
||||
|
||||
export const Pricing = () => {
|
||||
return (
|
||||
<section id="pricing" className="mx-auto max-w-6xl px-4 py-16 md:px-6 md:py-24">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<span className="island-kicker">Preise</span>
|
||||
<h2 className="mt-3 font-heading text-3xl font-bold leading-tight tracking-tight text-(--sea-ink) sm:text-4xl">
|
||||
Feste Preise. Keine Überraschungen.
|
||||
</h2>
|
||||
<p className="mt-4 text-(--sea-ink-soft) sm:text-lg">
|
||||
Wählen Sie das Paket, das zu Ihrem Betrieb passt. Nach dem Erstgespräch
|
||||
bekommen Sie einen festen Preis - schriftlich, ohne Überraschungen.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-12 grid gap-6 lg:grid-cols-3 lg:items-stretch">
|
||||
{offerlist.map((offer) => {
|
||||
const isHighlighted = offer.highlighted;
|
||||
return (
|
||||
<article
|
||||
key={offer.id}
|
||||
className={[
|
||||
"relative flex flex-col gap-5 rounded-3xl border p-6 sm:p-7",
|
||||
isHighlighted
|
||||
? "border-(--lagoon-deep) bg-(--surface-strong) shadow-[0_20px_50px_rgba(30,90,72,0.18)] lg:-translate-y-2"
|
||||
: "feature-card border-(--line)",
|
||||
].join(" ")}
|
||||
>
|
||||
{isHighlighted && (
|
||||
<span className="absolute -top-3 left-1/2 inline-flex -translate-x-1/2 items-center gap-1 rounded-full bg-(--lagoon-deep) px-3 py-1 text-xs font-semibold text-white shadow">
|
||||
<Sparkles className="h-3.5 w-3.5" aria-hidden />
|
||||
Empfehlung
|
||||
</span>
|
||||
)}
|
||||
|
||||
<header className="space-y-2">
|
||||
<h3 className="font-heading text-xl font-bold text-(--sea-ink)">
|
||||
{offer.name}
|
||||
</h3>
|
||||
<p className="text-sm text-(--sea-ink-soft)">{offer.description}</p>
|
||||
</header>
|
||||
|
||||
<div className="flex items-baseline gap-1">
|
||||
<span className="text-sm text-(--sea-ink-soft)">ab</span>
|
||||
<span className="font-heading text-4xl font-bold text-(--sea-ink)">
|
||||
{priceFormatter.format(offer.price)} €
|
||||
</span>
|
||||
</div>
|
||||
<div className="-mt-3 space-y-1 text-xs text-(--sea-ink-soft)">
|
||||
<p>zzgl. gesetzl. Umsatzsteuer</p>
|
||||
<p>{offer.priceNote}</p>
|
||||
</div>
|
||||
|
||||
<ul className="space-y-2.5 text-sm text-(--sea-ink)">
|
||||
{offer.features.map((feature) => (
|
||||
<li key={feature} className="flex items-start gap-2">
|
||||
<Check
|
||||
className="mt-0.5 h-4 w-4 shrink-0 text-(--lagoon-deep)"
|
||||
aria-hidden
|
||||
/>
|
||||
<span>{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="mt-auto pt-2">
|
||||
<BookingDialog>
|
||||
<Button
|
||||
variant={isHighlighted ? "default" : "outline"}
|
||||
className="w-full"
|
||||
>
|
||||
Erstgespräch buchen
|
||||
</Button>
|
||||
</BookingDialog>
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user