feat: Eigene Danke-Seite nach erfolgreicher Buchung

- Neue /danke Route mit ansprechendem Design
- Animierter Checkmark mit Pulse-Effekt
- Nächste Schritte Cards (E-Mail, Terminabstimmung, Kontakt)
- Trust-Elemente mit Vereinsinfos
- Payment Links leiten jetzt auf /danke um

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-12-04 14:57:26 +01:00
parent 062de06b2c
commit cb5ac108e7
5 changed files with 212 additions and 38 deletions

60
package-lock.json generated
View File

@@ -11,7 +11,8 @@
"@supabase/supabase-js": "^2.57.4", "@supabase/supabase-js": "^2.57.4",
"lucide-react": "^0.344.0", "lucide-react": "^0.344.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1" "react-dom": "^18.3.1",
"react-router-dom": "^7.10.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.9.1", "@eslint/js": "^9.9.1",
@@ -1944,6 +1945,19 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true "dev": true
}, },
"node_modules/cookie": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
"integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -3369,6 +3383,44 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-router": {
"version": "7.10.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.10.0.tgz",
"integrity": "sha512-FVyCOH4IZ0eDDRycODfUqoN8ZSR2LbTvtx6RPsBgzvJ8xAXlMZNCrOFpu+jb8QbtZnpAd/cEki2pwE848pNGxw==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/react-router-dom": {
"version": "7.10.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.10.0.tgz",
"integrity": "sha512-Q4haR150pN/5N75O30iIsRJcr3ef7p7opFaKpcaREy0GQit6uCRu1NEiIFIwnHJQy0bsziRFBweR/5EkmHgVUQ==",
"license": "MIT",
"dependencies": {
"react-router": "7.10.0"
},
"engines": {
"node": ">=20.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
}
},
"node_modules/read-cache": { "node_modules/read-cache": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -3501,6 +3553,12 @@
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
}, },
"node_modules/set-cookie-parser": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
"license": "MIT"
},
"node_modules/shebang-command": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",

View File

@@ -14,7 +14,8 @@
"@supabase/supabase-js": "^2.57.4", "@supabase/supabase-js": "^2.57.4",
"lucide-react": "^0.344.0", "lucide-react": "^0.344.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1" "react-dom": "^18.3.1",
"react-router-dom": "^7.10.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.9.1", "@eslint/js": "^9.9.1",

View File

