345 lines
15 KiB
TypeScript
345 lines
15 KiB
TypeScript
"use client";
|
||
|
||
import { motion, useScroll, useSpring } from "framer-motion";
|
||
import Link from "next/link";
|
||
import Header from "@/components/Header";
|
||
import Footer from "@/components/Footer";
|
||
import type { Locale } from "@/i18n-config";
|
||
import type { PrivacyApp } from "@/data/privacy";
|
||
|
||
const easeOutExpo = [0.16, 1, 0.3, 1] as [number, number, number, number];
|
||
|
||
export default function PrivacyDetailClient({
|
||
lang,
|
||
dict,
|
||
app,
|
||
otherApps,
|
||
}: {
|
||
lang: Locale;
|
||
dict: any;
|
||
app: PrivacyApp;
|
||
otherApps: PrivacyApp[];
|
||
}) {
|
||
const { scrollYProgress } = useScroll();
|
||
const scaleX = useSpring(scrollYProgress, {
|
||
stiffness: 100,
|
||
damping: 30,
|
||
restDelta: 0.001,
|
||
});
|
||
|
||
const isTr = lang === "tr";
|
||
|
||
return (
|
||
<div className="bg-[#F4F0E8] text-[#0A0A0A] font-body min-h-screen">
|
||
{/* Scroll indicator */}
|
||
<motion.div
|
||
className="fixed top-0 left-0 right-0 h-1.5 bg-[#FFE600] z-50 origin-[0%]"
|
||
style={{ scaleX }}
|
||
/>
|
||
|
||
<Header lang={lang} dict={dict.nav} />
|
||
|
||
<main className="pt-32 pb-24 px-6 max-w-6xl mx-auto">
|
||
{/* Back Link */}
|
||
<motion.div
|
||
className="mb-8"
|
||
initial={{ opacity: 0 }}
|
||
animate={{ opacity: 1 }}
|
||
>
|
||
<Link
|
||
href={`/${lang}/privacy`}
|
||
className="inline-flex items-center gap-2 font-mono text-[10px] tracking-[0.25em] uppercase text-[#A0998E] hover:text-[#0A0A0A] transition-colors"
|
||
>
|
||
<svg
|
||
width="14"
|
||
height="14"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
strokeWidth="2.5"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
>
|
||
<line x1="19" y1="12" x2="5" y2="12" />
|
||
<polyline points="12 19 5 12 12 5" />
|
||
</svg>
|
||
{isTr ? "TÜM GİZLİLİK POLİTİKALARI" : "ALL PRIVACY POLICIES"}
|
||
</Link>
|
||
</motion.div>
|
||
|
||
{/* Hero Header */}
|
||
<div className="border border-[#C8C2B8] bg-[#EDE8E0] p-8 sm:p-12 mb-12">
|
||
<div className="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-6">
|
||
<div className="flex items-center gap-4">
|
||
<div className="w-16 h-16 bg-[#FFE600] border-2 border-[#0A0A0A] flex items-center justify-center text-3xl flex-shrink-0">
|
||
{app.icon}
|
||
</div>
|
||
<div>
|
||
<div className="flex items-center gap-2 mb-1">
|
||
<span className="font-mono text-[9px] tracking-[0.2em] uppercase px-2 py-0.5 border border-[#C8C2B8] bg-[#F4F0E8] text-[#6A6460]">
|
||
{app.category[lang]}
|
||
</span>
|
||
<span className="font-mono text-[9px] text-[#A0998E]">
|
||
{app.version}
|
||
</span>
|
||
</div>
|
||
<h1 className="font-display font-black text-3xl sm:text-5xl uppercase text-[#0A0A0A] tracking-tight">
|
||
{app.name}
|
||
</h1>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex flex-col md:items-end gap-2">
|
||
<div className="flex gap-1.5">
|
||
{app.platforms.map((p) => (
|
||
<span
|
||
key={p}
|
||
className="font-mono text-[9px] uppercase px-2.5 py-1 bg-[#0A0A0A] text-[#F4F0E8] font-bold"
|
||
>
|
||
{p}
|
||
</span>
|
||
))}
|
||
</div>
|
||
<div className="font-mono text-[10px] text-[#A0998E]">
|
||
{isTr ? "Yürürlük / Güncelleme:" : "Effective / Last Updated:"} {app.lastUpdated[lang]}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<p className="text-[#6A6460] text-base leading-relaxed max-w-4xl border-t border-[#C8C2B8] pt-6">
|
||
{app.summary[lang]}
|
||
</p>
|
||
|
||
{/* Key Highlights */}
|
||
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mt-6 pt-6 border-t border-[#C8C2B8]">
|
||
{app.highlights[lang].map((h, i) => (
|
||
<div key={i} className="bg-[#F4F0E8] p-3 border border-[#E0DACF]">
|
||
<div className="font-mono text-[8px] uppercase tracking-wider text-[#A0998E] mb-1">
|
||
{h.label}
|
||
</div>
|
||
<div className="font-display font-bold text-xs text-[#0A0A0A]">
|
||
{h.value}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Content Layout: Sticky Sidebar + Main Sections */}
|
||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12">
|
||
{/* Sidebar Navigation */}
|
||
<aside className="lg:col-span-4">
|
||
<div className="sticky top-24 border border-[#C8C2B8] bg-[#EDE8E0] p-6 space-y-6">
|
||
<div>
|
||
<div className="font-mono text-[9px] tracking-[0.25em] uppercase text-[#A0998E] mb-4">
|
||
{isTr ? "İÇİNDEKİLER" : "TABLE OF CONTENTS"}
|
||
</div>
|
||
<nav className="space-y-2">
|
||
{app.permissions.length > 0 && (
|
||
<a
|
||
href="#permissions"
|
||
className="block font-mono text-[11px] text-[#6A6460] hover:text-[#0A0A0A] hover:translate-x-1 transition-all py-1 border-b border-[#E0DACF]"
|
||
>
|
||
{isTr ? "→ Donanım & Sistem İzinleri" : "→ Hardware & Permissions"}
|
||
</a>
|
||
)}
|
||
{app.sections.map((sec) => (
|
||
<a
|
||
key={sec.id}
|
||
href={`#${sec.id}`}
|
||
className="block font-mono text-[11px] text-[#6A6460] hover:text-[#0A0A0A] hover:translate-x-1 transition-all py-1 border-b border-[#E0DACF]"
|
||
>
|
||
→ {sec.title[lang]}
|
||
</a>
|
||
))}
|
||
<a
|
||
href="#data-deletion"
|
||
className="block font-mono text-[11px] text-[#FF4500] font-bold hover:translate-x-1 transition-all py-1"
|
||
>
|
||
→ {isTr ? "Veri Silme & Destek" : "Data Erasure & Contact"}
|
||
</a>
|
||
</nav>
|
||
</div>
|
||
|
||
<div className="pt-4 border-t border-[#C8C2B8]">
|
||
<div className="font-mono text-[9px] uppercase tracking-wider text-[#A0998E] mb-2">
|
||
{isTr ? "Gizlilik İletişim Hattı:" : "Privacy Contact Desk:"}
|
||
</div>
|
||
<a
|
||
href={`mailto:${app.contactEmail}`}
|
||
className="font-mono text-xs text-[#0A0A0A] font-bold hover:underline"
|
||
>
|
||
{app.contactEmail}
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
{/* Main Legal Content */}
|
||
<div className="lg:col-span-8 space-y-12">
|
||
{/* System Permissions (if applicable) */}
|
||
{app.permissions.length > 0 && (
|
||
<section id="permissions" className="border border-[#C8C2B8] bg-[#EDE8E0] p-8">
|
||
<div className="flex items-center gap-3 mb-6">
|
||
<span className="w-2.5 h-2.5 bg-[#FFE600]" />
|
||
<h2 className="font-display font-black text-xl uppercase text-[#0A0A0A]">
|
||
{isTr ? "Cihaz İzinleri ve Donanım Erişimi" : "Device Permissions & Hardware Access"}
|
||
</h2>
|
||
</div>
|
||
|
||
<p className="text-[#6A6460] text-sm leading-relaxed mb-6">
|
||
{isTr
|
||
? `${app.name} uygulaması, yalnızca temel işlevlerini kusursuz yerine getirebilmek için işletim sisteminizden (iOS / Android) aşağıdaki açık izinleri talep eder:`
|
||
: `${app.name} requests explicit permissions from your operating system (iOS / Android) solely to perform core functionality:`}
|
||
</p>
|
||
|
||
<div className="space-y-4">
|
||
{app.permissions.map((perm, idx) => (
|
||
<div
|
||
key={idx}
|
||
className="bg-[#F4F0E8] p-4 border border-[#C8C2B8] flex flex-col gap-2"
|
||
>
|
||
<div className="flex items-center justify-between">
|
||
<span className="font-display font-black text-sm uppercase text-[#0A0A0A]">
|
||
{perm.name[lang]}
|
||
</span>
|
||
<span
|
||
className={`font-mono text-[9px] uppercase px-2 py-0.5 font-bold ${
|
||
perm.required
|
||
? "bg-[#FFE600] text-[#0A0A0A]"
|
||
: "bg-[#E0DACF] text-[#6A6460]"
|
||
}`}
|
||
>
|
||
{perm.required
|
||
? isTr
|
||
? "ZORUNLU"
|
||
: "REQUIRED"
|
||
: isTr
|
||
? "İSTEĞE BAĞLI"
|
||
: "OPTIONAL"}
|
||
</span>
|
||
</div>
|
||
<p className="text-[#6A6460] text-xs leading-relaxed">
|
||
{perm.reason[lang]}
|
||
</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</section>
|
||
)}
|
||
|
||
{/* Sections */}
|
||
{app.sections.map((section, idx) => (
|
||
<section
|
||
key={section.id}
|
||
id={section.id}
|
||
className="border-b border-[#C8C2B8] pb-10 scroll-mt-28"
|
||
>
|
||
<div className="flex items-center gap-3 mb-4">
|
||
<span className="font-mono text-[10px] text-[#A0998E]">
|
||
#{String(idx + 1).padStart(2, "0")}
|
||
</span>
|
||
<h2 className="font-display font-black text-xl sm:text-2xl uppercase text-[#0A0A0A]">
|
||
{section.title[lang]}
|
||
</h2>
|
||
</div>
|
||
|
||
<p className="text-[#4A4540] text-sm sm:text-base leading-relaxed mb-4">
|
||
{section.content[lang]}
|
||
</p>
|
||
|
||
{section.bullets && (
|
||
<ul className="space-y-2.5 mt-4 bg-[#EDE8E0] p-6 border-l-2 border-[#FFE600] border-y border-r border-[#C8C2B8]">
|
||
{section.bullets[lang].map((bullet, bIdx) => (
|
||
<li key={bIdx} className="flex items-start gap-2.5 text-xs sm:text-sm text-[#4A4540]">
|
||
<span className="font-mono text-[#A0998E] flex-shrink-0 mt-0.5">•</span>
|
||
<span>{bullet}</span>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
)}
|
||
</section>
|
||
))}
|
||
|
||
{/* Data Deletion and Erasure Request Section */}
|
||
<section
|
||
id="data-deletion"
|
||
className="border-2 border-[#0A0A0A] bg-[#FFE600] p-8"
|
||
>
|
||
<div className="font-mono text-[9px] uppercase tracking-[0.2em] text-[#0A0A0A] font-bold mb-2">
|
||
{isTr ? "KULLANICI VERİ KONTROLÜ" : "USER DATA CONTROL"}
|
||
</div>
|
||
<h2 className="font-display font-black text-2xl uppercase text-[#0A0A0A] mb-3">
|
||
{isTr
|
||
? `${app.name} Verilerinizi Kalıcı Olarak Silin`
|
||
: `Permanently Erase Your ${app.name} Data`}
|
||
</h2>
|
||
<p className="text-[#0A0A0A]/85 text-xs sm:text-sm leading-relaxed mb-6">
|
||
{isTr
|
||
? "Uygulama içerisinden hesabınızı silebilir veya aşağıdaki buton aracılığıyla doğrudan veri silme ve KVKK hak talebinde bulunabilirsiniz. Talebiniz en geç 72 saat içinde işleme alınır."
|
||
: "You can delete your account within the app or trigger a formal GDPR/KVKK erasure request by emailing our automated privacy handler. All records are purged within 72 hours."}
|
||
</p>
|
||
|
||
<a
|
||
href={`mailto:${app.contactEmail}?subject=${encodeURIComponent(
|
||
`[${app.name}] Veri Silme ve Hesap Kapatma Talebi`
|
||
)}&body=${encodeURIComponent(
|
||
`Merhaba,\n\n${app.name} uygulamasında kayıtlı olan kullanıcı hesabımın ve tüm verilerimin kalıcı olarak silinmesini talep ediyorum.\n\nKayıtlı E-posta Adresim:\nKullanıcı / Hesap ID (varsa):\n\nTeşekkürler.`
|
||
)}`}
|
||
className="inline-flex items-center gap-3 px-6 py-3.5 bg-[#0A0A0A] text-[#F4F0E8] font-display font-black text-xs tracking-wider uppercase hover:bg-[#FF4500] transition-colors"
|
||
>
|
||
{isTr ? "VERİ SİLME TALEBİ OLUŞTUR" : "REQUEST DATA DELETION"}
|
||
<svg
|
||
width="14"
|
||
height="14"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
strokeWidth="2.5"
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
>
|
||
<line x1="22" y1="2" x2="11" y2="13" />
|
||
<polygon points="22 2 15 22 11 13 2 9 22 2" />
|
||
</svg>
|
||
</a>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Other Applications Footer Switcher */}
|
||
{otherApps.length > 0 && (
|
||
<div className="mt-24 pt-12 border-t border-[#C8C2B8]">
|
||
<div className="font-mono text-[10px] tracking-[0.25em] uppercase text-[#A0998E] mb-6">
|
||
{isTr ? "DİĞER UYGULAMA GİZLİLİK POLİTİKALARI" : "OTHER APPLICATION POLICIES"}
|
||
</div>
|
||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-6">
|
||
{otherApps.map((other) => (
|
||
<Link
|
||
key={other.slug}
|
||
href={`/${lang}/privacy/${other.slug}`}
|
||
className="border border-[#C8C2B8] bg-[#EDE8E0] p-5 hover:border-[#0A0A0A] transition-colors group flex items-center gap-4"
|
||
>
|
||
<div className="w-10 h-10 bg-[#FFE600] border border-[#0A0A0A] flex items-center justify-center text-xl flex-shrink-0">
|
||
{other.icon}
|
||
</div>
|
||
<div className="min-w-0">
|
||
<div className="font-display font-black text-sm uppercase text-[#0A0A0A] group-hover:text-[#FF4500] transition-colors truncate">
|
||
{other.name}
|
||
</div>
|
||
<div className="font-mono text-[9px] text-[#A0998E] truncate">
|
||
{other.category[lang]}
|
||
</div>
|
||
</div>
|
||
</Link>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</main>
|
||
|
||
<Footer lang={lang} dict={dict} />
|
||
</div>
|
||
);
|
||
}
|