From 0b92f999bcb0886285fb6fc0a946ef4f89b905ba Mon Sep 17 00:00:00 2001
From: bilalgursen
Date: Sun, 2 Aug 2026 19:29:42 +0300
Subject: [PATCH] Integrate Rybbit analytics and enhance user tracking features
- Added Rybbit analytics configuration in .mcp.json for improved data collection.
- Updated layout.tsx to conditionally load the Rybbit analytics script in production.
- Enhanced user interaction tracking in various components, including GirisForm, RevizyonKutusu, and SatinAlForm, by logging specific events.
- Updated privacy policy page to reflect new data handling practices and added a section on service providers and data transfer.
- Improved user navigation and experience by integrating Rybbit's live visitor widget in the site footer.
---
.mcp.json | 4 +
src/app/giris/giris-form.tsx | 3 +
src/app/gizlilik/page.tsx | 32 +++-
src/app/layout.tsx | 19 +-
src/app/listem/revizyon-kutusu.tsx | 2 +
src/app/listem/sohbet-client.tsx | 5 +
src/app/paket/satin-al-form.tsx | 6 +-
src/app/sonuc/sihirbaz-cagri-karti.tsx | 3 +
src/components/cta-sira-form.tsx | 6 +
src/components/hero-form.tsx | 6 +
src/components/katalog-arama.tsx | 24 ++-
.../manuel-liste/program-ekle-butonu.tsx | 3 +
.../manuel-liste/tercih-profili-kapisi.tsx | 6 +
src/components/rybbit-identify.tsx | 35 ++++
src/components/sihirbaz-adimlar.tsx | 15 +-
src/components/site-footer.tsx | 11 ++
src/components/user-nav.tsx | 3 +
src/lib/analitik-sunucu.ts | 53 ++++++
src/lib/analitik.ts | 91 ++++++++++
src/lib/auth.ts | 9 +-
src/lib/eposta.ts | 166 ++++++++++++++++++
src/lib/odeme.ts | 13 ++
22 files changed, 499 insertions(+), 16 deletions(-)
create mode 100644 src/components/rybbit-identify.tsx
create mode 100644 src/lib/analitik-sunucu.ts
create mode 100644 src/lib/analitik.ts
create mode 100644 src/lib/eposta.ts
diff --git a/.mcp.json b/.mcp.json
index bd98b4f..644d639 100644
--- a/.mcp.json
+++ b/.mcp.json
@@ -1,5 +1,9 @@
{
"mcpServers": {
+ "rybbit": {
+ "type": "http",
+ "url": "https://rybbit.kolaytercih.com/api/mcp"
+ },
"shadcn": {
"command": "npx",
"args": [
diff --git a/src/app/giris/giris-form.tsx b/src/app/giris/giris-form.tsx
index 5714105..46d0a3e 100644
--- a/src/app/giris/giris-form.tsx
+++ b/src/app/giris/giris-form.tsx
@@ -4,6 +4,7 @@ import { useState } from "react";
import { Mail } from "lucide-react";
import { toast } from "sonner";
import { authClient } from "@/lib/auth-client";
+import { olay } from "@/lib/analitik";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@@ -52,6 +53,7 @@ export function GirisForm({ callbackURL }: { callbackURL: string }) {
async function googleIleGiris() {
setBusy("google");
+ olay("giris_denendi", { yontem: "google" });
const { error } = await authClient.signIn.social({
provider: "google",
callbackURL,
@@ -80,6 +82,7 @@ export function GirisForm({ callbackURL }: { callbackURL: string }) {
}
setSent(true);
geriSayimBaslat();
+ olay("giris_denendi", { yontem: "eposta" });
}
if (sent) {
diff --git a/src/app/gizlilik/page.tsx b/src/app/gizlilik/page.tsx
index d67d183..54ce7b7 100644
--- a/src/app/gizlilik/page.tsx
+++ b/src/app/gizlilik/page.tsx
@@ -21,7 +21,7 @@ export default function GizlilikPage() {
Gizlilik ve Kişisel Verilerin Korunması
- Son güncelleme: 26 Temmuz 2026
+ Son güncelleme: 2 Ağustos 2026
@@ -56,6 +56,25 @@ export default function GizlilikPage() {
Verilerini üçüncü taraflara satmayız, reklam amacıyla paylaşmayız.
+
+
+ Hizmet sağlayıcılar ve yurt dışına aktarım
+
+
+ Hizmeti çalıştırabilmek için birkaç dış sağlayıcıdan yararlanıyoruz
+ ve verinin bir kısmı yalnızca ilgili iş için bu sağlayıcılara
+ iletilir. Giriş bağlantısı ve bilgilendirme e-postaları Resend
+ üzerinden gönderilir; e-posta adresin bu amaçla Avrupa
+ Birliği’ndeki (İrlanda) sunucularda işlenir. Ödemeler,
+ Türkiye’de yerleşik iyzico altyapısında gerçekleşir. Danışman
+ sohbetine yazdığın mesajlar, yanıt üretilebilmesi için
+ Anthropic’in yapay zekâ servisine (ABD) iletilir; bu mesajlar
+ sağlayıcının yapay zekâ modellerini eğitmek için kullanılmaz.
+ KVKK açısından bunlardan e-posta ve yapay zekâ sağlayıcısına yapılan
+ iletim yurt dışına aktarım sayılır ve hizmetin sunulabilmesi için
+ zorunludur.
+
+
Saklama ve silme
@@ -71,11 +90,18 @@ export default function GizlilikPage() {
- Çerezler
+ Çerezler ve analitik
Yalnızca oturumunu açık tutmak için zorunlu çerezler kullanılır;
- reklam veya izleme çerezi kullanılmaz.
+ reklam veya izleme çerezi kullanılmaz. Siteyi geliştirebilmek için
+ hangi sayfaların görüntülendiğini ve hangi adımların tamamlandığını
+ ölçen, çerez kullanmayan bir analitik aracı (Rybbit) çalıştırıyoruz;
+ bu araç kendi sunucumuzda barındırılır, veriler üçüncü taraf bir
+ reklam ağına gitmez. Giriş yaptığında ziyaretin hesabınla
+ eşleştirilir. Başarı sıralaman analitiğe ham hâliyle
+ gönderilmez; yalnızca “50-100 bin” gibi geniş bir
+ aralık olarak kaydedilir.
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 4fefebe..97bb549 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -84,12 +84,19 @@ export default function RootLayout({
// içerikle büyümeli, viewport tabanı body'deki min-h-dvh'den gelir.
className={`${calSans.variable} ${clarityCity.variable} ${geistMono.variable} ${bricolage.variable} antialiased`}
>
- {/* Rybbit analytics — beforeInteractive her zaman içine defer olarak enjekte edilir */}
-
+ {/* Rybbit analitik — beforeInteractive her zaman içine defer olarak
+ enjekte edilir. Yalnızca prod build'de: Rybbit localhost'u da takip
+ ettiği için dev trafiği prod verisini kirletmesin (DevPanel ile aynı
+ kapı). mask-patterns: /sonuc URL'i ham başarı sıralamasını,
+ /odeme/sonuc sipariş kimliğini taşıyor — path tek satırda toplanır. */}
+ {process.env.NODE_ENV === "production" ? (
+
+ ) : null}
{/* Site geneli progressive blur — üst ve alt */}
diff --git a/src/app/listem/revizyon-kutusu.tsx b/src/app/listem/revizyon-kutusu.tsx
index f46ea23..2d50e80 100644
--- a/src/app/listem/revizyon-kutusu.tsx
+++ b/src/app/listem/revizyon-kutusu.tsx
@@ -10,6 +10,7 @@ import { RefreshCcw } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { listeRevize } from "@/app/sonuc/actions";
+import { olay } from "@/lib/analitik";
export function RevizyonKutusu({ kalanHak }: { kalanHak: number }) {
const [feedback, setFeedback] = useState("");
@@ -38,6 +39,7 @@ export function RevizyonKutusu({ kalanHak }: { kalanHak: number }) {
requestId: crypto.randomUUID(),
});
if (sonuc.ok) {
+ olay("liste_revize", { sayfa: "listem" });
toast.success("Listen yeniden kuruldu.");
setFeedback("");
router.refresh();
diff --git a/src/app/listem/sohbet-client.tsx b/src/app/listem/sohbet-client.tsx
index 476d1a2..db50151 100644
--- a/src/app/listem/sohbet-client.tsx
+++ b/src/app/listem/sohbet-client.tsx
@@ -22,6 +22,7 @@ import { PromptSuggestion } from "@/components/ui/prompt-suggestion";
import { ScrollButton } from "@/components/ui/scroll-button";
import { DotsLoader } from "@/components/ui/loader";
import { Skeleton } from "@/components/ui/skeleton";
+import { olay } from "@/lib/analitik";
export interface Mesaj {
id: string;
@@ -119,6 +120,10 @@ export function SohbetClient({
}
setKredi((k) => k - 1);
+ // Bu bileşen /sonuc'taki popup'tan da kullanılıyor (sohbet-popup.tsx)
+ olay("danisman_sorusu", {
+ sayfa: location.pathname.startsWith("/listem") ? "listem" : "sonuc",
+ });
const reader = res.body!.getReader();
const decoder = new TextDecoder();
let birikmis = "";
diff --git a/src/app/paket/satin-al-form.tsx b/src/app/paket/satin-al-form.tsx
index 59820b7..d6fe33c 100644
--- a/src/app/paket/satin-al-form.tsx
+++ b/src/app/paket/satin-al-form.tsx
@@ -4,6 +4,7 @@ import { useActionState, useEffect } from "react";
import { ArrowRight } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
+import { olay } from "@/lib/analitik";
import { baslatOdeme, type OdemeBaslatDurum } from "./actions";
export function SatinAlForm({
@@ -25,7 +26,10 @@ export function SatinAlForm({
}, [state]);
return (
-