style: apply modern design to remaining pages

- Update about, contact, FAQ, forgot-password, lots, register, rules pages
- Apply consistent styling with bg-gray-50 and modern cards
- Update footer and layout with new design
- Add gagnants (winners) page

All pages now have consistent modern design matching homepage and dashboard

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
soufiane 2025-11-19 03:18:43 +01:00
parent 5d5375ff6b
commit d0ef196c0d
10 changed files with 1981 additions and 1443 deletions

View File

@ -1,233 +1,337 @@
'use client';
import type { Metadata } from "next"; import type { Metadata } from "next";
import Link from "next/link"; import Link from "next/link";
import Image from "next/image"; import { useState } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card";
import Button from "@/components/Button";
import { ROUTES } from "@/utils/constants";
export const metadata: Metadata = { interface Winner {
title: "À propos - Thé Tip Top", date: string;
description: "Découvrez l'histoire et les engagements de notre maison de thé niçoise", name: string;
prize: string;
prizeType: 'coffret-prestige' | 'boite-signature' | 'infuseur' | 'coffret-decouverte' | 'boite-detox';
boutique: string;
city: string;
testimonial?: {
initials: string;
text: string;
stars: number;
};
}
const winners: Winner[] = [
{
date: "15 janvier 2024",
name: "Marie L.",
prize: "Coffret prestige 69€",
prizeType: "coffret-prestige",
boutique: "Boutique Rivoli",
city: "Paris 1er"
},
{
date: "15 janvier 2024",
name: "Pierre L.",
prize: "Boîte 100g thé signature",
prizeType: "boite-signature",
boutique: "Boutique République",
city: "Lyon"
},
{
date: "14 janvier 2024",
name: "Sophie L.",
prize: "Infuseur à thé premium",
prizeType: "infuseur",
boutique: "Boutique Canebière",
city: "Marseille"
},
{
date: "14 janvier 2024",
name: "Thomas L.",
prize: "Coffret découverte 39€",
prizeType: "coffret-decouverte",
boutique: "Boutique Saint-Germain",
city: "Paris 6e"
},
{
date: "13 janvier 2024",
name: "Julie L.",
prize: "Boîte 100g thé détox",
prizeType: "boite-detox",
boutique: "Boutique Capitole",
city: "Toulouse"
},
{
date: "13 janvier 2024",
name: "Antoine L.",
prize: "Infuseur à thé premium",
prizeType: "infuseur",
boutique: "Boutique Promenade",
city: "Nice"
},
{
date: "12 janvier 2024",
name: "Camille L.",
prize: "Boîte 100g thé signature",
prizeType: "boite-signature",
boutique: "Boutique Sainte-Catherine",
city: "Bordeaux"
},
{
date: "12 janvier 2024",
name: "Maxime L.",
prize: "Infuseur à thé premium",
prizeType: "infuseur",
boutique: "Boutique Kléber",
city: "Strasbourg"
},
{
date: "11 janvier 2024",
name: "Emma L.",
prize: "Coffret prestige 69€",
prizeType: "coffret-prestige",
boutique: "Boutique Vieux-Lille",
city: "Lille"
},
{
date: "11 janvier 2024",
name: "Lucas L.",
prize: "Boîte 100g thé détox",
prizeType: "boite-detox",
boutique: "Boutique Commerce",
city: "Nantes"
},
];
const testimonials = [
{
initials: "ML",
name: "Marie L.",
city: "Paris 9e",
text: "J'ai gagné le coffret prestige ! Les thés sont délicieux, merci Thé Tip Top pour cette belle surprise !",
stars: 5
},
{
initials: "PD",
name: "Pierre D.",
city: "Lyon",
text: "Le thé signature est exceptionnel ! Je recommande vivement cette boutique, et le jeu est super !",
stars: 5
},
{
initials: "SB",
name: "Sophie B.",
city: "Marseille",
text: "Mon infuseur est magnifique ! Parfait pour mes thés du matin. Merci pour ce jeu génial !",
stars: 5
}
];
const getPrizeIcon = (type: string) => {
switch (type) {
case 'coffret-prestige':
return '🎁';
case 'boite-signature':
return '🌿';
case 'infuseur':
return '🍵';
case 'coffret-decouverte':
return '🎁';
case 'boite-detox':
return '📦';
default:
return '🎁';
}
};
const getPrizeColor = (type: string) => {
switch (type) {
case 'coffret-prestige':
return 'bg-pink-100 text-pink-700';
case 'boite-signature':
return 'bg-yellow-100 text-yellow-700';
case 'infuseur':
return 'bg-blue-100 text-blue-700';
case 'coffret-decouverte':
return 'bg-orange-100 text-orange-700';
case 'boite-detox':
return 'bg-green-100 text-green-700';
default:
return 'bg-gray-100 text-gray-700';
}
}; };
export default function AboutPage() { export default function AboutPage() {
return ( const [periodFilter, setPeriodFilter] = useState("Toutes les dates");
<div className="py-12"> const [typeFilter, setTypeFilter] = useState("Tous les lots");
{/* Hero Section */}
<section className="text-center mb-16">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
À propos de Thé Tip Top Nice
</h1>
<p className="text-lg md:text-xl text-gray-600 max-w-3xl mx-auto mb-8">
Depuis Nice, nous célébrons les thés d'exception et les moments à partager.
Découvrez notre histoire et ce qui guide notre maison au quotidien.
</p>
<Link href="#histoire">
<Button size="lg" className="px-8">
Explorer notre univers
</Button>
</Link>
</section>
{/* Histoire Section */} return (
<section id="histoire" className="mb-16"> <div className="min-h-screen bg-gray-50">
<div className="grid lg:grid-cols-2 gap-12 items-center"> {/* Hero Section */}
<div> <section className="bg-white py-12">
<h2 className="text-3xl font-bold text-gray-900 mb-6"> <div className="container mx-auto px-4">
Notre histoire <div className="max-w-4xl mx-auto text-center">
</h2> <h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
<p className="text-lg text-gray-700 mb-4 font-semibold"> Nos gagnants
Quinze ans de passion infusée. </h1>
</p> <p className="text-lg text-gray-600">
<p className="text-gray-600 leading-relaxed mb-4"> Découvrez les heureux gagnants de notre jeu-concours Thé Tip Top.
Née d'une envie simple faire (re)découvrir le vrai goût du thé notre maison Félicitations à tous les participants !
sélectionne des feuilles remarquables auprès de producteurs engagés. Au fil des années,
nous avons grandi sans rien céder à nos exigences : traçabilité, fraîcheur, respect des savoir-faire.
</p>
<p className="text-gray-600 leading-relaxed">
Aujourd'hui, notre boutique niçoise est le point de rencontre entre curieux et connaisseurs :
dégustations, conseils personnalisés et une carte qui évolue au rythme des récoltes.
</p> </p>
</div> </div>
</div>
</section>
{/* Image Placeholder */} {/* Stats Section */}
<div className="relative"> <section className="py-8">
<div className="bg-gradient-to-br from-primary-100 to-green-100 rounded-2xl overflow-hidden aspect-square flex items-center justify-center"> <div className="container mx-auto px-4">
<div className="text-center p-8"> <div className="max-w-5xl mx-auto">
<div className="mb-4 flex justify-center"> <div className="grid md:grid-cols-3 gap-6">
<Image {/* Stat 1 */}
src="/logos/logo.svg" <div className="bg-white rounded-xl shadow-md p-6 text-center">
alt="Logo Thé Tip Top" <div className="text-4xl font-bold text-[#1a4d2e] mb-2">10</div>
width={200} <div className="text-gray-900 font-semibold mb-1">Gagnants au total</div>
height={200} <div className="text-sm text-gray-500">Depuis le début du jeu</div>
className="object-contain" </div>
/>
</div> {/* Stat 2 */}
<p className="text-gray-600 font-medium">Notre boutique à Nice</p> <div className="bg-white rounded-xl shadow-md p-6 text-center">
<p className="text-sm text-gray-500 mt-2">Image à venir</p> <div className="text-4xl font-bold text-[#1a4d2e] mb-2">5</div>
<div className="text-gray-900 font-semibold mb-1">Jours d'activité</div>
<div className="text-sm text-gray-500">Jours avec des gagnants</div>
</div>
{/* Stat 3 */}
<div className="bg-white rounded-xl shadow-md p-6 text-center">
<div className="text-4xl font-bold text-[#1a4d2e] mb-2">10</div>
<div className="text-gray-900 font-semibold mb-1">Villes représentées</div>
<div className="text-sm text-gray-500">Dans toute la France</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
{/* Engagements Section */} {/* Winners List */}
<section className="mb-16"> <section className="py-8 pb-16">
<h2 className="text-3xl font-bold text-center text-gray-900 mb-12"> <div className="container mx-auto px-4">
Nos engagements <div className="max-w-5xl mx-auto">
</h2> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6"> <div className="p-6 border-b border-gray-200">
{/* Engagement 1 */} <div className="flex items-center gap-2">
<Card className="text-center hover:shadow-lg transition-shadow"> <span className="text-xl">🏆</span>
<CardContent className="pt-8"> <h2 className="text-xl font-bold text-gray-900">Liste des gagnants ({winners.length})</h2>
<div className="text-5xl mb-4">🌱</div> </div>
<h3 className="text-xl font-bold mb-3 text-gray-900"> </div>
Agriculture responsable
</h3>
<p className="text-gray-600 text-sm">
Des jardins certifiés et des pratiques respectueuses de la biodiversité,
pour des thés propres et expressifs.
</p>
</CardContent>
</Card>
{/* Engagement 2 */} {/* Table Header */}
<Card className="text-center hover:shadow-lg transition-shadow"> <div className="hidden md:grid md:grid-cols-4 gap-4 px-6 py-4 bg-gray-50 border-b border-gray-200 text-sm font-semibold text-gray-700">
<CardContent className="pt-8"> <div>DATE</div>
<div className="text-5xl mb-4">🤝</div> <div>GAGNANT</div>
<h3 className="text-xl font-bold mb-3 text-gray-900"> <div>LOT REMPORTÉ</div>
Filière équitable <div>BOUTIQUE</div>
</h3> </div>
<p className="text-gray-600 text-sm">
Des partenariats durables et rémunérateurs pour les fermes qui nous
confient leurs récoltes.
</p>
</CardContent>
</Card>
{/* Engagement 3 */} {/* Table Rows */}
<Card className="text-center hover:shadow-lg transition-shadow"> <div className="divide-y divide-gray-200">
<CardContent className="pt-8"> {winners.map((winner, index) => (
<div className="text-5xl mb-4"></div> <div key={index} className="px-6 py-4 hover:bg-gray-50 transition-colors">
<h3 className="text-xl font-bold mb-3 text-gray-900"> <div className="grid md:grid-cols-4 gap-4 items-center">
Fraîcheur & préparation {/* Date */}
</h3> <div className="flex items-center gap-2">
<p className="text-gray-600 text-sm"> <span className="text-gray-400 md:hidden font-semibold">📅</span>
Conditionnement soigné et rotations courtes pour préserver les arômes. <span className="text-gray-600">{winner.date}</span>
</p> </div>
</CardContent>
</Card>
{/* Engagement 4 */} {/* Name */}
<Card className="text-center hover:shadow-lg transition-shadow"> <div className="flex items-center gap-2">
<CardContent className="pt-8"> <span className="text-gray-400 md:hidden font-semibold">👤</span>
<div className="text-5xl mb-4">📚</div> <span className="font-medium text-gray-900">{winner.name}</span>
<h3 className="text-xl font-bold mb-3 text-gray-900"> </div>
Conseil & transmission
</h3> {/* Prize */}
<p className="text-gray-600 text-sm"> <div>
Ateliers, initiations et fiches pratiques : nous aimons partager nos <span className={`inline-flex items-center gap-2 px-3 py-1 rounded-full text-sm font-medium ${getPrizeColor(winner.prizeType)}`}>
méthodes d'infusion. <span>{getPrizeIcon(winner.prizeType)}</span>
</p> <span>{winner.prize}</span>
</CardContent> </span>
</Card> </div>
{/* Boutique */}
<div className="flex items-center gap-2">
<span className="text-gray-400 md:hidden font-semibold">🏪</span>
<div>
<div className="font-medium text-gray-900">{winner.boutique}</div>
<div className="text-sm text-gray-500">{winner.city}</div>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</section>
{/* Testimonials Section */}
<section className="pb-16">
<div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto">
<h2 className="text-2xl font-bold text-gray-900 mb-8 text-center">Témoignages de nos gagnants</h2>
<div className="grid md:grid-cols-3 gap-6">
{testimonials.map((testimonial, index) => (
<div key={index} className="bg-white rounded-xl shadow-md p-6">
<div className="flex items-center gap-3 mb-4">
<div className="w-12 h-12 bg-[#1a4d2e] text-white rounded-full flex items-center justify-center font-bold">
{testimonial.initials}
</div>
<div>
<div className="font-semibold text-gray-900">{testimonial.name}</div>
<div className="text-sm text-gray-500">{testimonial.city}</div>
</div>
</div>
<p className="text-gray-600 text-sm mb-3 italic">"{testimonial.text}"</p>
<div className="flex gap-1">
{[...Array(testimonial.stars)].map((_, i) => (
<span key={i} className="text-yellow-400"></span>
))}
</div>
</div>
))}
</div>
</div>
</div> </div>
</section> </section>
{/* CTA Section */} {/* CTA Section */}
<section className="mb-16"> <section className="pb-16">
<Card className="max-w-4xl mx-auto bg-gradient-to-r from-primary-600 to-primary-700 text-white"> <div className="container mx-auto px-4">
<CardContent className="py-12 text-center"> <div className="max-w-4xl mx-auto">
<h2 className="text-3xl font-bold mb-4 text-white"> <div className="bg-gradient-to-br from-[#1a4d2e] via-[#2d5a3d] to-[#1a4d2e] rounded-xl p-12 text-center text-white">
Participez à notre grand jeu autour du thé ! <h2 className="text-3xl md:text-4xl font-bold mb-4">
</h2> Vous aussi, rejoignez nos gagnants !
<p className="text-lg mb-8 text-white"> </h2>
À gagner : sélections premium, accessoires de dégustation et surprises maison. <p className="text-xl mb-8 text-white/90 max-w-2xl mx-auto">
Chaque achat vous donne une chance supplémentaire. Avec 100% de gagnants garantis, c'est votre tour de remporter un magnifique lot.
</p> Rendez-vous en boutique et tentez votre chance !
<Link href={ROUTES.GAME}> </p>
<Button variant="outline" size="lg" className="bg-white text-primary-600 hover:bg-primary-50 border-white"> <div className="flex flex-col sm:flex-row gap-4 justify-center">
Découvrir le jeu <Link
</Button> href="/register"
</Link> className="inline-flex items-center justify-center bg-[#f59e0b] hover:bg-[#d97706] text-white font-bold px-8 py-4 rounded-lg transition-all shadow-xl"
</CardContent> >
</Card> Participer maintenant
</section> </Link>
<Link
{/* Quote Section */} href="/lots"
<section className="mb-16"> className="inline-flex items-center justify-center bg-white hover:bg-gray-100 text-[#1a4d2e] font-bold px-8 py-4 rounded-lg transition-all"
<div className="max-w-3xl mx-auto text-center"> >
<blockquote className="text-2xl md:text-3xl font-light text-gray-700 italic mb-4"> Voir les lots
« Un thé bien infusé, c'est une minute pour soi et un souvenir à partager. » </Link>
</blockquote> </div>
<p className="text-gray-600 font-medium"> L'équipe Thé Tip Top</p> </div>
</div>
</section>
{/* Info Section */}
<section className="bg-gradient-to-r from-primary-50 to-green-50 py-12 -mx-4 px-4 sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
<div className="max-w-5xl mx-auto">
<div className="grid md:grid-cols-3 gap-8 text-center">
{/* Localisation */}
<Card>
<CardHeader>
<div className="text-4xl mb-2">📍</div>
<CardTitle className="text-xl"> nous trouver</CardTitle>
</CardHeader>
<CardContent>
<p className="text-gray-600">
18 Avenue Thiers<br />
06000 Nice, France
</p>
<p className="text-sm text-gray-500 mt-2">
Au cœur de Nice, proches des transports.
</p>
</CardContent>
</Card>
{/* Horaires */}
<Card>
<CardHeader>
<div className="text-4xl mb-2">🕐</div>
<CardTitle className="text-xl">Horaires</CardTitle>
</CardHeader>
<CardContent>
<p className="text-gray-600">
Du mardi au samedi<br />
10h 19h
</p>
<p className="text-sm text-gray-500 mt-2">
Fermé dimanche et lundi
</p>
</CardContent>
</Card>
{/* Contact */}
<Card>
<CardHeader>
<div className="text-4xl mb-2"></div>
<CardTitle className="text-xl">Contact</CardTitle>
</CardHeader>
<CardContent>
<p className="text-gray-600 mb-2">
<a href="mailto:contact@thetiptop.fr" className="hover:text-primary-600 transition-colors">
contact@thetiptop.fr
</a>
</p>
<p className="text-gray-600 mb-2">
<a href="tel:+33123456789" className="hover:text-primary-600 transition-colors">
01 23 45 67 89
</a>
</p>
<p className="text-sm text-gray-500 mt-2">
Conseils personnalisés par e-mail ou en boutique.
</p>
</CardContent>
</Card>
</div> </div>
</div> </div>
</section> </section>
</div> </div>
); );
} }

View File

@ -2,8 +2,7 @@
import { useState } from "react"; import { useState } from "react";
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card"; import Link from "next/link";
import Button from "@/components/Button";
export default function ContactPage() { export default function ContactPage() {
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
@ -11,17 +10,17 @@ export default function ContactPage() {
email: '', email: '',
subject: '', subject: '',
message: '', message: '',
notRobot: false, acceptPolicy: false,
}); });
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
const { name, value } = e.target; const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value })); setFormData(prev => ({ ...prev, [name]: value }));
}; };
const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData(prev => ({ ...prev, notRobot: e.target.checked })); setFormData(prev => ({ ...prev, acceptPolicy: e.target.checked }));
}; };
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
@ -40,300 +39,298 @@ export default function ContactPage() {
email: '', email: '',
subject: '', subject: '',
message: '', message: '',
notRobot: false, acceptPolicy: false,
}); });
setIsSubmitting(false); setIsSubmitting(false);
}; };
return ( return (
<div className="py-12"> <div className="min-h-screen bg-gray-50">
{/* Hero Section */} {/* Hero Section */}
<section className="text-center mb-16"> <section className="bg-white py-12">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6"> <div className="container mx-auto px-4">
Contactez-nous <div className="max-w-4xl mx-auto text-center">
</h1> <h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
<p className="text-lg md:text-xl text-gray-600 max-w-3xl mx-auto"> Contactez-nous
Une question, une suggestion ? Notre équipe est pour vous accompagner. </h1>
</p> <p className="text-lg text-gray-600">
Une question sur le jeu-concours ? Besoin d'aide ? Notre équipe est pour vous accompagner !
</p>
</div>
</div>
</section> </section>
<div className="grid lg:grid-cols-2 gap-12 mb-16"> {/* Main Content */}
{/* Contact Form */} <section className="py-12">
<div> <div className="container mx-auto px-4">
<Card className="shadow-xl"> <div className="max-w-6xl mx-auto">
<CardHeader className="bg-gradient-to-r from-primary-50 to-green-50"> <div className="grid lg:grid-cols-2 gap-12">
<CardTitle className="text-2xl text-primary-800">
Envoyez-nous un message {/* Contact Form */}
</CardTitle> <div>
</CardHeader> <div className="bg-white rounded-xl shadow-md p-8">
<CardContent className="pt-6"> <h2 className="text-2xl font-bold text-gray-900 mb-6">Envoyez-nous un message</h2>
<form onSubmit={handleSubmit} className="space-y-6">
{/* Nom complet */} <form onSubmit={handleSubmit} className="space-y-6">
<div> {/* Nom complet */}
<label htmlFor="fullName" className="block text-sm font-medium text-gray-700 mb-2"> <div>
Nom complet <span className="text-red-500">*</span> <label htmlFor="fullName" className="block text-sm font-semibold text-gray-700 mb-2">
</label> Nom complet <span className="text-red-500">*</span>
<input </label>
id="fullName" <input
name="fullName" id="fullName"
type="text" name="fullName"
required type="text"
value={formData.fullName} required
onChange={handleChange} value={formData.fullName}
placeholder="Votre nom et prénom" onChange={handleChange}
className="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent" placeholder="Votre nom et prénom"
/> className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent"
/>
</div>
{/* Email */}
<div>
<label htmlFor="email" className="block text-sm font-semibold text-gray-700 mb-2">
Email <span className="text-red-500">*</span>
</label>
<input
id="email"
name="email"
type="email"
required
value={formData.email}
onChange={handleChange}
placeholder="votre@email.com"
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent"
/>
</div>
{/* Sujet */}
<div>
<label htmlFor="subject" className="block text-sm font-semibold text-gray-700 mb-2">
Sujet <span className="text-red-500">*</span>
</label>
<select
id="subject"
name="subject"
required
value={formData.subject}
onChange={handleChange}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent bg-white"
>
<option value="">Sélectionnez un sujet</option>
<option value="jeu-concours">Question sur le jeu-concours</option>
<option value="code">Problème avec mon code</option>
<option value="lot">Réclamation de lot</option>
<option value="compte">Gestion de compte</option>
<option value="autre">Autre demande</option>
</select>
</div>
{/* Message */}
<div>
<label htmlFor="message" className="block text-sm font-semibold text-gray-700 mb-2">
Message <span className="text-red-500">*</span>
</label>
<textarea
id="message"
name="message"
required
value={formData.message}
onChange={handleChange}
placeholder="Décrivez votre demande en détail..."
rows={6}
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent resize-none"
/>
</div>
{/* Checkbox RGPD */}
<div className="flex items-start gap-3">
<input
id="acceptPolicy"
name="acceptPolicy"
type="checkbox"
required
checked={formData.acceptPolicy}
onChange={handleCheckboxChange}
className="mt-1 w-5 h-5 text-[#1a4d2e] border-gray-300 rounded focus:ring-2 focus:ring-[#1a4d2e]"
/>
<label htmlFor="acceptPolicy" className="text-sm text-gray-700 select-none cursor-pointer">
J'accepte que mes données soient collectées et traitées conformément à la{' '}
<Link href="/privacy" className="text-[#1a4d2e] underline hover:text-[#f59e0b]">
politique de confidentialité
</Link>{' '}
<span className="text-red-500">*</span>
</label>
</div>
{/* Submit Button */}
<div>
<button
type="submit"
disabled={isSubmitting}
className="w-full bg-[#1a4d2e] hover:bg-[#2d5a3d] disabled:bg-gray-400 text-white font-bold px-8 py-4 rounded-lg transition-all"
>
{isSubmitting ? "Envoi en cours..." : "Envoyer le message"}
</button>
</div>
</form>
</div>
</div>
{/* Contact Info */}
<div className="space-y-6">
{/* Nos coordonnées */}
<div className="bg-white rounded-xl shadow-md p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-6">Nos coordonnées</h2>
<div className="space-y-6">
{/* Siège social */}
<div className="flex items-start gap-4">
<div className="text-2xl flex-shrink-0">📍</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Siège social</h3>
<p className="text-gray-600 text-sm">
Thé Tip Top<br />
123 Avenue des Thés<br />
75001 Paris, France
</p>
</div>
</div>
{/* Téléphone */}
<div className="flex items-start gap-4">
<div className="text-2xl flex-shrink-0">📞</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Téléphone</h3>
<p className="text-gray-600 text-sm">
<a href="tel:+33123456789" className="hover:text-[#1a4d2e] transition-colors">
+33 1 23 45 67 89
</a><br />
<span className="text-xs">Du lundi au vendredi<br />9h00 - 18h00</span>
</p>
</div>
</div>
{/* Email */}
<div className="flex items-start gap-4">
<div className="text-2xl flex-shrink-0"></div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Email</h3>
<div className="text-gray-600 text-sm space-y-1">
<p>
<a href="mailto:contact@thetiptop.com" className="hover:text-[#1a4d2e] transition-colors">
contact@thetiptop.com
</a>
</p>
<p>
<a href="mailto:support@thetiptop.com" className="hover:text-[#1a4d2e] transition-colors">
support@thetiptop.com
</a>
</p>
<p>
<a href="mailto:privacy@thetiptop.com" className="hover:text-[#1a4d2e] transition-colors">
privacy@thetiptop.com
</a>
</p>
</div>
</div>
</div>
{/* Service client */}
<div className="flex items-start gap-4">
<div className="text-2xl flex-shrink-0">🕐</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Service client</h3>
<p className="text-gray-600 text-sm">
Réponse sous 24h<br />
Support multilingue<br />
Du lundi au samedi
</p>
</div>
</div>
</div>
</div> </div>
{/* Email */} {/* Nos boutiques */}
<div> <div className="bg-white rounded-xl shadow-md p-8">
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2"> <h2 className="text-2xl font-bold text-gray-900 mb-6">Nos boutiques</h2>
Email <span className="text-red-500">*</span>
</label>
<input
id="email"
name="email"
type="email"
required
value={formData.email}
onChange={handleChange}
placeholder="votre@email.com"
className="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
/>
</div>
{/* Sujet */} <div className="space-y-4">
<div> {/* Boutique 1 */}
<label htmlFor="subject" className="block text-sm font-medium text-gray-700 mb-2"> <div className="pb-4 border-b border-gray-200">
Sujet <span className="text-red-500">*</span> <h3 className="font-semibold text-gray-900 mb-2">Paris Rivoli</h3>
</label> <p className="text-gray-600 text-sm mb-1">
<input 123 Rue de Rivoli, 75001 Paris
id="subject" </p>
name="subject" <p className="text-sm text-gray-500">01 23 45 67 89</p>
type="text" </div>
required
value={formData.subject}
onChange={handleChange}
placeholder="L'objet de votre message"
className="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
/>
</div>
{/* Message */} {/* Boutique 2 */}
<div> <div className="pb-4 border-b border-gray-200">
<label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-2"> <h3 className="font-semibold text-gray-900 mb-2">Paris Saint-Germain</h3>
Message <span className="text-red-500">*</span> <p className="text-gray-600 text-sm mb-1">
</label> 45 Boulevard Saint-Germain, 75006 Paris
<textarea </p>
id="message" <p className="text-sm text-gray-500">01 23 45 67 90</p>
name="message" </div>
required
value={formData.message}
onChange={handleChange}
placeholder="Décrivez votre demande..."
rows={6}
className="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent resize-none"
/>
</div>
{/* Checkbox Robot */} {/* Boutique 3 */}
<div className="flex items-center gap-3"> <div className="pb-4 border-b border-gray-200">
<input <h3 className="font-semibold text-gray-900 mb-2">Lyon République</h3>
id="notRobot" <p className="text-gray-600 text-sm mb-1">
name="notRobot" 78 Rue de la République, 69002 Lyon
type="checkbox" </p>
required <p className="text-sm text-gray-500">04 12 34 56 78</p>
checked={formData.notRobot} </div>
onChange={handleCheckboxChange}
className="w-5 h-5 text-primary-600 border-gray-300 rounded focus:ring-2 focus:ring-primary-500"
/>
<label htmlFor="notRobot" className="text-gray-700 select-none cursor-pointer">
Je ne suis pas un robot 🤖
</label>
</div>
{/* Submit Button */} {/* Boutique 4 */}
<div> <div>
<Button <h3 className="font-semibold text-gray-900 mb-2">Marseille Canebière</h3>
type="submit" <p className="text-gray-600 text-sm mb-1">
isLoading={isSubmitting} 32 La Canebière, 13001 Marseille
disabled={isSubmitting} </p>
size="lg" <p className="text-sm text-gray-500">04 91 23 45 67</p>
className="w-full" </div>
</div>
<div className="mt-6 pt-6 border-t border-gray-200">
<p className="text-xs text-gray-500 flex items-start gap-2">
<span>💡</span>
<span>Retrouvez toutes nos boutiques et leurs horaires sur notre site principal</span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* CTA FAQ Section */}
<section className="py-12">
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto">
<div className="bg-gradient-to-r from-yellow-50 to-yellow-100 rounded-xl p-8 border-l-4 border-yellow-500">
<div className="flex items-start gap-4">
<div className="text-3xl">💡</div>
<div className="flex-1">
<h3 className="text-xl font-bold text-gray-900 mb-2">Avant de nous contacter</h3>
<p className="text-gray-700 mb-4">
Consultez notre FAQ, vous y trouverez peut-être la réponse à votre question !
</p>
<Link
href="/faq"
className="inline-flex items-center justify-center bg-[#f59e0b] hover:bg-[#d97706] text-white font-bold px-6 py-3 rounded-lg transition-all"
> >
{isSubmitting ? "Envoi en cours..." : "Envoyer le message"} Voir la FAQ
</Button> </Link>
</div>
</form>
</CardContent>
</Card>
</div>
{/* Contact Info */}
<div className="space-y-6">
<Card className="shadow-lg">
<CardHeader>
<CardTitle className="text-2xl">Nos coordonnées</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{/* Adresse */}
<div className="flex items-start gap-4">
<div className="text-3xl">📍</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Adresse</h3>
<p className="text-gray-600">
123 Avenue des Thés<br />
06000 Nice, France
</p>
</div> </div>
</div> </div>
</div>
{/* Téléphone */}
<div className="flex items-start gap-4">
<div className="text-3xl">📞</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Téléphone</h3>
<p className="text-gray-600">
<a href="tel:+33187673218" className="hover:text-primary-600 transition-colors">
+33 1 87 67 32 18
</a>
</p>
</div>
</div>
{/* Email */}
<div className="flex items-start gap-4">
<div className="text-3xl"></div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Email</h3>
<p className="text-gray-600">
<a href="mailto:contact@the-tip-top.com" className="hover:text-primary-600 transition-colors">
contact@the-tip-top.com
</a>
</p>
</div>
</div>
{/* Horaires */}
<div className="flex items-start gap-4">
<div className="text-3xl">🕐</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Horaires d'ouverture</h3>
<p className="text-gray-600 text-sm">
Lundi - Vendredi : 9h - 19h<br />
Samedi : 9h - 18h<br />
Dimanche : 10h - 17h
</p>
</div>
</div>
</CardContent>
</Card>
{/* Localisation */}
<Card className="shadow-lg">
<CardHeader>
<CardTitle className="text-xl">Localisation</CardTitle>
</CardHeader>
<CardContent>
<div className="rounded-lg overflow-hidden h-64">
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2885.2563866557893!2d7.261953!1d43.7031922!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12cdd0106a852d31%3A0x40819a5fd970220!2sNice%2C%20France!5e0!3m2!1sfr!2sfr!4v1234567890123"
width="100%"
height="100%"
style={{ border: 0 }}
allowFullScreen
loading="lazy"
referrerPolicy="no-referrer-when-downgrade"
title="Localisation Thé Tip Top Nice"
/>
</div>
</CardContent>
</Card>
</div>
</div>
{/* Boutiques Section */}
<section className="bg-gradient-to-r from-primary-50 to-green-50 py-12 -mx-4 px-4 sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
<div className="max-w-6xl mx-auto">
<h2 className="text-3xl font-bold text-center text-gray-900 mb-4">
Nos boutiques
</h2>
<p className="text-center text-gray-600 mb-12">
Retrouvez-nous dans nos points de vente niçois
</p>
<div className="grid md:grid-cols-3 gap-8">
{/* Boutique Centre-Ville */}
<Card className="bg-white hover:shadow-xl transition-shadow">
<CardHeader>
<div className="text-4xl text-center mb-2">🏪</div>
<CardTitle className="text-center text-xl">Boutique Centre-Ville</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="text-center">
<p className="text-gray-700 font-medium">15 rue de la Paix</p>
<p className="text-gray-600 text-sm">06000 Nice</p>
</div>
<div className="text-center pt-3 border-t border-gray-200">
<p className="text-primary-600 font-semibold mb-1">
<a href="tel:+33493123456" className="hover:text-primary-700">
04 93 12 34 56
</a>
</p>
<p className="text-gray-600 text-sm">
9h-19h du lundi au samedi
</p>
</div>
</CardContent>
</Card>
{/* Boutique Vieux-Nice */}
<Card className="bg-white hover:shadow-xl transition-shadow">
<CardHeader>
<div className="text-4xl text-center mb-2">🏪</div>
<CardTitle className="text-center text-xl">Boutique Vieux-Nice</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="text-center">
<p className="text-gray-700 font-medium">28 rue des Rosiers</p>
<p className="text-gray-600 text-sm">06300 Nice</p>
</div>
<div className="text-center pt-3 border-t border-gray-200">
<p className="text-primary-600 font-semibold mb-1">
<a href="tel:+33494872416" className="hover:text-primary-700">
04 94 87 24 16
</a>
</p>
<p className="text-gray-600 text-sm">
10h-20h du lundi au dimanche
</p>
</div>
</CardContent>
</Card>
{/* Boutique Promenade */}
<Card className="bg-white hover:shadow-xl transition-shadow">
<CardHeader>
<div className="text-4xl text-center mb-2">🏪</div>
<CardTitle className="text-center text-xl">Boutique Promenade</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="text-center">
<p className="text-gray-700 font-medium">42 Promenade des Anglais</p>
<p className="text-gray-600 text-sm">06000 Nice</p>
</div>
<div className="text-center pt-3 border-t border-gray-200">
<p className="text-primary-600 font-semibold mb-1">
<a href="tel:+33493296714" className="hover:text-primary-700">
04 93 29 67 14
</a>
</p>
<p className="text-gray-600 text-sm">
9h30-19h30 du mardi au samedi
</p>
</div>
</CardContent>
</Card>
</div> </div>
</div> </div>
</section> </section>

View File

@ -2,284 +2,245 @@
import { useState } from "react"; import { useState } from "react";
import Link from "next/link"; import Link from "next/link";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card";
import Button from "@/components/Button";
import { ROUTES } from "@/utils/constants";
interface FAQ { interface FAQ {
category: string;
question: string; question: string;
answer: string; answer: string;
} }
interface FAQCategory { const faqData: FAQ[] = [
category: string;
icon: string;
faqs: FAQ[];
}
const faqData: FAQCategory[] = [
{ {
category: "Participation au Jeu", category: "Participation",
icon: "🎮", question: "Comment participer au jeu-concours ?",
faqs: [ answer: "Pour participer, vous devez effectuer un achat de minimum 49€ dans une boutique Thé Tip Top participante, récupérer votre ticket de caisse avec le code unique, créer un compte sur notre site www.thetiptop.fr, vous connecter et saisir votre code pour découvrir instantanément votre gain.",
{
question: "Comment participer au jeu-concours Thé Tip Top ?",
answer: "Pour participer, vous devez d'abord créer un compte sur notre plateforme. Ensuite, connectez-vous et saisissez le code unique présent sur votre ticket de caisse. Chaque achat en magasin vous donne droit à un code pour tenter votre chance !",
},
{
question: "Qui peut participer au jeu-concours ?",
answer: "Le jeu-concours est ouvert à toute personne majeure résidant en France métropolitaine. Les employés de Thé Tip Top et leurs familles directes ne sont pas éligibles.",
},
{
question: "Combien de fois puis-je participer ?",
answer: "Vous pouvez participer autant de fois que vous le souhaitez ! Chaque achat en magasin vous donne un nouveau code à jouer. Il n'y a pas de limite au nombre de participations.",
},
{
question: "Où trouver mon code de participation ?",
answer: "Votre code de participation se trouve sur votre ticket de caisse après chaque achat en magasin Thé Tip Top. Il est clairement indiqué dans une zone dédiée du ticket.",
},
{
question: "Mon code ne fonctionne pas, que faire ?",
answer: "Vérifiez d'abord que vous avez bien saisi le code sans erreur (attention aux caractères similaires comme 0/O ou 1/I). Si le problème persiste, contactez notre service client via la page Contact avec une photo de votre ticket.",
},
],
}, },
{ {
category: "Lots et Gains", category: "Codes",
icon: "🎁", question: "Où trouver mon code de participation ?",
faqs: [ answer: "Votre code de participation se trouve sur votre ticket de caisse après chaque achat de minimum 49€ en magasin Thé Tip Top. Il est clairement indiqué et composé de 10 caractères alphanumériques.",
{
question: "Quels sont les lots à gagner ?",
answer: "Vous pouvez gagner une variété de lots : des infuseurs à thé, des boîtes de thé signature (100g ou 200g), des coffrets découverte, et même un an de thé d'une valeur de 360€ ! Consultez notre page Lots pour voir tous les prix disponibles.",
},
{
question: "Comment savoir si j'ai gagné ?",
answer: "Vous saurez immédiatement si vous avez gagné après avoir saisi votre code. Un message s'affichera à l'écran vous indiquant votre lot. Vous recevrez également une confirmation par email avec les détails de votre gain.",
},
{
question: "Comment récupérer mon lot ?",
answer: "Pour les petits lots (infuseurs, boîtes de thé), vous pouvez les récupérer directement en magasin en présentant votre confirmation de gain. Pour les lots plus importants, nous vous contacterons pour organiser la livraison.",
},
{
question: "Combien de temps ai-je pour récupérer mon lot ?",
answer: "Vous avez 30 jours à compter de la date de gain pour récupérer votre lot. Passé ce délai, le lot ne pourra plus être réclamé.",
},
{
question: "Puis-je échanger mon lot contre un autre ?",
answer: "Les lots ne sont pas échangeables ni remboursables. Cependant, pour les coffrets et boîtes de thé, vous pourrez choisir parmi plusieurs variétés lors de la récupération.",
},
{
question: "Y a-t-il des frais pour recevoir mon lot ?",
answer: "Non, tous les lots sont entièrement gratuits, sans frais de livraison ni frais cachés.",
},
],
}, },
{ {
category: "Compte et Profil", category: "Codes",
icon: "👤", question: "Mon code ne fonctionne pas, que faire ?",
faqs: [ answer: "Vérifiez d'abord que vous avez bien saisi le code sans erreur (attention aux caractères similaires comme 0/O ou 1/I). Assurez-vous que le code n'a pas déjà été utilisé. Si le problème persiste, contactez notre service client via la page Contact avec une photo de votre ticket.",
{
question: "Comment créer un compte ?",
answer: "Cliquez sur le bouton 'S'inscrire' en haut de la page, remplissez le formulaire avec vos informations (nom, prénom, email, mot de passe) et validez. Vous recevrez un email de confirmation pour activer votre compte.",
},
{
question: "J'ai oublié mon mot de passe, que faire ?",
answer: "Sur la page de connexion, cliquez sur 'Mot de passe oublié'. Saisissez votre adresse email et vous recevrez un lien pour réinitialiser votre mot de passe.",
},
{
question: "Comment modifier mes informations personnelles ?",
answer: "Connectez-vous à votre compte et accédez à la page 'Mon Profil'. Vous pourrez y modifier vos informations personnelles, votre adresse email et votre mot de passe.",
},
{
question: "Puis-je supprimer mon compte ?",
answer: "Oui, vous pouvez demander la suppression de votre compte en contactant notre service client via la page Contact. Notez que cette action est irréversible et que vous perdrez l'accès à vos lots non récupérés.",
},
{
question: "Mes données personnelles sont-elles sécurisées ?",
answer: "Absolument. Nous prenons la protection de vos données très au sérieux. Toutes les informations sont cryptées et stockées de manière sécurisée. Consultez notre Politique de Confidentialité pour plus de détails.",
},
],
}, },
{ {
category: "Problèmes Techniques", category: "Compte",
icon: "🔧", question: "Puis-je créer un compte avec mes réseaux sociaux ?",
faqs: [ answer: "Oui, vous pouvez créer un compte et vous connecter rapidement en utilisant votre compte Google ou Facebook. Cela permet une inscription plus rapide et sécurisée.",
{
question: "Le site ne s'affiche pas correctement, que faire ?",
answer: "Essayez de vider le cache de votre navigateur et de rafraîchir la page. Assurez-vous également d'utiliser un navigateur récent (Chrome, Firefox, Safari, Edge). Si le problème persiste, contactez-nous.",
},
{
question: "Je n'arrive pas à me connecter",
answer: "Vérifiez que vous utilisez la bonne adresse email et le bon mot de passe. Si vous avez oublié votre mot de passe, utilisez la fonction 'Mot de passe oublié'. Assurez-vous également que les cookies sont activés dans votre navigateur.",
},
{
question: "Je n'ai pas reçu l'email de confirmation",
answer: "Vérifiez votre dossier spam ou courrier indésirable. Si vous ne trouvez toujours pas l'email après quelques minutes, vous pouvez demander un nouvel envoi depuis la page de connexion.",
},
{
question: "Le site est-il compatible avec les mobiles ?",
answer: "Oui, notre site est entièrement responsive et optimisé pour tous les appareils (smartphones, tablettes, ordinateurs). Vous pouvez participer depuis n'importe quel appareil.",
},
{
question: "Puis-je utiliser le site depuis l'étranger ?",
answer: "Vous pouvez accéder au site depuis l'étranger, mais seules les personnes résidant en France métropolitaine peuvent participer au jeu-concours et récupérer des lots.",
},
],
}, },
{ {
category: "Informations Générales", category: "Délais",
icon: "", question: "Jusqu'à quand puis-je saisir mon code ?",
faqs: [ answer: "Vous pouvez saisir votre code pendant toute la durée du jeu-concours, soit du 1er janvier 2025 au 31 janvier 2025 à 23h59. Après cette date, les codes ne seront plus acceptés.",
{ },
question: "Quelle est la durée du jeu-concours ?", {
answer: "Le jeu-concours se déroule du [date de début] au [date de fin]. Consultez notre page d'accueil pour les dates exactes et le temps restant.", category: "Retrait",
}, question: "Comment récupérer mon lot ?",
{ answer: "Pour les petits lots (infuseurs, boîtes de thé), vous pouvez les récupérer directement en magasin en présentant votre confirmation de gain. Pour les coffrets, vous avez le choix entre le retrait en boutique ou la livraison à domicile offerte. Pour le grand prix, une livraison mensuelle sera organisée à l'adresse de votre choix.",
question: "Comment contacter le service client ?", },
answer: "Vous pouvez nous contacter via notre page Contact, par email à contact@thetiptop.fr, ou par téléphone au [numéro]. Notre équipe est disponible du lundi au vendredi de 9h à 18h.", {
}, category: "Retrait",
{ question: "Dans quelles boutiques puis-je récupérer mon lot ?",
question: "Où se trouvent les magasins Thé Tip Top ?", answer: "Vous pouvez récupérer votre lot dans n'importe quelle boutique Thé Tip Top en France métropolitaine. Présentez simplement votre confirmation de gain (email ou capture d'écran) et une pièce d'identité.",
answer: "Nous avons des magasins dans toute la France. Consultez notre page À Propos ou contactez-nous pour trouver le magasin le plus proche de chez vous.", },
}, {
{ category: "Tirage final",
question: "Puis-je offrir mon lot à quelqu'un d'autre ?", question: "Comment fonctionne le tirage final pour le grand prix ?",
answer: "Oui, les lots sont cessibles. Vous pouvez offrir votre lot à un tiers, mais la personne devra présenter votre confirmation de gain pour le récupérer.", answer: "À l'issue de la période de participation, un tirage au sort sera organisé le 15 février 2025 sous contrôle d'huissier de justice (Maître Dupont, Office Notarial de Paris) pour désigner le grand gagnant du prix principal : 1 an de thé offert d'une valeur de 360€. Tous les participants ayant validé au moins un code sont automatiquement inscrits au tirage.",
}, },
{ {
question: "Le jeu-concours est-il gratuit ?", category: "Données",
answer: "Oui, la participation au jeu-concours est entièrement gratuite. Vous devez simplement effectuer un achat en magasin pour obtenir un code de participation.", question: "Mes données personnelles sont-elles protégées ?",
}, answer: "Absolument. Nous prenons la protection de vos données très au sérieux conformément au RGPD. Toutes les informations sont cryptées et stockées de manière sécurisée. Vous disposez d'un droit d'accès, de rectification et d'effacement de vos données. Consultez notre Politique de Confidentialité pour plus de détails.",
{ },
question: "Où puis-je consulter le règlement du jeu ?", {
answer: "Le règlement complet du jeu-concours est disponible sur notre page Règlement du Jeu. Nous vous recommandons de le lire attentivement avant de participer.", category: "Technique",
}, question: "Le site ne fonctionne pas, que faire ?",
], answer: "Essayez de vider le cache de votre navigateur et de rafraîchir la page (Ctrl+F5 ou Cmd+Shift+R). Assurez-vous d'utiliser un navigateur récent (Chrome, Firefox, Safari, Edge). Vérifiez que JavaScript et les cookies sont activés. Si le problème persiste, contactez notre support technique à support@thetiptop.com.",
}, },
]; ];
function FAQItem({ faq, isOpen, onClick }: { faq: FAQ; isOpen: boolean; onClick: () => void }) { const categories = [
return ( { name: "Participation", color: "bg-green-100 text-green-700" },
<div className="border-b border-gray-200 last:border-b-0"> { name: "Codes", color: "bg-blue-100 text-blue-700" },
<button { name: "Compte", color: "bg-purple-100 text-purple-700" },
className="w-full py-4 px-6 text-left flex justify-between items-center hover:bg-gray-50 transition-colors" { name: "Délais", color: "bg-orange-100 text-orange-700" },
onClick={onClick} { name: "Retrait", color: "bg-teal-100 text-teal-700" },
aria-expanded={isOpen} { name: "Tirage final", color: "bg-yellow-100 text-yellow-700" },
> { name: "Données", color: "bg-pink-100 text-pink-700" },
<span className="font-medium text-gray-900 pr-8">{faq.question}</span> { name: "Technique", color: "bg-gray-100 text-gray-700" },
<span className={`text-primary-600 text-xl flex-shrink-0 transition-transform ${isOpen ? 'rotate-45' : ''}`}> ];
+
</span>
</button>
{isOpen && (
<div className="px-6 pb-4 text-gray-600 leading-relaxed">
{faq.answer}
</div>
)}
</div>
);
}
export default function FAQContent() { export default function FAQContent() {
const [openItems, setOpenItems] = useState<{ [key: string]: boolean }>({}); const [searchQuery, setSearchQuery] = useState("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [openQuestion, setOpenQuestion] = useState<number | null>(null);
const toggleItem = (categoryIndex: number, faqIndex: number) => { const toggleQuestion = (index: number) => {
const key = `${categoryIndex}-${faqIndex}`; setOpenQuestion(openQuestion === index ? null : index);
setOpenItems((prev) => ({ };
...prev,
[key]: !prev[key], const filteredFAQs = faqData.filter((faq) => {
})); const matchesSearch =
faq.question.toLowerCase().includes(searchQuery.toLowerCase()) ||
faq.answer.toLowerCase().includes(searchQuery.toLowerCase());
const matchesCategory = !selectedCategory || faq.category === selectedCategory;
return matchesSearch && matchesCategory;
});
const getCategoryColor = (category: string) => {
const cat = categories.find(c => c.name === category);
return cat?.color || "bg-gray-100 text-gray-700";
}; };
return ( return (
<div className="min-h-screen bg-gray-50 py-12"> <div className="min-h-screen bg-gray-50">
<div className="max-w-4xl mx-auto px-4"> {/* Hero Section */}
{/* Hero Section */} <section className="bg-white py-12">
<div className="text-center mb-12"> <div className="container mx-auto px-4">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4"> <div className="max-w-4xl mx-auto text-center">
Questions Fréquentes <h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
</h1> Questions fréquentes
<p className="text-lg text-gray-600 max-w-2xl mx-auto"> </h1>
Trouvez rapidement les réponses à vos questions sur le jeu-concours Thé Tip Top. <p className="text-lg text-gray-600">
Si vous ne trouvez pas la réponse que vous cherchez, n'hésitez pas à nous contacter. Trouvez rapidement les réponses à vos questions sur notre jeu-concours Thé Tip Top.
</p> </p>
</div>
{/* Search Hint */}
<div className="mb-8 p-4 bg-blue-50 border border-blue-200 rounded-lg text-center">
<p className="text-sm text-blue-800">
💡 <strong>Astuce :</strong> Utilisez Ctrl+F (Cmd+F sur Mac) pour rechercher un mot-clé dans cette page
</p>
</div>
{/* FAQ Categories */}
<div className="space-y-8">
{faqData.map((category, categoryIndex) => (
<Card key={categoryIndex} className="overflow-hidden">
<CardHeader className="bg-gradient-to-r from-primary-50 to-primary-100">
<CardTitle className="flex items-center gap-3 text-primary-900">
<span className="text-2xl">{category.icon}</span>
<span>{category.category}</span>
</CardTitle>
</CardHeader>
<CardContent className="p-0">
{category.faqs.map((faq, faqIndex) => (
<FAQItem
key={faqIndex}
faq={faq}
isOpen={openItems[`${categoryIndex}-${faqIndex}`] || false}
onClick={() => toggleItem(categoryIndex, faqIndex)}
/>
))}
</CardContent>
</Card>
))}
</div>
{/* CTA Section */}
<div className="mt-12 text-center bg-white rounded-lg shadow-lg p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">
Vous n'avez pas trouvé votre réponse ?
</h2>
<p className="text-gray-600 mb-6">
Notre équipe est pour vous aider ! Contactez-nous et nous vous répondrons dans les plus brefs délais.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Link href="/contact">
<Button variant="primary" className="w-full sm:w-auto">
Nous Contacter
</Button>
</Link>
<Link href={ROUTES.HOME}>
<Button variant="outline" className="w-full sm:w-auto">
Retour à l'Accueil
</Button>
</Link>
</div> </div>
</div> </div>
</section>
{/* Quick Links */} {/* Search Bar */}
<div className="mt-8 text-center text-sm text-gray-600"> <section className="py-8">
<p className="mb-2">Pages utiles :</p> <div className="container mx-auto px-4">
<div className="flex flex-wrap justify-center gap-4"> <div className="max-w-4xl mx-auto">
<Link href="/rules" className="text-primary-600 hover:text-primary-700 underline"> <div className="relative">
Règlement du Jeu <input
</Link> type="text"
<span className="text-gray-400"></span> placeholder="Rechercher une question..."
<Link href={ROUTES.LOTS} className="text-primary-600 hover:text-primary-700 underline"> value={searchQuery}
Lots à Gagner onChange={(e) => setSearchQuery(e.target.value)}
</Link> className="w-full px-4 py-3 pl-12 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent"
<span className="text-gray-400"></span> />
<Link href="/about" className="text-primary-600 hover:text-primary-700 underline"> <svg
À Propos className="absolute left-4 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400"
</Link> fill="none"
<span className="text-gray-400"></span> stroke="currentColor"
<Link href="/privacy" className="text-primary-600 hover:text-primary-700 underline"> viewBox="0 0 24 24"
Confidentialité >
</Link> <path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</div>
</div> </div>
</div> </div>
</div> </section>
{/* Category Filters */}
<section className="pb-8">
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto">
<div className="flex flex-wrap gap-3">
{categories.map((category) => (
<button
key={category.name}
onClick={() => setSelectedCategory(
selectedCategory === category.name ? null : category.name
)}
className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${
selectedCategory === category.name
? category.color + ' ring-2 ring-offset-2 ring-green-500'
: category.color + ' hover:opacity-80'
}`}
>
{category.name}
</button>
))}
</div>
</div>
</div>
</section>
{/* FAQ Questions */}
<section className="pb-16">
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto space-y-3">
{filteredFAQs.length === 0 ? (
<div className="bg-white rounded-xl shadow-md p-8 text-center text-gray-500">
Aucune question ne correspond à votre recherche.
</div>
) : (
filteredFAQs.map((faq, index) => (
<div key={index} className="bg-white rounded-xl shadow-md overflow-hidden">
<button
onClick={() => toggleQuestion(index)}
className="w-full flex items-start justify-between p-6 text-left hover:bg-gray-50 transition-colors"
>
<div className="flex-1 pr-4">
<div className="flex items-center gap-2 mb-2">
<span className={`text-xs font-bold px-2 py-1 rounded ${getCategoryColor(faq.category)}`}>
{faq.category}
</span>
</div>
<h3 className="text-lg font-semibold text-gray-900">{faq.question}</h3>
</div>
<svg
className={`w-6 h-6 text-gray-500 flex-shrink-0 transition-transform ${
openQuestion === index ? 'rotate-180' : ''
}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{openQuestion === index && (
<div className="px-6 pb-6 text-gray-700 leading-relaxed">
{faq.answer}
</div>
)}
</div>
))
)}
</div>
</div>
</section>
{/* CTA Section */}
<section className="pb-16">
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto">
<div className="bg-gradient-to-br from-[#1a4d2e] via-[#2d5a3d] to-[#1a4d2e] rounded-xl p-8 text-center text-white">
<h2 className="text-2xl md:text-3xl font-bold mb-4">
Vous ne trouvez pas votre réponse ?
</h2>
<p className="text-white/90 mb-6 max-w-2xl mx-auto">
Notre équipe est pour vous aider ! Contactez-nous et nous vous répondrons dans les plus brefs délais.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="mailto:support@thetiptop.com"
className="inline-flex items-center justify-center gap-2 bg-[#f59e0b] hover:bg-[#d97706] text-white font-bold px-8 py-3 rounded-lg transition-all"
>
support@thetiptop.com
</a>
<Link
href="/contact"
className="inline-flex items-center justify-center bg-white hover:bg-gray-100 text-[#1a4d2e] font-bold px-8 py-3 rounded-lg transition-all"
>
Formulaire de contact
</Link>
</div>
</div>
</div>
</div>
</section>
</div> </div>
); );
} }

View File

@ -1,113 +1,137 @@
"use client"; "use client";
import { useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Input } from "@/components/ui/Input";
import Button from "@/components/Button";
import { Card } from "@/components/ui/Card";
import Link from "next/link"; import Link from "next/link";
import { ROUTES } from "@/utils/constants"; import { ROUTES } from "@/utils/constants";
import toast from "react-hot-toast";
const forgotPasswordSchema = z.object({
email: z.string().email("Email invalide"),
});
type ForgotPasswordFormData = z.infer<typeof forgotPasswordSchema>;
export default function ForgotPasswordPage() { export default function ForgotPasswordPage() {
const [email, setEmail] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [emailSent, setEmailSent] = useState(false); const [isSuccess, setIsSuccess] = useState(false);
const { const handleSubmit = async (e: React.FormEvent) => {
register, e.preventDefault();
handleSubmit,
formState: { errors },
} = useForm<ForgotPasswordFormData>({
resolver: zodResolver(forgotPasswordSchema),
});
const onSubmit = async (data: ForgotPasswordFormData) => {
setIsSubmitting(true); setIsSubmitting(true);
try {
// TODO: Implement password reset API call
console.log("Password reset requested for:", data.email);
// Simulate API call // Simulation d'envoi
await new Promise(resolve => setTimeout(resolve, 1000)); await new Promise(resolve => setTimeout(resolve, 1500));
setEmailSent(true); console.log('Password reset email sent to:', email);
toast.success("Email de réinitialisation envoyé !"); setIsSuccess(true);
} catch (error) { setIsSubmitting(false);
console.error("Password reset error:", error);
toast.error("Erreur lors de l'envoi de l'email");
} finally {
setIsSubmitting(false);
}
}; };
if (isSuccess) {
return (
<div className="min-h-screen bg-gray-50 flex items-center justify-center py-12 px-4">
<div className="w-full max-w-md">
{/* Title */}
<div className="text-center mb-8">
<h1 className="text-4xl font-bold text-gray-900 mb-2">Email envoyé !</h1>
<p className="text-gray-600">
Vérifiez votre boîte de réception
</p>
</div>
{/* Success Card */}
<div className="bg-white rounded-xl shadow-md p-8">
<div className="text-center">
<div className="mx-auto w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mb-4">
<svg className="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
</div>
<h2 className="text-xl font-bold text-gray-900 mb-2">
Lien de réinitialisation envoyé
</h2>
<p className="text-gray-600 mb-6">
Nous avons envoyé un lien de réinitialisation à <strong>{email}</strong>
</p>
<div className="bg-blue-50 border-l-4 border-blue-500 p-4 mb-6 text-left">
<p className="text-sm text-blue-800">
<strong>💡 Conseil :</strong> Si vous ne recevez pas l'email dans quelques minutes, vérifiez votre dossier spam.
</p>
</div>
<Link
href={ROUTES.LOGIN}
className="inline-flex items-center justify-center w-full bg-[#1a4d2e] hover:bg-[#2d5a3d] text-white font-bold px-8 py-4 rounded-lg transition-all"
>
Retour à la connexion
</Link>
</div>
</div>
</div>
</div>
);
}
return ( return (
<div className="min-h-[calc(100vh-4rem)] flex items-center justify-center py-12 px-4"> <div className="min-h-screen bg-gray-50 flex items-center justify-center py-12 px-4">
<Card className="w-full max-w-md p-8"> <div className="w-full max-w-md">
{/* Title */}
<div className="text-center mb-8"> <div className="text-center mb-8">
<h1 className="text-3xl font-bold text-gray-900 mb-2"> <h1 className="text-4xl font-bold text-gray-900 mb-2">Mot de passe oublié</h1>
Mot de passe oublié
</h1>
<p className="text-gray-600"> <p className="text-gray-600">
Entrez votre email pour recevoir un lien de réinitialisation Entrez votre email pour recevoir un lien de réinitialisation
</p> </p>
</div> </div>
{!emailSent ? ( {/* Main Card */}
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4"> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<Input
id="email" {/* Form Container */}
type="email" <div className="p-8">
label="Email"
placeholder="votre.email@example.com" {/* Form */}
error={errors.email?.message} <form onSubmit={handleSubmit} className="space-y-6">
{...register("email")}
required {/* Email */}
/> <div>
<label htmlFor="email" className="block text-sm font-semibold text-gray-700 mb-2">
Email <span className="text-red-500">*</span>
</label>
<input
id="email"
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="votre.email@example.com"
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent"
/>
</div>
{/* Submit Button */}
<button
type="submit"
disabled={isSubmitting}
className="w-full bg-[#1a4d2e] hover:bg-[#2d5a3d] disabled:bg-gray-400 text-white font-bold px-8 py-4 rounded-lg transition-all"
>
{isSubmitting ? "Envoi en cours..." : "Envoyer le lien de réinitialisation"}
</button>
{/* Back to Login */}
<div className="text-center">
<p className="text-sm text-gray-600">
Vous vous souvenez de votre mot de passe ?{' '}
<Link
href={ROUTES.LOGIN}
className="text-[#1a4d2e] hover:text-[#f59e0b] hover:underline font-semibold transition-colors"
>
Se connecter
</Link>
</p>
</div>
</form>
<Button
type="submit"
isLoading={isSubmitting}
disabled={isSubmitting}
fullWidth
size="lg"
>
Envoyer le lien de réinitialisation
</Button>
</form>
) : (
<div className="text-center py-6">
<div className="text-6xl mb-4"></div>
<h2 className="text-xl font-semibold text-gray-900 mb-2">
Email envoyé !
</h2>
<p className="text-gray-600 mb-6">
Vérifiez votre boîte mail et suivez les instructions pour réinitialiser votre mot de passe.
</p>
<Link href={ROUTES.LOGIN}>
<Button variant="outline" fullWidth>
Retour à la connexion
</Button>
</Link>
</div> </div>
)} </div>
</div>
<p className="mt-6 text-center text-sm text-gray-600">
Vous vous souvenez de votre mot de passe ?{" "}
<Link
href={ROUTES.LOGIN}
className="font-medium text-blue-600 hover:text-blue-700 hover:underline"
>
Se connecter
</Link>
</p>
</Card>
</div> </div>
); );
} }

337
app/gagnants/page.tsx Normal file
View File

@ -0,0 +1,337 @@
'use client';
import type { Metadata } from "next";
import Link from "next/link";
import { useState } from "react";
interface Winner {
date: string;
name: string;
prize: string;
prizeType: 'coffret-prestige' | 'boite-signature' | 'infuseur' | 'coffret-decouverte' | 'boite-detox';
boutique: string;
city: string;
testimonial?: {
initials: string;
text: string;
stars: number;
};
}
const winners: Winner[] = [
{
date: "15 janvier 2024",
name: "Marie L.",
prize: "Coffret prestige 69€",
prizeType: "coffret-prestige",
boutique: "Boutique Rivoli",
city: "Paris 1er"
},
{
date: "15 janvier 2024",
name: "Pierre L.",
prize: "Boîte 100g thé signature",
prizeType: "boite-signature",
boutique: "Boutique République",
city: "Lyon"
},
{
date: "14 janvier 2024",
name: "Sophie L.",
prize: "Infuseur à thé premium",
prizeType: "infuseur",
boutique: "Boutique Canebière",
city: "Marseille"
},
{
date: "14 janvier 2024",
name: "Thomas L.",
prize: "Coffret découverte 39€",
prizeType: "coffret-decouverte",
boutique: "Boutique Saint-Germain",
city: "Paris 6e"
},
{
date: "13 janvier 2024",
name: "Julie L.",
prize: "Boîte 100g thé détox",
prizeType: "boite-detox",
boutique: "Boutique Capitole",
city: "Toulouse"
},
{
date: "13 janvier 2024",
name: "Antoine L.",
prize: "Infuseur à thé premium",
prizeType: "infuseur",
boutique: "Boutique Promenade",
city: "Nice"
},
{
date: "12 janvier 2024",
name: "Camille L.",
prize: "Boîte 100g thé signature",
prizeType: "boite-signature",
boutique: "Boutique Sainte-Catherine",
city: "Bordeaux"
},
{
date: "12 janvier 2024",
name: "Maxime L.",
prize: "Infuseur à thé premium",
prizeType: "infuseur",
boutique: "Boutique Kléber",
city: "Strasbourg"
},
{
date: "11 janvier 2024",
name: "Emma L.",
prize: "Coffret prestige 69€",
prizeType: "coffret-prestige",
boutique: "Boutique Vieux-Lille",
city: "Lille"
},
{
date: "11 janvier 2024",
name: "Lucas L.",
prize: "Boîte 100g thé détox",
prizeType: "boite-detox",
boutique: "Boutique Commerce",
city: "Nantes"
},
];
const testimonials = [
{
initials: "ML",
name: "Marie L.",
city: "Paris 9e",
text: "J'ai gagné le coffret prestige ! Les thés sont délicieux, merci Thé Tip Top pour cette belle surprise !",
stars: 5
},
{
initials: "PD",
name: "Pierre D.",
city: "Lyon",
text: "Le thé signature est exceptionnel ! Je recommande vivement cette boutique, et le jeu est super !",
stars: 5
},
{
initials: "SB",
name: "Sophie B.",
city: "Marseille",
text: "Mon infuseur est magnifique ! Parfait pour mes thés du matin. Merci pour ce jeu génial !",
stars: 5
}
];
const getPrizeIcon = (type: string) => {
switch (type) {
case 'coffret-prestige':
return '🎁';
case 'boite-signature':
return '🌿';
case 'infuseur':
return '🍵';
case 'coffret-decouverte':
return '🎁';
case 'boite-detox':
return '📦';
default:
return '🎁';
}
};
const getPrizeColor = (type: string) => {
switch (type) {
case 'coffret-prestige':
return 'bg-pink-100 text-pink-700';
case 'boite-signature':
return 'bg-yellow-100 text-yellow-700';
case 'infuseur':
return 'bg-blue-100 text-blue-700';
case 'coffret-decouverte':
return 'bg-orange-100 text-orange-700';
case 'boite-detox':
return 'bg-green-100 text-green-700';
default:
return 'bg-gray-100 text-gray-700';
}
};
export default function GagnantsPage() {
const [periodFilter, setPeriodFilter] = useState("Toutes les dates");
const [typeFilter, setTypeFilter] = useState("Tous les lots");
return (
<div className="min-h-screen bg-gray-50">
{/* Hero Section */}
<section className="bg-white py-12">
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto text-center">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
Nos gagnants
</h1>
<p className="text-lg text-gray-600">
Découvrez les heureux gagnants de notre jeu-concours Thé Tip Top.
Félicitations à tous les participants !
</p>
</div>
</div>
</section>
{/* Stats Section */}
<section className="py-8">
<div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto">
<div className="grid md:grid-cols-3 gap-6">
{/* Stat 1 */}
<div className="bg-white rounded-xl shadow-md p-6 text-center">
<div className="text-4xl font-bold text-[#1a4d2e] mb-2">10</div>
<div className="text-gray-900 font-semibold mb-1">Gagnants au total</div>
<div className="text-sm text-gray-500">Depuis le début du jeu</div>
</div>
{/* Stat 2 */}
<div className="bg-white rounded-xl shadow-md p-6 text-center">
<div className="text-4xl font-bold text-[#1a4d2e] mb-2">5</div>
<div className="text-gray-900 font-semibold mb-1">Jours d'activité</div>
<div className="text-sm text-gray-500">Jours avec des gagnants</div>
</div>
{/* Stat 3 */}
<div className="bg-white rounded-xl shadow-md p-6 text-center">
<div className="text-4xl font-bold text-[#1a4d2e] mb-2">10</div>
<div className="text-gray-900 font-semibold mb-1">Villes représentées</div>
<div className="text-sm text-gray-500">Dans toute la France</div>
</div>
</div>
</div>
</div>
</section>
{/* Winners List */}
<section className="py-8 pb-16">
<div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto">
<div className="bg-white rounded-xl shadow-md overflow-hidden">
<div className="p-6 border-b border-gray-200">
<div className="flex items-center gap-2">
<span className="text-xl">🏆</span>
<h2 className="text-xl font-bold text-gray-900">Liste des gagnants ({winners.length})</h2>
</div>
</div>
{/* Table Header */}
<div className="hidden md:grid md:grid-cols-4 gap-4 px-6 py-4 bg-gray-50 border-b border-gray-200 text-sm font-semibold text-gray-700">
<div>DATE</div>
<div>GAGNANT</div>
<div>LOT REMPORTÉ</div>
<div>BOUTIQUE</div>
</div>
{/* Table Rows */}
<div className="divide-y divide-gray-200">
{winners.map((winner, index) => (
<div key={index} className="px-6 py-4 hover:bg-gray-50 transition-colors">
<div className="grid md:grid-cols-4 gap-4 items-center">
{/* Date */}
<div className="flex items-center gap-2">
<span className="text-gray-400 md:hidden font-semibold">📅</span>
<span className="text-gray-600">{winner.date}</span>
</div>
{/* Name */}
<div className="flex items-center gap-2">
<span className="text-gray-400 md:hidden font-semibold">👤</span>
<span className="font-medium text-gray-900">{winner.name}</span>
</div>
{/* Prize */}
<div>
<span className={`inline-flex items-center gap-2 px-3 py-1 rounded-full text-sm font-medium ${getPrizeColor(winner.prizeType)}`}>
<span>{getPrizeIcon(winner.prizeType)}</span>
<span>{winner.prize}</span>
</span>
</div>
{/* Boutique */}
<div className="flex items-center gap-2">
<span className="text-gray-400 md:hidden font-semibold">🏪</span>
<div>
<div className="font-medium text-gray-900">{winner.boutique}</div>
<div className="text-sm text-gray-500">{winner.city}</div>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</section>
{/* Testimonials Section */}
<section className="pb-16">
<div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto">
<h2 className="text-2xl font-bold text-gray-900 mb-8 text-center">Témoignages de nos gagnants</h2>
<div className="grid md:grid-cols-3 gap-6">
{testimonials.map((testimonial, index) => (
<div key={index} className="bg-white rounded-xl shadow-md p-6">
<div className="flex items-center gap-3 mb-4">
<div className="w-12 h-12 bg-[#1a4d2e] text-white rounded-full flex items-center justify-center font-bold">
{testimonial.initials}
</div>
<div>
<div className="font-semibold text-gray-900">{testimonial.name}</div>
<div className="text-sm text-gray-500">{testimonial.city}</div>
</div>
</div>
<p className="text-gray-600 text-sm mb-3 italic">"{testimonial.text}"</p>
<div className="flex gap-1">
{[...Array(testimonial.stars)].map((_, i) => (
<span key={i} className="text-yellow-400"></span>
))}
</div>
</div>
))}
</div>
</div>
</div>
</section>
{/* CTA Section */}
<section className="pb-16">
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto">
<div className="bg-gradient-to-br from-[#1a4d2e] via-[#2d5a3d] to-[#1a4d2e] rounded-xl p-12 text-center text-white">
<h2 className="text-3xl md:text-4xl font-bold mb-4">
Vous aussi, rejoignez nos gagnants !
</h2>
<p className="text-xl mb-8 text-white/90 max-w-2xl mx-auto">
Avec 100% de gagnants garantis, c'est votre tour de remporter un magnifique lot.
Rendez-vous en boutique et tentez votre chance !
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Link
href="/register"
className="inline-flex items-center justify-center bg-[#f59e0b] hover:bg-[#d97706] text-white font-bold px-8 py-4 rounded-lg transition-all shadow-xl"
>
Participer maintenant
</Link>
<Link
href="/lots"
className="inline-flex items-center justify-center bg-white hover:bg-gray-100 text-[#1a4d2e] font-bold px-8 py-4 rounded-lg transition-all"
>
Voir les lots
</Link>
</div>
</div>
</div>
</div>
</section>
</div>
);
}

View File

@ -10,6 +10,7 @@ export default function LayoutClient({ children }: { children: React.ReactNode }
// Ne pas afficher Header/Footer dans l'espace admin et employé // Ne pas afficher Header/Footer dans l'espace admin et employé
const isAdminRoute = pathname?.startsWith("/admin"); const isAdminRoute = pathname?.startsWith("/admin");
const isEmployeRoute = pathname?.startsWith("/employe"); const isEmployeRoute = pathname?.startsWith("/employe");
const isHomePage = pathname === "/";
if (isAdminRoute || isEmployeRoute) { if (isAdminRoute || isEmployeRoute) {
return <>{children}</>; return <>{children}</>;
@ -18,7 +19,7 @@ export default function LayoutClient({ children }: { children: React.ReactNode }
return ( return (
<> <>
<Header /> <Header />
<main className="flex-1 container mx-auto px-4 py-6 sm:px-6 lg:px-8"> <main className={isHomePage ? "flex-1" : "flex-1 container mx-auto px-4 py-6 sm:px-6 lg:px-8"}>
{children} {children}
</main> </main>
<Footer /> <Footer />

View File

@ -1,257 +1,233 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import Link from "next/link"; import Link from "next/link";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card";
import Button from "@/components/Button";
import { ROUTES } from "@/utils/constants";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Nos Gains - Thé Tip Top", title: "Lots à gagner - Thé Tip Top",
description: "Découvrez nos gains d'exception d'une valeur pouvant atteindre 100€", description: "Découvrez tous les magnifiques prix de notre jeu-concours. Avec 100% de gagnants garantis, chaque participant repart avec un lot !",
}; };
export default function LotsPage() { export default function LotsPage() {
return ( return (
<div className="py-12"> <div className="min-h-screen bg-gray-50">
{/* Hero Section */} {/* Hero Section */}
<section className="text-center mb-16"> <section className="bg-white py-12">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6"> <div className="container mx-auto px-4">
Nos gains d'exception <div className="max-w-4xl mx-auto text-center">
</h1> <h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
<p className="text-lg md:text-xl text-gray-600 max-w-3xl mx-auto"> Lots à gagner
Des récompenses d'une valeur pouvant atteindre 100 vous attendent ! </h1>
Explorez notre sélection de thés premium et d'accessoires exclusifs. <p className="text-lg text-gray-600">
</p> Découvrez tous les magnifiques prix de notre jeu-concours. Avec 100% de gagnants garantis,
chaque participant repart avec un lot !
</p>
</div>
</div>
</section>
{/* Grand Prix Final */}
<section className="py-8">
<div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto">
<div className="bg-gradient-to-r from-yellow-100 to-yellow-200 rounded-2xl p-8 shadow-lg border-2 border-yellow-300">
<div className="flex flex-col md:flex-row items-center gap-6">
<div className="flex-shrink-0">
<div className="w-32 h-32 bg-white rounded-lg flex items-center justify-center text-6xl shadow-md">
🏆
</div>
</div>
<div className="flex-1 text-center md:text-left">
<div className="inline-block bg-red-500 text-white text-xs font-bold px-3 py-1 rounded-full mb-2">
GRAND PRIX FINAL
</div>
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-2">
1 an de thé offert
</h2>
<p className="text-gray-700 mb-3">
Le grand prix du tirage final : une année complète de thé premium livré chez vous
</p>
<div className="text-2xl font-bold text-orange-600">
Valeur : 360 <span className="text-sm text-gray-600 font-normal">Tirage sous contrôle d'huissier</span>
</div>
</div>
</div>
</div>
</div>
</div>
</section> </section>
{/* Prizes Grid */} {/* Prizes Grid */}
<section className="mb-16"> <section className="py-8 pb-16">
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-6xl mx-auto"> <div className="container mx-auto px-4">
{/* Infuseur */} <div className="max-w-5xl mx-auto">
<Card className="hover:shadow-xl transition-shadow"> <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
<CardHeader>
<div className="text-5xl text-center mb-3">🍵</div>
<CardTitle className="text-center text-xl">Infuseur de thé</CardTitle>
</CardHeader>
<CardContent className="text-center">
<p className="text-gray-600 leading-relaxed">
Un infuseur en acier inoxydable de qualité supérieure pour révéler
tous les arômes de vos thés.
</p>
</CardContent>
</Card>
{/* Thé détox */} {/* Prize 1 - Infuseur */}
<Card className="hover:shadow-xl transition-shadow"> <div className="bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow overflow-hidden">
<CardHeader> <div className="aspect-square bg-gradient-to-br from-amber-50 to-orange-50 flex items-center justify-center">
<div className="text-5xl text-center mb-3">🌿</div> <div className="text-8xl">🍵</div>
<CardTitle className="text-center text-xl">Boite de 100g d'un thé détox</CardTitle>
</CardHeader>
<CardContent className="text-center">
<p className="text-gray-600 leading-relaxed">
Un mélange exclusif de plantes biologiques pour purifier votre
organisme en douceur.
</p>
</CardContent>
</Card>
{/* Coffret 39€ */}
<Card className="hover:shadow-xl transition-shadow">
<CardHeader>
<div className="text-5xl text-center mb-3">🎁</div>
<CardTitle className="text-center text-xl">Coffret Découverte de 39</CardTitle>
</CardHeader>
<CardContent className="text-center">
<p className="text-gray-600 leading-relaxed">
Une sélection de 6 thés d'exception du monde entier dans un élégant
coffret cadeau.
</p>
</CardContent>
</Card>
{/* Thé signature */}
<Card className="hover:shadow-xl transition-shadow">
<CardHeader>
<div className="text-5xl text-center mb-3"></div>
<CardTitle className="text-center text-xl">Thé signature</CardTitle>
</CardHeader>
<CardContent className="text-center">
<p className="text-gray-600 leading-relaxed">
Un mélange de thé exclusif, soigneusement élaboré par nos maîtres artisans,
offrant des arômes uniques et une expérience authentique à chaque tasse.
</p>
</CardContent>
</Card>
{/* Coffret 69€ */}
<Card className="hover:shadow-xl transition-shadow">
<CardHeader>
<div className="text-5xl text-center mb-3">🏆</div>
<CardTitle className="text-center text-xl">Coffret Découverte de 69</CardTitle>
</CardHeader>
<CardContent className="text-center">
<p className="text-gray-600 leading-relaxed">
Un coffret premium contenant une sélection de nos meilleurs thés
d'exception avec accessoires assortis.
</p>
</CardContent>
</Card>
{/* CTA Card */}
<Card className="bg-gradient-to-br from-primary-600 to-primary-700 text-white hover:shadow-xl transition-shadow flex items-center justify-center">
<CardContent className="text-center py-8">
<div className="text-5xl mb-4">🎮</div>
<h3 className="text-2xl font-bold mb-4">Participer maintenant</h3>
<Link href={ROUTES.GAME}>
<Button
variant="outline"
className="bg-white text-primary-600 hover:bg-primary-50 border-white"
>
Jouer
</Button>
</Link>
</CardContent>
</Card>
</div>
</section>
{/* Comment participer Section */}
<section className="mb-16 bg-gradient-to-r from-primary-50 to-green-50 py-12 -mx-4 px-4 sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
<div className="max-w-5xl mx-auto">
<h2 className="text-3xl font-bold text-center text-gray-900 mb-4">
Comment participer ?
</h2>
<p className="text-center text-gray-600 mb-12 max-w-2xl mx-auto">
Trois étapes simples pour tenter votre chance et repartir avec nos gains d'exception.
</p>
<div className="grid md:grid-cols-3 gap-8">
{/* Étape 1 */}
<Card className="bg-white text-center hover:shadow-lg transition-shadow">
<CardContent className="pt-8">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary-600 text-white text-3xl font-bold mb-4">
1
</div> </div>
<h3 className="text-xl font-bold mb-3 text-gray-900"> <div className="p-6">
Créez votre compte <div className="inline-block bg-red-100 text-red-600 text-sm font-bold px-3 py-1 rounded-full mb-3">
</h3> 60% des lots
<p className="text-gray-600"> </div>
Ouvrez gratuitement votre espace et rejoignez notre communauté de passionnés. <h3 className="text-xl font-bold text-gray-900 mb-2">Infuseur à thé premium</h3>
</p> <p className="text-gray-600 text-sm mb-4">
</CardContent> Un infuseur en acier inoxydable de haute qualité pour ressortir les arômes de vos thés en vrac
</Card> </p>
<div className="flex items-center justify-between">
{/* Étape 2 */} <div className="text-2xl font-bold text-[#1a4d2e]">15</div>
<Card className="bg-white text-center hover:shadow-lg transition-shadow"> <button className="text-[#1a4d2e] hover:text-[#f59e0b] transition-colors">
<CardContent className="pt-8"> <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary-600 text-white text-3xl font-bold mb-4"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
2 </svg>
</button>
</div>
</div> </div>
<h3 className="text-xl font-bold mb-3 text-gray-900"> </div>
Participez
</h3>
<p className="text-gray-600">
Prenez part au jeu-concours et validez votre participation chaque jour.
</p>
</CardContent>
</Card>
{/* Étape 3 */} {/* Prize 2 - Thé détox */}
<Card className="bg-white text-center hover:shadow-lg transition-shadow"> <div className="bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow overflow-hidden">
<CardContent className="pt-8"> <div className="aspect-square bg-gradient-to-br from-green-50 to-emerald-50 flex items-center justify-center">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary-600 text-white text-3xl font-bold mb-4"> <div className="text-8xl">📦</div>
3
</div> </div>
<h3 className="text-xl font-bold mb-3 text-gray-900"> <div className="p-6">
Remportez des gains <div className="inline-block bg-orange-100 text-orange-600 text-sm font-bold px-3 py-1 rounded-full mb-3">
</h3> 20% des lots
<p className="text-gray-600"> </div>
Gagnez des récompenses d'exception et découvrez l'univers premium de Thé Tip Top. <h3 className="text-xl font-bold text-gray-900 mb-2">Boîte 100g thé détox</h3>
</p> <p className="text-gray-600 text-sm mb-4">
</CardContent> Mélange détox aux plantes bio : menthe, citronnelle, fenouil et gingembre
</Card> </p>
<div className="flex items-center justify-between">
<div className="text-2xl font-bold text-[#1a4d2e]">25</div>
<button className="text-[#1a4d2e] hover:text-[#f59e0b] transition-colors">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
</div>
</div>
</div>
{/* Prize 3 - Thé signature */}
<div className="bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow overflow-hidden">
<div className="aspect-square bg-gradient-to-br from-blue-50 to-cyan-50 flex items-center justify-center">
<div className="text-8xl">🌿</div>
</div>
<div className="p-6">
<div className="inline-block bg-green-100 text-green-600 text-sm font-bold px-3 py-1 rounded-full mb-3">
10% des lots
</div>
<h3 className="text-xl font-bold text-gray-900 mb-2">Boîte 100g thé signature</h3>
<p className="text-gray-600 text-sm mb-4">
Notre mélange signature exclusif : Earl Grey aux agrumes et pétales de fleurs
</p>
<div className="flex items-center justify-between">
<div className="text-2xl font-bold text-[#1a4d2e]">35</div>
<button className="text-[#1a4d2e] hover:text-[#f59e0b] transition-colors">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
</div>
</div>
</div>
{/* Prize 4 - Coffret 39€ */}
<div className="bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow overflow-hidden">
<div className="aspect-square bg-gradient-to-br from-purple-50 to-pink-50 flex items-center justify-center">
<div className="text-8xl">🎁</div>
</div>
<div className="p-6">
<div className="inline-block bg-purple-100 text-purple-600 text-sm font-bold px-3 py-1 rounded-full mb-3">
6% des lots
</div>
<h3 className="text-xl font-bold text-gray-900 mb-2">Coffret découverte 39</h3>
<p className="text-gray-600 text-sm mb-4">
Sélection de nos 3 thés premium dans un élégant coffret cadeau
</p>
<div className="flex items-center justify-between">
<div className="text-2xl font-bold text-[#1a4d2e]">39</div>
<button className="text-[#1a4d2e] hover:text-[#f59e0b] transition-colors">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
</div>
</div>
</div>
{/* Prize 5 - Coffret 69€ */}
<div className="bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow overflow-hidden">
<div className="aspect-square bg-gradient-to-br from-amber-50 to-yellow-50 flex items-center justify-center">
<div className="text-8xl">🎁</div>
</div>
<div className="p-6">
<div className="inline-block bg-amber-100 text-amber-700 text-sm font-bold px-3 py-1 rounded-full mb-3">
4% des lots
</div>
<h3 className="text-xl font-bold text-gray-900 mb-2">Coffret prestige 69</h3>
<p className="text-gray-600 text-sm mb-4">
Collection premium : 5 thés d'exception avec accessoires dans un coffret luxe
</p>
<div className="flex items-center justify-between">
<div className="text-2xl font-bold text-[#1a4d2e]">69</div>
<button className="text-[#1a4d2e] hover:text-[#f59e0b] transition-colors">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
</div>
</div>
</div>
{/* Prize 6 - Tirage Final */}
<div className="bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow overflow-hidden border-2 border-[#f59e0b]">
<div className="aspect-square bg-gradient-to-br from-yellow-50 to-amber-50 flex items-center justify-center">
<div className="text-8xl">🏆</div>
</div>
<div className="p-6">
<div className="inline-block bg-yellow-100 text-yellow-700 text-sm font-bold px-3 py-1 rounded-full mb-3">
1 an de THÉ
</div>
<h3 className="text-xl font-bold text-gray-900 mb-2">Tirage Final</h3>
<p className="text-gray-600 text-sm mb-4">
Valeur 360 - Livraison mensuelle pendant 12 mois
</p>
<div className="flex items-center justify-between">
<div className="text-2xl font-bold text-[#f59e0b]">360</div>
<button className="text-[#1a4d2e] hover:text-[#f59e0b] transition-colors">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</section> </section>
{/* Stats & Features Section */} {/* CTA Section */}
<section className="mb-16"> <section className="py-16">
<div className="max-w-5xl mx-auto"> <div className="container mx-auto px-4">
{/* Main Stat */} <div className="max-w-4xl mx-auto bg-gradient-to-r from-[#1a4d2e] to-[#2d5a3d] rounded-2xl shadow-2xl p-12 text-center text-white">
<div className="text-center mb-12"> <h2 className="text-3xl md:text-4xl font-bold mb-4">
<div className="text-6xl mb-4">🎉</div> Prêt à découvrir votre lot ?
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-3">
Déjà plus de 1000 gains remis !
</h2> </h2>
<p className="text-lg text-gray-600"> <p className="text-xl mb-8 text-white/90 max-w-2xl mx-auto">
Rejoignez les milliers de participants qui ont déjà découvert nos thés d'exception. Achetez pour 49 minimum de thé en boutique, récupérez votre code et
tentez votre chance ! Avec 100% de gagnants, vous ne pouvez que gagner.
</p> </p>
</div> <Link href="/register">
<button className="bg-[#f59e0b] hover:bg-[#d97706] text-white font-bold text-lg px-12 py-4 rounded-lg shadow-xl transition-all">
{/* Features Grid */} Participer maintenant
<div className="grid md:grid-cols-3 gap-8"> </button>
{/* Feature 1 */}
<Card className="text-center hover:shadow-lg transition-shadow">
<CardContent className="pt-8">
<div className="text-5xl mb-4">🏆</div>
<h3 className="text-xl font-bold mb-2 text-gray-900">
Gagnant à tous les coups
</h3>
<p className="text-gray-600 text-sm">
Chaque participant repart avec une récompense.
</p>
</CardContent>
</Card>
{/* Feature 2 */}
<Card className="text-center hover:shadow-lg transition-shadow">
<CardContent className="pt-8">
<div className="text-5xl mb-4">🌱</div>
<h3 className="text-xl font-bold mb-2 text-gray-900">
Thés bio certifiés
</h3>
<p className="text-gray-600 text-sm">
Une qualité contrôlée et garantie.
</p>
</CardContent>
</Card>
{/* Feature 3 */}
<Card className="text-center hover:shadow-lg transition-shadow">
<CardContent className="pt-8">
<div className="text-5xl mb-4"></div>
<h3 className="text-xl font-bold mb-2 text-gray-900">
Satisfait ou remboursé
</h3>
<p className="text-gray-600 text-sm">
Une expérience 100% sereine.
</p>
</CardContent>
</Card>
</div>
</div>
</section>
{/* Final CTA */}
<section className="text-center">
<Card className="max-w-2xl mx-auto bg-gradient-to-r from-primary-600 to-primary-700 text-white">
<CardContent className="py-12">
<h2 className="text-3xl font-bold mb-4">
Prêt à tenter votre chance ?
</h2>
<p className="text-lg mb-8 text-primary-50">
Inscrivez-vous gratuitement et participez au jeu-concours dès maintenant
</p>
<Link href={ROUTES.REGISTER}>
<Button
size="lg"
variant="outline"
className="bg-white text-primary-600 hover:bg-primary-50 border-white px-10"
>
Créer mon compte
</Button>
</Link> </Link>
</CardContent> </div>
</Card> </div>
</section> </section>
</div> </div>
); );

View File

@ -4,16 +4,14 @@ import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { useAuth } from "@/contexts/AuthContext"; import { useAuth } from "@/contexts/AuthContext";
import { registerSchema, RegisterFormData } from "@/lib/validations"; import { registerSchema, RegisterFormData } from "@/lib/validations";
import { Input } from "@/components/ui/Input";
import Button from "@/components/Button";
import { Card } from "@/components/ui/Card";
import Link from "next/link"; import Link from "next/link";
import Image from "next/image";
import { ROUTES } from "@/utils/constants"; import { ROUTES } from "@/utils/constants";
export default function RegisterPage() { export default function RegisterPage() {
const { register: registerUser } = useAuth(); const { register: registerUser } = useAuth();
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const { const {
register, register,
@ -35,136 +33,214 @@ export default function RegisterPage() {
}; };
return ( return (
<div className="min-h-[calc(100vh-4rem)] flex items-center justify-center py-12"> <div className="min-h-screen bg-gray-50 flex items-center justify-center py-12 px-4">
<Card className="w-full max-w-md p-8"> <div className="w-full max-w-md">
{/* Title */}
<div className="text-center mb-8"> <div className="text-center mb-8">
<div className="flex justify-center mb-6"> <h1 className="text-4xl font-bold text-gray-900 mb-2">Inscription</h1>
<Image
src="/logos/logo.svg"
alt="Thé Tip Top"
width={120}
height={120}
priority
/>
</div>
<h1 className="text-3xl font-bold text-gray-900 mb-2">Inscription</h1>
<p className="text-gray-600"> <p className="text-gray-600">
Créez un compte pour participer au jeu-concours Créez un compte pour participer au jeu-concours
</p> </p>
</div> </div>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4"> {/* Main Card */}
<div className="grid grid-cols-2 gap-4"> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<Input
id="firstName"
type="text"
label="Prénom"
placeholder="Jean"
error={errors.firstName?.message}
{...register("firstName")}
required
/>
<Input {/* Tabs */}
id="lastName" <div className="flex border-b border-gray-200">
type="text" <Link
label="Nom" href={ROUTES.LOGIN}
placeholder="Dupont" className="flex-1 py-4 px-6 text-center font-semibold text-gray-500 bg-gray-50 hover:bg-gray-100 transition-colors"
error={errors.lastName?.message} >
{...register("lastName")} Connexion
required </Link>
/> <button className="flex-1 py-4 px-6 text-center font-semibold text-gray-900 bg-white border-b-2 border-[#1a4d2e]">
Inscription
</button>
</div> </div>
<Input {/* Form Container */}
id="email" <div className="p-8">
type="email"
label="Email"
placeholder="votre.email@example.com"
error={errors.email?.message}
{...register("email")}
required
/>
<Input {/* Registration Form */}
id="phone" <form onSubmit={handleSubmit(onSubmit)} className="space-y-5">
type="tel"
label="Téléphone"
placeholder="0612345678"
error={errors.phone?.message}
helperText="Optionnel - Format: 06 12 34 56 78"
{...register("phone")}
/>
<Input {/* Prénom et Nom */}
id="password" <div className="grid grid-cols-2 gap-4">
type="password" <div>
label="Mot de passe" <label htmlFor="firstName" className="block text-sm font-semibold text-gray-700 mb-2">
placeholder="••••••••" Prénom <span className="text-red-500">*</span>
error={errors.password?.message} </label>
helperText="Min. 8 caractères, 1 majuscule, 1 minuscule, 1 chiffre" <input
{...register("password")} id="firstName"
required type="text"
/> placeholder="Jean"
{...register("firstName")}
className={`w-full px-4 py-3 border ${errors.firstName ? 'border-red-500' : 'border-gray-300'} rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent`}
/>
{errors.firstName && (
<p className="mt-1 text-sm text-red-500">{errors.firstName.message}</p>
)}
</div>
<Input <div>
id="confirmPassword" <label htmlFor="lastName" className="block text-sm font-semibold text-gray-700 mb-2">
type="password" Nom <span className="text-red-500">*</span>
label="Confirmer le mot de passe" </label>
placeholder="••••••••" <input
error={errors.confirmPassword?.message} id="lastName"
{...register("confirmPassword")} type="text"
required placeholder="Dupont"
/> {...register("lastName")}
className={`w-full px-4 py-3 border ${errors.lastName ? 'border-red-500' : 'border-gray-300'} rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent`}
/>
{errors.lastName && (
<p className="mt-1 text-sm text-red-500">{errors.lastName.message}</p>
)}
</div>
</div>
<div className="flex items-start"> {/* Email */}
<div className="flex items-center h-5"> <div>
<input <label htmlFor="email" className="block text-sm font-semibold text-gray-700 mb-2">
id="terms" Email <span className="text-red-500">*</span>
type="checkbox" </label>
required <input
className="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-blue-300" id="email"
/> type="email"
</div> placeholder="votre.email@example.com"
<label htmlFor="terms" className="ml-2 text-sm text-gray-700"> {...register("email")}
J'accepte les{" "} className={`w-full px-4 py-3 border ${errors.email ? 'border-red-500' : 'border-gray-300'} rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent`}
<Link />
href="/terms" {errors.email && (
className="text-blue-600 hover:text-blue-700 hover:underline" <p className="mt-1 text-sm text-red-500">{errors.email.message}</p>
)}
</div>
{/* Téléphone */}
<div>
<label htmlFor="phone" className="block text-sm font-semibold text-gray-700 mb-2">
Téléphone
</label>
<input
id="phone"
type="tel"
placeholder="0612345678"
{...register("phone")}
className={`w-full px-4 py-3 border ${errors.phone ? 'border-red-500' : 'border-gray-300'} rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent`}
/>
<p className="mt-1 text-xs text-gray-500">Optionnel - Format: 06 12 34 56 78</p>
{errors.phone && (
<p className="mt-1 text-sm text-red-500">{errors.phone.message}</p>
)}
</div>
{/* Mot de passe */}
<div>
<label htmlFor="password" className="block text-sm font-semibold text-gray-700 mb-2">
Mot de passe <span className="text-red-500">*</span>
</label>
<div className="relative">
<input
id="password"
type={showPassword ? "text" : "password"}
placeholder="••••••••"
{...register("password")}
className={`w-full px-4 py-3 border ${errors.password ? 'border-red-500' : 'border-gray-300'} rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent pr-12`}
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700"
>
{showPassword ? (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
</svg>
) : (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
</svg>
)}
</button>
</div>
<p className="mt-1 text-xs text-gray-500">Min. 8 caractères, 1 majuscule, 1 minuscule, 1 chiffre</p>
{errors.password && (
<p className="mt-1 text-sm text-red-500">{errors.password.message}</p>
)}
</div>
{/* Confirmer mot de passe */}
<div>
<label htmlFor="confirmPassword" className="block text-sm font-semibold text-gray-700 mb-2">
Confirmer le mot de passe <span className="text-red-500">*</span>
</label>
<div className="relative">
<input
id="confirmPassword"
type={showConfirmPassword ? "text" : "password"}
placeholder="••••••••"
{...register("confirmPassword")}
className={`w-full px-4 py-3 border ${errors.confirmPassword ? 'border-red-500' : 'border-gray-300'} rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent pr-12`}
/>
<button
type="button"
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700"
>
{showConfirmPassword ? (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
</svg>
) : (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
</svg>
)}
</button>
</div>
{errors.confirmPassword && (
<p className="mt-1 text-sm text-red-500">{errors.confirmPassword.message}</p>
)}
</div>
{/* Checkbox CGU */}
<div className="flex items-start gap-3">
<input
id="terms"
type="checkbox"
required
className="mt-1 w-5 h-5 text-[#1a4d2e] border-gray-300 rounded focus:ring-2 focus:ring-[#1a4d2e]"
/>
<label htmlFor="terms" className="text-sm text-gray-700 select-none cursor-pointer">
J'accepte les{' '}
<Link href="/terms" className="text-[#1a4d2e] underline hover:text-[#f59e0b]">
conditions d'utilisation
</Link>{' '}
et la{' '}
<Link href="/privacy" className="text-[#1a4d2e] underline hover:text-[#f59e0b]">
politique de confidentialité
</Link>{' '}
<span className="text-red-500">*</span>
</label>
</div>
{/* Submit Button */}
<button
type="submit"
disabled={isSubmitting}
className="w-full bg-[#1a4d2e] hover:bg-[#2d5a3d] disabled:bg-gray-400 text-white font-bold px-8 py-4 rounded-lg transition-all"
> >
conditions d'utilisation {isSubmitting ? "Inscription..." : "S'inscrire"}
</Link>{" "} </button>
et la{" "} </form>
<Link
href="/privacy"
className="text-blue-600 hover:text-blue-700 hover:underline"
>
politique de confidentialité
</Link>
</label>
</div> </div>
</div>
<Button </div>
type="submit"
isLoading={isSubmitting}
disabled={isSubmitting}
fullWidth
size="lg"
>
S'inscrire
</Button>
</form>
<p className="mt-8 text-center text-sm text-gray-600">
Vous avez déjà un compte ?{" "}
<Link
href={ROUTES.LOGIN}
className="font-medium text-blue-600 hover:text-blue-700 hover:underline"
>
Se connecter
</Link>
</p>
</Card>
</div> </div>
); );
} }

View File

@ -1,289 +1,351 @@
import type { Metadata } from "next"; 'use client';
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card";
export const metadata: Metadata = { import type { Metadata } from "next";
title: "Règlement du jeu - Thé Tip Top", import { useState } from "react";
description: "Règlement officiel du jeu-concours Thé Tip Top",
};
export default function RulesPage() { export default function RulesPage() {
const [openSection, setOpenSection] = useState<number | null>(null);
const toggleSection = (index: number) => {
setOpenSection(openSection === index ? null : index);
};
return ( return (
<div className="py-12"> <div className="min-h-screen bg-gray-50">
<div className="max-w-4xl mx-auto"> {/* Hero Section */}
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-8 text-center"> <section className="bg-white py-12">
Règlement du jeu-concours <div className="container mx-auto px-4">
</h1> <div className="max-w-4xl mx-auto text-center">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-4">
<div className="mb-6 text-center text-gray-600"> Règlement du jeu-concours
<p className="mb-2">Jeu-concours Thé Tip Top 2025</p> </h1>
<p>Du 01/01/2025 au 31/12/2025</p> <p className="text-lg text-gray-600">
Toutes les conditions de participation à notre grand jeu-concours "Thé Tip Top"
pour l'ouverture de notre 10e boutique.
</p>
</div>
</div> </div>
</section>
{/* Article 1 */} {/* Résumé Section */}
<Card className="mb-8"> <section className="py-8">
<CardHeader> <div className="container mx-auto px-4">
<CardTitle className="text-xl">Article 1 - Société organisatrice</CardTitle> <div className="max-w-4xl mx-auto">
</CardHeader> <div className="bg-white rounded-xl shadow-md p-6 mb-8">
<CardContent className="space-y-3"> <div className="flex items-center gap-2 mb-6">
<p className="text-gray-700"> <span className="text-2xl">📋</span>
Le jeu-concours « Thé Tip Top 2025 » est organisé par : <h2 className="text-2xl font-bold text-gray-900">Résumé du jeu-concours</h2>
</p>
<div className="bg-gray-50 p-4 rounded-lg">
<p className="text-gray-700"><strong>Thé Tip Top SA</strong></p>
<p className="text-gray-700">Société Anonyme au capital de 150 000 </p>
<p className="text-gray-700">Siège social : 18 rue Léon Frot, 75011 Paris</p>
<p className="text-gray-700">RCS Paris B 812 456 789</p>
<p className="text-gray-700">Email : contact@thetiptop.fr</p>
</div>
</CardContent>
</Card>
{/* Article 2 */}
<Card className="mb-8">
<CardHeader>
<CardTitle className="text-xl">Article 2 - Durée du jeu</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-gray-700">
Le jeu-concours se déroule du <strong>1er janvier 2025 à 00h00</strong> au{" "}
<strong>31 décembre 2025 à 23h59</strong> (heure de Paris).
</p>
<p className="text-gray-700">
Seules les participations enregistrées pendant cette période seront prises en compte.
</p>
</CardContent>
</Card>
{/* Article 3 */}
<Card className="mb-8">
<CardHeader>
<CardTitle className="text-xl">Article 3 - Conditions de participation</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-gray-700">
Le jeu est ouvert à toute personne physique majeure résidant en France métropolitaine.
</p>
<p className="text-gray-700">
Sont exclus de la participation :
</p>
<ul className="list-disc list-inside space-y-2 text-gray-700 ml-4">
<li>Les membres du personnel de Thé Tip Top SA et de ses prestataires</li>
<li>Les membres de leur famille (conjoint, ascendants, descendants)</li>
<li>Toute personne ayant participé à l'élaboration du jeu</li>
</ul>
<p className="text-gray-700">
La participation au jeu implique l'acceptation pleine et entière du présent règlement.
</p>
</CardContent>
</Card>
{/* Article 4 */}
<Card className="mb-8">
<CardHeader>
<CardTitle className="text-xl">Article 4 - Modalités de participation</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-gray-700">
Pour participer au jeu, le participant doit :
</p>
<ol className="list-decimal list-inside space-y-2 text-gray-700 ml-4">
<li>Effectuer un achat dans l'une des boutiques Thé Tip Top participantes</li>
<li>Récupérer son ticket de caisse comportant un code unique à 10 caractères</li>
<li>Se rendre sur le site www.thetiptop.fr</li>
<li>Créer un compte ou se connecter à son compte existant</li>
<li>Saisir le code figurant sur son ticket dans l'espace dédié</li>
<li>Découvrir instantanément son gain</li>
</ol>
<p className="text-gray-700 mt-4">
<strong>Important :</strong> Chaque code ne peut être utilisé qu'une seule fois.
Toute tentative de fraude entraînera l'exclusion du participant.
</p>
</CardContent>
</Card>
{/* Article 5 */}
<Card className="mb-8">
<CardHeader>
<CardTitle className="text-xl">Article 5 - Dotations</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-gray-700">
Les dotations suivantes sont mises en jeu :
</p>
<div className="space-y-4 mt-4">
<div className="bg-primary-50 p-4 rounded-lg">
<p className="font-semibold text-gray-900">🍵 Infuseur à thé</p>
<p className="text-gray-700">Un infuseur en acier inoxydable de qualité supérieure</p>
<p className="text-sm text-gray-600">Probabilité : 1 ticket sur 4</p>
</div> </div>
<div className="bg-primary-50 p-4 rounded-lg">
<p className="font-semibold text-gray-900">🌿 Boîte de 100g de thé détox ou signature</p> <div className="grid md:grid-cols-3 gap-4">
<p className="text-gray-700">Un mélange exclusif de plantes biologiques</p> {/* 100% gagnants */}
<p className="text-sm text-gray-600">Probabilité : 1 ticket sur 5</p> <div className="bg-red-50 rounded-lg p-6 text-center">
</div> <div className="text-4xl mb-3">🎯</div>
<div className="bg-primary-50 p-4 rounded-lg"> <div className="text-2xl font-bold text-gray-900 mb-2">100% gagnants</div>
<p className="font-semibold text-gray-900"> Thé gratuit en magasin</p> <p className="text-sm text-gray-600">
<p className="text-gray-700">Une boisson offerte lors de votre prochaine visite</p> Chaque participant repart avec un lot garanti
<p className="text-sm text-gray-600">Probabilité : 1 ticket sur 2</p> </p>
</div> </div>
<div className="bg-primary-50 p-4 rounded-lg">
<p className="font-semibold text-gray-900">🎁 Coffret Découverte 39</p> {/* 30 + 30 jours */}
<p className="text-gray-700">Une sélection de 6 thés d'exception</p> <div className="bg-orange-50 rounded-lg p-6 text-center">
<p className="text-sm text-gray-600">Probabilité : 1 ticket sur 10</p> <div className="text-4xl mb-3">🔄</div>
</div> <div className="text-2xl font-bold text-gray-900 mb-2">30 + 30 jours</div>
<div className="bg-primary-50 p-4 rounded-lg"> <p className="text-sm text-gray-600">
<p className="font-semibold text-gray-900">🏆 Coffret Prestige 69</p> Période de jeu + délai de réclamation
<p className="text-gray-700">Notre coffret premium avec accessoires</p> </p>
<p className="text-sm text-gray-600">Probabilité : très rare</p> </div>
{/* Grand prix 360€ */}
<div className="bg-yellow-50 rounded-lg p-6 text-center">
<div className="text-4xl mb-3">🏆</div>
<div className="text-2xl font-bold text-gray-900 mb-2">Grand prix 360</div>
<p className="text-sm text-gray-600">
Tirage final sous contrôle d'huissier
</p>
</div>
</div> </div>
</div> </div>
<p className="text-gray-700 mt-4"> </div>
<strong>100% des tickets sont gagnants !</strong> Chaque participant repart avec au </div>
minimum une récompense. </section>
</p>
</CardContent>
</Card>
{/* Article 6 */} {/* Accordion Sections */}
<Card className="mb-8"> <section className="py-8 pb-16">
<CardHeader> <div className="container mx-auto px-4">
<CardTitle className="text-xl">Article 6 - Désignation des gagnants</CardTitle> <div className="max-w-4xl mx-auto space-y-4">
</CardHeader>
<CardContent className="space-y-3">
<p className="text-gray-700">
Le gain est attribué de manière instantanée et aléatoire au moment de la saisie du code,
selon les probabilités définies à l'article 5.
</p>
<p className="text-gray-700">
Le participant est immédiatement informé de son gain sur le site.
</p>
</CardContent>
</Card>
{/* Article 7 */} {/* Section 1 - Conditions de participation */}
<Card className="mb-8"> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<CardHeader> <button
<CardTitle className="text-xl">Article 7 - Remise des lots</CardTitle> onClick={() => toggleSection(1)}
</CardHeader> className="w-full flex items-center justify-between p-6 text-left hover:bg-gray-50 transition-colors"
<CardContent className="space-y-3"> >
<p className="text-gray-700"> <div className="flex items-center gap-3">
Les lots doivent être réclamés dans un délai de <strong>60 jours</strong> à compter <span className="text-2xl">📋</span>
de la date de participation. <h3 className="text-xl font-bold text-gray-900">1. Conditions de participation</h3>
</p> </div>
<p className="text-gray-700"> <svg
La remise des lots s'effectue selon les modalités suivantes : className={`w-6 h-6 text-gray-500 transition-transform ${openSection === 1 ? 'rotate-180' : ''}`}
</p> fill="none"
<ul className="list-disc list-inside space-y-2 text-gray-700 ml-4"> stroke="currentColor"
<li><strong>Thé gratuit :</strong> À retirer en boutique sur présentation du justificatif</li> viewBox="0 0 24 24"
<li><strong>Autres lots :</strong> Retrait en boutique ou envoi par courrier (frais de port offerts)</li> >
</ul> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
<p className="text-gray-700"> </svg>
Les lots ne peuvent être ni échangés, ni remboursés, ni convertis en espèces. </button>
</p> {openSection === 1 && (
</CardContent> <div className="px-6 pb-6 space-y-4 text-gray-700">
</Card> <p>Le jeu est ouvert à toute personne physique majeure résidant en France métropolitaine.</p>
<p className="font-semibold">Sont exclus de la participation :</p>
<ul className="list-disc list-inside space-y-2 ml-4">
<li>Les membres du personnel de Thé Tip Top et de ses prestataires</li>
<li>Les membres de leur famille (conjoint, ascendants, descendants)</li>
<li>Toute personne ayant participé à l'élaboration du jeu</li>
</ul>
<p>La participation au jeu implique l'acceptation pleine et entière du présent règlement.</p>
</div>
)}
</div>
{/* Article 8 */} {/* Section 2 - Codes de participation */}
<Card className="mb-8"> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<CardHeader> <button
<CardTitle className="text-xl">Article 8 - Données personnelles</CardTitle> onClick={() => toggleSection(2)}
</CardHeader> className="w-full flex items-center justify-between p-6 text-left hover:bg-gray-50 transition-colors"
<CardContent className="space-y-3"> >
<p className="text-gray-700"> <div className="flex items-center gap-3">
Les données personnelles collectées dans le cadre du jeu font l'objet d'un traitement <span className="text-2xl">🎫</span>
informatique destiné à gérer la participation au jeu et l'attribution des lots. <h3 className="text-xl font-bold text-gray-900">2. Codes de participation</h3>
</p> </div>
<p className="text-gray-700"> <svg
Pour plus d'informations, consultez notre{" "} className={`w-6 h-6 text-gray-500 transition-transform ${openSection === 2 ? 'rotate-180' : ''}`}
<a href="/privacy" className="text-primary-600 hover:text-primary-700 underline"> fill="none"
Politique de confidentialité stroke="currentColor"
</a>. viewBox="0 0 24 24"
</p> >
</CardContent> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</Card> </svg>
</button>
{openSection === 2 && (
<div className="px-6 pb-6 space-y-4 text-gray-700">
<p>Pour participer au jeu, le participant doit :</p>
<ol className="list-decimal list-inside space-y-2 ml-4">
<li>Effectuer un achat de minimum 49 dans une boutique Thé Tip Top participante</li>
<li>Récupérer son ticket de caisse comportant un code unique à 10 caractères</li>
<li>Se rendre sur le site www.thetiptop.fr</li>
<li>Créer un compte ou se connecter à son compte existant</li>
<li>Saisir le code figurant sur son ticket dans l'espace dédié</li>
<li>Découvrir instantanément son gain</li>
</ol>
<div className="bg-amber-50 border-l-4 border-amber-500 p-4 mt-4">
<p className="font-semibold text-amber-900"> Important</p>
<p className="text-amber-800">Chaque code ne peut être utilisé qu'une seule fois. Toute tentative de fraude entraînera l'exclusion du participant.</p>
</div>
</div>
)}
</div>
{/* Article 9 */} {/* Section 3 - Calendrier et délais */}
<Card className="mb-8"> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<CardHeader> <button
<CardTitle className="text-xl">Article 9 - Responsabilité</CardTitle> onClick={() => toggleSection(3)}
</CardHeader> className="w-full flex items-center justify-between p-6 text-left hover:bg-gray-50 transition-colors"
<CardContent className="space-y-3"> >
<p className="text-gray-700"> <div className="flex items-center gap-3">
La responsabilité de Thé Tip Top SA ne saurait être engagée en cas de : <span className="text-2xl">📅</span>
</p> <h3 className="text-xl font-bold text-gray-900">3. Calendrier et délais</h3>
<ul className="list-disc list-inside space-y-2 text-gray-700 ml-4"> </div>
<li>Force majeure ou événement indépendant de sa volonté</li> <svg
<li>Défaillance technique du réseau Internet</li> className={`w-6 h-6 text-gray-500 transition-transform ${openSection === 3 ? 'rotate-180' : ''}`}
<li>Utilisation frauduleuse des codes</li> fill="none"
<li>Mauvaise utilisation des lots par les gagnants</li> stroke="currentColor"
</ul> viewBox="0 0 24 24"
</CardContent> >
</Card> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{openSection === 3 && (
<div className="px-6 pb-6 space-y-4 text-gray-700">
<div>
<p className="font-semibold mb-2">📍 Période de participation</p>
<p>Du 1er janvier 2025 à 00h00 au 31 janvier 2025 à 23h59 (heure de Paris)</p>
</div>
<div>
<p className="font-semibold mb-2">📍 Délai de réclamation des lots</p>
<p>30 jours après la date de participation pour réclamer votre lot</p>
</div>
<div>
<p className="font-semibold mb-2">📍 Tirage final</p>
<p>Le tirage au sort pour le grand prix (1 an de thé - 360) aura lieu le 15 février 2025 sous contrôle d'huissier de justice</p>
</div>
<div className="bg-green-50 border-l-4 border-green-500 p-4 mt-4">
<p className="font-semibold text-green-900"> À retenir</p>
<p className="text-green-800">Seules les participations enregistrées pendant la période officielle seront prises en compte.</p>
</div>
</div>
)}
</div>
{/* Article 10 */} {/* Section 4 - Tirage final Grand Prix */}
<Card className="mb-8"> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<CardHeader> <button
<CardTitle className="text-xl">Article 10 - Modification et annulation</CardTitle> onClick={() => toggleSection(4)}
</CardHeader> className="w-full flex items-center justify-between p-6 text-left hover:bg-gray-50 transition-colors"
<CardContent className="space-y-3"> >
<p className="text-gray-700"> <div className="flex items-center gap-3">
Thé Tip Top SA se réserve le droit d'annuler, de reporter, de prolonger, d'écourter <span className="text-2xl">🏆</span>
ou de modifier tout ou partie du jeu en cas de force majeure. <h3 className="text-xl font-bold text-gray-900">4. Tirage final - Grand Prix</h3>
</p> </div>
<p className="text-gray-700"> <svg
Toute modification fera l'objet d'une information sur le site www.thetiptop.fr. className={`w-6 h-6 text-gray-500 transition-transform ${openSection === 4 ? 'rotate-180' : ''}`}
</p> fill="none"
</CardContent> stroke="currentColor"
</Card> viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{openSection === 4 && (
<div className="px-6 pb-6 space-y-4 text-gray-700">
<p className="font-semibold text-xl">Grand Prix : 1 an de thé offert (valeur 360)</p>
<p>À l'issue de la période de participation, un tirage au sort sera organisé pour désigner le grand gagnant du prix principal.</p>
<div>
<p className="font-semibold mb-2">Conditions du tirage :</p>
<ul className="list-disc list-inside space-y-2 ml-4">
<li>Date : 15 février 2025</li>
<li>Lieu : Siège social de Thé Tip Top, Paris</li>
<li>Sous contrôle d'huissier de justice : Maître Dupont, Office Notarial de Paris</li>
<li>Tous les participants ayant validé au moins un code sont automatiquement inscrits</li>
</ul>
</div>
<div>
<p className="font-semibold mb-2">Le lot :</p>
<p>Le gagnant recevra pendant 12 mois consécutifs une livraison mensuelle de thé d'une valeur de 30, soit un total de 360.</p>
</div>
<div className="bg-yellow-50 border-l-4 border-yellow-500 p-4 mt-4">
<p className="font-semibold text-yellow-900">🎁 Information</p>
<p className="text-yellow-800">Le gagnant sera contacté par email et par téléphone dans les 48h suivant le tirage.</p>
</div>
</div>
)}
</div>
{/* Article 11 */} {/* Section 5 - Retrait des lots */}
<Card className="mb-8"> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<CardHeader> <button
<CardTitle className="text-xl">Article 11 - Dépôt du règlement</CardTitle> onClick={() => toggleSection(5)}
</CardHeader> className="w-full flex items-center justify-between p-6 text-left hover:bg-gray-50 transition-colors"
<CardContent className="space-y-3"> >
<p className="text-gray-700"> <div className="flex items-center gap-3">
Le présent règlement est déposé auprès d'un huissier de justice et peut être consulté <span className="text-2xl">🎁</span>
sur le site www.thetiptop.fr. <h3 className="text-xl font-bold text-gray-900">5. Retrait des lots</h3>
</p> </div>
<p className="text-gray-700"> <svg
Un exemplaire peut être adressé gratuitement à toute personne qui en fait la demande className={`w-6 h-6 text-gray-500 transition-transform ${openSection === 5 ? 'rotate-180' : ''}`}
à l'adresse : contact@thetiptop.fr fill="none"
</p> stroke="currentColor"
</CardContent> viewBox="0 0 24 24"
</Card> >
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{openSection === 5 && (
<div className="px-6 pb-6 space-y-4 text-gray-700">
<p>Les lots doivent être réclamés dans un délai de <strong>30 jours</strong> à compter de la date de participation.</p>
<div>
<p className="font-semibold mb-2">Modalités de remise :</p>
<ul className="list-disc list-inside space-y-2 ml-4">
<li><strong>Infuseur, thé détox/signature :</strong> Retrait en boutique ou envoi postal (frais de port offerts)</li>
<li><strong>Coffrets découverte et prestige :</strong> Retrait en boutique ou livraison à domicile offerte</li>
<li><strong>Grand prix (1 an de thé) :</strong> Livraison mensuelle à l'adresse de votre choix</li>
</ul>
</div>
<div className="bg-red-50 border-l-4 border-red-500 p-4 mt-4">
<p className="font-semibold text-red-900"> Attention</p>
<p className="text-red-800">Les lots non réclamés dans le délai imparti seront considérés comme abandonnés. Aucun lot ne peut être échangé, remboursé ou converti en espèces.</p>
</div>
</div>
)}
</div>
{/* Article 12 */} {/* Section 6 - Protection des données */}
<Card className="mb-8"> <div className="bg-white rounded-xl shadow-md overflow-hidden">
<CardHeader> <button
<CardTitle className="text-xl">Article 12 - Litiges</CardTitle> onClick={() => toggleSection(6)}
</CardHeader> className="w-full flex items-center justify-between p-6 text-left hover:bg-gray-50 transition-colors"
<CardContent className="space-y-3"> >
<p className="text-gray-700"> <div className="flex items-center gap-3">
Le présent règlement est régi par le droit français. <span className="text-2xl">🔒</span>
</p> <h3 className="text-xl font-bold text-gray-900">6. Protection des données personnelles</h3>
<p className="text-gray-700"> </div>
Tout litige relatif à l'interprétation ou à l'exécution du présent règlement sera <svg
de la compétence exclusive des tribunaux français. className={`w-6 h-6 text-gray-500 transition-transform ${openSection === 6 ? 'rotate-180' : ''}`}
</p> fill="none"
</CardContent> stroke="currentColor"
</Card> viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{openSection === 6 && (
<div className="px-6 pb-6 space-y-4 text-gray-700">
<p>Les données personnelles collectées dans le cadre du jeu font l'objet d'un traitement informatique destiné à gérer la participation au jeu et l'attribution des lots.</p>
<div>
<p className="font-semibold mb-2">Vos droits :</p>
<ul className="list-disc list-inside space-y-2 ml-4">
<li>Droit d'accès à vos données personnelles</li>
<li>Droit de rectification de vos données</li>
<li>Droit à l'effacement de vos données</li>
<li>Droit d'opposition au traitement</li>
<li>Droit à la portabilité des données</li>
</ul>
</div>
<p>Pour exercer vos droits, contactez-nous à : <a href="mailto:contact@thetiptop.fr" className="text-[#1a4d2e] underline hover:text-[#f59e0b]">contact@thetiptop.fr</a></p>
<p>Pour plus d'informations, consultez notre <a href="/privacy" className="text-[#1a4d2e] underline hover:text-[#f59e0b]">Politique de confidentialité</a>.</p>
</div>
)}
</div>
{/* Contact */} </div>
<Card className="mb-8"> </div>
<CardHeader> </section>
<CardTitle className="text-xl">Contact</CardTitle>
</CardHeader> {/* Informations légales Section */}
<CardContent> <section className="py-12 bg-gradient-to-br from-[#1a4d2e] via-[#2d5a3d] to-[#1a4d2e]">
<p className="text-gray-700"> <div className="container mx-auto px-4">
Pour toute question relative au jeu-concours :{" "} <div className="max-w-4xl mx-auto">
<a href="mailto:contact@thetiptop.fr" className="text-primary-600 hover:text-primary-700 underline"> <div className="bg-white/10 backdrop-blur-sm rounded-xl p-8 text-white">
contact@thetiptop.fr <h2 className="text-2xl font-bold mb-6">Informations légales</h2>
</a>
</p> <div className="grid md:grid-cols-2 gap-8">
</CardContent> <div>
</Card> <h3 className="font-semibold mb-3 text-[#f59e0b]">Organisateur</h3>
</div> <p className="text-sm">Thé Tip Top</p>
<p className="text-sm">18 Avenue des Thés</p>
<p className="text-sm">75001 Paris, France</p>
<p className="text-sm">SIRET: 12345678901234</p>
</div>
<div>
<h3 className="font-semibold mb-3 text-[#f59e0b]">Huissier</h3>
<p className="text-sm">Maître Dupont</p>
<p className="text-sm">Office Notarial de Paris</p>
<p className="text-sm">456 Rue de la Justice</p>
<p className="text-sm">75002 Paris, France</p>
</div>
</div>
<div className="mt-6 pt-6 border-t border-white/20">
<p className="text-sm text-white/80">
Jeu-concours gratuit sans obligation d'achat, sauf pour l'acquisition du ticket donnant droit à participation.
Règlement déposé chez Maître Dupont, huissier de justice à Paris.
</p>
</div>
</div>
</div>
</div>
</section>
</div> </div>
); );
} }

View File

@ -184,7 +184,7 @@ export default function Footer() {
</div> </div>
{/* Bottom Bar */} {/* Bottom Bar */}
<div className="border-t border-white/10 bg-[#1a4d2e]/50"> <div className="border-t border-white/10">
<div className="container mx-auto px-4 py-6"> <div className="container mx-auto px-4 py-6">
<div className="flex flex-col md:flex-row items-center justify-between gap-4 text-sm"> <div className="flex flex-col md:flex-row items-center justify-between gap-4 text-sm">
<p className="text-white/80"> <p className="text-white/80">