Files
kolaytercih/src/components/cerez-bilgi.tsx
bilalgursen 9e4c5608eb
All checks were successful
Deploy / deploy (push) Successful in 6m27s
feat(kvkk): çerez politikası, ölçümü kapatma ve ilk ziyaret bilgi bandı
- /cerez-politikasi: çerez aydınlatma metni (ad, amaç, süre, taraf),
  Rybbit ölçümünün kapsamı ve hukuki dayanağı (KVKK md. 5/2-f,
  Çerez Rehberi Temmuz 2025 §5.9)
- OlcumTercihi: Rybbit'i tarayıcıda kapatan düğme (disable-rybbit)
- CerezBilgi: ilk ziyarette bir kez görünen bilgilendirme (onay
  penceresi değil; rıza gerektiren çerez yok)
- gizlilik: analitik bölümü kodla eşitlendi (e-posta/ad gönderilmiyor)
- alt bilgi ve sitemap'e sayfa eklendi
- docs: hukuki analiz ve meşru menfaat denge testi

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 10:11:38 +03:00

81 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
// İlk ziyarette bir kez görünen çerez bilgilendirmesi. Onay penceresi DEĞİL:
// sitede açık rıza gerektiren çerez yok (zorunlu çerezler + kendi
// sunucumuzdaki ölçüm; bkz. /cerez-politikasi). KVKK Çerez Rehberi (Temmuz
// 2025) §9, veri işleme şartından bağımsız olarak siteye girişte
// bilgilendirme bekliyor; bu bant onu karşılar. Kabul/ret düğmesi yoktur,
// çünkü sorulan bir rıza yoktur — ölçümü kapatma anahtarı politika
// sayfasındadır. Kapatma kalıcıdır (localStorage).
import { useEffect, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { Button } from "@/components/ui/button";
import { ViewportPortal } from "@/components/viewport-portal";
import { kromGizliMi } from "@/components/header-gate";
const GORULDU_KEY = "kolaytercih.cerez-bilgi";
export function CerezBilgi() {
const pathname = usePathname();
// SSR/ilk boyada gizli başla; durum mount'ta okunur.
const [goruldu, setGoruldu] = useState(true);
useEffect(() => {
try {
// eslint-disable-next-line react-hooks/set-state-in-effect
setGoruldu(Boolean(localStorage.getItem(GORULDU_KEY)));
} catch {
// Depolama kapalıysa "görüldü" saklanamaz; her sayfada çıkmasın.
setGoruldu(true);
}
}, []);
if (goruldu) return null;
// Giriş/ödeme gibi kromsuz akışlarda ve politikanın kendisinde gösterilmez.
if (pathname && kromGizliMi(pathname)) return null;
if (pathname === "/cerez-politikasi") return null;
function kapat() {
setGoruldu(true);
try {
localStorage.setItem(GORULDU_KEY, "1");
} catch {}
}
return (
<ViewportPortal>
{/* z-45: KaydetBanner'ın (z-40) üstünde, modalların (z-50) altında */}
<div className="pointer-events-none fixed inset-x-0 bottom-4 z-45 px-4 print:hidden">
<section
aria-label="Çerez bilgilendirmesi"
className="pointer-events-auto mx-auto flex max-w-xl flex-wrap items-center gap-3 rounded-2xl border border-slate-200 bg-card p-4 shadow-xl sm:flex-nowrap sm:gap-4"
>
<p className="min-w-0 flex-1 text-sm leading-snug text-slate-700">
Bu sitede reklam ya da izleme çerezi yok. Yalnız oturumun ve listen
için gerekli çerezleri ve kendi sunucumuzda çalışan çerezsiz
ziyaret ölçümünü kullanıyoruz.{" "}
<Link
href="/cerez-politikasi"
onClick={kapat}
className="font-semibold text-primary underline"
>
Ayrıntılar ve ölçümü kapatma
</Link>
</p>
<Button
type="button"
variant="outline"
size="lg"
onClick={kapat}
className="w-full cursor-pointer px-6 transition-[background-color,border-color,color,transform] duration-150 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500 active:scale-[0.97] sm:w-auto"
>
Tamam
</Button>
</section>
</div>
</ViewportPortal>
);
}