feat: add privacy policy page localizations
All checks were successful
Deploy Portfolio to VPS / deploy (push) Successful in 27s

This commit is contained in:
Chneemann 2026-08-06 11:44:11 +02:00
parent 5b525acf62
commit ea2defe0f0
No known key found for this signature in database
3 changed files with 83 additions and 53 deletions

View file

@ -1,20 +1,27 @@
import Link from "next/link"; "use client";
import { useTranslations } from "next-intl";
import { Link } from "@/i18n/navigation";
/** /**
* GDPR privacy policy page outlining data collection, self-hosted analytics, and user rights * GDPR privacy policy page outlining data collection, self-hosted analytics, and user rights
*/ */
export default function PrivacyPage() { export default function PrivacyPage() {
const tCommon = useTranslations("Common");
const tPrivacy = useTranslations("Privacy");
return ( return (
<section className="relative pt-18 py-6 px-4 md:px-6 md:pt-24 max-w-5xl mx-auto"> <section className="relative pt-18 py-6 px-4 md:px-6 md:pt-24 max-w-5xl mx-auto">
{/* Page Heading & Navigation */} {/* Page Heading & Navigation */}
<h1 className="text-3xl font-bold text-white mb-2 tracking-tight"> <h1 className="text-3xl font-bold text-white mb-2 tracking-tight">
Privacy Policy<span className="text-blue-500">.</span> {tCommon("privacy")}
<span className="text-blue-500">.</span>
</h1> </h1>
<Link <Link
href="/" href="/"
className="text-sm font-mono text-blue-400 hover:underline mb-8 inline-flex items-center gap-2 transition-colors" className="text-sm font-mono text-blue-400 hover:underline mb-8 inline-flex items-center gap-2 transition-colors"
> >
Back to Homepage {tCommon("backHome")}
</Link> </Link>
<div className="space-y-8 text-slate-300 leading-relaxed text-sm"> <div className="space-y-8 text-slate-300 leading-relaxed text-sm">
@ -22,27 +29,23 @@ export default function PrivacyPage() {
<div className="group relative rounded-2xl border border-slate-700/60 bg-slate-900/95 p-6 shadow-2xl shadow-black/60 border-t-slate-600/50 space-y-3 overflow-hidden"> <div className="group relative rounded-2xl border border-slate-700/60 bg-slate-900/95 p-6 shadow-2xl shadow-black/60 border-t-slate-600/50 space-y-3 overflow-hidden">
<div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" /> <div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" />
<h2 className="text-lg font-semibold text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-white flex items-center gap-2">
<span className="text-blue-500 font-mono text-sm">//</span> Data <span className="text-blue-500 font-mono text-sm">//</span>{" "}
Protection at a Glance {tPrivacy("section1Title")}
</h2> </h2>
<div className="space-y-1"> <div className="space-y-1">
<h3 className="font-semibold ">General Information</h3> <h3 className="font-semibold ">{tPrivacy("generalInfoTitle")}</h3>
<p className="text-slate-300 text-xs leading-relaxed"> <p className="text-slate-300 text-xs leading-relaxed">
The following notes provide a simple overview of what happens to {tPrivacy("generalInfoText")}
your personal data when you visit this website. Personal data is
any data that can be used to personally identify you.
</p> </p>
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
<h3 className="font-semibold pt-2"> <h3 className="font-semibold pt-2">
Data Collection on This Website {tPrivacy("dataCollectionTitle")}
</h3> </h3>
<p className="text-slate-300 text-xs leading-relaxed"> <p className="text-slate-300 text-xs leading-relaxed">
Data processing on this website is carried out by the website {tPrivacy("dataCollectionText")}
operator. Your data is collected when you provide it to us, or
automatically by our IT systems when you visit the site.
</p> </p>
</div> </div>
</div> </div>
@ -52,17 +55,15 @@ export default function PrivacyPage() {
<div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" /> <div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" />
<h2 className="text-lg font-semibold text-white mb-2 flex items-center gap-2"> <h2 className="text-lg font-semibold text-white mb-2 flex items-center gap-2">
<span className="text-blue-500 font-mono text-sm">//</span> <span className="text-blue-500 font-mono text-sm">//</span>
Responsible Party (Controller) {tPrivacy("section2Title")}
</h2> </h2>
<p> <p>{tPrivacy("section2Intro")}</p>
The controller responsible for data processing on this website is:
</p>
<div className="pt-2 font-mono text-xs space-y-1 bg-slate-950/60 p-4 rounded-xl border border-slate-800/80"> <div className="pt-2 font-mono text-xs space-y-1 bg-slate-950/60 p-4 rounded-xl border border-slate-800/80">
<p className="font-semibold text-slate-100 text-sm">André Kempf</p> <p className="font-semibold text-slate-100 text-sm">André Kempf</p>
<p>Großschneidersweg 2a</p> <p>Großschneidersweg 2a</p>
<p>76149 Karlsruhe, Germany</p> <p>76149 Karlsruhe, Germany</p>
<p className="pt-2"> <p className="pt-2">
Email:{" "} {tCommon("emailLabel")}:{" "}
<span className="text-blue-400 hover:underline cursor-pointer"> <span className="text-blue-400 hover:underline cursor-pointer">
dev@andre-kempf.com dev@andre-kempf.com
</span> </span>
@ -75,18 +76,10 @@ export default function PrivacyPage() {
<div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" /> <div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" />
<h2 className="text-lg font-semibold text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-white flex items-center gap-2">
<span className="text-blue-500 font-mono text-sm">//</span> <span className="text-blue-500 font-mono text-sm">//</span>
Hosting & Server Infrastructure {tPrivacy("section3Title")}
</h2> </h2>
<p> <p>{tPrivacy("hostingText1")}</p>
This website is hosted externally on web servers operated by Netcup <p>{tPrivacy("hostingText2")}</p>
GmbH. Personal data processed on this website is stored on the
host&apos;s secure servers.
</p>
<p>
The hosting provider automatically processes technical access data
in server environment variables necessary to establish a stable
connection and deliver page assets securely.
</p>
</div> </div>
{/* Privacy-Preserving Analytics Principles */} {/* Privacy-Preserving Analytics Principles */}
@ -94,36 +87,29 @@ export default function PrivacyPage() {
<div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" /> <div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" />
<h2 className="text-lg font-semibold text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-white flex items-center gap-2">
<span className="text-blue-500 font-mono text-sm">//</span> <span className="text-blue-500 font-mono text-sm">//</span>
Server Analytics & Privacy-First Tracking {tPrivacy("section4Title")}
</h2> </h2>
<p> <p>{tPrivacy("analyticsText1")}</p>
To evaluate website reach and optimize user experience, this website
processes minimal access metrics (e.g., total daily views, coarse
device category, and daily visitor counts).
</p>
<div className="p-4 rounded-xl bg-slate-950/60 border border-slate-800/80 space-y-2 text-xs font-mono"> <div className="p-4 rounded-xl bg-slate-950/60 border border-slate-800/80 space-y-2 text-xs font-mono">
<p className="text-emerald-400 font-semibold"> <p className="text-emerald-400 font-semibold">
// Key privacy guarantees: // {tPrivacy("analyticsGuaranteesTitle")}
</p> </p>
<ul className="list-disc list-inside space-y-1 text-slate-400"> <ul className="list-disc list-inside space-y-1 text-slate-400">
<li> <li>
<strong>No Cookies:</strong> We do not store cookies or local <strong>{tPrivacy("cookieTitle")}:</strong>{" "}
storage identifiers on your device. {tPrivacy("cookieText")}
</li> </li>
<li> <li>
<strong>Anonymized IPs:</strong> IP addresses are instantly <strong>{tPrivacy("ipTitle")}:</strong> {tPrivacy("ipText")}
hashed with a daily salt and never stored in plain text.
</li> </li>
<li> <li>
<strong>Zero Third Parties:</strong> Analytics data is processed <strong>{tPrivacy("thirdPartyTitle")}:</strong>{" "}
locally on our own server and never shared with external {tPrivacy("thirdPartyText")}
tracking services.
</li> </li>
</ul> </ul>
</div> </div>
<p className="text-xs text-slate-400 pt-1"> <p className="text-xs text-slate-400 pt-1">
The legal basis for this processing is our legitimate interest in {tPrivacy("analyticsText2")}
maintaining and optimizing our online portfolio (Art. 6(1)(f) GDPR).
</p> </p>
</div> </div>
@ -131,15 +117,10 @@ export default function PrivacyPage() {
<div className="group relative rounded-2xl border border-slate-700/60 bg-slate-900/95 p-6 shadow-2xl shadow-black/60 border-t-slate-600/50 space-y-3 overflow-hidden"> <div className="group relative rounded-2xl border border-slate-700/60 bg-slate-900/95 p-6 shadow-2xl shadow-black/60 border-t-slate-600/50 space-y-3 overflow-hidden">
<div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" /> <div className="absolute -top-12 -right-12 w-24 h-24 bg-blue-500/10 rounded-full blur-xl pointer-events-none" />
<h2 className="text-lg font-semibold text-white flex items-center gap-2"> <h2 className="text-lg font-semibold text-white flex items-center gap-2">
<span className="text-blue-500 font-mono text-sm">//</span> Your <span className="text-blue-500 font-mono text-sm">//</span>{" "}
Rights {tPrivacy("section5Title")}
</h2> </h2>
<p> <p>{tPrivacy("section5Text")}</p>
You have the right at any time to receive information free of charge
about the origin, recipient, and purpose of your stored personal
data. You also have a right to request the correction or deletion of
this data.
</p>
</div> </div>
</div> </div>
</section> </section>

View file

@ -86,5 +86,30 @@
"section4Title": "Streitschlichtung", "section4Title": "Streitschlichtung",
"disputeText1": "Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit:", "disputeText1": "Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit:",
"disputeText2": "Ich bin nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen." "disputeText2": "Ich bin nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen."
},
"Privacy": {
"backHome": "Zurück zur Startseite",
"section1Title": "Datenschutz auf einen Blick",
"generalInfoTitle": "Allgemeine Hinweise",
"generalInfoText": "Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren personenbezogenen Daten passiert, wenn Sie diese Website besuchen. Personenbezogene Daten sind alle Daten, mit denen Sie persönlich identifiziert werden können.",
"dataCollectionTitle": "Datenerfassung auf dieser Website",
"dataCollectionText": "Die Datenverarbeitung auf dieser Website erfolgt durch den Website-Betreiber. Ihre Daten werden zum einen dadurch erhoben, dass Sie uns diese mitteilen, zum anderen automatisch beim Besuch der Website durch unsere IT-Systeme erfasst.",
"section2Title": "Verantwortliche Stelle",
"section2Intro": "Die verantwortliche Stelle für die Datenverarbeitung auf dieser Website ist:",
"section3Title": "Hosting & Server-Infrastruktur",
"hostingText1": "Diese Website wird extern auf Webservern der Netcup GmbH gehostet. Personenbezogene Daten, die auf dieser Website erfasst werden, werden auf den Servern des Hosters gespeichert.",
"hostingText2": "Der Hosting-Anbieter verarbeitet automatisch technische Zugriffsdaten in Server-Umgebungsvariablen, die erforderlich sind, um eine stabile Verbindung aufzubauen und Seiteninhalte sicher auszuliefern.",
"section4Title": "Server-Analyse & Datenschutzfreundliches Tracking",
"analyticsText1": "Zur Auswertung der Reichweite und Optimierung der Nutzererfahrung verarbeitet diese Website minimale Zugriffsmetriken (z. B. tägliche Gesamtaufrufe, grobe Gerätekategorien und tägliche Besucherzahlen).",
"analyticsGuaranteesTitle": "Wichtige Datenschutzgarantien:",
"cookieTitle": "Keine Cookies",
"cookieText": "Wir speichern keine Cookies oder Local-Storage-Identifier auf Ihrem Endgerät.",
"ipTitle": "Anonymisierte IP-Adressen",
"ipText": "IP-Adressen werden sofort mit einem täglichen Salt gehasht und niemals im Klartext gespeichert.",
"thirdPartyTitle": "Keine Drittanbieter",
"thirdPartyText": "Analysedaten werden lokal auf unserem eigenen Server verarbeitet und niemals an externe Tracking-Dienste weitergegeben.",
"analyticsText2": "Die Rechtsgrundlage für diese Verarbeitung ist unser berechtigtes Interesse an der Pflege und Optimierung unseres Online-Portfolios (Art. 6 Abs. 1 lit. f DSGVO).",
"section5Title": "Ihre Rechte",
"section5Text": "Sie haben jederzeit das Recht, unentgeltlich Auskunft über Herkunft, Empfänger und Zweck Ihrer gespeicherten personenbezogenen Daten zu erhalten. Außerdem haben Sie das Recht, die Berichtigung oder Löschung dieser Daten zu verlangen."
} }
} }

View file

@ -86,5 +86,29 @@
"section4Title": "Dispute Resolution", "section4Title": "Dispute Resolution",
"disputeText1": "The European Commission provides a platform for online dispute resolution (OS):", "disputeText1": "The European Commission provides a platform for online dispute resolution (OS):",
"disputeText2": "I am neither willing nor obligated to participate in dispute resolution proceedings before a consumer arbitration board." "disputeText2": "I am neither willing nor obligated to participate in dispute resolution proceedings before a consumer arbitration board."
},
"Privacy": {
"section1Title": "Data Protection at a Glance",
"generalInfoTitle": "General Information",
"generalInfoText": "The following notes provide a simple overview of what happens to your personal data when you visit this website. Personal data is any data that can be used to personally identify you.",
"dataCollectionTitle": "Data Collection on This Website",
"dataCollectionText": "Data processing on this website is carried out by the website operator. Your data is collected when you provide it to us, or automatically by our IT systems when you visit the site.",
"section2Title": "Responsible Party (Controller)",
"section2Intro": "The controller responsible for data processing on this website is:",
"section3Title": "Hosting & Server Infrastructure",
"hostingText1": "This website is hosted externally on web servers operated by Netcup GmbH. Personal data processed on this website is stored on the host's secure servers.",
"hostingText2": "The hosting provider automatically processes technical access data in server environment variables necessary to establish a stable connection and deliver page assets securely.",
"section4Title": "Server Analytics & Privacy-First Tracking",
"analyticsText1": "To evaluate website reach and optimize user experience, this website processes minimal access metrics (e.g., total daily views, coarse device category, and daily visitor counts).",
"analyticsGuaranteesTitle": "Key privacy guarantees:",
"cookieTitle": "No Cookies",
"cookieText": "We do not store cookies or local storage identifiers on your device.",
"ipTitle": "Anonymized IPs",
"ipText": "IP addresses are instantly hashed with a daily salt and never stored in plain text.",
"thirdPartyTitle": "Zero Third Parties",
"thirdPartyText": "Analytics data is processed locally on our own server and never shared with external tracking services.",
"analyticsText2": "The legal basis for this processing is our legitimate interest in maintaining and optimizing our online portfolio (Art. 6(1)(f) GDPR).",
"section5Title": "Your Rights",
"section5Text": "You have the right at any time to receive information free of charge about the origin, recipient, and purpose of your stored personal data. You also have a right to request the correction or deletion of this data."
} }
} }