All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 1m29s
The project uses a custom i18n provider, not next-intl directly. This was causing a client-side crash on page load. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
import { useI18n } from "@/lib/i18n";
|
|
import { motion, AnimatePresence } from "framer-motion";
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
const STORAGE_KEY = "cookie-consent";
|
|
|
|
export function CookieConsent() {
|
|
const { t } = useI18n();
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setVisible(!localStorage.getItem(STORAGE_KEY));
|
|
}, []);
|
|
|
|
function acceptAll() {
|
|
localStorage.setItem(STORAGE_KEY, "all");
|
|
setVisible(false);
|
|
}
|
|
|
|
function essentialOnly() {
|
|
localStorage.setItem(STORAGE_KEY, "essential");
|
|
setVisible(false);
|
|
}
|
|
|
|
return (
|
|
<AnimatePresence>
|
|
{visible && (
|
|
<motion.div
|
|
initial={{ y: 100, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
exit={{ y: 100, opacity: 0 }}
|
|
transition={{ type: "spring", damping: 25, stiffness: 300 }}
|
|
className="fixed bottom-0 inset-x-0 z-50 p-4"
|
|
>
|
|
<div className="mx-auto max-w-3xl rounded-t-2xl border border-border bg-background/95 backdrop-blur-md shadow-2xl p-6">
|
|
<div className="flex items-start gap-3">
|
|
<span className="text-2xl shrink-0" aria-hidden="true">
|
|
🍪
|
|
</span>
|
|
<div className="flex-1 min-w-0">
|
|
<h3 className="font-semibold text-foreground mb-1">
|
|
{t("cookieConsent.title")}
|
|
</h3>
|
|
<p className="text-sm text-muted-foreground leading-relaxed">
|
|
{t("cookieConsent.description")}
|
|
</p>
|
|
<div className="flex flex-wrap items-center gap-3 mt-4">
|
|
<Button variant="outline" size="sm" onClick={essentialOnly}>
|
|
{t("cookieConsent.essentialOnly")}
|
|
</Button>
|
|
<Button size="sm" onClick={acceptAll}>
|
|
{t("cookieConsent.acceptAll")}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
);
|
|
}
|