All checks were successful
Deploy / deploy (push) Successful in 6m27s
- /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>
73 lines
2.6 KiB
TypeScript
73 lines
2.6 KiB
TypeScript
"use client";
|
||
|
||
// Kullanım ölçümünü (Rybbit) bu tarayıcıda kapatan/açan anahtar — KVKK
|
||
// md. 11 itiraz hakkının arayüzü, /cerez-politikasi sayfasında durur.
|
||
//
|
||
// Rybbit betiği yüklenirken localStorage'da `disable-rybbit` anahtarını
|
||
// görürse hiçbir şey göndermez (betiğin kendi vazgeçme kapısı). Betik
|
||
// yüklendikten sonra durdurulamadığı için tercih değişince sayfa yenilenir.
|
||
|
||
import { useEffect, useState } from "react";
|
||
import { Button } from "@/components/ui/button";
|
||
|
||
const KAPALI_KEY = "disable-rybbit";
|
||
// Rybbit'in bu tarayıcıya yazdığı kimlikler; ölçüm kapanınca silinir.
|
||
const RYBBIT_KIMLIK_KEYLERI = ["rybbit-user-id", "rybbit-visitor-id"];
|
||
|
||
export function OlcumTercihi() {
|
||
// null = henüz okunmadı (SSR/ilk boya)
|
||
const [kapali, setKapali] = useState<boolean | null>(null);
|
||
const [hata, setHata] = useState(false);
|
||
|
||
useEffect(() => {
|
||
try {
|
||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||
setKapali(localStorage.getItem(KAPALI_KEY) !== null);
|
||
} catch {
|
||
setKapali(false);
|
||
}
|
||
}, []);
|
||
|
||
function degistir() {
|
||
try {
|
||
if (kapali) {
|
||
localStorage.removeItem(KAPALI_KEY);
|
||
} else {
|
||
localStorage.setItem(KAPALI_KEY, "1");
|
||
for (const k of RYBBIT_KIMLIK_KEYLERI) localStorage.removeItem(k);
|
||
}
|
||
} catch {
|
||
setHata(true);
|
||
return;
|
||
}
|
||
window.location.reload();
|
||
}
|
||
|
||
return (
|
||
<div className="mt-3 flex flex-wrap items-center gap-3 rounded-2xl border border-slate-200 bg-card p-4 sm:flex-nowrap sm:gap-4">
|
||
<div className="min-w-0 flex-1">
|
||
<p className="font-heading text-base font-bold text-slate-900">
|
||
{kapali ? "Ölçüm bu tarayıcıda kapalı" : "Ölçüm bu tarayıcıda açık"}
|
||
</p>
|
||
<p className="text-sm leading-snug text-slate-500" role="status">
|
||
{hata
|
||
? "Tarayıcın bu tercihi saklamaya izin vermiyor."
|
||
: kapali
|
||
? "Ziyaretlerin sayılmıyor. Site aynı şekilde çalışır."
|
||
: "Kapatırsan ziyaretlerin sayılmaz; site aynı şekilde çalışır."}
|
||
</p>
|
||
</div>
|
||
<Button
|
||
type="button"
|
||
variant="outline"
|
||
size="lg"
|
||
disabled={kapali === null}
|
||
onClick={degistir}
|
||
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"
|
||
>
|
||
{kapali ? "Ölçümü aç" : "Ölçümü kapat"}
|
||
</Button>
|
||
</div>
|
||
);
|
||
}
|