Merge pull request #1 from jessy-david-dev/dev
Dev
This commit was merged in pull request #1.
This commit is contained in:
@@ -2,21 +2,21 @@
|
|||||||
|
|
||||||
Portfolio personnel de développeur web, construit avec **Next.js** et un ensemble de technologies modernes.
|
Portfolio personnel de développeur web, construit avec **Next.js** et un ensemble de technologies modernes.
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✨ Fonctionnalités
|
## ✨ Fonctionnalités
|
||||||
|
|
||||||
- ⚡ **Next.js App Router** & Server Components
|
- ⚡ **Next.js App Router** & Server Components
|
||||||
- 🎨 **Tailwind CSS** pour un design moderne et responsive
|
- 🎨 **Tailwind CSS** pour un design moderne et responsive
|
||||||
- 📧 **Formulaire de contact** via API Route
|
- 📧 **Formulaire de contact** via API Route
|
||||||
- 🗺️ **Sitemap dynamique** pour un SEO optimisé
|
- 🗺️ **Sitemap dynamique** pour un SEO optimisé
|
||||||
- 🌐 **PWA Ready** (manifest + icônes)
|
- 🌐 **PWA Ready** (manifest + icônes)
|
||||||
- 🔥 **Animations fluides** et transitions modernes
|
- 🔥 **Animations fluides** et transitions modernes
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -115,9 +115,9 @@ Ce projet est sous licence **MIT** – voir le fichier [LICENSE](LICENSE) pour p
|
|||||||
|
|
||||||
**Jessy David**
|
**Jessy David**
|
||||||
|
|
||||||
- 🌐 Website : [jessy-david.dev](https://jessy-david.dev)
|
- 🌐 Website : [jessy-david.dev](https://jessy-david.dev)
|
||||||
- 🐙 GitHub : [@jessydavid-dev](https://github.com/jessydavid-dev)
|
- 🐙 GitHub : [@jessydavid-dev](https://github.com/jessydavid-dev)
|
||||||
- 📧 Email : [contact@jessy-david.dev](mailto:contact@jessy-david.dev)
|
- 📧 Email : [contact@jessy-david.dev](mailto:contact@jessy-david.dev)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+227
-185
@@ -1,5 +1,6 @@
|
|||||||
import Footer from "@/component/layout/Footer";
|
import Footer from "@/component/layout/Footer";
|
||||||
import NavBar from "@/component/layout/NavBar";
|
import NavBar from "@/component/layout/NavBar";
|
||||||
|
import CookieBanner from "@/component/ui/CookieBanner";
|
||||||
import GridBackground from "@/component/ui/GridBackground";
|
import GridBackground from "@/component/ui/GridBackground";
|
||||||
import type { Metadata, Viewport } from "next";
|
import type { Metadata, Viewport } from "next";
|
||||||
import { Inter } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
@@ -7,216 +8,257 @@ import { ReactNode } from "react";
|
|||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
|
||||||
const inter = Inter({
|
const inter = Inter({
|
||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
display: "swap",
|
display: "swap",
|
||||||
variable: "--font-inter",
|
variable: "--font-inter",
|
||||||
});
|
});
|
||||||
|
|
||||||
const siteConfig = {
|
const siteConfig = {
|
||||||
name: "Jessy David",
|
name: "Jessy David",
|
||||||
title: "Jessy David | Développeur Web Full-Stack",
|
title: "Jessy David | Développeur Web Full-Stack",
|
||||||
description:
|
description:
|
||||||
"Développeur Web Full-Stack passionné, spécialisé en React, Next.js et Node.js. Création de sites web modernes, applications web performantes et solutions digitales sur mesure.",
|
"Développeur Web Full-Stack passionné, spécialisé en React, Next.js et Node.js. Création de sites web modernes, applications web performantes et solutions digitales sur mesure.",
|
||||||
url: "https://jessy-david.dev",
|
url: "https://jessy-david.dev",
|
||||||
ogImage: "https://jessy-david.dev/og-image.jpg",
|
ogImage: "https://jessy-david.dev/og-image.jpg",
|
||||||
author: "Jessy David",
|
author: "Jessy David",
|
||||||
keywords: [
|
keywords: [
|
||||||
"développeur web",
|
"développeur web",
|
||||||
"développeur full-stack",
|
"développeur full-stack",
|
||||||
"React",
|
"React",
|
||||||
"Next.js",
|
"Next.js",
|
||||||
"Node.js",
|
"Node.js",
|
||||||
"TypeScript",
|
"TypeScript",
|
||||||
"JavaScript",
|
"JavaScript",
|
||||||
"création site web",
|
"création site web",
|
||||||
"freelance",
|
"freelance",
|
||||||
"France",
|
"France",
|
||||||
"portfolio",
|
"portfolio",
|
||||||
"Jessy David",
|
"Jessy David",
|
||||||
],
|
],
|
||||||
twitterHandle: "@jessydavid",
|
twitterHandle: "@jessydavid",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: {
|
title: {
|
||||||
default: siteConfig.title,
|
default: siteConfig.title,
|
||||||
template: `%s | ${siteConfig.name}`,
|
template: `%s | ${siteConfig.name}`,
|
||||||
|
},
|
||||||
|
description: siteConfig.description,
|
||||||
|
keywords: siteConfig.keywords,
|
||||||
|
authors: [{ name: siteConfig.author, url: siteConfig.url }],
|
||||||
|
creator: siteConfig.author,
|
||||||
|
publisher: siteConfig.author,
|
||||||
|
|
||||||
|
metadataBase: new URL(siteConfig.url),
|
||||||
|
alternates: {
|
||||||
|
canonical: "/",
|
||||||
|
languages: {
|
||||||
|
"fr-FR": "/",
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
robots: {
|
||||||
|
index: true,
|
||||||
|
follow: true,
|
||||||
|
nocache: false,
|
||||||
|
googleBot: {
|
||||||
|
index: true,
|
||||||
|
follow: true,
|
||||||
|
noimageindex: false,
|
||||||
|
"max-video-preview": -1,
|
||||||
|
"max-image-preview": "large",
|
||||||
|
"max-snippet": -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
openGraph: {
|
||||||
|
type: "website",
|
||||||
|
locale: "fr_FR",
|
||||||
|
url: siteConfig.url,
|
||||||
|
siteName: siteConfig.name,
|
||||||
|
title: siteConfig.title,
|
||||||
description: siteConfig.description,
|
description: siteConfig.description,
|
||||||
keywords: siteConfig.keywords,
|
images: [
|
||||||
authors: [{ name: siteConfig.author, url: siteConfig.url }],
|
{
|
||||||
creator: siteConfig.author,
|
url: siteConfig.ogImage,
|
||||||
publisher: siteConfig.author,
|
width: 1200,
|
||||||
|
height: 630,
|
||||||
|
alt: `${siteConfig.name} - Portfolio Développeur Web`,
|
||||||
|
type: "image/jpeg",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
metadataBase: new URL(siteConfig.url),
|
twitter: {
|
||||||
alternates: {
|
card: "summary_large_image",
|
||||||
canonical: "/",
|
title: siteConfig.title,
|
||||||
languages: {
|
description: siteConfig.description,
|
||||||
"fr-FR": "/",
|
creator: siteConfig.twitterHandle,
|
||||||
},
|
images: [siteConfig.ogImage],
|
||||||
},
|
},
|
||||||
|
|
||||||
robots: {
|
icons: {
|
||||||
index: true,
|
icon: [
|
||||||
follow: true,
|
{ url: "/favicon.ico", sizes: "any" },
|
||||||
nocache: false,
|
{ url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
|
||||||
googleBot: {
|
{ url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
|
||||||
index: true,
|
],
|
||||||
follow: true,
|
apple: [
|
||||||
noimageindex: false,
|
{
|
||||||
"max-video-preview": -1,
|
url: "/apple-touch-icon.png",
|
||||||
"max-image-preview": "large",
|
sizes: "180x180",
|
||||||
"max-snippet": -1,
|
type: "image/png",
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
|
},
|
||||||
|
|
||||||
openGraph: {
|
manifest: "/site.webmanifest",
|
||||||
type: "website",
|
|
||||||
locale: "fr_FR",
|
|
||||||
url: siteConfig.url,
|
|
||||||
siteName: siteConfig.name,
|
|
||||||
title: siteConfig.title,
|
|
||||||
description: siteConfig.description,
|
|
||||||
images: [
|
|
||||||
{
|
|
||||||
url: siteConfig.ogImage,
|
|
||||||
width: 1200,
|
|
||||||
height: 630,
|
|
||||||
alt: `${siteConfig.name} - Portfolio Développeur Web`,
|
|
||||||
type: "image/jpeg",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
twitter: {
|
category: "technology",
|
||||||
card: "summary_large_image",
|
|
||||||
title: siteConfig.title,
|
|
||||||
description: siteConfig.description,
|
|
||||||
creator: siteConfig.twitterHandle,
|
|
||||||
images: [siteConfig.ogImage],
|
|
||||||
},
|
|
||||||
|
|
||||||
icons: {
|
verification: {
|
||||||
icon: [
|
google: "ton-code-google-search-console",
|
||||||
{ url: "/favicon.ico", sizes: "any" },
|
},
|
||||||
{ url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
|
|
||||||
{ url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
|
|
||||||
],
|
|
||||||
apple: [
|
|
||||||
{
|
|
||||||
url: "/apple-touch-icon.png",
|
|
||||||
sizes: "180x180",
|
|
||||||
type: "image/png",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
manifest: "/site.webmanifest",
|
other: {
|
||||||
|
"msapplication-TileColor": "#0f172a",
|
||||||
category: "technology",
|
"theme-color": "#0f172a",
|
||||||
|
},
|
||||||
verification: {
|
|
||||||
google: "ton-code-google-search-console",
|
|
||||||
},
|
|
||||||
|
|
||||||
other: {
|
|
||||||
"msapplication-TileColor": "#0f172a",
|
|
||||||
"theme-color": "#0f172a",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const viewport: Viewport = {
|
export const viewport: Viewport = {
|
||||||
themeColor: [
|
themeColor: [
|
||||||
{ media: "(prefers-color-scheme: light)", color: "#ffffff" },
|
{ media: "(prefers-color-scheme: light)", color: "#ffffff" },
|
||||||
{ media: "(prefers-color-scheme: dark)", color: "#0f172a" },
|
{ media: "(prefers-color-scheme: dark)", color: "#0f172a" },
|
||||||
],
|
],
|
||||||
width: "device-width",
|
width: "device-width",
|
||||||
initialScale: 1,
|
initialScale: 1,
|
||||||
maximumScale: 5,
|
maximumScale: 5,
|
||||||
userScalable: true,
|
userScalable: true,
|
||||||
colorScheme: "dark",
|
colorScheme: "dark",
|
||||||
};
|
};
|
||||||
|
|
||||||
const jsonLd = {
|
const jsonLd = {
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
"@type": "WebSite",
|
"@type": "WebSite",
|
||||||
"@id": `${siteConfig.url}/#website`,
|
"@id": `${siteConfig.url}/#website`,
|
||||||
url: siteConfig.url,
|
url: siteConfig.url,
|
||||||
name: siteConfig.name,
|
name: siteConfig.name,
|
||||||
description: siteConfig.description,
|
description: siteConfig.description,
|
||||||
inLanguage: "fr-FR",
|
inLanguage: "fr-FR",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
"@id": `${siteConfig.url}/#person`,
|
"@id": `${siteConfig.url}/#person`,
|
||||||
name: siteConfig.name,
|
name: siteConfig.name,
|
||||||
url: siteConfig.url,
|
url: siteConfig.url,
|
||||||
image: siteConfig.ogImage,
|
image: siteConfig.ogImage,
|
||||||
jobTitle: "Développeur Web Full-Stack",
|
jobTitle: "Développeur Web Full-Stack",
|
||||||
description: siteConfig.description,
|
description: siteConfig.description,
|
||||||
sameAs: [
|
sameAs: [
|
||||||
"https://github.com/jessydavid-dev",
|
"https://github.com/jessydavid-dev",
|
||||||
"https://linkedin.com/in/jessy-david",
|
"https://linkedin.com/in/jessy-david",
|
||||||
"https://twitter.com/jessydavid",
|
"https://twitter.com/jessydavid",
|
||||||
],
|
],
|
||||||
knowsAbout: [
|
knowsAbout: [
|
||||||
"React",
|
"React",
|
||||||
"Next.js",
|
"Next.js",
|
||||||
"TypeScript",
|
"TypeScript",
|
||||||
"Node.js",
|
"Node.js",
|
||||||
"JavaScript",
|
"JavaScript",
|
||||||
"Tailwind CSS",
|
"Tailwind CSS",
|
||||||
"PostgreSQL",
|
"PostgreSQL",
|
||||||
"MongoDB",
|
"MongoDB",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"@type": "ProfilePage",
|
"@type": "ProfilePage",
|
||||||
"@id": `${siteConfig.url}/#profilepage`,
|
"@id": `${siteConfig.url}/#profilepage`,
|
||||||
url: siteConfig.url,
|
url: siteConfig.url,
|
||||||
name: `Portfolio de ${siteConfig.name}`,
|
name: `Portfolio de ${siteConfig.name}`,
|
||||||
description: siteConfig.description,
|
description: siteConfig.description,
|
||||||
mainEntity: { "@id": `${siteConfig.url}/#person` },
|
mainEntity: { "@id": `${siteConfig.url}/#person` },
|
||||||
inLanguage: "fr-FR",
|
inLanguage: "fr-FR",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<html lang="fr" className={inter.variable}>
|
<html lang="fr" className={inter.variable}>
|
||||||
<head>
|
<head>
|
||||||
<script
|
{/* Google Tag Manager - Consent Mode par défaut */}
|
||||||
type="application/ld+json"
|
<script
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
dangerouslySetInnerHTML={{
|
||||||
/>
|
__html: `
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
|
||||||
|
// Consentement par défaut : tout refusé (RGPD compliant)
|
||||||
|
gtag('consent', 'default', {
|
||||||
|
'analytics_storage': 'denied',
|
||||||
|
'ad_storage': 'denied',
|
||||||
|
'ad_user_data': 'denied',
|
||||||
|
'ad_personalization': 'denied',
|
||||||
|
'wait_for_update': 500
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/* Google Tag Manager */}
|
||||||
|
<script
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: `
|
||||||
|
(function(w,d,s,l,i){w[l]=w[l]||[];
|
||||||
|
w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});
|
||||||
|
var f=d.getElementsByTagName(s)[0],
|
||||||
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
|
||||||
|
j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
|
||||||
|
f.parentNode.insertBefore(j,f);
|
||||||
|
})(window,document,'script','dataLayer','GTM-TJDQ3XJD');
|
||||||
|
`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<script
|
||||||
<link
|
type="application/ld+json"
|
||||||
rel="preconnect"
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||||
href="https://fonts.gstatic.com"
|
/>
|
||||||
crossOrigin="anonymous"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<link
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
rel="dns-prefetch"
|
<link
|
||||||
href="https://www.google-analytics.com"
|
rel="preconnect"
|
||||||
/>
|
href="https://fonts.gstatic.com"
|
||||||
</head>
|
crossOrigin="anonymous"
|
||||||
<body className={`${inter.className} antialiased`}>
|
/>
|
||||||
<GridBackground variant="light" />
|
|
||||||
<NavBar />
|
<link rel="dns-prefetch" href="https://www.googletagmanager.com" />
|
||||||
<main id="main-content" className="relative z-10">
|
</head>
|
||||||
{children}
|
<body className={`${inter.className} antialiased`}>
|
||||||
</main>
|
{/* Google Tag Manager (noscript) */}
|
||||||
<Footer />
|
<noscript>
|
||||||
</body>
|
<iframe
|
||||||
</html>
|
src="https://www.googletagmanager.com/ns.html?id=GTM-TJDQ3XJD"
|
||||||
);
|
height="0"
|
||||||
|
width="0"
|
||||||
|
style={{ display: "none", visibility: "hidden" }}
|
||||||
|
/>
|
||||||
|
</noscript>
|
||||||
|
|
||||||
|
<GridBackground variant="light" />
|
||||||
|
<NavBar />
|
||||||
|
<main id="main-content" className="relative z-10">
|
||||||
|
{children}
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
<CookieBanner />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
import { ArrowLeft, FileText, Scale, User } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export default function MentionsLegales() {
|
||||||
|
return (
|
||||||
|
<section className="min-h-screen py-20 bg-slate-900 relative overflow-hidden">
|
||||||
|
{/* Grid Background */}
|
||||||
|
<div
|
||||||
|
className="absolute inset-0 opacity-20"
|
||||||
|
style={{
|
||||||
|
backgroundImage:
|
||||||
|
"linear-gradient(to right, #1e293b 1px, transparent 1px), linear-gradient(to bottom, #1e293b 1px, transparent 1px)",
|
||||||
|
backgroundSize: "60px 60px",
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
|
||||||
|
{/* Decorative blobs */}
|
||||||
|
<div className="absolute top-20 left-10 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl"></div>
|
||||||
|
<div className="absolute bottom-20 right-10 w-96 h-96 bg-purple-500/10 rounded-full blur-3xl"></div>
|
||||||
|
|
||||||
|
<div className="container mx-auto px-4 max-w-4xl relative z-10">
|
||||||
|
{/* Back button */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, x: -20 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className="mb-8"
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
href="/"
|
||||||
|
className="inline-flex items-center gap-2 text-slate-400 hover:text-white transition-colors group"
|
||||||
|
>
|
||||||
|
<ArrowLeft className="w-5 h-5 group-hover:-translate-x-1 transition-transform" />
|
||||||
|
Retour à l'accueil
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.6 }}
|
||||||
|
className="text-center mb-12"
|
||||||
|
>
|
||||||
|
<div className="inline-flex items-center gap-2 bg-linear-to-r from-blue-500/10 to-purple-500/10 rounded-full px-4 py-2 mb-4">
|
||||||
|
<Scale className="w-4 h-4 text-blue-400" />
|
||||||
|
<span className="text-sm font-semibold text-slate-300">
|
||||||
|
Informations légales
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">
|
||||||
|
Mentions Légales
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-slate-400">
|
||||||
|
Conformément à la loi n° 2004-575 du 21 juin 2004 pour la confiance
|
||||||
|
dans l'économie numérique
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.6, delay: 0.2 }}
|
||||||
|
className="space-y-8"
|
||||||
|
>
|
||||||
|
{/* Éditeur du site */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className="p-2 bg-blue-500/20 rounded-lg">
|
||||||
|
<User className="w-5 h-5 text-blue-400" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-bold text-white">
|
||||||
|
1. Éditeur du site
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="text-slate-300 space-y-2">
|
||||||
|
<p>
|
||||||
|
<strong>Nom :</strong> Jessy DAVID
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Adresse :</strong> Angers, France
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Email :</strong>{" "}
|
||||||
|
<a
|
||||||
|
href="mailto:contact@jessy-david.dev"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
contact@jessy-david.dev
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Site web :</strong>{" "}
|
||||||
|
<a
|
||||||
|
href="https://jessy-david.dev"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
https://jessy-david.dev
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Hébergeur */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className="p-2 bg-purple-500/20 rounded-lg">
|
||||||
|
<FileText className="w-5 h-5 text-purple-400" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-bold text-white">2. Hébergeur</h2>
|
||||||
|
</div>
|
||||||
|
<div className="text-slate-300 space-y-2">
|
||||||
|
<p>
|
||||||
|
<strong>Nom :</strong> QuantumCraft Studios
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Adresse :</strong> 58 RUE DE MONCEAU 75008 PARIS, FRANCE
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Site web :</strong>{" "}
|
||||||
|
<a
|
||||||
|
href="https://quantumcraft-studios.com"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
https://quantumcraft-studios.com
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Propriété intellectuelle */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
3. Propriété intellectuelle
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
L'ensemble du contenu de ce site (textes, images, vidéos,
|
||||||
|
logos, graphismes, etc.) est la propriété exclusive de Jessy
|
||||||
|
DAVID, sauf mention contraire. Toute reproduction,
|
||||||
|
représentation, modification, publication, adaptation de tout ou
|
||||||
|
partie des éléments du site, quel que soit le moyen ou le
|
||||||
|
procédé utilisé, est interdite sans l'autorisation écrite
|
||||||
|
préalable de Jessy DAVID.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Toute exploitation non autorisée du site ou de l'un
|
||||||
|
quelconque des éléments qu'il contient sera considérée
|
||||||
|
comme constitutive d'une contrefaçon et poursuivie
|
||||||
|
conformément aux dispositions des articles L.335-2 et suivants
|
||||||
|
du Code de Propriété Intellectuelle.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Limitation de responsabilité */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
4. Limitation de responsabilité
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Jessy DAVID s'efforce d'assurer au mieux de ses
|
||||||
|
possibilités l'exactitude et la mise à jour des
|
||||||
|
informations diffusées sur ce site, dont il se réserve le droit
|
||||||
|
de corriger, à tout moment et sans préavis, le contenu.
|
||||||
|
Toutefois, Jessy DAVID ne peut garantir l'exactitude, la
|
||||||
|
précision ou l'exhaustivité des informations mises à
|
||||||
|
disposition sur ce site.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
En conséquence, Jessy DAVID décline toute responsabilité pour
|
||||||
|
toute imprécision, inexactitude ou omission portant sur des
|
||||||
|
informations disponibles sur ce site.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Liens hypertextes */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
5. Liens hypertextes
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Le site jessy-david.dev peut contenir des liens hypertextes vers
|
||||||
|
d'autres sites. Jessy DAVID n'exerce aucun contrôle
|
||||||
|
sur ces sites et décline toute responsabilité quant à leur
|
||||||
|
contenu. La décision d'activer les liens appartient
|
||||||
|
exclusivement aux visiteurs du site.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Protection des données */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
6. Protection des données personnelles
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Conformément au Règlement Général sur la Protection des Données
|
||||||
|
(RGPD) et à la loi n° 78-17 du 6 janvier 1978 modifiée (loi
|
||||||
|
Informatique et Libertés), vous disposez d'un droit
|
||||||
|
d'accès, de rectification, de suppression et
|
||||||
|
d'opposition aux données personnelles vous concernant.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Pour plus d'informations sur la collecte et le traitement
|
||||||
|
de vos données, veuillez consulter la{" "}
|
||||||
|
<Link
|
||||||
|
href="/politique-de-confidentialite"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
Politique de Confidentialité
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Pour exercer vos droits, vous pouvez me contacter à
|
||||||
|
l'adresse suivante :{" "}
|
||||||
|
<a
|
||||||
|
href="mailto:contact@jessy-david.dev"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
contact@jessy-david.dev
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Cookies */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">7. Cookies</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Ce site utilise des cookies pour améliorer l'expérience
|
||||||
|
utilisateur. Pour plus d'informations sur
|
||||||
|
l'utilisation des cookies, veuillez consulter la{" "}
|
||||||
|
<Link
|
||||||
|
href="/politique-de-confidentialite"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
Politique de Confidentialité
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Loi applicable */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
8. Droit applicable et juridiction
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Les présentes mentions légales sont régies par le droit
|
||||||
|
français. En cas de litige, les tribunaux français seront seuls
|
||||||
|
compétents.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Date de mise à jour */}
|
||||||
|
<div className="text-center text-slate-500 text-sm pt-8">
|
||||||
|
Dernière mise à jour : Janvier 2026
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,470 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
import {
|
||||||
|
ArrowLeft,
|
||||||
|
Cookie,
|
||||||
|
Database,
|
||||||
|
Eye,
|
||||||
|
Lock,
|
||||||
|
Mail,
|
||||||
|
Shield,
|
||||||
|
UserCheck,
|
||||||
|
} from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export default function PolitiqueDeConfidentialite() {
|
||||||
|
return (
|
||||||
|
<section className="min-h-screen py-20 bg-slate-900 relative overflow-hidden">
|
||||||
|
{/* Grid Background */}
|
||||||
|
<div
|
||||||
|
className="absolute inset-0 opacity-20"
|
||||||
|
style={{
|
||||||
|
backgroundImage:
|
||||||
|
"linear-gradient(to right, #1e293b 1px, transparent 1px), linear-gradient(to bottom, #1e293b 1px, transparent 1px)",
|
||||||
|
backgroundSize: "60px 60px",
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
|
||||||
|
{/* Decorative blobs */}
|
||||||
|
<div className="absolute top-20 left-10 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl"></div>
|
||||||
|
<div className="absolute bottom-20 right-10 w-96 h-96 bg-purple-500/10 rounded-full blur-3xl"></div>
|
||||||
|
|
||||||
|
<div className="container mx-auto px-4 max-w-4xl relative z-10">
|
||||||
|
{/* Back button */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, x: -20 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className="mb-8"
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
href="/"
|
||||||
|
className="inline-flex items-center gap-2 text-slate-400 hover:text-white transition-colors group"
|
||||||
|
>
|
||||||
|
<ArrowLeft className="w-5 h-5 group-hover:-translate-x-1 transition-transform" />
|
||||||
|
Retour à l'accueil
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.6 }}
|
||||||
|
className="text-center mb-12"
|
||||||
|
>
|
||||||
|
<div className="inline-flex items-center gap-2 bg-linear-to-r from-blue-500/10 to-purple-500/10 rounded-full px-4 py-2 mb-4">
|
||||||
|
<Shield className="w-4 h-4 text-blue-400" />
|
||||||
|
<span className="text-sm font-semibold text-slate-300">
|
||||||
|
Protection de vos données
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">
|
||||||
|
Politique de Confidentialité
|
||||||
|
</h1>
|
||||||
|
<p className="text-xl text-slate-400">
|
||||||
|
Conformément au RGPD et à la loi n° 78-17 du 6 janvier 1978 modifiée
|
||||||
|
</p>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.6, delay: 0.2 }}
|
||||||
|
className="space-y-8"
|
||||||
|
>
|
||||||
|
{/* Introduction */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className="p-2 bg-blue-500/20 rounded-lg">
|
||||||
|
<Lock className="w-5 h-5 text-blue-400" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-bold text-white">1. Introduction</h2>
|
||||||
|
</div>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
La présente politique de confidentialité a pour but
|
||||||
|
d'informer les utilisateurs du site jessy-david.dev de la
|
||||||
|
manière dont leurs données personnelles sont collectées,
|
||||||
|
traitées et protégées, conformément au Règlement Général sur la
|
||||||
|
Protection des Données (RGPD - Règlement UE 2016/679) et à la
|
||||||
|
loi n° 78-17 du 6 janvier 1978 relative à l'informatique,
|
||||||
|
aux fichiers et aux libertés, modifiée par la loi n° 2004-801 du
|
||||||
|
6 août 2004.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Responsable du traitement :</strong> Jessy DAVID
|
||||||
|
<br />
|
||||||
|
<strong>Email :</strong>{" "}
|
||||||
|
<a
|
||||||
|
href="mailto:contact@jessy-david.dev"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
contact@jessy-david.dev
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Données collectées */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className="p-2 bg-purple-500/20 rounded-lg">
|
||||||
|
<Database className="w-5 h-5 text-purple-400" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-bold text-white">
|
||||||
|
2. Données personnelles collectées
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Je collecte les données personnelles suivantes dans le cadre de
|
||||||
|
l'utilisation de ce site :
|
||||||
|
</p>
|
||||||
|
<div className="bg-slate-900/50 rounded-xl p-4">
|
||||||
|
<h3 className="font-semibold text-white mb-3">
|
||||||
|
Via le formulaire de contact :
|
||||||
|
</h3>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>
|
||||||
|
<strong>Nom et prénom</strong> - pour vous identifier
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Adresse email</strong> - pour vous répondre
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Message</strong> - pour comprendre votre demande
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="bg-slate-900/50 rounded-xl p-4">
|
||||||
|
<h3 className="font-semibold text-white mb-3">
|
||||||
|
Données techniques automatiquement collectées :
|
||||||
|
</h3>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>Adresse IP (anonymisée)</li>
|
||||||
|
<li>Type de navigateur et système d'exploitation</li>
|
||||||
|
<li>Pages visitées et durée de visite</li>
|
||||||
|
<li>
|
||||||
|
Source de trafic (moteur de recherche, lien direct, etc.)
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Finalités */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className="p-2 bg-green-500/20 rounded-lg">
|
||||||
|
<Eye className="w-5 h-5 text-green-400" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-bold text-white">
|
||||||
|
3. Finalités du traitement
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Les données personnelles sont collectées pour les finalités
|
||||||
|
suivantes :
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>
|
||||||
|
<strong>Répondre à vos demandes de contact</strong> - Base
|
||||||
|
légale : consentement
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Améliorer l'expérience utilisateur</strong> -
|
||||||
|
Base légale : intérêt légitime
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Analyser les statistiques de fréquentation</strong> -
|
||||||
|
Base légale : consentement (cookies)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Assurer la sécurité du site</strong> (protection
|
||||||
|
anti-spam via Cloudflare Turnstile) - Base légale : intérêt
|
||||||
|
légitime
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Durée de conservation */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
4. Durée de conservation des données
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Vos données personnelles sont conservées pour une durée limitée
|
||||||
|
:
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>
|
||||||
|
<strong>Données du formulaire de contact :</strong> 3 ans à
|
||||||
|
compter du dernier contact
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Cookies analytiques :</strong> 13 mois maximum
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Logs de sécurité :</strong> 12 mois
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
À l'expiration de ces délais, vos données sont supprimées
|
||||||
|
ou anonymisées.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Destinataires */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
5. Destinataires des données
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Vos données personnelles sont strictement confidentielles et ne
|
||||||
|
sont communiquées qu'aux destinataires suivants :
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>
|
||||||
|
<strong>Jessy DAVID</strong> - Responsable du traitement
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Hébergeur (QuantumCraft Studios)</strong> - pour le
|
||||||
|
stockage technique
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Cloudflare</strong> - pour la protection anti-spam
|
||||||
|
(Turnstile)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Fournisseur d'emails</strong> - pour l'envoi
|
||||||
|
des messages de contact
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Je ne vends, ne loue, ni ne partage vos données personnelles
|
||||||
|
avec des tiers à des fins commerciales.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Transferts hors UE */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
6. Transferts de données hors UE
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Certains de mes prestataires (hébergeur, Cloudflare) peuvent
|
||||||
|
être situés en dehors de l'Union Européenne. Dans ce cas,
|
||||||
|
je m'assure que ces transferts sont encadrés par des
|
||||||
|
garanties appropriées conformément au RGPD (Clauses
|
||||||
|
Contractuelles Types, Data Privacy Framework, etc.).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Cookies */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className="p-2 bg-orange-500/20 rounded-lg">
|
||||||
|
<Cookie className="w-5 h-5 text-orange-400" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-bold text-white">
|
||||||
|
7. Cookies et traceurs
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Ce site utilise des cookies pour assurer son bon fonctionnement
|
||||||
|
et améliorer votre expérience de navigation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="bg-slate-900/50 rounded-xl p-4">
|
||||||
|
<h3 className="font-semibold text-white mb-3">
|
||||||
|
Cookies strictement nécessaires (exemptés de consentement) :
|
||||||
|
</h3>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>
|
||||||
|
<strong>Session</strong> - Maintien de la session de
|
||||||
|
navigation
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Sécurité (Cloudflare Turnstile)</strong> -
|
||||||
|
Protection anti-spam
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Préférences cookies</strong> - Mémorisation de vos
|
||||||
|
choix
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-slate-900/50 rounded-xl p-4">
|
||||||
|
<h3 className="font-semibold text-white mb-3">
|
||||||
|
Cookies analytiques (soumis à consentement) :
|
||||||
|
</h3>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>
|
||||||
|
<strong>Google Analytics</strong> - Analyse du trafic et
|
||||||
|
comportement des visiteurs
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Vous pouvez à tout moment modifier vos préférences en matière de
|
||||||
|
cookies via la bannière de gestion des cookies accessible depuis
|
||||||
|
le bas de page.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Droits des utilisateurs */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className="p-2 bg-cyan-500/20 rounded-lg">
|
||||||
|
<UserCheck className="w-5 h-5 text-cyan-400" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-bold text-white">8. Vos droits</h2>
|
||||||
|
</div>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Conformément au RGPD et à la loi Informatique et Libertés, vous
|
||||||
|
disposez des droits suivants sur vos données personnelles :
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>
|
||||||
|
<strong>Droit d'accès</strong> - Obtenir une copie de vos
|
||||||
|
données
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Droit de rectification</strong> - Corriger des données
|
||||||
|
inexactes
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Droit à l'effacement</strong> - Demander la
|
||||||
|
suppression de vos données
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Droit à la limitation</strong> - Limiter le traitement
|
||||||
|
de vos données
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Droit d'opposition</strong> - Vous opposer au
|
||||||
|
traitement
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Droit à la portabilité</strong> - Recevoir vos données
|
||||||
|
dans un format structuré
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Droit de retirer votre consentement</strong> - À tout
|
||||||
|
moment
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div className="bg-blue-500/10 border border-blue-500/20 rounded-xl p-4 mt-4">
|
||||||
|
<p className="flex items-start gap-2">
|
||||||
|
<Mail className="w-5 h-5 text-blue-400 mt-0.5 shrink-0" />
|
||||||
|
<span>
|
||||||
|
Pour exercer vos droits, contactez-moi à :{" "}
|
||||||
|
<a
|
||||||
|
href="mailto:contact@jessy-david.dev"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
contact@jessy-david.dev
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
Je répondrai à votre demande dans un délai maximum de 30
|
||||||
|
jours.
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Réclamation CNIL */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
9. Réclamation auprès de la CNIL
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Si vous estimez que le traitement de vos données personnelles
|
||||||
|
constitue une violation de vos droits, vous pouvez introduire
|
||||||
|
une réclamation auprès de la Commission Nationale de
|
||||||
|
l'Informatique et des Libertés (CNIL) :
|
||||||
|
</p>
|
||||||
|
<div className="bg-slate-900/50 rounded-xl p-4">
|
||||||
|
<p>
|
||||||
|
<strong>CNIL</strong>
|
||||||
|
</p>
|
||||||
|
<p>3 Place de Fontenoy - TSA 80715</p>
|
||||||
|
<p>75334 PARIS CEDEX 07</p>
|
||||||
|
<p>
|
||||||
|
Site web :{" "}
|
||||||
|
<a
|
||||||
|
href="https://www.cnil.fr"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||||
|
>
|
||||||
|
www.cnil.fr
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Sécurité */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
10. Sécurité des données
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Je mets en œuvre toutes les mesures techniques et
|
||||||
|
organisationnelles appropriées pour garantir un niveau de
|
||||||
|
sécurité adapté au risque :
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-slate-400">
|
||||||
|
<li>Chiffrement SSL/TLS des communications</li>
|
||||||
|
<li>Protection contre les attaques (Cloudflare)</li>
|
||||||
|
<li>Accès restreint aux données personnelles</li>
|
||||||
|
<li>Mises à jour régulières de sécurité</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Modifications */}
|
||||||
|
<div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-6">
|
||||||
|
<h2 className="text-xl font-bold text-white mb-4">
|
||||||
|
11. Modifications de la politique
|
||||||
|
</h2>
|
||||||
|
<div className="text-slate-300 space-y-4">
|
||||||
|
<p>
|
||||||
|
Je me réserve le droit de modifier cette politique de
|
||||||
|
confidentialité à tout moment. En cas de modification
|
||||||
|
substantielle, je vous en informerai par une notification
|
||||||
|
visible sur ce site. La date de dernière mise à jour sera
|
||||||
|
toujours indiquée en bas de cette page.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Date de mise à jour */}
|
||||||
|
<div className="text-center text-slate-500 text-sm pt-8">
|
||||||
|
Dernière mise à jour : Janvier 2026
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,7 +2,15 @@
|
|||||||
|
|
||||||
import { siteConfig } from "@/config/site";
|
import { siteConfig } from "@/config/site";
|
||||||
import { motion, type Variants } from "framer-motion";
|
import { motion, type Variants } from "framer-motion";
|
||||||
import { Github, Heart, Linkedin, Mail } from "lucide-react";
|
import {
|
||||||
|
Cookie,
|
||||||
|
Github,
|
||||||
|
Heart,
|
||||||
|
Linkedin,
|
||||||
|
Mail,
|
||||||
|
Scale,
|
||||||
|
Shield,
|
||||||
|
} from "lucide-react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
@@ -16,6 +24,19 @@ const socials = [
|
|||||||
{ name: "Email", href: "mailto:contact@jessy-david.dev", icon: Mail },
|
{ name: "Email", href: "mailto:contact@jessy-david.dev", icon: Mail },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const legalLinks = [
|
||||||
|
{
|
||||||
|
name: "Mentions légales",
|
||||||
|
href: "/mentions-legales",
|
||||||
|
icon: Scale,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Politique de confidentialité",
|
||||||
|
href: "/politique-de-confidentialite",
|
||||||
|
icon: Shield,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const containerVariants: Variants = {
|
const containerVariants: Variants = {
|
||||||
hidden: { opacity: 0 },
|
hidden: { opacity: 0 },
|
||||||
visible: {
|
visible: {
|
||||||
@@ -112,6 +133,32 @@ export default function Footer() {
|
|||||||
QuantumCraft Studios
|
QuantumCraft Studios
|
||||||
</Link>
|
</Link>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Liens légaux */}
|
||||||
|
<motion.div
|
||||||
|
variants={itemVariants}
|
||||||
|
className="flex flex-wrap items-center justify-center gap-4"
|
||||||
|
>
|
||||||
|
{legalLinks.map((item) => (
|
||||||
|
<Link
|
||||||
|
key={item.name}
|
||||||
|
href={item.href}
|
||||||
|
className="flex items-center gap-1.5 text-slate-500 hover:text-blue-400 text-sm transition-colors"
|
||||||
|
>
|
||||||
|
<item.icon className="w-3.5 h-3.5" />
|
||||||
|
{item.name}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
window.dispatchEvent(new Event("openCookieSettings"))
|
||||||
|
}
|
||||||
|
className="flex items-center gap-1.5 text-slate-500 hover:text-blue-400 text-sm transition-colors cursor-pointer"
|
||||||
|
>
|
||||||
|
<Cookie className="w-3.5 h-3.5" />
|
||||||
|
Gérer les cookies
|
||||||
|
</button>
|
||||||
|
</motion.div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Copyright */}
|
{/* Copyright */}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ interface NavLink {
|
|||||||
|
|
||||||
// Configuration des liens de navigation avec leurs icônes
|
// Configuration des liens de navigation avec leurs icônes
|
||||||
const navLinks: NavLink[] = [
|
const navLinks: NavLink[] = [
|
||||||
{ href: "#home", label: "Accueil", icon: Home },
|
{ href: "/", label: "Accueil", icon: Home },
|
||||||
{ href: "#about", label: "À propos", icon: User },
|
{ href: "#about", label: "À propos", icon: User },
|
||||||
{ href: "#skills", label: "Compétences", icon: Code2 },
|
{ href: "#skills", label: "Compétences", icon: Code2 },
|
||||||
{ href: "#projects", label: "Projets", icon: FolderKanban },
|
{ href: "#projects", label: "Projets", icon: FolderKanban },
|
||||||
@@ -90,7 +90,7 @@ export default function NavBar() {
|
|||||||
<div className="flex items-center justify-between h-16">
|
<div className="flex items-center justify-between h-16">
|
||||||
{/* Logo et nom - lien vers l'accueil */}
|
{/* Logo et nom - lien vers l'accueil */}
|
||||||
<SmoothLink
|
<SmoothLink
|
||||||
href="#home"
|
href="/"
|
||||||
className="relative group flex items-center gap-3"
|
className="relative group flex items-center gap-3"
|
||||||
onClick={handleLinkClick}
|
onClick={handleLinkClick}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -291,6 +291,35 @@ export default function Contact() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Consentement RGPD */}
|
||||||
|
<div className="flex items-start gap-3">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="rgpd-consent"
|
||||||
|
name="rgpd-consent"
|
||||||
|
required
|
||||||
|
disabled={isSubmitting}
|
||||||
|
className="mt-1 w-4 h-4 rounded border-slate-600 bg-slate-900/50 text-blue-500 focus:ring-blue-500 focus:ring-offset-0 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="rgpd-consent"
|
||||||
|
className="text-sm text-slate-400 cursor-pointer"
|
||||||
|
>
|
||||||
|
J'accepte que mes données personnelles (nom, email,
|
||||||
|
message) soient collectées et traitées pour répondre à ma
|
||||||
|
demande, conformément à la{" "}
|
||||||
|
<a
|
||||||
|
href="/politique-de-confidentialite"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-blue-400 hover:text-blue-300 underline transition-colors"
|
||||||
|
>
|
||||||
|
Politique de Confidentialité
|
||||||
|
</a>
|
||||||
|
. *
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Message d'erreur */}
|
{/* Message d'erreur */}
|
||||||
{error && (
|
{error && (
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
|
import { Cookie, X, Check, Settings } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
type CookiePreferences = {
|
||||||
|
necessary: boolean;
|
||||||
|
analytics: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const COOKIE_CONSENT_KEY = "cookie-consent";
|
||||||
|
const COOKIE_PREFERENCES_KEY = "cookie-preferences";
|
||||||
|
|
||||||
|
function getInitialPreferences(): CookiePreferences {
|
||||||
|
if (typeof window === "undefined") {
|
||||||
|
return { necessary: true, analytics: false };
|
||||||
|
}
|
||||||
|
const savedPreferences = localStorage.getItem(COOKIE_PREFERENCES_KEY);
|
||||||
|
if (savedPreferences) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(savedPreferences);
|
||||||
|
} catch {
|
||||||
|
return { necessary: true, analytics: false };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { necessary: true, analytics: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CookieBanner() {
|
||||||
|
const [showBanner, setShowBanner] = useState(false);
|
||||||
|
const [showSettings, setShowSettings] = useState(false);
|
||||||
|
const [preferences, setPreferences] = useState<CookiePreferences>(
|
||||||
|
getInitialPreferences,
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Vérifier si l'utilisateur a déjà donné son consentement
|
||||||
|
const consent = localStorage.getItem(COOKIE_CONSENT_KEY);
|
||||||
|
if (!consent) {
|
||||||
|
// Délai pour ne pas afficher immédiatement au chargement
|
||||||
|
const timer = setTimeout(() => setShowBanner(true), 1000);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
} else {
|
||||||
|
// Appliquer les préférences sauvegardées au chargement
|
||||||
|
const savedPreferences = localStorage.getItem(COOKIE_PREFERENCES_KEY);
|
||||||
|
if (savedPreferences) {
|
||||||
|
try {
|
||||||
|
const prefs = JSON.parse(savedPreferences);
|
||||||
|
if (prefs.analytics) {
|
||||||
|
// @ts-expect-error - gtag n'est pas typé
|
||||||
|
window.gtag?.("consent", "update", {
|
||||||
|
analytics_storage: "granted",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignorer les erreurs de parsing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleAcceptAll = () => {
|
||||||
|
const newPreferences = { necessary: true, analytics: true };
|
||||||
|
saveConsent(newPreferences);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRejectAll = () => {
|
||||||
|
const newPreferences = { necessary: true, analytics: false };
|
||||||
|
saveConsent(newPreferences);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSavePreferences = () => {
|
||||||
|
saveConsent(preferences);
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveConsent = (prefs: CookiePreferences) => {
|
||||||
|
localStorage.setItem(COOKIE_CONSENT_KEY, "true");
|
||||||
|
localStorage.setItem(COOKIE_PREFERENCES_KEY, JSON.stringify(prefs));
|
||||||
|
setPreferences(prefs);
|
||||||
|
setShowBanner(false);
|
||||||
|
setShowSettings(false);
|
||||||
|
|
||||||
|
// Activer/désactiver Google Analytics selon le consentement
|
||||||
|
if (prefs.analytics) {
|
||||||
|
enableAnalytics();
|
||||||
|
} else {
|
||||||
|
disableAnalytics();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const enableAnalytics = () => {
|
||||||
|
// Active Google Analytics via GTM Consent Mode
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
// @ts-expect-error - gtag n'est pas typé
|
||||||
|
window.gtag?.("consent", "update", {
|
||||||
|
analytics_storage: "granted",
|
||||||
|
});
|
||||||
|
// Envoyer un événement pour GTM
|
||||||
|
// @ts-expect-error - dataLayer n'est pas typé
|
||||||
|
window.dataLayer?.push({ event: "cookie_consent_analytics" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const disableAnalytics = () => {
|
||||||
|
// Désactive Google Analytics via GTM Consent Mode
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
// @ts-expect-error - gtag n'est pas typé
|
||||||
|
window.gtag?.("consent", "update", {
|
||||||
|
analytics_storage: "denied",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fonction pour rouvrir la bannière (appelable depuis le footer)
|
||||||
|
useEffect(() => {
|
||||||
|
const handleOpenCookieSettings = () => {
|
||||||
|
setShowBanner(true);
|
||||||
|
setShowSettings(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("openCookieSettings", handleOpenCookieSettings);
|
||||||
|
return () =>
|
||||||
|
window.removeEventListener(
|
||||||
|
"openCookieSettings",
|
||||||
|
handleOpenCookieSettings,
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnimatePresence>
|
||||||
|
{showBanner && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ y: 100, opacity: 0 }}
|
||||||
|
animate={{ y: 0, opacity: 1 }}
|
||||||
|
exit={{ y: 100, opacity: 0 }}
|
||||||
|
transition={{ type: "spring", damping: 25, stiffness: 200 }}
|
||||||
|
className="fixed bottom-0 left-0 right-0 z-50 p-4 md:p-6"
|
||||||
|
>
|
||||||
|
<div className="container mx-auto max-w-4xl">
|
||||||
|
<div className="bg-slate-800/95 backdrop-blur-xl border border-slate-700 rounded-2xl shadow-2xl shadow-black/20 overflow-hidden">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="flex items-center justify-between p-4 md:p-6 border-b border-slate-700">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="p-2 bg-blue-500/20 rounded-lg">
|
||||||
|
<Cookie className="w-5 h-5 text-blue-400" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-lg font-bold text-white">
|
||||||
|
Gestion des cookies
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowBanner(false)}
|
||||||
|
className="p-2 text-slate-400 hover:text-white transition-colors rounded-lg hover:bg-slate-700"
|
||||||
|
aria-label="Fermer"
|
||||||
|
>
|
||||||
|
<X className="w-5 h-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<div className="p-4 md:p-6">
|
||||||
|
{!showSettings ? (
|
||||||
|
<>
|
||||||
|
<p className="text-slate-300 mb-6">
|
||||||
|
Ce site utilise des cookies pour améliorer votre
|
||||||
|
expérience. Les cookies nécessaires sont essentiels au bon
|
||||||
|
fonctionnement du site. Vous pouvez choisir
|
||||||
|
d'accepter ou de refuser les cookies analytiques.{" "}
|
||||||
|
<Link
|
||||||
|
href="/politique-de-confidentialite"
|
||||||
|
className="text-blue-400 hover:text-blue-300 transition-colors underline"
|
||||||
|
>
|
||||||
|
En savoir plus
|
||||||
|
</Link>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Boutons */}
|
||||||
|
<div className="flex flex-col sm:flex-row gap-3">
|
||||||
|
<button
|
||||||
|
onClick={handleRejectAll}
|
||||||
|
className="flex-1 px-6 py-3 bg-slate-700 hover:bg-slate-600 text-white font-semibold rounded-xl transition-colors"
|
||||||
|
>
|
||||||
|
Refuser tout
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowSettings(true)}
|
||||||
|
className="flex-1 px-6 py-3 bg-slate-700 hover:bg-slate-600 text-white font-semibold rounded-xl transition-colors flex items-center justify-center gap-2"
|
||||||
|
>
|
||||||
|
<Settings className="w-4 h-4" />
|
||||||
|
Personnaliser
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleAcceptAll}
|
||||||
|
className="flex-1 px-6 py-3 bg-linear-to-r from-blue-600 to-purple-600 hover:from-blue-500 hover:to-purple-500 text-white font-semibold rounded-xl transition-all"
|
||||||
|
>
|
||||||
|
Accepter tout
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<p className="text-slate-300 mb-6">
|
||||||
|
Personnalisez vos préférences de cookies ci-dessous.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Options de cookies */}
|
||||||
|
<div className="space-y-4 mb-6">
|
||||||
|
{/* Cookies nécessaires */}
|
||||||
|
<div className="flex items-center justify-between p-4 bg-slate-900/50 rounded-xl">
|
||||||
|
<div className="flex-1">
|
||||||
|
<h4 className="font-semibold text-white mb-1">
|
||||||
|
Cookies nécessaires
|
||||||
|
</h4>
|
||||||
|
<p className="text-sm text-slate-400">
|
||||||
|
Essentiels au fonctionnement du site (session,
|
||||||
|
sécurité, préférences).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="ml-4">
|
||||||
|
<div className="w-12 h-6 bg-blue-600 rounded-full flex items-center justify-end px-1 cursor-not-allowed">
|
||||||
|
<div className="w-4 h-4 bg-white rounded-full flex items-center justify-center">
|
||||||
|
<Check className="w-3 h-3 text-blue-600" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Cookies analytiques */}
|
||||||
|
<div className="flex items-center justify-between p-4 bg-slate-900/50 rounded-xl">
|
||||||
|
<div className="flex-1">
|
||||||
|
<h4 className="font-semibold text-white mb-1">
|
||||||
|
Cookies analytiques
|
||||||
|
</h4>
|
||||||
|
<p className="text-sm text-slate-400">
|
||||||
|
Google Analytics pour comprendre comment vous
|
||||||
|
utilisez ce site.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="ml-4">
|
||||||
|
<button
|
||||||
|
onClick={() =>
|
||||||
|
setPreferences((prev) => ({
|
||||||
|
...prev,
|
||||||
|
analytics: !prev.analytics,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
className={`w-12 h-6 rounded-full flex items-center px-1 transition-colors ${
|
||||||
|
preferences.analytics
|
||||||
|
? "bg-blue-600 justify-end"
|
||||||
|
: "bg-slate-600 justify-start"
|
||||||
|
}`}
|
||||||
|
aria-label={
|
||||||
|
preferences.analytics
|
||||||
|
? "Désactiver les cookies analytiques"
|
||||||
|
: "Activer les cookies analytiques"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="w-4 h-4 bg-white rounded-full flex items-center justify-center">
|
||||||
|
{preferences.analytics && (
|
||||||
|
<Check className="w-3 h-3 text-blue-600" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Boutons */}
|
||||||
|
<div className="flex flex-col sm:flex-row gap-3">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowSettings(false)}
|
||||||
|
className="flex-1 px-6 py-3 bg-slate-700 hover:bg-slate-600 text-white font-semibold rounded-xl transition-colors"
|
||||||
|
>
|
||||||
|
Retour
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleSavePreferences}
|
||||||
|
className="flex-1 px-6 py-3 bg-linear-to-r from-blue-600 to-purple-600 hover:from-blue-500 hover:to-purple-500 text-white font-semibold rounded-xl transition-all"
|
||||||
|
>
|
||||||
|
Sauvegarder mes choix
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user