128 lines
5.9 KiB
TypeScript
128 lines
5.9 KiB
TypeScript
// 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;
|
||
} |