@@ -29,17 +29,6 @@ function useScrollAnimation() {
function App() { function App() {
const [activeTestimonial, setActiveTestimonial] = useState(0); const [activeTestimonial, setActiveTestimonial] = useState(0);
const [openFaq, setOpenFaq] = useState<number | null>(null); const [openFaq, setOpenFaq] = useState<number | null>(null);
const [showSuccess, setShowSuccess] = useState(false);
// Check for successful payment redirect
useEffect(() => {
const params = new URLSearchParams(window.location.search);
if (params.get('success') === 'true') {
setShowSuccess(true);
// Remove query param from URL
window.history.replaceState({}, '', window.location.pathname);
}
}, []);
// Scroll animation refs // Scroll animation refs
const problemSection = useScrollAnimation(); const problemSection = useScrollAnimation();
@@ -79,27 +68,6 @@ function App() {
return ( return (
<div className="min-h-screen scroll-smooth"> <div className="min-h-screen scroll-smooth">
{/* SUCCESS MODAL */}
{showSuccess && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<div className="bg-white rounded-lg shadow-2xl p-8 max-w-md mx-4 text-center">
<div className="w-16 h-16 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-4">
<Check className="w-8 h-8 text-white" />
</div>
<h2 className="text-2xl font-bold text-gray-900 mb-2">Buchung erfolgreich!</h2>
<p className="text-gray-600 mb-6">
Vielen Dank für Ihre Buchung. Sie erhalten in Kürze eine Bestätigungs-E-Mail mit allen Details zu Ihrer SunHouse-Führung.
</p>
<button
onClick={() => setShowSuccess(false)}
className="bg-green-500 hover:bg-green-600 text-white font-bold px-6 py-3 rounded-lg transition-colors duration-300"
>
Verstanden
</button>
</div>
</div>
)}
{/* SECTION 1: HERO */} {/* SECTION 1: HERO */}
<section className="relative min-h-screen flex items-center justify-center bg-gray-900"> <section className="relative min-h-screen flex items-center justify-center bg-gray-900">
<div <div
@@ -471,7 +439,7 @@ function App() {
</ul> </ul>
<a <a
href="https://buy.stripe.com/test_fZu28q3Mk4Pcdjcbq8ebu03" href="https://buy.stripe.com/test_00w14m96EchE7YS51Kebu06"
className="block w-full text-center border-2 border-green-500 text-green-500 font-bold px-6 py-3 rounded-lg hover:bg-green-50 transition-colors duration-300" className="block w-full text-center border-2 border-green-500 text-green-500 font-bold px-6 py-3 rounded-lg hover:bg-green-50 transition-colors duration-300"
> >
Jetzt Buchen Jetzt Buchen
@@ -523,7 +491,7 @@ function App() {
</ul> </ul>
<a <a
href="https://buy.stripe.com/test_9B628qfv25Tga70gKsebu04" href="https://buy.stripe.com/test_4gMeVceqYa9w7YSfGoebu07"
className="block w-full text-center bg-green-500 text-white font-bold px-6 py-3 rounded-lg hover:bg-green-600 transition-colors duration-300" className="block w-full text-center bg-green-500 text-white font-bold px-6 py-3 rounded-lg hover:bg-green-600 transition-colors duration-300"
> >
Gruppe Buchen Gruppe Buchen
@@ -570,7 +538,7 @@ function App() {
</ul> </ul>
<a <a
href="https://buy.stripe.com/test_bJe7sKfv2bdA4MGdygebu05" href="https://buy.stripe.com/test_28EfZg0A85Tgfrkcucebu08"
className="block w-full text-center border-2 border-green-500 text-green-500 font-bold px-6 py-3 rounded-lg hover:bg-green-50 transition-colors duration-300" className="block w-full text-center border-2 border-green-500 text-green-500 font-bold px-6 py-3 rounded-lg hover:bg-green-50 transition-colors duration-300"
> >
Premium Buchen Premium Buchen

View File

@@ -1,10 +1,17 @@
import { StrictMode } from 'react'; import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import App from './App.tsx'; import App from './App.tsx';
import ThankYou from './pages/ThankYou.tsx';
import './index.css'; import './index.css';
createRoot(document.getElementById('root')!).render( createRoot(document.getElementById('root')!).render(
<StrictMode> <StrictMode>
<App /> <BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="/danke" element={<ThankYou />} />
</Routes>
</BrowserRouter>
</StrictMode> </StrictMode>
); );

140
src/pages/ThankYou.tsx Normal file
View File

@@ -0,0 +1,140 @@
import { useEffect, useState } from 'react';
import { Check, Mail, Calendar, Phone, ArrowRight, Home } from 'lucide-react';
export default function ThankYou() {
const [isVisible, setIsVisible] = useState(false);
const [checkmarkVisible, setCheckmarkVisible] = useState(false);
useEffect(() => {
// Trigger animations
setTimeout(() => setCheckmarkVisible(true), 100);
setTimeout(() => setIsVisible(true), 400);
}, []);
return (
<div className="min-h-screen bg-gradient-to-br from-green-50 via-white to-green-50">
{/* Decorative background elements */}
<div className="absolute inset-0 overflow-hidden pointer-events-none">
<div className="absolute -top-40 -right-40 w-80 h-80 bg-green-200 rounded-full opacity-20 blur-3xl"></div>
<div className="absolute -bottom-40 -left-40 w-80 h-80 bg-green-300 rounded-full opacity-20 blur-3xl"></div>
</div>
{/* Logo */}
<div className="absolute top-6 left-6 z-20">
<a href="/">
<img
src="/Sunhouse-energy-logo-02.png"
alt="SunHouse Energy Logo"
className="h-12 md:h-16 w-auto"
/>
</a>
</div>
<div className="relative z-10 min-h-screen flex items-center justify-center px-4 py-20">
<div className="max-w-2xl w-full">
{/* Success checkmark animation */}
<div className={`flex justify-center mb-8 transition-all duration-700 ${checkmarkVisible ? 'opacity-100 scale-100' : 'opacity-0 scale-50'}`}>
<div className="relative">
<div className="w-24 h-24 md:w-32 md:h-32 bg-green-500 rounded-full flex items-center justify-center shadow-lg shadow-green-500/30">
<Check className="w-12 h-12 md:w-16 md:h-16 text-white stroke-[3]" />
</div>
{/* Pulse animation */}
<div className="absolute inset-0 w-24 h-24 md:w-32 md:h-32 bg-green-500 rounded-full animate-ping opacity-20"></div>
</div>
</div>
{/* Main content */}
<div className={`transition-all duration-700 delay-200 ${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'}`}>
<h1 className="text-3xl md:text-5xl font-bold text-gray-900 text-center mb-4">
Vielen Dank für Ihre Buchung!
</h1>
<p className="text-lg md:text-xl text-gray-600 text-center mb-12 max-w-xl mx-auto">
Wir freuen uns, Sie bald im SunHouse Musterhaus begrüßen zu dürfen.
</p>
{/* Next steps cards */}
<div className="space-y-4 mb-12">
<div className="bg-white rounded-xl shadow-md p-6 flex items-start gap-4 hover:shadow-lg transition-shadow duration-300">
<div className="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center flex-shrink-0">
<Mail className="w-6 h-6 text-green-600" />
</div>
<div>
<h3 className="font-bold text-gray-900 mb-1">Bestätigung per E-Mail</h3>
<p className="text-gray-600">
Sie erhalten in wenigen Minuten eine Bestätigungs-E-Mail mit Ihrer Buchungsübersicht und Rechnung.
</p>
</div>
</div>
<div className="bg-white rounded-xl shadow-md p-6 flex items-start gap-4 hover:shadow-lg transition-shadow duration-300">
<div className="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center flex-shrink-0">
<Calendar className="w-6 h-6 text-green-600" />
</div>
<div>
<h3 className="font-bold text-gray-900 mb-1">Terminabstimmung</h3>
<p className="text-gray-600">
Wir kontaktieren Sie innerhalb von 24 Stunden, um einen passenden Termin für Ihre Führung zu vereinbaren.
</p>
</div>
</div>
<div className="bg-white rounded-xl shadow-md p-6 flex items-start gap-4 hover:shadow-lg transition-shadow duration-300">
<div className="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center flex-shrink-0">
<Phone className="w-6 h-6 text-green-600" />
</div>
<div>
<h3 className="font-bold text-gray-900 mb-1">Fragen?</h3>
<p className="text-gray-600">
Bei Fragen erreichen Sie uns jederzeit unter{' '}
<a href="mailto:info@sunhouse.energy" className="text-green-600 hover:underline font-medium">
info@sunhouse.energy
</a>
</p>
</div>
</div>
</div>
{/* CTA buttons */}
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="/"
className="inline-flex items-center justify-center gap-2 bg-green-500 hover:bg-green-600 text-white font-bold px-8 py-4 rounded-lg shadow-lg hover:shadow-xl transition-all duration-300"
>
<Home className="w-5 h-5" />
Zur Startseite
</a>
<a
href="https://linkedin.com/in/manfred-josef-hampel"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center gap-2 border-2 border-gray-300 hover:border-green-500 text-gray-700 hover:text-green-600 font-bold px-8 py-4 rounded-lg transition-all duration-300"
>
Manfred auf LinkedIn
<ArrowRight className="w-5 h-5" />
</a>
</div>
</div>
{/* Trust elements */}
<div className={`mt-16 pt-8 border-t border-gray-200 transition-all duration-700 delay-500 ${isVisible ? 'opacity-100' : 'opacity-0'}`}>
<p className="text-center text-gray-500 text-sm mb-4">
Ihre Buchung wird durchgeführt von
</p>
<div className="flex flex-col md:flex-row items-center justify-center gap-4 text-center">
<div>
<p className="font-bold text-gray-900">Institut für Nachhaltigkeit</p>
<p className="text-gray-500 text-sm">Karres 56, 6462 Karres, Österreich</p>
</div>
<div className="hidden md:block w-px h-8 bg-gray-300"></div>
<div>
<p className="text-gray-500 text-sm">ZVR-Zahl: 1767456655</p>
<p className="text-gray-500 text-sm">Gemeinnütziger Verein</p>
</div>
</div>
</div>
</div>
</div>
</div>
);
}