feat: add privacy hub and application privacy subpages
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user