feat: add privacy hub and application privacy subpages
This commit is contained in:
@@ -103,7 +103,7 @@ export default function Footer({ lang, dict }: { lang: Locale; dict: any }) {
|
||||
© 2026 Ayris Tech — {dict.footer.rights}
|
||||
</p>
|
||||
<div className="flex items-center gap-6">
|
||||
<Link href="#" className="font-mono text-[10px] tracking-[0.15em] uppercase text-[#C8C2B8] hover:text-[#0A0A0A] transition-colors">
|
||||
<Link href={`/${lang}/privacy`} className="font-mono text-[10px] tracking-[0.15em] uppercase text-[#C8C2B8] hover:text-[#0A0A0A] transition-colors">
|
||||
{dict.footer.privacy}
|
||||
</Link>
|
||||
<Link href="#" className="font-mono text-[10px] tracking-[0.15em] uppercase text-[#C8C2B8] hover:text-[#0A0A0A] transition-colors">
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { motion, AnimatePresence } 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 PrivacyClient({
|
||||
lang,
|
||||
dict,
|
||||
apps,
|
||||
}: {
|
||||
lang: Locale;
|
||||
dict: any;
|
||||
apps: PrivacyApp[];
|
||||
}) {
|
||||
const [selectedPlatform, setSelectedPlatform] = useState<string>("ALL");
|
||||
const [searchQuery, setSearchQuery] = useState<string>("");
|
||||
|
||||
const isTr = lang === "tr";
|
||||
|
||||
const platforms = [
|
||||
{ id: "ALL", label: isTr ? "TÜM UYGULAMALAR" : "ALL PRODUCTS" },
|
||||
{ id: "iOS", label: "iOS" },
|
||||
{ id: "Android", label: "ANDROID" },
|
||||
{ id: "Web", label: "WEB & CLOUD" },
|
||||
{ id: "API", label: "API & SDK" },
|
||||
];
|
||||
|
||||
const filteredApps = apps.filter((app) => {
|
||||
const matchesPlatform =
|
||||
selectedPlatform === "ALL" ||
|
||||
app.platforms.some((p) =>
|
||||
selectedPlatform === "Web"
|
||||
? p === "Web" || p === "Cloud" || p === "SaaS"
|
||||
: selectedPlatform === "API"
|
||||
? p === "API" || p === "SDK"
|
||||
: p === selectedPlatform
|
||||
);
|
||||
|
||||
const matchesSearch =
|
||||
searchQuery.trim() === "" ||
|
||||
app.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
app.summary[lang].toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
app.category[lang].toLowerCase().includes(searchQuery.toLowerCase());
|
||||
|
||||
return matchesPlatform && matchesSearch;
|
||||
});
|
||||
|
||||
const corePrinciples = [
|
||||
{
|
||||
code: "SEC-01",
|
||||
title: isTr ? "Sıfır Veri Satışı" : "Zero Data Monetization",
|
||||
desc: isTr
|
||||
? "Kişisel ve kurumsal verileriniz hiçbir reklam ağı veya üçüncü taraf veri simsarı ile paylaşılmaz, satılmaz veya kiralanmaz."
|
||||
: "Your data is strictly yours. We never sell, rent, or trade your personal records to third-party ad brokers.",
|
||||
badge: isTr ? "KESİN İLKE" : "CORE PRINCIPLE",
|
||||
},
|
||||
{
|
||||
code: "SEC-02",
|
||||
title: isTr ? "Uçtan Uca Şifreleme" : "End-to-End Encryption",
|
||||
desc: isTr
|
||||
? "Tüm veri akışları TLS 1.3 protokolü ile aktarılır, veri tabanlarımızda AES-256 seviyesinde şifrelenerek depolanır."
|
||||
: "All communication is locked with TLS 1.3 and stored with military-grade AES-256 encryption at rest.",
|
||||
badge: "AES-256",
|
||||
},
|
||||
{
|
||||
code: "SEC-03",
|
||||
title: isTr ? "KVKK & GDPR Uyumu" : "Global Compliance",
|
||||
desc: isTr
|
||||
? "Tüm ürünlerimiz 6698 sayılı KVKK ve Avrupa Birliği GDPR standartları ile tam uyumlu olarak geliştirilir."
|
||||
: "Engineered from day one in strict compliance with EU GDPR and Turkish KVKK data protection statutes.",
|
||||
badge: "ISO/GDPR",
|
||||
},
|
||||
{
|
||||
code: "SEC-04",
|
||||
title: isTr ? "Anında Veri Silme" : "Instant Data Deletion",
|
||||
desc: isTr
|
||||
? "Uygulama içi ayarlardan veya tek tıkla destek e-postası ile tüm verilerinizi geri döndürülemez biçimde silebilirsiniz."
|
||||
: "Permanent, irrevocable deletion of your account and files on demand directly in-app or via our security desk.",
|
||||
badge: isTr ? "TAM KONTROL" : "FULL CONTROL",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="bg-[#F4F0E8] text-[#0A0A0A] font-body min-h-screen">
|
||||
<Header lang={lang} dict={dict.nav} />
|
||||
|
||||
<main className="pt-32 pb-24 px-6 max-w-7xl mx-auto">
|
||||
{/* Page Header */}
|
||||
<div className="border-b border-[#C8C2B8] pb-12 mb-16">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-3 h-3 bg-[#FFE600]" />
|
||||
<span className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{isTr ? "AYRİS TECH — GİZLİLİK VE VERİ MERKEZİ" : "AYRIS TECH — PRIVACY & COMPLIANCE HUB"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<motion.h1
|
||||
className="font-display font-black text-4xl sm:text-6xl lg:text-7xl uppercase leading-[0.9] tracking-tight mb-6"
|
||||
initial={{ opacity: 0, y: 25 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, ease: easeOutExpo }}
|
||||
>
|
||||
{isTr ? "GİZLİLİK" : "PRIVACY"}<br />
|
||||
<span className="text-stroke">{isTr ? "POLİTİKALARI" : "POLICIES"}</span>
|
||||
</motion.h1>
|
||||
|
||||
<p className="text-[#6A6460] text-base sm:text-lg max-w-3xl leading-relaxed">
|
||||
{isTr
|
||||
? "Ayris Tech bünyesindeki tüm mobil uygulamalar, bulut platformları ve geliştirici servislerinin veri işleme ilkelerine, izinlerine ve kullanıcı hakları bildirimlerine buradan ulaşabilirsiniz."
|
||||
: "Access the transparent privacy policies, hardware permission scopes, and data subject rights for all Ayris Tech applications, cloud services, and developer tools."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Core Principles Matrix */}
|
||||
<div className="mb-20">
|
||||
<div className="flex items-center justify-between mb-8 border-b border-[#C8C2B8] pb-4">
|
||||
<div className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E]">
|
||||
{isTr ? "01 / GÜVENLİK VE GİZLİLİK STANDARTLARIMIZ" : "01 / SECURITY & PRIVACY BENCHMARKS"}
|
||||
</div>
|
||||
<span className="font-mono text-[10px] text-[#A0998E]">
|
||||
ISO 27001 · KVKK · GDPR
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{corePrinciples.map((item, idx) => (
|
||||
<motion.div
|
||||
key={item.code}
|
||||
className="border border-[#C8C2B8] bg-[#EDE8E0] p-6 flex flex-col justify-between hover:border-[#0A0A0A] transition-colors"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: idx * 0.08, duration: 0.6 }}
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<span className="font-mono text-[10px] text-[#A0998E]">{item.code}</span>
|
||||
<span className="font-mono text-[9px] tracking-wider px-2 py-0.5 bg-[#FFE600] text-[#0A0A0A] font-bold">
|
||||
{item.badge}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="font-display font-black text-lg uppercase mb-3 text-[#0A0A0A]">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-[#6A6460] text-[13px] leading-relaxed">
|
||||
{item.desc}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Apps Privacy Directory */}
|
||||
<div className="mb-24">
|
||||
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6 mb-8 border-b border-[#C8C2B8] pb-6">
|
||||
<div>
|
||||
<div className="font-mono text-[10px] tracking-[0.3em] uppercase text-[#A0998E] mb-2">
|
||||
{isTr ? "02 / UYGULAMA GİZLİLİK REHBERİ" : "02 / APPLICATION DIRECTORY"}
|
||||
</div>
|
||||
<h2 className="font-display font-black text-2xl sm:text-3xl uppercase text-[#0A0A0A]">
|
||||
{isTr ? "UYGULAMALARIMIZ VE SERVİSLERİMİZ" : "APPLICATIONS & PLATFORMS"}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
{/* Filter Tabs */}
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
{platforms.map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setSelectedPlatform(tab.id)}
|
||||
className={`font-mono text-[10px] tracking-[0.15em] uppercase px-3.5 py-2 border transition-all cursor-pointer ${
|
||||
selectedPlatform === tab.id
|
||||
? "bg-[#0A0A0A] text-[#F4F0E8] border-[#0A0A0A] font-bold"
|
||||
: "bg-[#EDE8E0] text-[#6A6460] border-[#C8C2B8] hover:border-[#0A0A0A] hover:text-[#0A0A0A]"
|
||||
}`}
|
||||
>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search Box */}
|
||||
<div className="mb-8">
|
||||
<div className="relative">
|
||||
<input
|
||||
type="text"
|
||||
placeholder={
|
||||
isTr
|
||||
? "Uygulama adı, platform veya anahtar kelime ile filtreleyin..."
|
||||
: "Filter by application name, category, or keyword..."
|
||||
}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full bg-[#EDE8E0] border border-[#C8C2B8] focus:border-[#0A0A0A] px-4 py-3.5 font-mono text-[13px] text-[#0A0A0A] placeholder-[#A0998E] outline-none transition-colors"
|
||||
/>
|
||||
{searchQuery && (
|
||||
<button
|
||||
onClick={() => setSearchQuery("")}
|
||||
className="absolute right-4 top-1/2 -translate-y-1/2 font-mono text-[11px] text-[#A0998E] hover:text-[#0A0A0A]"
|
||||
>
|
||||
{isTr ? "TEMİZLE" : "CLEAR"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Apps Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<AnimatePresence mode="popLayout">
|
||||
{filteredApps.map((app, idx) => (
|
||||
<motion.div
|
||||
key={app.slug}
|
||||
layout
|
||||
initial={{ opacity: 0, scale: 0.96 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.96 }}
|
||||
transition={{ duration: 0.4, delay: idx * 0.05 }}
|
||||
className="border border-[#C8C2B8] bg-[#EDE8E0] p-8 flex flex-col justify-between hover:border-[#0A0A0A] transition-all group"
|
||||
>
|
||||
<div>
|
||||
{/* Top Row: Icon, Category, Platforms */}
|
||||
<div className="flex items-start justify-between gap-4 mb-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-14 h-14 bg-[#FFE600] border-2 border-[#0A0A0A] flex items-center justify-center text-2xl flex-shrink-0 group-hover:scale-105 transition-transform">
|
||||
{app.icon}
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-mono text-[9px] tracking-[0.2em] uppercase text-[#A0998E]">
|
||||
{app.category[lang]}
|
||||
</div>
|
||||
<h3 className="font-display font-black text-2xl uppercase text-[#0A0A0A] tracking-tight">
|
||||
{app.name}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-1.5 justify-end">
|
||||
{app.platforms.map((p) => (
|
||||
<span
|
||||
key={p}
|
||||
className="font-mono text-[9px] uppercase px-2 py-0.5 border border-[#C8C2B8] bg-[#F4F0E8] text-[#6A6460]"
|
||||
>
|
||||
{p}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Summary */}
|
||||
<p className="text-[#6A6460] text-[14px] leading-relaxed mb-6">
|
||||
{app.summary[lang]}
|
||||
</p>
|
||||
|
||||
{/* Highlights Badges */}
|
||||
<div className="grid grid-cols-2 gap-2 mb-8 pt-4 border-t border-[#C8C2B8]">
|
||||
{app.highlights[lang].slice(0, 4).map((h, i) => (
|
||||
<div key={i} className="bg-[#F4F0E8] p-2.5 border border-[#E0DACF]">
|
||||
<div className="font-mono text-[8px] uppercase tracking-wider text-[#A0998E]">
|
||||
{h.label}
|
||||
</div>
|
||||
<div className="font-display font-bold text-[11px] text-[#0A0A0A] truncate">
|
||||
{h.value}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Action */}
|
||||
<div className="pt-4 border-t border-[#C8C2B8] flex items-center justify-between">
|
||||
<span className="font-mono text-[10px] text-[#A0998E]">
|
||||
{isTr ? "Son Güncelleme:" : "Updated:"} {app.lastUpdated[lang]}
|
||||
</span>
|
||||
<Link
|
||||
href={`/${lang}/privacy/${app.slug}`}
|
||||
className="btn-brutal btn-brutal-yellow inline-flex items-center gap-2 px-5 py-2.5 font-display font-black text-[11px] tracking-wider uppercase"
|
||||
>
|
||||
{isTr ? "POLİTİKAYI İNCELE" : "VIEW POLICY"}
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" />
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
|
||||
{filteredApps.length === 0 && (
|
||||
<div className="col-span-2 border border-dashed border-[#C8C2B8] p-12 text-center">
|
||||
<div className="font-mono text-[11px] text-[#A0998E] uppercase tracking-wider mb-2">
|
||||
{isTr ? "Kayıt Bulunamadı" : "No Applications Found"}
|
||||
</div>
|
||||
<p className="text-[#6A6460] text-sm">
|
||||
{isTr
|
||||
? "Aradığınız kriterlere uygun uygulama gizlilik politikası bulunamadı."
|
||||
: "No application policies matched your filter criteria."}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Data Subject Request & Deletion Box */}
|
||||
<motion.div
|
||||
className="border-2 border-[#0A0A0A] bg-[#FFE600] p-8 sm:p-12"
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8 }}
|
||||
>
|
||||
<div className="max-w-4xl flex flex-col md:flex-row md:items-center justify-between gap-8">
|
||||
<div>
|
||||
<span className="font-mono text-[10px] tracking-[0.25em] uppercase text-[#0A0A0A] font-bold block mb-2">
|
||||
{isTr ? "KVKK MADDE 11 & GDPR HAK TALEPLERİ" : "DATA SUBJECT RIGHTS & ERASURE"}
|
||||
</span>
|
||||
<h2 className="font-display font-black text-2xl sm:text-3xl uppercase text-[#0A0A0A] leading-tight mb-3">
|
||||
{isTr ? "VERİLERİNİZİ SİLMEK VEYA BİLGİ ALMAK MI İSTİYORSUNUZ?" : "NEED TO ERASE YOUR DATA OR INQUIRE?"}
|
||||
</h2>
|
||||
<p className="text-[#0A0A0A]/80 text-sm leading-relaxed max-w-xl">
|
||||
{isTr
|
||||
? "Herhangi bir uygulamamızdaki hesabınızın, fişlerinizin, dava kayıtlarınızın veya kişisel verilerinizin kalıcı olarak silinmesini doğrudan talep edebilirsiniz."
|
||||
: "Request permanent deletion of your account records, telemetry data, or stored files across any of our applications instantly."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="mailto:privacy@ayristech.com?subject=Veri%20Silme%20ve%20Bilgi%20Talebi%20(Ayris%20Tech)&body=Merhaba,%20ilgili%20uygulamadaki%20verilerimin%20silinmesini/bilgilendirilmesini%20talep%20ediyorum.%0A%0AUygulama%20Ad%C4%B1:%0AKullan%C4%B1c%C4%B1%20E-postas%C4%B1:"
|
||||
className="px-8 py-4 bg-[#0A0A0A] text-[#F4F0E8] font-display font-black text-xs tracking-widest uppercase hover:bg-[#FF4500] transition-colors flex-shrink-0 text-center"
|
||||
>
|
||||
{isTr ? "HAK / SİLME TALEBİ GÖNDER" : "SUBMIT ERASURE REQUEST"}
|
||||
</a>
|
||||
</div>
|
||||
</motion.div>
|
||||
</main>
|
||||
|
||||
<Footer lang={lang} dict={dict} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user