92 lines
3.3 KiB
TypeScript
92 lines
3.3 KiB
TypeScript
"use client";
|
|
import React, { useState, useEffect, useRef } from "react";
|
|
import Link from "next/link";
|
|
|
|
export default function CookieConsent() {
|
|
const [visible, setVisible] = useState(false);
|
|
const acceptRef = useRef<HTMLButtonElement>(null);
|
|
|
|
useEffect(() => {
|
|
try {
|
|
const consent = localStorage.getItem("bb_cookie_consent");
|
|
if (!consent) {
|
|
// Delay slightly so it doesn't flash on first paint
|
|
const timer = setTimeout(() => setVisible(true), 1200);
|
|
return () => clearTimeout(timer);
|
|
}
|
|
} catch {
|
|
// localStorage unavailable (SSR or private mode)
|
|
}
|
|
}, []);
|
|
|
|
// Focus the accept button when banner appears (accessibility)
|
|
useEffect(() => {
|
|
if (visible) {
|
|
acceptRef?.current?.focus();
|
|
}
|
|
}, [visible]);
|
|
|
|
const handleAccept = () => {
|
|
try {
|
|
localStorage.setItem("bb_cookie_consent", "accepted");
|
|
} catch {}
|
|
setVisible(false);
|
|
};
|
|
|
|
const handleDecline = () => {
|
|
try {
|
|
localStorage.setItem("bb_cookie_consent", "declined");
|
|
} catch {}
|
|
setVisible(false);
|
|
};
|
|
|
|
if (!visible) return null;
|
|
|
|
return (
|
|
<div
|
|
role="dialog"
|
|
aria-modal="false"
|
|
aria-label="Cookie consent"
|
|
aria-describedby="cookie-consent-desc"
|
|
className="fixed bottom-0 left-0 right-0 z-[9999] bg-[#0d1117] border-t border-[#2a3a50] shadow-2xl"
|
|
>
|
|
<div className="max-w-container mx-auto px-4 py-4 flex flex-col sm:flex-row items-start sm:items-center gap-4 justify-between">
|
|
<div className="flex-1 min-w-0">
|
|
<p
|
|
id="cookie-consent-desc"
|
|
className="text-[#aaa] text-sm font-body leading-relaxed"
|
|
>
|
|
<span className="font-bold text-white">BroadcastBeat</span> uses cookies and similar technologies to improve your experience, analyze site traffic, and serve relevant advertising. By clicking{" "}
|
|
<strong className="text-white">Accept All</strong>, you consent to our use of cookies.{" "}
|
|
<Link
|
|
href="/privacy"
|
|
className="text-[#3b82f6] underline hover:text-blue-400 focus:outline-none focus-visible:ring-1 focus-visible:ring-[#3b82f6] transition-colors"
|
|
>
|
|
Privacy Policy
|
|
</Link>
|
|
</p>
|
|
</div>
|
|
<div className="flex items-center gap-3 flex-shrink-0">
|
|
<button
|
|
type="button"
|
|
onClick={handleDecline}
|
|
className="px-4 py-2 text-sm font-body font-bold text-[#888] border border-[#333] rounded hover:border-[#555] hover:text-[#aaa] transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#3b82f6] focus-visible:ring-offset-1 focus-visible:ring-offset-[#0d1117]"
|
|
aria-label="Decline non-essential cookies"
|
|
>
|
|
Decline
|
|
</button>
|
|
<button
|
|
ref={acceptRef}
|
|
type="button"
|
|
onClick={handleAccept}
|
|
className="px-5 py-2 text-sm font-body font-bold text-white bg-[#3b82f6] rounded hover:bg-blue-500 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#3b82f6] focus-visible:ring-offset-2 focus-visible:ring-offset-[#0d1117]"
|
|
aria-label="Accept all cookies"
|
|
>
|
|
Accept All
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|