feat: fix accents, improve candidature API, add legal pages
- Fix all missing French accents across 16 files (é, è, ê, à, ô, ç) - Improve candidature API error handling: check env vars, better messages - Add Mentions légales page (/mentions-legales) - Add CGV page (/cgv) - Add Politique de confidentialité page (/confidentialite) - Business info: Enguerrand Ozano, SIREN 994538932, TVA FR16994538932 https://claude.ai/code/session_01H2aRGDaKgarPvhay2HxN6Y
This commit is contained in:
@@ -55,7 +55,7 @@ export default async function DashboardPage() {
|
||||
Bonjour {profile?.full_name?.split(" ")[0] || "!"} 👋
|
||||
</h1>
|
||||
<p className="text-white/60">
|
||||
Voici un apercu de ta progression dans le programme.
|
||||
Voici un aperçu de ta progression dans le programme.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -69,7 +69,7 @@ export default async function DashboardPage() {
|
||||
<ProgressBar value={progressPercent} showPercentage={false} />
|
||||
</Card>
|
||||
<Card>
|
||||
<p className="text-white/40 text-sm mb-1">Modules completes</p>
|
||||
<p className="text-white/40 text-sm mb-1">Modules complétés</p>
|
||||
<p className="text-2xl font-bold text-white">
|
||||
{completedModules}
|
||||
<span className="text-white/30 text-lg font-normal">
|
||||
@@ -122,11 +122,11 @@ export default async function DashboardPage() {
|
||||
<Card className="text-center py-12">
|
||||
<div className="text-4xl mb-4">🚀</div>
|
||||
<h3 className="text-white font-semibold text-lg mb-2">
|
||||
Le programme arrive bientot !
|
||||
Le programme arrive bientôt !
|
||||
</h3>
|
||||
<p className="text-white/40 text-sm max-w-md mx-auto">
|
||||
Les modules de formation sont en cours de preparation. Tu seras
|
||||
notifie des qu'ils seront disponibles.
|
||||
Les modules de formation sont en cours de préparation. Tu seras
|
||||
notifié dès qu'ils seront disponibles.
|
||||
</p>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
@@ -86,7 +86,7 @@ export default async function ModulePage({ params }: ModulePageProps) {
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
Complete
|
||||
Complété
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -133,7 +133,7 @@ export default async function ModulePage({ params }: ModulePageProps) {
|
||||
d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||
/>
|
||||
</svg>
|
||||
Telecharger le PDF
|
||||
Télécharger le PDF
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
@@ -144,7 +144,7 @@ export default async function ModulePage({ params }: ModulePageProps) {
|
||||
<div className="text-center">
|
||||
<div className="text-4xl mb-3">🎬</div>
|
||||
<p className="text-white/40 text-sm">
|
||||
Le contenu sera bientot disponible
|
||||
Le contenu sera bientôt disponible
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -53,7 +53,7 @@ export default async function FormationsPage() {
|
||||
</p>
|
||||
<ProgressBar
|
||||
value={progressPercent}
|
||||
label={`${completedModules} modules completes sur ${totalModules}`}
|
||||
label={`${completedModules} modules complétés sur ${totalModules}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -72,7 +72,7 @@ export default async function FormationsPage() {
|
||||
Semaine {week}
|
||||
</h2>
|
||||
<span className="text-white/30 text-sm">
|
||||
{weekCompleted}/{weekTotal} completes
|
||||
{weekCompleted}/{weekTotal} complétés
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
@@ -101,7 +101,7 @@ export default async function FormationsPage() {
|
||||
Aucun module disponible
|
||||
</h3>
|
||||
<p className="text-white/40 text-sm">
|
||||
Les modules de formation seront bientot disponibles.
|
||||
Les modules de formation seront bientôt disponibles.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -42,14 +42,26 @@ export async function POST(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// Validation age
|
||||
// Validation âge
|
||||
if (body.age < 18 || body.age > 65) {
|
||||
return NextResponse.json(
|
||||
{ error: "L'age doit etre entre 18 et 65 ans." },
|
||||
{ error: "L'âge doit être entre 18 et 65 ans." },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Vérifier que les variables d'environnement Supabase sont configurées
|
||||
if (!process.env.NEXT_PUBLIC_SUPABASE_URL || !process.env.SUPABASE_SERVICE_ROLE_KEY) {
|
||||
console.error("Variables Supabase manquantes:", {
|
||||
url: !!process.env.NEXT_PUBLIC_SUPABASE_URL,
|
||||
serviceRole: !!process.env.SUPABASE_SERVICE_ROLE_KEY,
|
||||
});
|
||||
return NextResponse.json(
|
||||
{ error: "Configuration serveur incomplète. Contactez l'administrateur." },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
const supabase = createAdminClient();
|
||||
|
||||
// Vérifier si une candidature existe déjà avec cet email
|
||||
@@ -61,7 +73,7 @@ export async function POST(request: Request) {
|
||||
|
||||
if (existing) {
|
||||
return NextResponse.json(
|
||||
{ error: "Une candidature avec cet email existe deja." },
|
||||
{ error: "Une candidature avec cet email existe déjà." },
|
||||
{ status: 409 }
|
||||
);
|
||||
}
|
||||
@@ -90,7 +102,7 @@ export async function POST(request: Request) {
|
||||
if (insertError) {
|
||||
console.error("Erreur insertion candidature:", insertError);
|
||||
return NextResponse.json(
|
||||
{ error: "Erreur lors de l'enregistrement de la candidature." },
|
||||
{ error: "Erreur lors de l'enregistrement. Vérifiez que la base de données est configurée." },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
@@ -104,30 +116,30 @@ export async function POST(request: Request) {
|
||||
await resend.emails.send({
|
||||
from: "HookLab <noreply@hooklab.fr>",
|
||||
to: body.email,
|
||||
subject: "Candidature HookLab recue !",
|
||||
subject: "Candidature HookLab reçue !",
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<h1 style="color: #6D5EF6;">Candidature recue !</h1>
|
||||
<h1 style="color: #6D5EF6;">Candidature reçue !</h1>
|
||||
<p>Salut ${body.firstname},</p>
|
||||
<p>Merci pour ta candidature au programme HookLab !</p>
|
||||
<p>Notre equipe va etudier ton profil et te repondre sous <strong>24 heures</strong>.</p>
|
||||
<p>A tres vite,<br/>L'equipe HookLab</p>
|
||||
<p>Notre équipe va étudier ton profil et te répondre sous <strong>24 heures</strong>.</p>
|
||||
<p>À très vite,<br/>L'équipe HookLab</p>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
} catch (emailError) {
|
||||
// Log l'erreur mais ne bloque pas la candidature
|
||||
console.error("Erreur envoi email:", emailError);
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{ message: "Candidature enregistree avec succes." },
|
||||
{ message: "Candidature enregistrée avec succès." },
|
||||
{ status: 201 }
|
||||
);
|
||||
} catch {
|
||||
} catch (err) {
|
||||
console.error("Erreur serveur candidature:", err);
|
||||
return NextResponse.json(
|
||||
{ error: "Erreur serveur. Veuillez reessayer." },
|
||||
{ error: "Erreur serveur. Veuillez réessayer." },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -128,18 +128,18 @@ export async function POST(request: Request) {
|
||||
await resend.emails.send({
|
||||
from: "HookLab <noreply@hooklab.fr>",
|
||||
to: email,
|
||||
subject: "Bienvenue dans HookLab ! Tes acces sont prets",
|
||||
subject: "Bienvenue dans HookLab ! Tes accès sont prêts",
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<h1 style="color: #6D5EF6;">Bienvenue dans HookLab !</h1>
|
||||
<p>Ton paiement a ete confirme. Voici tes acces :</p>
|
||||
<p>Ton paiement a été confirmé. Voici tes accès :</p>
|
||||
<div style="background: #1A1F2E; padding: 20px; border-radius: 12px; margin: 20px 0;">
|
||||
<p style="color: #fff; margin: 5px 0;"><strong>Email :</strong> ${email}</p>
|
||||
<p style="color: #fff; margin: 5px 0;"><strong>Mot de passe :</strong> ${tempPassword}</p>
|
||||
</div>
|
||||
<p>Connecte-toi sur <a href="${process.env.NEXT_PUBLIC_APP_URL}/login" style="color: #6D5EF6;">hooklab.fr/login</a> pour commencer.</p>
|
||||
<p><strong>Pense a changer ton mot de passe apres ta premiere connexion !</strong></p>
|
||||
<p>A tres vite,<br/>L'equipe HookLab</p>
|
||||
<p><strong>Pense à changer ton mot de passe après ta première connexion !</strong></p>
|
||||
<p>À très vite,<br/>L'équipe HookLab</p>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
@@ -204,7 +204,7 @@ export async function POST(request: Request) {
|
||||
}
|
||||
|
||||
default:
|
||||
console.log(`Webhook non gere: ${event.type}`);
|
||||
console.log(`Webhook non géré: ${event.type}`);
|
||||
}
|
||||
|
||||
return NextResponse.json({ received: true });
|
||||
|
||||
@@ -124,7 +124,7 @@ export default function CandidaturePage() {
|
||||
Candidature <span className="gradient-text">HookLab</span>
|
||||
</h1>
|
||||
<p className="text-white/60">
|
||||
Reponds a quelques questions pour qu'on puisse evaluer ton
|
||||
Réponds à quelques questions pour qu'on puisse évaluer ton
|
||||
profil.
|
||||
</p>
|
||||
</div>
|
||||
@@ -151,8 +151,8 @@ export default function CandidaturePage() {
|
||||
</h2>
|
||||
<Input
|
||||
id="firstname"
|
||||
label="Prenom"
|
||||
placeholder="Ton prenom"
|
||||
label="Prénom"
|
||||
placeholder="Ton prénom"
|
||||
value={formData.firstname}
|
||||
onChange={(e) => updateField("firstname", e.target.value)}
|
||||
/>
|
||||
@@ -166,7 +166,7 @@ export default function CandidaturePage() {
|
||||
/>
|
||||
<Input
|
||||
id="phone"
|
||||
label="Telephone"
|
||||
label="Téléphone"
|
||||
type="tel"
|
||||
placeholder="06 12 34 56 78"
|
||||
value={formData.phone}
|
||||
@@ -174,7 +174,7 @@ export default function CandidaturePage() {
|
||||
/>
|
||||
<Input
|
||||
id="age"
|
||||
label="Age"
|
||||
label="Âge"
|
||||
type="number"
|
||||
placeholder="25"
|
||||
min="18"
|
||||
@@ -186,13 +186,13 @@ export default function CandidaturePage() {
|
||||
{/* Persona selection */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="block text-sm font-medium text-white/80">
|
||||
Tu es plutot...
|
||||
Tu es plutôt...
|
||||
</label>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{[
|
||||
{
|
||||
id: "jeune",
|
||||
label: "Etudiant / Jeune",
|
||||
label: "Étudiant / Jeune",
|
||||
emoji: "🎓",
|
||||
},
|
||||
{
|
||||
@@ -231,13 +231,13 @@ export default function CandidaturePage() {
|
||||
|
||||
<div className="space-y-1.5">
|
||||
<label className="block text-sm font-medium text-white/80">
|
||||
Experience e-commerce / reseaux sociaux
|
||||
Expérience e-commerce / réseaux sociaux
|
||||
</label>
|
||||
<div className="space-y-2">
|
||||
{[
|
||||
"Debutant complet",
|
||||
"J'ai deja teste des choses",
|
||||
"Je genere deja des revenus en ligne",
|
||||
"Débutant complet",
|
||||
"J'ai déjà testé des choses",
|
||||
"Je génère déjà des revenus en ligne",
|
||||
].map((opt) => (
|
||||
<button
|
||||
key={opt}
|
||||
@@ -281,11 +281,11 @@ export default function CandidaturePage() {
|
||||
|
||||
<div className="space-y-1.5">
|
||||
<label className="block text-sm font-medium text-white/80">
|
||||
Disponibilite pour commencer
|
||||
Disponibilité pour commencer
|
||||
</label>
|
||||
<div className="space-y-2">
|
||||
{[
|
||||
"Immediatement",
|
||||
"Immédiatement",
|
||||
"Dans 1-2 semaines",
|
||||
"Dans 1 mois",
|
||||
].map((opt) => (
|
||||
@@ -360,7 +360,7 @@ export default function CandidaturePage() {
|
||||
<Textarea
|
||||
id="biggest_fear"
|
||||
label="Quelle est ta plus grande peur ?"
|
||||
placeholder="Qu'est-ce qui pourrait t'empecher de reussir ?"
|
||||
placeholder="Qu'est-ce qui pourrait t'empêcher de réussir ?"
|
||||
rows={3}
|
||||
value={formData.biggest_fear}
|
||||
onChange={(e) => updateField("biggest_fear", e.target.value)}
|
||||
@@ -419,7 +419,7 @@ export default function CandidaturePage() {
|
||||
|
||||
{/* Step indicator text */}
|
||||
<p className="text-center text-white/30 text-sm mt-4">
|
||||
Etape {step} sur 3
|
||||
Étape {step} sur 3
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
126
app/cgv/page.tsx
Normal file
126
app/cgv/page.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
import Link from "next/link";
|
||||
|
||||
export default function CGV() {
|
||||
return (
|
||||
<main className="min-h-screen py-20 md:py-32">
|
||||
<div className="max-w-3xl mx-auto px-4 sm:px-6">
|
||||
<Link href="/" className="inline-flex items-center gap-2 mb-10 text-white/40 hover:text-white text-sm transition-colors">
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
Retour à l'accueil
|
||||
</Link>
|
||||
|
||||
<h1 className="text-3xl md:text-4xl font-bold text-white mb-10">Conditions Générales de Vente</h1>
|
||||
|
||||
<div className="space-y-8 text-white/70 text-sm leading-relaxed">
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 1 - Objet</h2>
|
||||
<p>
|
||||
Les présentes Conditions Générales de Vente (CGV) régissent la vente du programme de formation
|
||||
en ligne “HookLab” proposé par Enguerrand Ozano, entrepreneur individuel, SIREN 994 538 932,
|
||||
situé au 35 rue Moïse Lambert, 59148 Flines-lez-Raches, France.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 2 - Description du service</h2>
|
||||
<p>
|
||||
HookLab est un programme de coaching en ligne d'une durée de 8 semaines, comprenant :
|
||||
</p>
|
||||
<ul className="mt-3 space-y-1 list-disc list-inside">
|
||||
<li>Des modules vidéo hebdomadaires</li>
|
||||
<li>Des appels de groupe hebdomadaires</li>
|
||||
<li>Un support WhatsApp illimité</li>
|
||||
<li>L'accès à une communauté privée d'entrepreneurs</li>
|
||||
<li>Des templates et scripts de contenu</li>
|
||||
<li>Une certification HookLab</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 3 - Prix et modalités de paiement</h2>
|
||||
<p>
|
||||
Le prix du programme est de <strong className="text-white">980€ TTC</strong>, payable en 2 mensualités
|
||||
de 490€. Le premier paiement est exigé lors de l'inscription et donne accès immédiat au programme.
|
||||
Le second paiement est prélevé automatiquement 30 jours après le premier.
|
||||
</p>
|
||||
<p className="mt-3">
|
||||
TVA applicable : FR16994538932. Les paiements sont sécurisés via la plateforme Stripe.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 4 - Processus de candidature</h2>
|
||||
<p>
|
||||
L'accès au programme est soumis à la validation d'un formulaire de candidature. L'éditeur
|
||||
se réserve le droit de refuser toute candidature sans avoir à en justifier les raisons. En cas de
|
||||
refus, aucun paiement n'est effectué.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 5 - Droit de rétractation</h2>
|
||||
<p>
|
||||
Conformément à l'article L221-18 du Code de la consommation, le client dispose d'un délai de
|
||||
<strong className="text-white"> 14 jours</strong> à compter de la date d'achat pour exercer son droit
|
||||
de rétractation, sans avoir à justifier de motifs ni à payer de pénalités.
|
||||
</p>
|
||||
<p className="mt-3">
|
||||
Pour exercer ce droit, le client doit envoyer un email à <strong className="text-white">contact@hooklab.fr</strong> en
|
||||
indiquant sa volonté de se rétracter. Le remboursement sera effectué dans un délai de 14 jours
|
||||
suivant la réception de la demande.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 6 - Accès au programme</h2>
|
||||
<p>
|
||||
L'accès au programme est personnel et non cessible. Le client s'engage à ne pas partager ses
|
||||
identifiants de connexion ni le contenu du programme avec des tiers. Tout manquement à cette
|
||||
obligation pourra entraîner la résiliation immédiate de l'accès sans remboursement.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 7 - Limitation de responsabilité</h2>
|
||||
<p>
|
||||
HookLab est un programme de formation et de coaching. Les résultats obtenus dépendent de
|
||||
l'implication et des actions de chaque participant. Aucune garantie de revenus n'est formulée.
|
||||
Les témoignages présentés sur le site sont des exemples individuels et ne constituent pas une
|
||||
promesse de résultats similaires.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 8 - Protection des données</h2>
|
||||
<p>
|
||||
Les données personnelles collectées sont traitées conformément à notre{" "}
|
||||
<Link href="/confidentialite" className="text-primary hover:underline">
|
||||
Politique de confidentialité
|
||||
</Link>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">Article 9 - Droit applicable et litiges</h2>
|
||||
<p>
|
||||
Les présentes CGV sont soumises au droit français. En cas de litige, une solution amiable sera
|
||||
recherchée avant toute action judiciaire. À défaut, les tribunaux compétents seront ceux du
|
||||
ressort du siège social de l'éditeur.
|
||||
</p>
|
||||
<p className="mt-3">
|
||||
Conformément à l'article L612-1 du Code de la consommation, le consommateur peut recourir
|
||||
gratuitement au service de médiation MEDICYS, par voie électronique à{" "}
|
||||
<span className="text-white">www.medicys.fr</span> ou par courrier.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<p className="text-white/40 pt-4 border-t border-dark-border">
|
||||
Dernière mise à jour : février 2026
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
129
app/confidentialite/page.tsx
Normal file
129
app/confidentialite/page.tsx
Normal file
@@ -0,0 +1,129 @@
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Confidentialite() {
|
||||
return (
|
||||
<main className="min-h-screen py-20 md:py-32">
|
||||
<div className="max-w-3xl mx-auto px-4 sm:px-6">
|
||||
<Link href="/" className="inline-flex items-center gap-2 mb-10 text-white/40 hover:text-white text-sm transition-colors">
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
Retour à l'accueil
|
||||
</Link>
|
||||
|
||||
<h1 className="text-3xl md:text-4xl font-bold text-white mb-10">Politique de confidentialité</h1>
|
||||
|
||||
<div className="space-y-8 text-white/70 text-sm leading-relaxed">
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">1. Responsable du traitement</h2>
|
||||
<p>
|
||||
Le responsable du traitement des données personnelles est :
|
||||
</p>
|
||||
<ul className="mt-3 space-y-1">
|
||||
<li><strong className="text-white">Enguerrand Ozano</strong></li>
|
||||
<li>SIREN : 994 538 932</li>
|
||||
<li>35 rue Moïse Lambert, 59148 Flines-lez-Raches, France</li>
|
||||
<li>Email : contact@hooklab.fr</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">2. Données collectées</h2>
|
||||
<p>Nous collectons les données suivantes :</p>
|
||||
<ul className="mt-3 space-y-1 list-disc list-inside">
|
||||
<li><strong className="text-white">Formulaire de candidature :</strong> prénom, email, téléphone, âge, profil (étudiant/parent), expérience, disponibilité, motivation, objectifs, pseudo TikTok</li>
|
||||
<li><strong className="text-white">Inscription :</strong> email, mot de passe (chiffré)</li>
|
||||
<li><strong className="text-white">Paiement :</strong> les données bancaires sont traitées directement par Stripe et ne sont jamais stockées sur nos serveurs</li>
|
||||
<li><strong className="text-white">Navigation :</strong> cookies techniques nécessaires au fonctionnement du site</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">3. Finalités du traitement</h2>
|
||||
<p>Les données personnelles sont collectées pour :</p>
|
||||
<ul className="mt-3 space-y-1 list-disc list-inside">
|
||||
<li>Traiter les candidatures au programme HookLab</li>
|
||||
<li>Gérer l'accès à la plateforme de formation</li>
|
||||
<li>Traiter les paiements et la facturation</li>
|
||||
<li>Envoyer des communications relatives au programme (emails transactionnels)</li>
|
||||
<li>Améliorer nos services</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">4. Base légale</h2>
|
||||
<p>
|
||||
Le traitement des données est fondé sur :
|
||||
</p>
|
||||
<ul className="mt-3 space-y-1 list-disc list-inside">
|
||||
<li>L'exécution du contrat (accès au programme après paiement)</li>
|
||||
<li>Le consentement (formulaire de candidature)</li>
|
||||
<li>L'intérêt légitime (amélioration des services)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">5. Durée de conservation</h2>
|
||||
<ul className="space-y-1 list-disc list-inside">
|
||||
<li>Données de candidature : 2 ans à compter de la collecte</li>
|
||||
<li>Données de compte utilisateur : durée de l'abonnement + 3 ans</li>
|
||||
<li>Données de facturation : 10 ans (obligation légale)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">6. Sous-traitants</h2>
|
||||
<p>Vos données peuvent être transmises aux sous-traitants suivants :</p>
|
||||
<ul className="mt-3 space-y-1 list-disc list-inside">
|
||||
<li><strong className="text-white">Supabase</strong> (hébergement base de données et authentification) - Singapour/UE</li>
|
||||
<li><strong className="text-white">Stripe</strong> (paiement sécurisé) - États-Unis, certifié Privacy Shield</li>
|
||||
<li><strong className="text-white">Vercel</strong> (hébergement du site) - États-Unis</li>
|
||||
<li><strong className="text-white">Resend</strong> (envoi d'emails transactionnels) - États-Unis</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">7. Vos droits</h2>
|
||||
<p>
|
||||
Conformément au RGPD, vous disposez des droits suivants :
|
||||
</p>
|
||||
<ul className="mt-3 space-y-1 list-disc list-inside">
|
||||
<li><strong className="text-white">Droit d'accès :</strong> obtenir une copie de vos données</li>
|
||||
<li><strong className="text-white">Droit de rectification :</strong> corriger vos données inexactes</li>
|
||||
<li><strong className="text-white">Droit à l'effacement :</strong> demander la suppression de vos données</li>
|
||||
<li><strong className="text-white">Droit à la portabilité :</strong> récupérer vos données dans un format structuré</li>
|
||||
<li><strong className="text-white">Droit d'opposition :</strong> vous opposer au traitement de vos données</li>
|
||||
<li><strong className="text-white">Droit de limitation :</strong> restreindre le traitement de vos données</li>
|
||||
</ul>
|
||||
<p className="mt-3">
|
||||
Pour exercer vos droits, contactez-nous à <strong className="text-white">contact@hooklab.fr</strong>.
|
||||
Vous pouvez également adresser une réclamation à la CNIL (www.cnil.fr).
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">8. Cookies</h2>
|
||||
<p>
|
||||
Le site utilise uniquement des cookies techniques nécessaires au fonctionnement de la plateforme
|
||||
(authentification, préférences de session). Aucun cookie publicitaire ou de tracking tiers n'est
|
||||
utilisé.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">9. Sécurité</h2>
|
||||
<p>
|
||||
Nous mettons en œuvre des mesures techniques et organisationnelles appropriées pour protéger
|
||||
vos données personnelles : chiffrement des mots de passe, connexions HTTPS, accès restreint
|
||||
aux données, hébergement sécurisé.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<p className="text-white/40 pt-4 border-t border-dark-border">
|
||||
Dernière mise à jour : février 2026
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ export default function LoginPage() {
|
||||
router.push("/dashboard");
|
||||
router.refresh();
|
||||
} catch {
|
||||
setError("Erreur de connexion. Veuillez reessayer.");
|
||||
setError("Erreur de connexion. Veuillez réessayer.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ export default function LoginPage() {
|
||||
Content de te revoir
|
||||
</h1>
|
||||
<p className="text-white/60 text-sm">
|
||||
Connecte-toi pour acceder a tes formations.
|
||||
Connecte-toi pour accéder à tes formations.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
84
app/mentions-legales/page.tsx
Normal file
84
app/mentions-legales/page.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import Link from "next/link";
|
||||
|
||||
export default function MentionsLegales() {
|
||||
return (
|
||||
<main className="min-h-screen py-20 md:py-32">
|
||||
<div className="max-w-3xl mx-auto px-4 sm:px-6">
|
||||
<Link href="/" className="inline-flex items-center gap-2 mb-10 text-white/40 hover:text-white text-sm transition-colors">
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
Retour à l'accueil
|
||||
</Link>
|
||||
|
||||
<h1 className="text-3xl md:text-4xl font-bold text-white mb-10">Mentions légales</h1>
|
||||
|
||||
<div className="space-y-8 text-white/70 text-sm leading-relaxed">
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">1. Éditeur du site</h2>
|
||||
<p>
|
||||
Le site <strong className="text-white">hooklab.fr</strong> est édité par :
|
||||
</p>
|
||||
<ul className="mt-3 space-y-1">
|
||||
<li><strong className="text-white">Nom :</strong> Enguerrand Ozano</li>
|
||||
<li><strong className="text-white">Statut :</strong> Entrepreneur individuel</li>
|
||||
<li><strong className="text-white">SIREN :</strong> 994 538 932</li>
|
||||
<li><strong className="text-white">Numéro de TVA :</strong> FR16994538932</li>
|
||||
<li><strong className="text-white">Adresse :</strong> 35 rue Moïse Lambert, 59148 Flines-lez-Raches, France</li>
|
||||
<li><strong className="text-white">Email :</strong> contact@hooklab.fr</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">2. Hébergement</h2>
|
||||
<p>Le site est hébergé par :</p>
|
||||
<ul className="mt-3 space-y-1">
|
||||
<li><strong className="text-white">Vercel Inc.</strong></li>
|
||||
<li>440 N Barranca Ave #4133, Covina, CA 91723, États-Unis</li>
|
||||
<li>Site web : vercel.com</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">3. Propriété intellectuelle</h2>
|
||||
<p>
|
||||
L'ensemble des contenus présents sur le site hooklab.fr (textes, images, vidéos, logos, éléments graphiques)
|
||||
sont protégés par le droit d'auteur et le droit de la propriété intellectuelle. Toute reproduction,
|
||||
représentation, modification ou exploitation non autorisée est interdite.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">4. Responsabilité</h2>
|
||||
<p>
|
||||
L'éditeur s'efforce de fournir des informations aussi précises que possible. Toutefois, il ne
|
||||
pourra être tenu responsable des omissions, des inexactitudes ou des carences dans la mise à jour.
|
||||
Les résultats présentés dans les témoignages sont des exemples individuels et ne constituent pas une
|
||||
garantie de résultats similaires.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">5. Liens hypertextes</h2>
|
||||
<p>
|
||||
Le site peut contenir des liens vers d'autres sites. L'éditeur ne dispose d'aucun moyen
|
||||
de contrôle du contenu de ces sites tiers et décline toute responsabilité quant à leur contenu.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold text-white mb-3">6. Droit applicable</h2>
|
||||
<p>
|
||||
Les présentes mentions légales sont soumises au droit français. En cas de litige, les tribunaux
|
||||
français seront seuls compétents.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<p className="text-white/40 pt-4 border-t border-dark-border">
|
||||
Dernière mise à jour : février 2026
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -23,38 +23,38 @@ export default function MerciPage() {
|
||||
</div>
|
||||
|
||||
<h1 className="text-3xl md:text-4xl font-bold tracking-[-0.02em] mb-4">
|
||||
Candidature <span className="gradient-text">envoyee !</span>
|
||||
Candidature <span className="gradient-text">envoyée !</span>
|
||||
</h1>
|
||||
|
||||
<p className="text-white/60 text-lg mb-2">
|
||||
Merci pour ta candidature. Notre equipe va etudier ton profil
|
||||
Merci pour ta candidature. Notre équipe va étudier ton profil
|
||||
attentivement.
|
||||
</p>
|
||||
|
||||
<p className="text-white/40 mb-8">
|
||||
Tu recevras une reponse par email sous 24 heures. Pense a verifier
|
||||
Tu recevras une réponse par email sous 24 heures. Pense à vérifier
|
||||
tes spams !
|
||||
</p>
|
||||
|
||||
{/* Étapes suivantes */}
|
||||
<div className="bg-dark-light border border-dark-border rounded-[20px] p-6 mb-8 text-left">
|
||||
<h2 className="text-white font-semibold mb-4">Prochaines etapes</h2>
|
||||
<h2 className="text-white font-semibold mb-4">Prochaines étapes</h2>
|
||||
<div className="space-y-4">
|
||||
{[
|
||||
{
|
||||
step: "1",
|
||||
title: "Analyse de ton profil",
|
||||
desc: "Notre equipe evalue ta candidature",
|
||||
desc: "Notre équipe évalue ta candidature",
|
||||
},
|
||||
{
|
||||
step: "2",
|
||||
title: "Email de confirmation",
|
||||
desc: "Tu recois un email avec le lien de paiement",
|
||||
desc: "Tu reçois un email avec le lien de paiement",
|
||||
},
|
||||
{
|
||||
step: "3",
|
||||
title: "Acces au programme",
|
||||
desc: "Tu commences ta formation immediatement",
|
||||
title: "Accès au programme",
|
||||
desc: "Tu commences ta formation immédiatement",
|
||||
},
|
||||
].map((item) => (
|
||||
<div key={item.step} className="flex items-start gap-3">
|
||||
@@ -71,7 +71,7 @@ export default function MerciPage() {
|
||||
</div>
|
||||
|
||||
<Link href="/">
|
||||
<Button variant="secondary">Retour a l'accueil</Button>
|
||||
<Button variant="secondary">Retour à l'accueil</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function RegisterPage() {
|
||||
}
|
||||
|
||||
if (password.length < 8) {
|
||||
setError("Le mot de passe doit contenir au moins 8 caracteres.");
|
||||
setError("Le mot de passe doit contenir au moins 8 caractères.");
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export default function RegisterPage() {
|
||||
|
||||
if (authError) {
|
||||
if (authError.message.includes("already registered")) {
|
||||
setError("Un compte avec cet email existe deja.");
|
||||
setError("Un compte avec cet email existe déjà.");
|
||||
} else {
|
||||
setError(authError.message);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export default function RegisterPage() {
|
||||
router.push("/dashboard");
|
||||
router.refresh();
|
||||
} catch {
|
||||
setError("Erreur lors de l'inscription. Veuillez reessayer.");
|
||||
setError("Erreur lors de l'inscription. Veuillez réessayer.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -77,10 +77,10 @@ export default function RegisterPage() {
|
||||
</span>
|
||||
</Link>
|
||||
<h1 className="text-2xl font-bold text-white mb-2">
|
||||
Creer ton compte
|
||||
Créer ton compte
|
||||
</h1>
|
||||
<p className="text-white/60 text-sm">
|
||||
Inscris-toi pour acceder au programme.
|
||||
Inscris-toi pour accéder au programme.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -108,7 +108,7 @@ export default function RegisterPage() {
|
||||
id="password"
|
||||
label="Mot de passe"
|
||||
type="password"
|
||||
placeholder="Minimum 8 caracteres"
|
||||
placeholder="Minimum 8 caractères"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
@@ -130,13 +130,13 @@ export default function RegisterPage() {
|
||||
)}
|
||||
|
||||
<Button type="submit" loading={loading} className="w-full">
|
||||
Creer mon compte
|
||||
Créer mon compte
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<div className="mt-6 text-center">
|
||||
<p className="text-white/40 text-sm">
|
||||
Deja un compte ?{" "}
|
||||
Déjà un compte ?{" "}
|
||||
<Link
|
||||
href="/login"
|
||||
className="text-primary hover:text-primary-hover transition-colors"
|
||||
|
||||
Reference in New Issue
Block a user