Responsive : toutes les pages et composants Header/Footer

- Header : menu hamburger animé pour mobile, nav cachée sur petit écran
- Footer : grid 2 colonnes sur mobile, 4 colonnes sur desktop
- Accueil : titres et paddings adaptés mobile/tablette/desktop
- ReglesJeu : titres, cartes et CTA responsives
- MentionsLegales / Confidentialite : paddings et titres adaptés mobile
- Contact : padding et formulaire adaptés mobile
- Admin : tableau avec scroll horizontal sur mobile
- Employe : formulaire de recherche en colonne sur mobile
- Ajout composants Layout, Header, Footer et logo depuis branche Alexis

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Emma781227
2026-06-24 10:19:52 +02:00
parent 4727a3a268
commit 4ea733440f
9 changed files with 316 additions and 691 deletions

View File

@@ -6,7 +6,7 @@ export default function Footer() {
{/* Partie principale */} {/* Partie principale */}
<div className="max-w-7xl mx-auto px-6 py-12 grid md:grid-cols-4 gap-10"> <div className="max-w-7xl mx-auto px-6 py-10 grid grid-cols-2 md:grid-cols-4 gap-8">
{/* Logo */} {/* Logo */}

View File

@@ -1,58 +1,92 @@
import { Link } from 'react-router-dom' import { useState } from 'react'
import { Link, useLocation } from 'react-router-dom'
import logo from '../assets/img/logo.png' import logo from '../assets/img/logo.png'
export default function Header() { export default function Header() {
const [menuOpen, setMenuOpen] = useState(false)
const { pathname } = useLocation()
const navLinks = [
{ to: '/accueil', label: 'Accueil' },
{ to: '/regles-jeu', label: 'Règles du jeu' },
]
return ( return (
<header className="bg-white shadow-sm"> <header className="bg-white shadow-sm relative z-50">
<div className="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between"> <div className="max-w-7xl mx-auto px-4 sm:px-6 py-4 flex items-center justify-between">
<Link to="/accueil" className="flex items-center">
<img
src={logo}
alt="Thé Tip Top"
className="h-12 w-auto"
/>
<Link to="/accueil" className="flex items-center flex-shrink-0">
<img src={logo} alt="Thé Tip Top" className="h-10 sm:h-12 w-auto" />
</Link> </Link>
<nav className="flex items-center gap-6"> {/* Nav desktop */}
<Link <nav className="hidden md:flex items-center gap-6">
to="/accueil" {navLinks.map((link) => (
className="text-gray-700 hover:text-green-700 font-medium"
>
Accueil
</Link>
<Link
to="/regles-jeu"
className="text-gray-700 hover:text-green-700 font-medium"
>
Règles du jeu
</Link>
<div className="flex items-center gap-2">
<Link <Link
to="/connexion" key={link.to}
className="bg-green-700 text-white px-4 py-2 rounded-lg hover:bg-green-800 transition-colors" to={link.to}
className={`font-medium transition-colors ${
pathname === link.to ? 'text-green-700' : 'text-gray-700 hover:text-green-700'
}`}
> >
{link.label}
</Link>
))}
<div className="flex items-center gap-2">
<Link to="/connexion" className="bg-green-700 text-white px-4 py-2 rounded-lg hover:bg-green-800 transition-colors text-sm">
Connexion Connexion
</Link> </Link>
<Link to="/inscription" className="bg-green-700 text-white px-4 py-2 rounded-lg hover:bg-green-800 transition-colors text-sm">
<Link
to="/inscription"
className="bg-green-700 text-white px-4 py-2 rounded-lg hover:bg-green-800 transition-colors"
>
Inscription Inscription
</Link> </Link>
</div> </div>
</nav> </nav>
{/* Hamburger mobile */}
<button
onClick={() => setMenuOpen(!menuOpen)}
className="md:hidden flex flex-col justify-center items-center w-9 h-9 gap-1.5"
aria-label="Ouvrir le menu"
>
<span className={`block w-6 h-0.5 bg-gray-700 transition-all duration-300 origin-center ${menuOpen ? 'rotate-45 translate-y-2' : ''}`} />
<span className={`block w-6 h-0.5 bg-gray-700 transition-all duration-300 ${menuOpen ? 'opacity-0' : ''}`} />
<span className={`block w-6 h-0.5 bg-gray-700 transition-all duration-300 origin-center ${menuOpen ? '-rotate-45 -translate-y-2' : ''}`} />
</button>
</div> </div>
{/* Menu mobile déroulant */}
{menuOpen && (
<div className="md:hidden bg-white border-t border-gray-100 px-4 pb-4">
{navLinks.map((link) => (
<Link
key={link.to}
to={link.to}
onClick={() => setMenuOpen(false)}
className={`block py-3 font-medium border-b border-gray-50 ${
pathname === link.to ? 'text-green-700' : 'text-gray-700'
}`}
>
{link.label}
</Link>
))}
<div className="flex flex-col gap-2 pt-3">
<Link
to="/connexion"
onClick={() => setMenuOpen(false)}
className="w-full text-center bg-green-700 text-white px-4 py-2.5 rounded-lg hover:bg-green-800 transition-colors text-sm font-medium"
>
Connexion
</Link>
<Link
to="/inscription"
onClick={() => setMenuOpen(false)}
className="w-full text-center border border-green-700 text-green-700 px-4 py-2.5 rounded-lg hover:bg-green-50 transition-colors text-sm font-medium"
>
Inscription
</Link>
</div>
</div>
)}
</header> </header>
) )
} }

View File

@@ -5,72 +5,51 @@ export default function Accueil() {
<div className="bg-green-50"> <div className="bg-green-50">
{/* Hero */} {/* Hero */}
<section className="max-w-7xl mx-auto px-6 py-24"> <section className="max-w-7xl mx-auto px-4 sm:px-6 py-12 sm:py-16 md:py-24">
<div className="text-center max-w-3xl mx-auto"> <div className="text-center max-w-3xl mx-auto">
<h1 className="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold text-green-800 mb-4 sm:mb-6 leading-tight">
<h1 className="text-5xl md:text-6xl font-bold text-green-800 mb-6">
Bienvenue au jeu-concours Thé Tip Top Bienvenue au jeu-concours Thé Tip Top
</h1> </h1>
<p className="text-base sm:text-lg md:text-xl text-gray-600 mb-8 sm:mb-10">
<p className="text-xl text-gray-600 mb-10"> À l'occasion de l'ouverture de notre 10ᵉ boutique à Nice, participez à notre jeu-concours
À l'occasion de l'ouverture de notre 10ᵉ boutique à Nice, participez à notre jeu-concours et tentez de gagner des lots exceptionnels ! Tous les tickets sont gagnants, alors n'attendez plus pour découvrir votre lot. et tentez de gagner des lots exceptionnels ! Tous les tickets sont gagnants, alors n'attendez
plus pour découvrir votre lot.
</p> </p>
<div className="flex flex-col sm:flex-row justify-center gap-3 sm:gap-4">
<div className="flex flex-col sm:flex-row justify-center gap-4">
<Link <Link
to="/saisir-code-unique" to="/saisir-code-unique"
className="bg-green-700 hover:bg-green-800 text-white font-semibold px-8 py-4 rounded-xl transition-colors" className="bg-green-700 hover:bg-green-800 text-white font-semibold px-6 sm:px-8 py-3 sm:py-4 rounded-xl transition-colors text-sm sm:text-base"
> >
Tester mon code Tester mon code
</Link> </Link>
<Link <Link
to="/regles-jeu" to="/regles-jeu"
className="border border-green-700 text-green-700 hover:bg-green-100 font-semibold px-8 py-4 rounded-xl transition-colors" className="border border-green-700 text-green-700 hover:bg-green-100 font-semibold px-6 sm:px-8 py-3 sm:py-4 rounded-xl transition-colors text-sm sm:text-base"
> >
Découvrir les règles Découvrir les règles
</Link> </Link>
</div> </div>
</div> </div>
</section> </section>
{/* Comment participer */} {/* Comment participer */}
<section className="max-w-5xl mx-auto px-6 pb-20"> <section className="max-w-5xl mx-auto px-4 sm:px-6 pb-12 sm:pb-20">
<h2 className="text-2xl sm:text-3xl font-bold text-green-800 mb-6 sm:mb-8 text-center">
<h2 className="text-3xl font-bold text-green-800 mb-8 text-center">
Comment participer ? Comment participer ?
</h2> </h2>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<div className="grid md:grid-cols-4 gap-6"> {[
{ num: '1', text: 'Achat de 49 € minimum' },
<div className="bg-white rounded-2xl shadow p-6 text-center"> { num: '2', text: 'Recevez votre code unique' },
<div className="text-3xl font-bold text-green-700 mb-3">1</div> { num: '3', text: 'Saisissez le code sur le site' },
<p>Achat de 49 € minimum</p> { num: '4', text: 'Découvrez votre lot' },
</div> ].map((step) => (
<div key={step.num} className="bg-white rounded-2xl shadow p-4 sm:p-6 text-center">
<div className="bg-white rounded-2xl shadow p-6 text-center"> <div className="text-2xl sm:text-3xl font-bold text-green-700 mb-2 sm:mb-3">{step.num}</div>
<div className="text-3xl font-bold text-green-700 mb-3">2</div> <p className="text-sm sm:text-base text-gray-700">{step.text}</p>
<p>Recevez votre code unique</p> </div>
</div> ))}
<div className="bg-white rounded-2xl shadow p-6 text-center">
<div className="text-3xl font-bold text-green-700 mb-3">3</div>
<p>Saisissez le code sur le site</p>
</div>
<div className="bg-white rounded-2xl shadow p-6 text-center">
<div className="text-3xl font-bold text-green-700 mb-3">4</div>
<p>Découvrez votre lot</p>
</div>
</div> </div>
</section> </section>
</div> </div>

View File

@@ -13,57 +13,59 @@ const MOCK_USERS = [
export default function Admin() { export default function Admin() {
return ( return (
<div className="min-h-screen bg-gray-50 p-6"> <div className="min-h-screen bg-gray-50 p-4 sm:p-6">
<div className="max-w-4xl mx-auto"> <div className="max-w-4xl mx-auto">
<h1 className="text-2xl font-bold text-gray-800 mb-6">Tableau de bord Admin</h1> <h1 className="text-xl sm:text-2xl font-bold text-gray-800 mb-4 sm:mb-6">Tableau de bord Admin</h1>
{/* Stats */} {/* Stats */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8"> <div className="grid grid-cols-2 md:grid-cols-4 gap-3 sm:gap-4 mb-6 sm:mb-8">
{[ {[
{ label: 'Participants', value: MOCK_STATS.totalParticipants }, { label: 'Participants', value: MOCK_STATS.totalParticipants },
{ label: 'Gains remis', value: MOCK_STATS.gainsRemis }, { label: 'Gains remis', value: MOCK_STATS.gainsRemis },
{ label: 'En attente', value: MOCK_STATS.gainsEnAttente }, { label: 'En attente', value: MOCK_STATS.gainsEnAttente },
{ label: 'Taux participation', value: MOCK_STATS.tauxParticipation }, { label: 'Taux participation', value: MOCK_STATS.tauxParticipation },
].map((stat) => ( ].map((stat) => (
<div key={stat.label} className="bg-white rounded-xl shadow p-4 text-center"> <div key={stat.label} className="bg-white rounded-xl shadow p-3 sm:p-4 text-center">
<p className="text-2xl font-bold text-green-700">{stat.value}</p> <p className="text-xl sm:text-2xl font-bold text-green-700">{stat.value}</p>
<p className="text-sm text-gray-500 mt-1">{stat.label}</p> <p className="text-xs sm:text-sm text-gray-500 mt-1">{stat.label}</p>
</div> </div>
))} ))}
</div> </div>
{/* Tirage au sort */} {/* Tirage au sort */}
<div className="bg-white rounded-xl shadow p-6 mb-6"> <div className="bg-white rounded-xl shadow p-4 sm:p-6 mb-4 sm:mb-6">
<h2 className="text-lg font-bold text-gray-800 mb-3">Grand tirage au sort</h2> <h2 className="text-base sm:text-lg font-bold text-gray-800 mb-3">Grand tirage au sort</h2>
<button <button
onClick={() => alert('TODO: connecter au backend')} onClick={() => alert('TODO: connecter au backend')}
className="bg-green-700 hover:bg-green-800 text-white font-semibold px-6 py-2.5 rounded-lg transition-colors" className="bg-green-700 hover:bg-green-800 text-white font-semibold px-5 sm:px-6 py-2 sm:py-2.5 rounded-lg transition-colors text-sm sm:text-base"
> >
Lancer le tirage Lancer le tirage
</button> </button>
</div> </div>
{/* Liste participants */} {/* Liste participants */}
<div className="bg-white rounded-xl shadow p-6"> <div className="bg-white rounded-xl shadow p-4 sm:p-6">
<h2 className="text-lg font-bold text-gray-800 mb-4">Participants</h2> <h2 className="text-base sm:text-lg font-bold text-gray-800 mb-4">Participants</h2>
<table className="w-full text-sm"> <div className="overflow-x-auto -mx-4 sm:mx-0">
<thead> <table className="w-full text-sm min-w-[400px]">
<tr className="text-left text-gray-500 border-b"> <thead>
<th className="pb-2">Nom</th> <tr className="text-left text-gray-500 border-b">
<th className="pb-2">Email</th> <th className="pb-2 px-4 sm:px-0">Nom</th>
<th className="pb-2 text-right">Gains</th> <th className="pb-2 px-4 sm:px-0">Email</th>
</tr> <th className="pb-2 px-4 sm:px-0 text-right">Gains</th>
</thead>
<tbody>
{MOCK_USERS.map((user) => (
<tr key={user.id} className="border-b last:border-0">
<td className="py-3 font-medium text-gray-800">{user.name}</td>
<td className="py-3 text-gray-500">{user.email}</td>
<td className="py-3 text-right text-green-700 font-semibold">{user.gains}</td>
</tr> </tr>
))} </thead>
</tbody> <tbody>
</table> {MOCK_USERS.map((user) => (
<tr key={user.id} className="border-b last:border-0">
<td className="py-3 px-4 sm:px-0 font-medium text-gray-800 whitespace-nowrap">{user.name}</td>
<td className="py-3 px-4 sm:px-0 text-gray-500 text-xs sm:text-sm">{user.email}</td>
<td className="py-3 px-4 sm:px-0 text-right text-green-700 font-semibold">{user.gains}</td>
</tr>
))}
</tbody>
</table>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,183 +1,99 @@
export default function Confidentialite() { export default function Confidentialite() {
return ( return (
<main className="bg-green-50 min-h-screen px-6 py-16"> <main className="bg-green-50 min-h-screen px-4 sm:px-6 py-10 sm:py-16">
<div className="max-w-5xl mx-auto bg-white rounded-2xl shadow p-5 sm:p-8 md:p-10">
<div className="max-w-5xl mx-auto bg-white rounded-2xl shadow p-10"> <h1 className="text-2xl sm:text-3xl md:text-4xl font-bold text-green-800 mb-4 sm:mb-6">
<h1 className="text-4xl font-bold text-green-800 mb-6">
Politique de confidentialité Politique de confidentialité
</h1> </h1>
<p className="text-gray-600 mb-8 sm:mb-10 leading-relaxed text-sm sm:text-base">
<p className="text-gray-600 mb-10 leading-relaxed"> Thé Tip Top accorde une grande importance à la protection de vos données personnelles.
Thé Tip Top accorde une grande importance à la protection de vos Cette politique explique quelles informations sont collectées, comment elles sont utilisées
données personnelles. Cette politique explique quelles informations et quels sont vos droits.
sont collectées, comment elles sont utilisées et quels sont vos droits.
</p> </p>
<section className="mb-6 sm:mb-8">
<h2 className="text-lg sm:text-xl md:text-2xl font-bold text-green-700 mb-2 sm:mb-3">
{/* Article 1 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 1 – Responsable du traitement Article 1 – Responsable du traitement
</h2> </h2>
<p className="text-gray-700 leading-relaxed text-sm sm:text-base">
<p className="text-gray-700 leading-relaxed"> Le responsable du traitement des données collectées via le site du jeu-concours
« 100% Gagnant » est la société Thé Tip Top, située au 18 rue Léon Frot, 75011 Paris.
Le responsable du traitement des données collectées via le site
du jeu-concours « 100% Gagnant » est la société Thé Tip Top,
située au 18 rue Léon Frot, 75011 Paris.
</p> </p>
</section> </section>
<section className="mb-6 sm:mb-8">
<h2 className="text-lg sm:text-xl md:text-2xl font-bold text-green-700 mb-2 sm:mb-3">
{/* Article 2 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 2 – Données collectées Article 2 – Données collectées
</h2> </h2>
<p className="text-gray-700 mb-3 text-sm sm:text-base">Dans le cadre de votre participation, nous pouvons collecter :</p>
<p className="text-gray-700 mb-3"> <ul className="list-disc list-inside text-gray-700 space-y-2 text-sm sm:text-base">
Dans le cadre de votre participation, nous pouvons collecter :
</p>
<ul className="list-disc list-inside text-gray-700 space-y-2">
<li>Nom et prénom</li> <li>Nom et prénom</li>
<li>Adresse email</li> <li>Adresse email</li>
<li>Informations du compte utilisateur</li> <li>Informations du compte utilisateur</li>
<li>Code de participation au jeu</li> <li>Code de participation au jeu</li>
<li>Informations liées aux gains obtenus</li> <li>Informations liées aux gains obtenus</li>
</ul> </ul>
</section> </section>
<section className="mb-6 sm:mb-8">
<h2 className="text-lg sm:text-xl md:text-2xl font-bold text-green-700 mb-2 sm:mb-3">
{/* Article 3 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 3 – Utilisation des données Article 3 – Utilisation des données
</h2> </h2>
<p className="text-gray-700 leading-relaxed text-sm sm:text-base">
<p className="text-gray-700 leading-relaxed"> Les données collectées sont utilisées uniquement pour : gérer votre participation au
jeu-concours, vérifier les codes, attribuer les lots, vous contacter en cas de gain
Les données collectées sont utilisées uniquement pour : et améliorer l'expérience utilisateur.
gérer votre participation au jeu-concours, vérifier les codes,
attribuer les lots, vous contacter en cas de gain et améliorer
l'expérience utilisateur.
</p> </p>
</section> </section>
<section className="mb-6 sm:mb-8">
<h2 className="text-lg sm:text-xl md:text-2xl font-bold text-green-700 mb-2 sm:mb-3">
{/* Article 4 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 4 – Conservation des données Article 4 – Conservation des données
</h2> </h2>
<p className="text-gray-700 leading-relaxed text-sm sm:text-base">
<p className="text-gray-700 leading-relaxed"> Vos données sont conservées uniquement pendant la durée nécessaire au fonctionnement
du jeu-concours et au respect des obligations légales de Thé Tip Top.
Vos données sont conservées uniquement pendant la durée nécessaire
au fonctionnement du jeu-concours et au respect des obligations
légales de Thé Tip Top.
</p> </p>
</section> </section>
<section className="mb-6 sm:mb-8">
<h2 className="text-lg sm:text-xl md:text-2xl font-bold text-green-700 mb-2 sm:mb-3">
{/* Article 5 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 5 – Cookies Article 5 – Cookies
</h2> </h2>
<p className="text-gray-700 leading-relaxed text-sm sm:text-base">
<p className="text-gray-700 leading-relaxed"> Le site utilise des cookies nécessaires au fonctionnement ainsi que des cookies
statistiques permettant d'améliorer les services proposés. Vous pouvez gérer vos
Le site utilise des cookies nécessaires au fonctionnement du site préférences à tout moment.
ainsi que des cookies statistiques permettant d'améliorer les
services proposés. Vous pouvez gérer vos préférences à tout moment.
</p> </p>
</section> </section>
<section className="mb-6 sm:mb-8">
<h2 className="text-lg sm:text-xl md:text-2xl font-bold text-green-700 mb-2 sm:mb-3">
{/* Article 6 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 6 – Vos droits Article 6 – Vos droits
</h2> </h2>
<p className="text-gray-700 mb-3 text-sm sm:text-base">Conformément au RGPD, vous disposez des droits suivants :</p>
<p className="text-gray-700 mb-3"> <ul className="list-disc list-inside text-gray-700 space-y-2 text-sm sm:text-base">
Conformément au RGPD, vous disposez des droits suivants :
</p>
<ul className="list-disc list-inside text-gray-700 space-y-2">
<li>Droit d'accès à vos données</li> <li>Droit d'accès à vos données</li>
<li>Droit de rectification</li> <li>Droit de rectification</li>
<li>Droit de suppression</li> <li>Droit de suppression</li>
<li>Droit d'opposition</li> <li>Droit d'opposition</li>
<li>Droit à la limitation du traitement</li> <li>Droit à la limitation du traitement</li>
</ul> </ul>
</section> </section>
{/* Article 7 */}
<section> <section>
<h2 className="text-lg sm:text-xl md:text-2xl font-bold text-green-700 mb-2 sm:mb-3">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 7 – Contact Article 7 – Contact
</h2> </h2>
<p className="text-gray-700 text-sm sm:text-base">
Pour toute question concernant vos données personnelles :<br />
<p className="text-gray-700">
Pour toute question concernant vos données personnelles :
<br />
<strong>Email :</strong> contact@thetiptop.fr <strong>Email :</strong> contact@thetiptop.fr
</p> </p>
</section> </section>
</div> </div>
</main> </main>
) )
} }

View File

@@ -1,174 +1,81 @@
export default function Contact() { export default function Contact() {
return ( return (
<main className="bg-green-50 min-h-screen px-6 py-16"> <main className="bg-green-50 min-h-screen px-4 sm:px-6 py-10 sm:py-16">
<div className="max-w-6xl mx-auto grid md:grid-cols-2 gap-6 sm:gap-8">
<div className="max-w-6xl mx-auto grid md:grid-cols-2 gap-8">
{/* Informations */} {/* Informations */}
<section className="bg-white rounded-2xl shadow p-10"> <section className="bg-white rounded-2xl shadow p-5 sm:p-8 md:p-10">
<h1 className="text-2xl sm:text-3xl md:text-4xl font-bold text-green-800 mb-4 sm:mb-6">
<h1 className="text-4xl font-bold text-green-800 mb-6">
Contact Contact
</h1> </h1>
<p className="text-gray-600 leading-relaxed mb-6 sm:mb-8 text-sm sm:text-base">
Une question concernant le jeu-concours, votre participation ou votre lot ?
<p className="text-gray-600 leading-relaxed mb-8"> Notre équipe ThéTipTop est à votre écoute.
Une question concernant le jeu-concours, votre participation
ou votre lot ? Notre équipe ThéTipTop est à votre écoute.
</p> </p>
<div className="space-y-5 text-gray-700">
<div className="space-y-6 text-gray-700">
<div> <div>
<h2 className="font-semibold text-green-700"> <h2 className="font-semibold text-green-700 mb-1">Adresse</h2>
Adresse <p className="text-sm sm:text-base">ThéTipTop<br />18 rue Léon Frot<br />75011 Paris, France</p>
</h2>
<p>
ThéTipTop
<br />
18 rue Léon Frot
<br />
75011 Paris, France
</p>
</div> </div>
<div> <div>
<h2 className="font-semibold text-green-700"> <h2 className="font-semibold text-green-700 mb-1">Email</h2>
Email <a href="mailto:contact@thetiptop.fr" className="text-sm sm:text-base hover:text-green-700">contact@thetiptop.fr</a>
</h2>
<p>
contact@thetiptop.fr
</p>
</div> </div>
<div> <div>
<h2 className="font-semibold text-green-700"> <h2 className="font-semibold text-green-700 mb-1">Téléphone</h2>
Téléphone <a href="tel:+33184802034" className="text-sm sm:text-base hover:text-green-700">01 84 80 20 34</a>
</h2>
<p>
01 84 80 20 34
</p>
</div> </div>
</div> </div>
</section> </section>
{/* Formulaire */} {/* Formulaire */}
<section className="bg-white rounded-2xl shadow p-5 sm:p-8 md:p-10">
<section className="bg-white rounded-2xl shadow p-10"> <h2 className="text-xl sm:text-2xl font-bold text-green-800 mb-4 sm:mb-6">
<h2 className="text-2xl font-bold text-green-800 mb-6">
Envoyez-nous un message Envoyez-nous un message
</h2> </h2>
<form className="space-y-4 sm:space-y-5">
<form className="space-y-5">
<div> <div>
<label className="block text-gray-700 mb-1.5 text-sm sm:text-base">Nom</label>
<label className="block text-gray-700 mb-2">
Nom
</label>
<input <input
type="text" type="text"
placeholder="Votre nom" placeholder="Votre nom"
className="w-full border border-gray-300 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-green-600" className="w-full border border-gray-300 rounded-xl px-4 py-2.5 sm:py-3 text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-green-600"
/> />
</div> </div>
<div> <div>
<label className="block text-gray-700 mb-1.5 text-sm sm:text-base">Email</label>
<label className="block text-gray-700 mb-2">
Email
</label>
<input <input
type="email" type="email"
placeholder="Votre email" placeholder="Votre email"
className="w-full border border-gray-300 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-green-600" className="w-full border border-gray-300 rounded-xl px-4 py-2.5 sm:py-3 text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-green-600"
/> />
</div> </div>
<div> <div>
<label className="block text-gray-700 mb-1.5 text-sm sm:text-base">Sujet</label>
<label className="block text-gray-700 mb-2">
Sujet
</label>
<input <input
type="text" type="text"
placeholder="Sujet de votre demande" placeholder="Sujet de votre demande"
className="w-full border border-gray-300 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-green-600" className="w-full border border-gray-300 rounded-xl px-4 py-2.5 sm:py-3 text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-green-600"
/> />
</div> </div>
<div> <div>
<label className="block text-gray-700 mb-1.5 text-sm sm:text-base">Message</label>
<label className="block text-gray-700 mb-2">
Message
</label>
<textarea <textarea
rows="5" rows="4"
placeholder="Votre message..." placeholder="Votre message..."
className="w-full border border-gray-300 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-green-600" className="w-full border border-gray-300 rounded-xl px-4 py-2.5 sm:py-3 text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-green-600 resize-none"
/> />
</div> </div>
<button <button
type="submit" type="submit"
className="w-full bg-green-700 hover:bg-green-800 text-white font-semibold py-3 rounded-xl transition" className="w-full bg-green-700 hover:bg-green-800 text-white font-semibold py-2.5 sm:py-3 rounded-xl transition text-sm sm:text-base"
> >
Envoyer le message Envoyer le message
</button> </button>
</form> </form>
</section> </section>
</div> </div>
</main> </main>
) )
} }

View File

@@ -22,49 +22,47 @@ export default function Employe() {
} }
return ( return (
<div className="min-h-screen bg-gray-50 p-6"> <div className="min-h-screen bg-gray-50 p-4 sm:p-6">
<div className="max-w-lg mx-auto"> <div className="max-w-lg mx-auto">
<h1 className="text-2xl font-bold text-gray-800 mb-1">Espace Employé</h1> <h1 className="text-xl sm:text-2xl font-bold text-gray-800 mb-1">Espace Employé</h1>
<p className="text-gray-500 mb-6">Vérifier et remettre un lot</p> <p className="text-gray-500 mb-5 sm:mb-6 text-sm sm:text-base">Vérifier et remettre un lot</p>
<form onSubmit={handleSearch} className="flex gap-2 mb-6"> <form onSubmit={handleSearch} className="flex flex-col sm:flex-row gap-2 mb-5 sm:mb-6">
<input <input
type="text" type="text"
value={code} value={code}
onChange={(e) => setCode(e.target.value)} onChange={(e) => setCode(e.target.value)}
required required
placeholder="Code ticket (TTT-XXXXX)" placeholder="Code ticket (TTT-XXXXX)"
className="flex-1 border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500 font-mono" className="flex-1 border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-green-500 font-mono text-sm"
/> />
<button <button
type="submit" type="submit"
className="bg-green-700 hover:bg-green-800 text-white font-semibold px-5 py-2.5 rounded-lg transition-colors" className="bg-green-700 hover:bg-green-800 text-white font-semibold px-5 py-2.5 rounded-lg transition-colors text-sm sm:text-base whitespace-nowrap"
> >
Rechercher Rechercher
</button> </button>
</form> </form>
{gain && ( {gain && (
<div className="bg-white rounded-xl shadow p-6 space-y-3"> <div className="bg-white rounded-xl shadow p-4 sm:p-6 space-y-3">
<div className="flex justify-between items-start"> <div className="flex flex-col sm:flex-row sm:justify-between sm:items-start gap-2">
<div> <div>
<p className="font-bold text-gray-800 text-lg">{gain.lot}</p> <p className="font-bold text-gray-800 text-base sm:text-lg">{gain.lot}</p>
<p className="text-sm text-gray-500 font-mono">{gain.code}</p> <p className="text-xs sm:text-sm text-gray-500 font-mono">{gain.code}</p>
</div> </div>
<span className={`text-xs font-semibold px-3 py-1 rounded-full ${gain.status === 'DELIVERED' ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'}`}> <span className={`self-start text-xs font-semibold px-3 py-1 rounded-full ${gain.status === 'DELIVERED' ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'}`}>
{gain.status === 'DELIVERED' ? 'Remis' : 'À remettre'} {gain.status === 'DELIVERED' ? 'Remis' : 'À remettre'}
</span> </span>
</div> </div>
<div className="border-t pt-3 space-y-1">
<div className="border-t pt-3">
<p className="text-sm text-gray-600"><span className="font-medium">Client :</span> {gain.client}</p> <p className="text-sm text-gray-600"><span className="font-medium">Client :</span> {gain.client}</p>
<p className="text-sm text-gray-600"><span className="font-medium">Email :</span> {gain.email}</p> <p className="text-sm text-gray-600"><span className="font-medium">Email :</span> {gain.email}</p>
</div> </div>
{gain.status === 'PENDING' && ( {gain.status === 'PENDING' && (
<button <button
onClick={handleDeliver} onClick={handleDeliver}
className="w-full bg-green-700 hover:bg-green-800 text-white font-semibold py-2.5 rounded-lg transition-colors mt-2" className="w-full bg-green-700 hover:bg-green-800 text-white font-semibold py-2.5 rounded-lg transition-colors mt-2 text-sm sm:text-base"
> >
Confirmer la remise du lot Confirmer la remise du lot
</button> </button>

View File

@@ -1,202 +1,73 @@
export default function MentionsLegales() { export default function MentionsLegales() {
return ( return (
<main className="bg-green-50 min-h-screen px-6 py-16"> <main className="bg-green-50 min-h-screen px-4 sm:px-6 py-10 sm:py-16">
<div className="max-w-5xl mx-auto bg-white rounded-2xl shadow p-5 sm:p-8 md:p-10">
<div className="max-w-5xl mx-auto bg-white rounded-2xl shadow p-10"> <h1 className="text-2xl sm:text-3xl md:text-4xl font-bold text-green-800 mb-4 sm:mb-6">
<h1 className="text-4xl font-bold text-green-800 mb-6">
Mentions légales Mentions légales
</h1> </h1>
<p className="text-gray-600 mb-10"> <p className="text-gray-600 mb-8 sm:mb-10 text-sm sm:text-base">
Conformément à la loi n°2004-575 du 21 juin 2004 pour la Confiance Conformément à la loi n°2004-575 du 21 juin 2004 pour la Confiance dans l'Économie
dans l'Économie Numérique (LCEN), les présentes mentions légales Numérique (LCEN), les présentes mentions légales précisent les informations relatives
précisent les informations relatives au site du jeu-concours au site du jeu-concours « 100% Gagnant » de Thé Tip Top.
« 100% Gagnant » de Thé Tip Top.
</p> </p>
{[
{/* Article 1 */} {
<section className="mb-8"> title: 'Article 1 – Société éditrice du site',
content: (
<h2 className="text-2xl font-bold text-green-700 mb-3"> <div className="text-gray-700 space-y-2 text-sm sm:text-base">
Article 1 – Société éditrice du site <p><strong>Dénomination sociale :</strong> Thé Tip Top</p>
</h2> <p><strong>Forme juridique :</strong> Société à Responsabilité Limitée (SARL)</p>
<p><strong>Capital social :</strong> 150 000 €</p>
<div className="text-gray-700 space-y-2"> <p><strong>Siège social :</strong> 18 rue Léon Frot, 75011 Paris, France</p>
<p><strong>Représentant légal :</strong> Eric Bourdon, Gérant</p>
<p> <p><strong>SIRET :</strong> 362 521 879 00054</p>
<strong>Dénomination sociale :</strong> Thé Tip Top <p><strong>TVA intracommunautaire :</strong> FR12 948140589</p>
</p> <p><strong>Email :</strong> contact@thetiptop.fr</p>
<p><strong>Téléphone :</strong> 01 84 80 20 34</p>
<p> </div>
<strong>Forme juridique :</strong> Société à Responsabilité Limitée (SARL) ),
</p> },
{
<p> title: 'Article 2 – Développement du site',
<strong>Capital social :</strong> 150 000 € content: <p className="text-gray-700 text-sm sm:text-base">Le site du jeu-concours « 100% Gagnant » a été conçu et développé par Furious Ducks, responsable de la conception technique, de l'application web, de l'API et de l'infrastructure.</p>,
</p> },
{
<p> title: 'Article 3 – Hébergement',
<strong>Siège social :</strong> 18 rue Léon Frot, 75011 Paris, France content: <p className="text-gray-700 text-sm sm:text-base">Le site est hébergé par HexaCloud Hostinger.</p>,
</p> },
{
<p> title: 'Article 4 – Propriété intellectuelle',
<strong>Représentant légal :</strong> Eric Bourdon, Gérant content: <p className="text-gray-700 leading-relaxed text-sm sm:text-base">L'ensemble des éléments présents sur le site appartient à Thé Tip Top ou à ses partenaires. Toute reproduction ou utilisation sans autorisation préalable est interdite.</p>,
</p> },
{
<p> title: 'Article 5 – Cookies',
<strong>SIRET :</strong> 362 521 879 00054 content: <p className="text-gray-700 leading-relaxed text-sm sm:text-base">Le site peut utiliser des cookies nécessaires à son fonctionnement ainsi que des cookies d'analyse. L'utilisateur peut gérer ses préférences à tout moment.</p>,
</p> },
{
<p> title: 'Article 6 – Responsabilité',
<strong>TVA intracommunautaire :</strong> FR12 948140589 content: <p className="text-gray-700 leading-relaxed text-sm sm:text-base">Thé Tip Top s'efforce de fournir des informations exactes. Toutefois, la société ne peut être tenue responsable des erreurs, interruptions de service ou dommages liés à l'utilisation d'Internet.</p>,
</p> },
{
<p> title: 'Article 7 – Droit applicable',
<strong>Email :</strong> contact@thetiptop.fr content: <p className="text-gray-700 text-sm sm:text-base">Le présent site est soumis au droit français. Tout litige relève des juridictions françaises compétentes.</p>,
</p> },
{
<p> title: 'Article 8 – Engagement responsable',
<strong>Téléphone :</strong> 01 84 80 20 34 content: <p className="text-gray-700 leading-relaxed text-sm sm:text-base">Thé Tip Top s'engage dans une démarche responsable : optimisation des ressources numériques, limitation de la collecte des données personnelles et utilisation de technologies adaptées.</p>,
</p> },
].map((article) => (
</div> <section key={article.title} className="mb-6 sm:mb-8">
<h2 className="text-lg sm:text-xl md:text-2xl font-bold text-green-700 mb-2 sm:mb-3">
</section> {article.title}
</h2>
{article.content}
</section>
{/* Article 2 */} ))}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 2 – Développement du site
</h2>
<p className="text-gray-700">
Le site du jeu-concours « 100% Gagnant » a été conçu et développé
par Furious Ducks, responsable de la conception technique,
de l'application web, de l'API et de l'infrastructure.
</p>
</section>
{/* Article 3 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 3 – Hébergement
</h2>
<p className="text-gray-700">
Le site est hébergé par HexaCloud Hostinger.
</p>
</section>
{/* Article 4 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 4 – Propriété intellectuelle
</h2>
<p className="text-gray-700 leading-relaxed">
L'ensemble des éléments présents sur le site (textes, images,
logos, graphismes, logiciels, marques et contenus) appartient
à Thé Tip Top ou à ses partenaires.
Toute reproduction ou utilisation sans autorisation préalable
est interdite.
</p>
</section>
{/* Article 5 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 5 – Cookies
</h2>
<p className="text-gray-700 leading-relaxed">
Le site peut utiliser des cookies nécessaires à son fonctionnement
ainsi que des cookies d'analyse et de mesure d'audience.
L'utilisateur peut gérer ses préférences à tout moment.
</p>
</section>
{/* Article 6 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 6 – Responsabilité
</h2>
<p className="text-gray-700 leading-relaxed">
Thé Tip Top s'efforce de fournir des informations exactes.
Toutefois, la société ne peut être tenue responsable des erreurs,
interruptions de service ou dommages liés à l'utilisation d'Internet.
</p>
</section>
{/* Article 7 */}
<section className="mb-8">
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 7 – Droit applicable
</h2>
<p className="text-gray-700">
Le présent site est soumis au droit français.
Tout litige relève des juridictions françaises compétentes.
</p>
</section>
{/* Article 8 */}
<section>
<h2 className="text-2xl font-bold text-green-700 mb-3">
Article 8 – Engagement responsable
</h2>
<p className="text-gray-700 leading-relaxed">
Thé Tip Top s'engage dans une démarche responsable :
optimisation des ressources numériques, limitation de la collecte
des données personnelles et utilisation de technologies adaptées.
</p>
</section>
</div> </div>
</main> </main>
) )
} }

View File

@@ -4,179 +4,97 @@ export default function ReglesJeu() {
return ( return (
<div className="bg-green-50 min-h-screen"> <div className="bg-green-50 min-h-screen">
{/* Hero */} {/* Hero */}
<section className="max-w-7xl mx-auto px-6 py-20"> <section className="max-w-7xl mx-auto px-4 sm:px-6 py-12 sm:py-16 md:py-20">
<div className="text-center max-w-3xl mx-auto"> <div className="text-center max-w-3xl mx-auto">
<h1 className="text-3xl sm:text-4xl md:text-5xl font-bold text-green-800 mb-4 sm:mb-6">
<h1 className="text-5xl font-bold text-green-800 mb-6">
Règles du jeu Règles du jeu
</h1> </h1>
<p className="text-base sm:text-xl text-gray-600">
<p className="text-xl text-gray-600">
Participez au jeu-concours ThéTipTop et découvrez immédiatement Participez au jeu-concours ThéTipTop et découvrez immédiatement
le lot que vous avez gagné. le lot que vous avez gagné.
</p> </p>
</div> </div>
</section> </section>
{/* Comment participer */} {/* Comment participer */}
<section className="max-w-6xl mx-auto px-6 pb-16"> <section className="max-w-6xl mx-auto px-4 sm:px-6 pb-12 sm:pb-16">
<h2 className="text-2xl sm:text-3xl font-bold text-green-800 text-center mb-8 sm:mb-10">
<h2 className="text-3xl font-bold text-green-800 text-center mb-10">
Comment participer ? Comment participer ?
</h2> </h2>
<div className="grid sm:grid-cols-2 md:grid-cols-3 gap-4 sm:gap-6">
{[
<div className="grid md:grid-cols-3 gap-6"> {
num: '1',
title: 'Obtenez un code',
<div className="bg-white rounded-2xl shadow p-8 text-center"> text: "Achetez un produit ThéTipTop d'une valeur supérieure à 49€ en ligne ou en magasin pour recevoir un code unique à 10 chiffres.",
},
<div className="text-4xl font-bold text-green-700 mb-4"> {
1 num: '2',
title: 'Créez votre compte',
text: "Inscrivez-vous sur le site du jeu-concours afin d'accéder à votre espace participant.",
},
{
num: '3',
title: 'Découvrez votre lot',
text: 'Entrez votre code dans votre espace client et découvrez immédiatement votre récompense.',
},
].map((step) => (
<div key={step.num} className="bg-white rounded-2xl shadow p-6 sm:p-8 text-center">
<div className="text-3xl sm:text-4xl font-bold text-green-700 mb-3 sm:mb-4">{step.num}</div>
<h3 className="text-lg sm:text-xl font-semibold mb-2 sm:mb-3">{step.title}</h3>
<p className="text-gray-600 text-sm sm:text-base">{step.text}</p>
</div> </div>
))}
<h3 className="text-xl font-semibold mb-3">
Obtenez un code
</h3>
<p className="text-gray-600">
Achetez un produit ThéTipTop d'une valeur supérieure à 49€
en ligne ou en magasin pour recevoir un code unique à 10 chiffres.
</p>
</div>
<div className="bg-white rounded-2xl shadow p-8 text-center">
<div className="text-4xl font-bold text-green-700 mb-4">
2
</div>
<h3 className="text-xl font-semibold mb-3">
Créez votre compte
</h3>
<p className="text-gray-600">
Inscrivez-vous sur le site du jeu-concours afin d'accéder
à votre espace participant.
</p>
</div>
<div className="bg-white rounded-2xl shadow p-8 text-center">
<div className="text-4xl font-bold text-green-700 mb-4">
3
</div>
<h3 className="text-xl font-semibold mb-3">
Découvrez votre lot
</h3>
<p className="text-gray-600">
Entrez votre code dans votre espace client et découvrez
immédiatement votre récompense.
</p>
</div>
</div> </div>
</section> </section>
{/* Lots */} {/* Lots */}
<section className="max-w-5xl mx-auto px-6 pb-16"> <section className="max-w-5xl mx-auto px-4 sm:px-6 pb-12 sm:pb-16">
<div className="bg-white rounded-2xl shadow p-6 sm:p-10">
<div className="bg-white rounded-2xl shadow p-10"> <h2 className="text-2xl sm:text-3xl font-bold text-green-800 mb-4 sm:mb-6 text-center">
<h2 className="text-3xl font-bold text-green-800 mb-6 text-center">
Que pouvez-vous gagner ? Que pouvez-vous gagner ?
</h2> </h2>
<p className="text-gray-600 text-base sm:text-lg text-center leading-relaxed mb-6 sm:mb-8">
<p className="text-gray-600 text-lg text-center leading-relaxed mb-8">
Tous les billets sont gagnants ! Les récompenses peuvent aller Tous les billets sont gagnants ! Les récompenses peuvent aller
d'un infuseur à thé à un coffret découverte d'une valeur de 69€, d'un infuseur à thé à un coffret découverte d'une valeur de 69€,
en passant par des thés détox et des thés signatures. en passant par des thés détox et des thés signatures.
</p> </p>
<div className="bg-green-50 rounded-xl p-4 sm:p-6 text-center">
<h3 className="text-xl sm:text-2xl font-bold text-green-700 mb-2">Grand gagnant</h3>
<div className="bg-green-50 rounded-xl p-6 text-center"> <p className="text-gray-700 text-sm sm:text-base">
Le participant tiré au sort remportera une année de thé d'une valeur de 360€ !
<h3 className="text-2xl font-bold text-green-700 mb-2">
Grand gagnant
</h3>
<p className="text-gray-700">
Le participant tiré au sort remportera une année de thé
d'une valeur de 360€ !
</p> </p>
</div> </div>
</div> </div>
</section> </section>
{/* CTA */} {/* CTA */}
<section className="max-w-5xl mx-auto px-6 pb-20"> <section className="max-w-5xl mx-auto px-4 sm:px-6 pb-12 sm:pb-20">
<div className="bg-green-700 rounded-2xl p-6 sm:p-10 text-center text-white">
<div className="bg-green-700 rounded-2xl p-10 text-center text-white"> <h2 className="text-2xl sm:text-3xl font-bold mb-3 sm:mb-4">
<h2 className="text-3xl font-bold mb-4">
Ne manquez pas votre chance ! Ne manquez pas votre chance !
</h2> </h2>
<p className="mb-6 sm:mb-8 text-base sm:text-lg">
<p className="mb-8 text-lg"> Inscrivez-vous, entrez votre code de ticket et retirez votre lot en magasin ou en ligne.
Inscrivez-vous, entrez votre code de ticket et retirez votre lot
en magasin ou en ligne.
</p> </p>
<div className="flex flex-col sm:flex-row justify-center gap-3 sm:gap-4">
<div className="flex flex-col sm:flex-row justify-center gap-4">
<Link <Link
to="/inscription" to="/inscription"
className="bg-white text-green-700 px-8 py-3 rounded-xl font-semibold hover:bg-green-50" className="bg-white text-green-700 px-6 sm:px-8 py-3 rounded-xl font-semibold hover:bg-green-50 text-sm sm:text-base"
> >
Inscrivez-vous Inscrivez-vous
</Link> </Link>
<Link <Link
to="/saisir-code-unique" to="/saisir-code-unique"
className="border border-white px-8 py-3 rounded-xl font-semibold hover:bg-green-800" className="border border-white px-6 sm:px-8 py-3 rounded-xl font-semibold hover:bg-green-800 text-sm sm:text-base"
> >
Entrer mon code de ticket Entrer mon code de ticket
</Link> </Link>
</div> </div>
</div> </div>
</section> </section>
</div> </div>
) )
} }