Refactor website to use shadcn components

This commit is contained in:
2025-06-28 12:01:43 +00:00
parent 1648e376bf
commit 8c05ad29cb
78 changed files with 3858 additions and 2722 deletions

View File

@@ -0,0 +1,128 @@
// CookieConsentBanner.tsx
'use client';
import {useEffect, useState} from 'react';
export default function CookieConsentBanner() {
const [visible, setVisible] = useState(false);
const [loading, setLoading] = useState(false);
const [stats, setStats] = useState(false);
const [personalization, setPersonalization] = useState(false);
useEffect(() => {
const consent = localStorage.getItem('cookie_consent');
if (!consent) setVisible(true);
const show = () => {
setVisible(true);
};
window.addEventListener('show-cookie-banner', show);
return () => window.removeEventListener('show-cookie-banner', show);
}, []);
const handleAccept = () => {
setLoading(true);
setTimeout(() => {
localStorage.setItem('cookie_consent', 'true');
localStorage.setItem('cookie_stats', stats.toString());
localStorage.setItem('cookie_personalization', personalization.toString());
setVisible(false);
setLoading(false);
}, 1000);
};
const handleAcceptAll = () => {
setLoading(true);
setStats(true);
setPersonalization(true);
setTimeout(() => {
localStorage.setItem('cookie_consent', 'true');
localStorage.setItem('cookie_stats', 'true');
localStorage.setItem('cookie_personalization', 'true');
setVisible(false);
setLoading(false);
}, 1000);
};
const handleDecline = () => {
localStorage.setItem('cookie_consent', 'false');
localStorage.setItem('cookie_stats', 'false');
localStorage.setItem('cookie_personalization', 'false');
setVisible(false);
};
return visible ? (
<div className="fixed inset-0 z-50 bg-black/50 flex items-center justify-center px-4">
<div className="bg-white max-w-2xl w-full rounded-xl shadow-lg overflow-hidden text-sm text-gray-800">
<div className="px-6 py-4 border-b border-gray-200">
<h2 className="text-lg font-semibold">Wir nutzen Cookies und andere Technologien.</h2>
</div>
<div className="px-6 py-4 space-y-4 max-h-[60vh] overflow-y-auto">
<p>
Diese Website nutzt Cookies und vergleichbare Funktionen zur Verarbeitung von
Endgeräteinformationen und personenbezogenen Daten. Die Verarbeitung dient der Einbindung von
Inhalten, externen Diensten und Elementen Dritter, der statistischen Analyse/Messung, der
personalisierten Werbung sowie der Einbindung sozialer Medien.
</p>
<p>
Je nach Funktion werden dabei Daten an Dritte weitergegeben und in Länder außerhalb der EU
übertragen, in denen kein angemessenes Datenschutzniveau besteht z. B. die USA. Ihre
Einwilligung ist freiwillig und kann jederzeit über das Symbol unten links widerrufen werden.
</p>
<div className="space-y-2">
<label className="block">
<input type="checkbox" defaultChecked disabled className="mr-2"/>
Notwendige Cookies (immer aktiv)
</label>
<label className="block">
<input
type="checkbox"
checked={stats}
onChange={(e) => setStats(e.target.checked)}
className="mr-2"
/>
Statistiken (z. B. Besuchertracking)
</label>
<label className="block">
<input
type="checkbox"
checked={personalization}
onChange={(e) => setPersonalization(e.target.checked)}
className="mr-2"
/>
Personalisierung (z. B. eingebettete Medien, Google Maps)
</label>
</div>
</div>
<div className="px-6 py-4 border-t border-gray-200 flex flex-col sm:flex-row sm:justify-end gap-2">
<div className="flex flex-wrap gap-2">
<button
onClick={handleDecline}
className="px-4 py-2 border rounded text-gray-600 hover:bg-gray-100"
>
Ablehnen
</button>
<button
onClick={handleAccept}
className="px-4 py-2 border rounded text-gray-700 hover:bg-gray-100 disabled:opacity-60"
disabled={loading}
>
{loading ? 'Speichere ...' : 'Akzeptieren'}
</button>
<button
onClick={handleAcceptAll}
className="px-4 py-2 bg-red-700 text-white rounded hover:bg-red-800 disabled:opacity-60"
disabled={loading}
>
{loading ? 'Speichere ...' : 'Alles akzeptieren'}
</button>
</div>
</div>
<div className="px-6 py-3 border-t border-gray-100 text-xs text-gray-500 flex justify-start gap-4">
<a href="/legal/imprint" className="hover:underline">Impressum</a>
<a href="/legal/privacy" className="hover:underline">Datenschutzerklärung</a>
</div>
</div>
</div>
) : null;
}