Compare commits

..

15 Commits

Author SHA1 Message Date
a99a48e32c Merge dev into preprod: GTM/GA4, security fixes, mobile improvements 2025-12-05 15:38:04 +01:00
a80d42271d fix: replace vulnerable email regex with safe helper function
- Use isValidEmail from helpers instead of inline regex
- Fixes SonarQube Security Hotspot for DoS via backtracking

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 14:44:51 +01:00
d192dad7e6 chore: trigger deployment
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 14:20:38 +01:00
33b9b05e2f fix: simplify mobile navigation
- Remove Inscription/Connexion buttons from hero on mobile
- Simplify Participer button on mobile menu (direct link instead of dropdown)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 14:08:17 +01:00
923334a92c chore: trigger pipeline after disk cleanup
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 13:52:39 +01:00
340aa93c4e fix: use beforeInteractive strategy for GTM and GA4
- Changed GTM script from afterInteractive to beforeInteractive
- Changed GA4 scripts to beforeInteractive for earlier loading
- Hardcoded IDs to avoid template literal issues

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 13:46:28 +01:00
8fc3851cf7 chore: trigger pipeline rebuild
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 13:42:03 +01:00
4dcc091b53 feat: add GTM + improve mobile hero section
- Added Google Tag Manager (GTM-WN8H6RTC) script and noscript
- Added padding-top on mobile hero to avoid header overlap
- Reduced subtitle text size on mobile for better readability
- Added Inscription/Connexion buttons on mobile for non-authenticated users

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 13:30:26 +01:00
e64de7c41a fix: improve hero section responsive design for mobile
- Reduced title sizes on mobile (text-3xl to text-7xl progressive)
- Reduced subtitle sizes on mobile (text-2xl to text-6xl progressive)
- Adjusted description text size for better mobile readability
- Reduced button padding and font size on mobile

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 13:07:41 +01:00
c5f0d6b14c fix: change Total Participations stat card to blue color
- Client page: Total Participations now uses blue-600/blue-100
- History page: Total stat card now uses blue-600/blue-100

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 12:32:42 +01:00
211355f6a4 fix: update stat cards to use primary colors instead of green/blue
- Changed Réclamés stat card on history page from green to primary
- Changed Réclamés filter button from green to primary
- Unified Gains réclamés on client page to use primary-600

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 12:15:33 +01:00
0efd921bbf feat: update client dashboard page with new color palette
- Replace hex colors with primary/secondary/beige Tailwind classes
- Update background gradient to use beige colors
- Update buttons to use primary green theme
- Update statistics cards with primary/secondary colors
- Update table headers and borders

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 11:59:08 +01:00
98b23fe12e feat: add active/inactive clients statistics to admin dashboard
- Add activeClients and inactiveClients to AdminStatistics type
- Add pie chart showing client status (active/inactive)
- Add detailed stats rows for active/inactive clients

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 11:49:06 +01:00
41313a2477 fix: update tests to match new color palette
- Update theme.test.ts to expect primary/secondary colors instead of blue/yellow/green
- Update PrizeCard.test.tsx to expect beige-300 and primary-500 border classes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 11:27:40 +01:00
81a3e0bfae feat: update color palette to WCAG AA compliant green theme
- Update primary colors to forest green (#0B6029)
- Update all page titles to use primary-300/500 colors
- Update components (Header, Footer, Button, etc.)
- Fix email to thetiptopgr3@gmail.com
- Adjust hero section spacing

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 11:18:19 +01:00
33 changed files with 650 additions and 606 deletions

View File

@ -45,15 +45,15 @@ describe('PrizeCard', () => {
const { container } = render(<PrizeCard {...defaultProps} />); const { container } = render(<PrizeCard {...defaultProps} />);
const card = container.firstChild; const card = container.firstChild;
expect(card).toHaveClass('border-[#e5e4dc]'); expect(card).toHaveClass('border-beige-300');
expect(card).not.toHaveClass('border-[#d4a574]'); expect(card).not.toHaveClass('border-primary-500');
}); });
it('should render with grand prix styling when isGrandPrix is true', () => { it('should render with grand prix styling when isGrandPrix is true', () => {
const { container } = render(<PrizeCard {...defaultProps} isGrandPrix />); const { container } = render(<PrizeCard {...defaultProps} isGrandPrix />);
const card = container.firstChild; const card = container.firstChild;
expect(card).toHaveClass('border-[#d4a574]'); expect(card).toHaveClass('border-primary-500');
}); });
it('should apply custom className', () => { it('should apply custom className', () => {

View File

@ -21,32 +21,32 @@ import {
describe('Theme Utility', () => { describe('Theme Utility', () => {
describe('Constants', () => { describe('Constants', () => {
it('should have all status colors defined', () => { it('should have all status colors defined', () => {
expect(STATUS_COLORS.PENDING).toBe('bg-yellow-100 text-yellow-800'); expect(STATUS_COLORS.PENDING).toBe('bg-secondary-100 text-secondary-800');
expect(STATUS_COLORS.CLAIMED).toBe('bg-green-100 text-green-800'); expect(STATUS_COLORS.CLAIMED).toBe('bg-primary-100 text-primary-800');
expect(STATUS_COLORS.REJECTED).toBe('bg-red-100 text-red-800'); expect(STATUS_COLORS.REJECTED).toBe('bg-red-100 text-red-800');
expect(STATUS_COLORS.ACTIVE).toBe('bg-green-100 text-green-800'); expect(STATUS_COLORS.ACTIVE).toBe('bg-primary-100 text-primary-800');
expect(STATUS_COLORS.INACTIVE).toBe('bg-gray-100 text-gray-800'); expect(STATUS_COLORS.INACTIVE).toBe('bg-gray-100 text-gray-800');
expect(STATUS_COLORS.EXPIRED).toBe('bg-red-100 text-red-800'); expect(STATUS_COLORS.EXPIRED).toBe('bg-red-100 text-red-800');
}); });
it('should have all badge colors defined', () => { it('should have all badge colors defined', () => {
expect(BADGE_COLORS.info).toBe('bg-blue-100 text-blue-800'); expect(BADGE_COLORS.info).toBe('bg-blue-100 text-blue-800');
expect(BADGE_COLORS.success).toBe('bg-green-100 text-green-800'); expect(BADGE_COLORS.success).toBe('bg-primary-100 text-primary-800');
expect(BADGE_COLORS.warning).toBe('bg-yellow-100 text-yellow-800'); expect(BADGE_COLORS.warning).toBe('bg-secondary-100 text-secondary-800');
expect(BADGE_COLORS.error).toBe('bg-red-100 text-red-800'); expect(BADGE_COLORS.error).toBe('bg-red-100 text-red-800');
expect(BADGE_COLORS.purple).toBe('bg-purple-100 text-purple-800'); expect(BADGE_COLORS.purple).toBe('bg-purple-100 text-purple-800');
expect(BADGE_COLORS.pink).toBe('bg-pink-100 text-pink-800'); expect(BADGE_COLORS.pink).toBe('bg-pink-100 text-pink-800');
expect(BADGE_COLORS.amber).toBe('bg-amber-100 text-amber-800'); expect(BADGE_COLORS.amber).toBe('bg-secondary-200 text-secondary-800');
expect(BADGE_COLORS.gray).toBe('bg-gray-100 text-gray-800'); expect(BADGE_COLORS.gray).toBe('bg-gray-100 text-gray-800');
}); });
it('should have all button styles defined', () => { it('should have all button styles defined', () => {
expect(BUTTON_STYLES.primary).toContain('bg-blue-600'); expect(BUTTON_STYLES.primary).toContain('bg-primary-500');
expect(BUTTON_STYLES.secondary).toContain('bg-gray-600'); expect(BUTTON_STYLES.secondary).toContain('bg-secondary-500');
expect(BUTTON_STYLES.success).toContain('bg-green-600'); expect(BUTTON_STYLES.success).toContain('bg-primary-500');
expect(BUTTON_STYLES.danger).toContain('bg-red-600'); expect(BUTTON_STYLES.danger).toContain('bg-red-600');
expect(BUTTON_STYLES.warning).toContain('bg-yellow-600'); expect(BUTTON_STYLES.warning).toContain('bg-secondary-400');
expect(BUTTON_STYLES.outline).toContain('border-blue-600'); expect(BUTTON_STYLES.outline).toContain('border-primary-500');
expect(BUTTON_STYLES.ghost).toContain('text-gray-600'); expect(BUTTON_STYLES.ghost).toContain('text-gray-600');
}); });
@ -74,28 +74,28 @@ describe('Theme Utility', () => {
it('should have role colors defined', () => { it('should have role colors defined', () => {
expect(ROLE_COLORS.ADMIN).toBe('bg-red-100 text-red-800'); expect(ROLE_COLORS.ADMIN).toBe('bg-red-100 text-red-800');
expect(ROLE_COLORS.EMPLOYEE).toBe('bg-blue-100 text-blue-800'); expect(ROLE_COLORS.EMPLOYEE).toBe('bg-blue-100 text-blue-800');
expect(ROLE_COLORS.CLIENT).toBe('bg-green-100 text-green-800'); expect(ROLE_COLORS.CLIENT).toBe('bg-primary-100 text-primary-800');
}); });
it('should have prize colors defined', () => { it('should have prize colors defined', () => {
expect(PRIZE_COLORS.INFUSEUR).toBe('bg-blue-100 text-blue-800'); expect(PRIZE_COLORS.INFUSEUR).toBe('bg-blue-100 text-blue-800');
expect(PRIZE_COLORS.THE_SIGNATURE).toBe('bg-green-100 text-green-800'); expect(PRIZE_COLORS.THE_SIGNATURE).toBe('bg-primary-100 text-primary-800');
expect(PRIZE_COLORS.COFFRET_DECOUVERTE).toBe('bg-purple-100 text-purple-800'); expect(PRIZE_COLORS.COFFRET_DECOUVERTE).toBe('bg-purple-100 text-purple-800');
expect(PRIZE_COLORS.COFFRET_PRESTIGE).toBe('bg-amber-100 text-amber-800'); expect(PRIZE_COLORS.COFFRET_PRESTIGE).toBe('bg-secondary-200 text-secondary-800');
expect(PRIZE_COLORS.THE_GRATUIT).toBe('bg-pink-100 text-pink-800'); expect(PRIZE_COLORS.THE_GRATUIT).toBe('bg-pink-100 text-pink-800');
}); });
}); });
describe('getStatusColor', () => { describe('getStatusColor', () => {
it('should return correct color for known statuses', () => { it('should return correct color for known statuses', () => {
expect(getStatusColor('PENDING')).toBe('bg-yellow-100 text-yellow-800'); expect(getStatusColor('PENDING')).toBe('bg-secondary-100 text-secondary-800');
expect(getStatusColor('CLAIMED')).toBe('bg-green-100 text-green-800'); expect(getStatusColor('CLAIMED')).toBe('bg-primary-100 text-primary-800');
expect(getStatusColor('REJECTED')).toBe('bg-red-100 text-red-800'); expect(getStatusColor('REJECTED')).toBe('bg-red-100 text-red-800');
}); });
it('should handle lowercase statuses', () => { it('should handle lowercase statuses', () => {
expect(getStatusColor('pending')).toBe('bg-yellow-100 text-yellow-800'); expect(getStatusColor('pending')).toBe('bg-secondary-100 text-secondary-800');
expect(getStatusColor('claimed')).toBe('bg-green-100 text-green-800'); expect(getStatusColor('claimed')).toBe('bg-primary-100 text-primary-800');
}); });
it('should return gray for unknown statuses', () => { it('should return gray for unknown statuses', () => {
@ -106,16 +106,16 @@ describe('Theme Utility', () => {
describe('getButtonStyle', () => { describe('getButtonStyle', () => {
it('should return primary style by default', () => { it('should return primary style by default', () => {
expect(getButtonStyle()).toContain('bg-blue-600'); expect(getButtonStyle()).toContain('bg-primary-500');
}); });
it('should return correct style for variant', () => { it('should return correct style for variant', () => {
expect(getButtonStyle('primary')).toContain('bg-blue-600'); expect(getButtonStyle('primary')).toContain('bg-primary-500');
expect(getButtonStyle('secondary')).toContain('bg-gray-600'); expect(getButtonStyle('secondary')).toContain('bg-secondary-500');
expect(getButtonStyle('success')).toContain('bg-green-600'); expect(getButtonStyle('success')).toContain('bg-primary-500');
expect(getButtonStyle('danger')).toContain('bg-red-600'); expect(getButtonStyle('danger')).toContain('bg-red-600');
expect(getButtonStyle('warning')).toContain('bg-yellow-600'); expect(getButtonStyle('warning')).toContain('bg-secondary-400');
expect(getButtonStyle('outline')).toContain('border-blue-600'); expect(getButtonStyle('outline')).toContain('border-primary-500');
expect(getButtonStyle('ghost')).toContain('text-gray-600'); expect(getButtonStyle('ghost')).toContain('text-gray-600');
}); });
}); });
@ -140,13 +140,13 @@ describe('Theme Utility', () => {
it('should return correct color for known roles', () => { it('should return correct color for known roles', () => {
expect(getRoleColor('ADMIN')).toBe('bg-red-100 text-red-800'); expect(getRoleColor('ADMIN')).toBe('bg-red-100 text-red-800');
expect(getRoleColor('EMPLOYEE')).toBe('bg-blue-100 text-blue-800'); expect(getRoleColor('EMPLOYEE')).toBe('bg-blue-100 text-blue-800');
expect(getRoleColor('CLIENT')).toBe('bg-green-100 text-green-800'); expect(getRoleColor('CLIENT')).toBe('bg-primary-100 text-primary-800');
}); });
it('should handle lowercase roles', () => { it('should handle lowercase roles', () => {
expect(getRoleColor('admin')).toBe('bg-red-100 text-red-800'); expect(getRoleColor('admin')).toBe('bg-red-100 text-red-800');
expect(getRoleColor('employee')).toBe('bg-blue-100 text-blue-800'); expect(getRoleColor('employee')).toBe('bg-blue-100 text-blue-800');
expect(getRoleColor('client')).toBe('bg-green-100 text-green-800'); expect(getRoleColor('client')).toBe('bg-primary-100 text-primary-800');
}); });
it('should return gray for unknown roles', () => { it('should return gray for unknown roles', () => {
@ -157,9 +157,9 @@ describe('Theme Utility', () => {
describe('getPrizeColor', () => { describe('getPrizeColor', () => {
it('should return correct color for known prize types', () => { it('should return correct color for known prize types', () => {
expect(getPrizeColor('INFUSEUR')).toBe('bg-blue-100 text-blue-800'); expect(getPrizeColor('INFUSEUR')).toBe('bg-blue-100 text-blue-800');
expect(getPrizeColor('THE_SIGNATURE')).toBe('bg-green-100 text-green-800'); expect(getPrizeColor('THE_SIGNATURE')).toBe('bg-primary-100 text-primary-800');
expect(getPrizeColor('COFFRET_DECOUVERTE')).toBe('bg-purple-100 text-purple-800'); expect(getPrizeColor('COFFRET_DECOUVERTE')).toBe('bg-purple-100 text-purple-800');
expect(getPrizeColor('COFFRET_PRESTIGE')).toBe('bg-amber-100 text-amber-800'); expect(getPrizeColor('COFFRET_PRESTIGE')).toBe('bg-secondary-200 text-secondary-800');
expect(getPrizeColor('THE_GRATUIT')).toBe('bg-pink-100 text-pink-800'); expect(getPrizeColor('THE_GRATUIT')).toBe('bg-pink-100 text-pink-800');
}); });

View File

@ -8,15 +8,15 @@ import { Leaf } from "lucide-react";
export default function AboutPage() { export default function AboutPage() {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0]"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100">
{/* Hero Section */} {/* Hero Section */}
<section className="bg-gradient-to-r from-white to-[#faf9f5] py-12 border-b-2 border-[#e5e4dc]"> <section className="bg-gradient-to-r from-white to-beige-50 py-12 border-b-2 border-beige-300">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto text-center"> <div className="max-w-4xl mx-auto text-center">
<h1 className="text-4xl md:text-5xl font-bold text-[#5a5a4e] mb-4"> <h1 className="text-4xl md:text-5xl font-bold text-primary-300 mb-4">
À propos de Thé Tip Top à Nice À propos de Thé Tip Top à Nice
</h1> </h1>
<p className="text-lg text-[#8a8a7a]"> <p className="text-lg text-gray-600">
Notre passion pour le thé d'exception et nos événements uniques à Nice Notre passion pour le thé d'exception et nos événements uniques à Nice
</p> </p>
</div> </div>
@ -29,9 +29,9 @@ export default function AboutPage() {
<div className="grid md:grid-cols-2 gap-16 items-center"> <div className="grid md:grid-cols-2 gap-16 items-center">
{/* Texte */} {/* Texte */}
<div className="order-2 md:order-1 space-y-6"> <div className="order-2 md:order-1 space-y-6">
<h2 className="text-4xl md:text-5xl font-bold text-[#5a5a4e] leading-tight"> <h2 className="text-4xl md:text-5xl font-bold text-primary-300 leading-tight">
Notre Histoire Notre Histoire
<span className="block text-3xl md:text-4xl text-[#d4a574] mt-2"> <span className="block text-3xl md:text-4xl text-primary-500 mt-2">
Thé Tip Top Nice Thé Tip Top Nice
</span> </span>
</h2> </h2>
@ -66,30 +66,30 @@ export default function AboutPage() {
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto"> <div className="max-w-5xl mx-auto">
<div className="text-center mb-8"> <div className="text-center mb-8">
<h2 className="text-3xl font-bold text-[#5a5a4e] mb-2">Notre Engagement - Thé Tip Top </h2> <h2 className="text-3xl font-bold text-primary-300 mb-2">Notre Engagement - Thé Tip Top </h2>
<p className="text-[#8a8a7a]">Qualité, Durabilité et Respect au Cœur de Chaque Thé</p> <p className="text-gray-600">Qualité, Durabilité et Respect au Cœur de Chaque Thé</p>
</div> </div>
<div className="grid md:grid-cols-3 gap-4"> <div className="grid md:grid-cols-3 gap-4">
<div className="bg-gradient-to-br from-[#d4a574]/10 to-[#c4956a]/10 rounded-lg p-6 text-center border border-[#d4a574]/20 hover:shadow-lg transition-shadow"> <div className="bg-gradient-to-br from-primary-50 to-primary-100 rounded-lg p-6 text-center border border-primary-200 hover:shadow-lg transition-shadow">
<div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center shadow-lg"> <div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center shadow-lg">
<Leaf className="w-8 h-8 text-white" /> <Leaf className="w-8 h-8 text-white" />
</div> </div>
<div className="text-2xl font-bold text-[#5a5a4e] mb-2">Thé bio</div> <div className="text-2xl font-bold text-gray-800 mb-2">Thé bio</div>
<p className="text-sm text-[#8a8a7a]"> <p className="text-sm text-gray-600">
Tous nos thés sont certifiés biologiques et cultivés dans le respect de l'environnement. Tous nos thés sont certifiés biologiques et cultivés dans le respect de l'environnement.
</p> </p>
</div> </div>
<div className="bg-gradient-to-br from-[#d4a574]/10 to-[#c4956a]/10 rounded-lg p-6 text-center border border-[#d4a574]/20 hover:shadow-lg transition-shadow"> <div className="bg-gradient-to-br from-primary-50 to-primary-100 rounded-lg p-6 text-center border border-primary-200 hover:shadow-lg transition-shadow">
<div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-3xl shadow-lg">🌍</div> <div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-3xl shadow-lg">🌍</div>
<div className="text-2xl font-bold text-[#5a5a4e] mb-2">Commerce équitable </div> <div className="text-2xl font-bold text-gray-800 mb-2">Commerce équitable </div>
<p className="text-sm text-[#8a8a7a]"> <p className="text-sm text-gray-600">
Nous soutenons les producteurs locaux en collaborant avec des partenaires engagés dans des pratiques durables et équitables Nous soutenons les producteurs locaux en collaborant avec des partenaires engagés dans des pratiques durables et équitables
</p> </p>
</div> </div>
<div className="bg-gradient-to-br from-[#d4a574]/10 to-[#c4956a]/10 rounded-lg p-6 text-center border border-[#d4a574]/20 hover:shadow-lg transition-shadow"> <div className="bg-gradient-to-br from-primary-50 to-primary-100 rounded-lg p-6 text-center border border-primary-200 hover:shadow-lg transition-shadow">
<div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-3xl shadow-lg">📦</div> <div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-3xl shadow-lg">📦</div>
<div className="text-2xl font-bold text-[#5a5a4e] mb-2">Livraison rapide</div> <div className="text-2xl font-bold text-gray-800 mb-2">Livraison rapide</div>
<p className="text-sm text-[#8a8a7a]"> <p className="text-sm text-gray-600">
Expédition sous 24h pour que vous puissiez savourer rapidement vos thés Expédition sous 24h pour que vous puissiez savourer rapidement vos thés
</p> </p>
</div> </div>
@ -102,26 +102,26 @@ export default function AboutPage() {
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto"> <div className="max-w-5xl mx-auto">
<div className="text-center mb-8"> <div className="text-center mb-8">
<h2 className="text-2xl italic text-[#5a5a4e] mb-4"> <h2 className="text-2xl italic text-gray-800 mb-4">
"Le thé, un art de vivre, une invitation à la découverte." "Le thé, un art de vivre, une invitation à la découverte."
</h2> </h2>
<p className="text-[#8a8a7a]">Philosophie de Thé Tip Top</p> <p className="text-gray-600">Philosophie de Thé Tip Top</p>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
{/* Contact Section */} {/* Contact Section */}
<section className="py-12 bg-gradient-to-br from-[#d4a574]/10 to-[#c4956a]/10"> <section className="py-12 bg-gradient-to-br from-primary-50 to-primary-100">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-3xl mx-auto text-center"> <div className="max-w-3xl mx-auto text-center">
<h3 className="text-2xl font-bold text-[#5a5a4e] mb-4">Contactez-nous</h3> <h3 className="text-2xl font-bold text-gray-800 mb-4">Contactez-nous</h3>
<p className="text-[#8a8a7a] mb-4"> <p className="text-gray-600 mb-4">
Une question sur notre histoire ou nos thés ? N'hésitez pas à nous écrire ! Une question sur notre histoire ou nos thés ? N'hésitez pas à nous écrire !
</p> </p>
<a <a
href="mailto:thetiptopgr3@gmail.com" href="mailto:thetiptopgr3@gmail.com"
className="inline-flex items-center gap-2 text-[#d4a574] hover:text-[#c4956a] font-semibold transition-colors" className="inline-flex items-center gap-2 text-primary-500 hover:text-primary-600 font-semibold transition-colors"
> >
<span></span> <span></span>
thetiptopgr3@gmail.com thetiptopgr3@gmail.com

View File

@ -187,6 +187,12 @@ export default function AdminDashboardAdvanced() {
{ name: "Admins", value: stats.users.admins || 0, color: "#3b82f6" }, { name: "Admins", value: stats.users.admins || 0, color: "#3b82f6" },
].filter(item => item.value > 0); ].filter(item => item.value > 0);
// Données pour le graphique des clients actifs/inactifs
const clientStatusData = [
{ name: "Actifs", value: stats.users.activeClients || 0, color: "#10b981" },
{ name: "Inactifs", value: stats.users.inactiveClients || 0, color: "#ef4444" },
].filter(item => item.value > 0);
const ticketDistributedPercent = stats.tickets.total > 0 const ticketDistributedPercent = stats.tickets.total > 0
? ((stats.tickets.distributed / stats.tickets.total) * 100).toFixed(1) ? ((stats.tickets.distributed / stats.tickets.total) * 100).toFixed(1)
: 0; : 0;
@ -389,6 +395,39 @@ export default function AdminDashboardAdvanced() {
</div> </div>
)} )}
{/* Graphique Clients Actifs/Inactifs */}
{clientStatusData.length > 0 && (
<div className="bg-white rounded-2xl shadow-md border border-gray-100 p-6 hover:shadow-lg transition-shadow">
<h2 className="text-xl font-bold text-gray-800 mb-4 flex items-center gap-3">
<div className="w-10 h-10 bg-emerald-100 rounded-xl flex items-center justify-center">
<UserIcon className="w-5 h-5 text-emerald-600" />
</div>
Statut des Clients
</h2>
<ResponsiveContainer width="100%" height={300}>
<PieChart>
<Pie
data={clientStatusData}
cx="50%"
cy="50%"
labelLine={false}
label={({ name, value }) => `${name}: ${value}`}
outerRadius={80}
innerRadius={40}
fill="#8884d8"
dataKey="value"
>
{clientStatusData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} />
))}
</Pie>
<Tooltip />
<Legend />
</PieChart>
</ResponsiveContainer>
</div>
)}
{/* Graphique répartition par genre */} {/* Graphique répartition par genre */}
{genderChartData.length > 0 && ( {genderChartData.length > 0 && (
<div className="bg-white rounded-2xl shadow-md border border-gray-100 p-6 hover:shadow-lg transition-shadow"> <div className="bg-white rounded-2xl shadow-md border border-gray-100 p-6 hover:shadow-lg transition-shadow">
@ -502,6 +541,8 @@ export default function AdminDashboardAdvanced() {
<div className="space-y-3"> <div className="space-y-3">
<StatRow label="Total" value={stats?.users?.total || 0} /> <StatRow label="Total" value={stats?.users?.total || 0} />
<StatRow label="Clients" value={stats?.users?.clients || 0} color="green" /> <StatRow label="Clients" value={stats?.users?.clients || 0} color="green" />
<StatRow label="Clients actifs" value={stats?.users?.activeClients || 0} color="green" />
<StatRow label="Clients inactifs" value={stats?.users?.inactiveClients || 0} color="red" />
<StatRow label="Employés" value={stats?.users?.employees || 0} color="purple" /> <StatRow label="Employés" value={stats?.users?.employees || 0} color="purple" />
<StatRow label="Admins" value={stats?.users?.admins || 0} color="blue" /> <StatRow label="Admins" value={stats?.users?.admins || 0} color="blue" />
</div> </div>

View File

@ -64,21 +64,21 @@ export default function ClientPage() {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0] py-8"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100 py-8">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
{/* Welcome Section */} {/* Welcome Section */}
<div className="mb-8"> <div className="mb-8">
<h1 className="text-4xl font-bold text-[#5a5a4e] mb-2"> <h1 className="text-4xl font-bold text-primary-500 mb-2">
Bonjour {user?.firstName} ! 👋 Bonjour {user?.firstName} !
</h1> </h1>
<p className="text-[#8a8a7a]"> <p className="text-gray-600">
Bienvenue dans votre espace client Bienvenue dans votre espace client
</p> </p>
</div> </div>
{/* Quick Action */} {/* Quick Action */}
<div className="mb-8"> <div className="mb-8">
<div className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] text-white rounded-xl shadow-md p-8 border-2 border-[#e5e4dc]"> <div className="bg-gradient-to-r from-primary-500 to-primary-600 text-white rounded-xl shadow-md p-8 border-2 border-primary-400">
<div className="flex flex-col md:flex-row items-center justify-between gap-4"> <div className="flex flex-col md:flex-row items-center justify-between gap-4">
<div> <div>
<h2 className="text-2xl font-bold mb-2"> <h2 className="text-2xl font-bold mb-2">
@ -89,8 +89,8 @@ export default function ClientPage() {
</p> </p>
</div> </div>
<Link href={ROUTES.GAME}> <Link href={ROUTES.GAME}>
<button className="bg-white text-[#d4a574] hover:bg-[#f5f5f0] font-bold px-8 py-4 rounded-lg transition-all shadow-lg hover:scale-105 duration-300 whitespace-nowrap"> <button className="bg-white text-primary-500 hover:bg-beige-50 font-bold px-8 py-4 rounded-lg transition-all shadow-lg hover:scale-105 duration-300 whitespace-nowrap">
Jouer maintenant 🎮 Jouer maintenant
</button> </button>
</Link> </Link>
</div> </div>
@ -99,10 +99,10 @@ export default function ClientPage() {
{/* Statistics Cards */} {/* Statistics Cards */}
<div className="grid md:grid-cols-3 gap-6 mb-8"> <div className="grid md:grid-cols-3 gap-6 mb-8">
<div className="bg-white rounded-xl shadow-md p-6 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 border border-beige-300">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-[#8a8a7a] mb-2"> <p className="text-sm font-medium text-gray-600 mb-2">
Total Participations Total Participations
</p> </p>
<p className="text-4xl font-bold text-blue-600"> <p className="text-4xl font-bold text-blue-600">
@ -117,36 +117,36 @@ export default function ClientPage() {
</div> </div>
</div> </div>
<div className="bg-white rounded-xl shadow-md p-6 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 border border-beige-300">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-[#8a8a7a] mb-2"> <p className="text-sm font-medium text-gray-600 mb-2">
Gains réclamés Gains réclamés
</p> </p>
<p className="text-4xl font-bold text-green-600"> <p className="text-4xl font-bold text-primary-600">
{stats.claimed} {stats.claimed}
</p> </p>
</div> </div>
<div className="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center"> <div className="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center">
<svg className="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg> </svg>
</div> </div>
</div> </div>
</div> </div>
<div className="bg-white rounded-xl shadow-md p-6 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 border border-beige-300">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-[#8a8a7a] mb-2"> <p className="text-sm font-medium text-gray-600 mb-2">
En attente En attente
</p> </p>
<p className="text-4xl font-bold text-yellow-600"> <p className="text-4xl font-bold text-secondary-600">
{stats.pending} {stats.pending}
</p> </p>
</div> </div>
<div className="w-16 h-16 bg-yellow-100 rounded-full flex items-center justify-center"> <div className="w-16 h-16 bg-secondary-100 rounded-full flex items-center justify-center">
<svg className="w-8 h-8 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-8 h-8 text-secondary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg> </svg>
</div> </div>
@ -155,12 +155,12 @@ export default function ClientPage() {
</div> </div>
{/* Recent Tickets */} {/* Recent Tickets */}
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<div className="px-6 py-4 border-b border-[#e5e4dc]"> <div className="px-6 py-4 border-b border-beige-300">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-xl font-bold text-[#5a5a4e]">Mes derniers tickets</h2> <h2 className="text-xl font-bold text-primary-500">Mes derniers tickets</h2>
<Link href={ROUTES.HISTORY}> <Link href={ROUTES.HISTORY}>
<button className="text-[#d4a574] hover:text-[#c4956a] font-semibold text-sm transition-colors"> <button className="text-primary-500 hover:text-primary-600 font-semibold text-sm transition-colors">
Voir tout l'historique Voir tout l'historique
</button> </button>
</Link> </Link>
@ -170,11 +170,11 @@ export default function ClientPage() {
{tickets.length === 0 ? ( {tickets.length === 0 ? (
<div className="text-center py-12"> <div className="text-center py-12">
<div className="text-6xl mb-4">🎲</div> <div className="text-6xl mb-4">🎲</div>
<p className="text-[#8a8a7a] mb-4"> <p className="text-gray-600 mb-4">
Vous n'avez pas encore participé au jeu Vous n'avez pas encore participé au jeu
</p> </p>
<Link href={ROUTES.GAME}> <Link href={ROUTES.GAME}>
<button className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300"> <button className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300">
Jouer maintenant Jouer maintenant
</button> </button>
</Link> </Link>
@ -183,22 +183,22 @@ export default function ClientPage() {
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="min-w-full"> <table className="min-w-full">
<thead> <thead>
<tr className="border-b border-[#e5e4dc]"> <tr className="border-b border-beige-300">
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-primary-500 uppercase tracking-wider">
Code Ticket Code Ticket
</th> </th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-primary-500 uppercase tracking-wider">
Gain Gain
</th> </th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-primary-500 uppercase tracking-wider">
Statut Statut
</th> </th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-primary-500 uppercase tracking-wider">
Date Date
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-[#e5e4dc]"> <tbody className="divide-y divide-beige-200">
{tickets.slice(0, 5).map((ticket) => ( {tickets.slice(0, 5).map((ticket) => (
<TicketTableRow key={ticket.id} ticket={ticket} /> <TicketTableRow key={ticket.id} ticket={ticket} />
))} ))}

View File

@ -67,15 +67,15 @@ export default function ContactPage() {
}; };
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0]"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100">
{/* Hero Section */} {/* Hero Section */}
<section className="bg-gradient-to-r from-white to-[#faf9f5] py-12 border-b-2 border-[#e5e4dc]"> <section className="bg-gradient-to-r from-white to-beige-50 py-12 border-b-2 border-beige-300">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto text-center"> <div className="max-w-4xl mx-auto text-center">
<h1 className="text-4xl md:text-5xl font-bold text-[#5a5a4e] mb-4"> <h1 className="text-4xl md:text-5xl font-bold text-primary-300 mb-4">
Contactez-nous Contactez-nous
</h1> </h1>
<p className="text-lg text-[#8a8a7a]"> <p className="text-lg text-gray-600">
Une question sur le jeu-concours ? Besoin d'aide ? Notre équipe est pour vous accompagner ! Une question sur le jeu-concours ? Besoin d'aide ? Notre équipe est pour vous accompagner !
</p> </p>
</div> </div>
@ -90,13 +90,13 @@ export default function ContactPage() {
{/* Contact Form */} {/* Contact Form */}
<div> <div>
<div className="bg-white rounded-xl shadow-md p-8 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-8 border border-beige-300">
<h2 className="text-2xl font-bold text-[#5a5a4e] mb-6">Envoyez-nous un message</h2> <h2 className="text-2xl font-bold text-gray-800 mb-6">Envoyez-nous un message</h2>
<form onSubmit={handleSubmit} className="space-y-6"> <form onSubmit={handleSubmit} className="space-y-6">
{/* Nom complet */} {/* Nom complet */}
<div> <div>
<label htmlFor="fullName" className="block text-sm font-semibold text-[#5a5a4e] mb-2"> <label htmlFor="fullName" className="block text-sm font-semibold text-gray-700 mb-2">
Nom complet <span className="text-red-500">*</span> Nom complet <span className="text-red-500">*</span>
</label> </label>
<input <input
@ -107,13 +107,13 @@ export default function ContactPage() {
value={formData.fullName} value={formData.fullName}
onChange={handleChange} onChange={handleChange}
placeholder="Votre nom et prénom" placeholder="Votre nom et prénom"
className="w-full px-4 py-3 border-2 border-[#e5e4dc] rounded-lg focus:outline-none focus:ring-2 focus:ring-[#d4a574] focus:border-[#d4a574]" className="w-full px-4 py-3 border-2 border-beige-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
/> />
</div> </div>
{/* Email */} {/* Email */}
<div> <div>
<label htmlFor="email" className="block text-sm font-semibold text-[#5a5a4e] mb-2"> <label htmlFor="email" className="block text-sm font-semibold text-gray-700 mb-2">
Email <span className="text-red-500">*</span> Email <span className="text-red-500">*</span>
</label> </label>
<input <input
@ -124,13 +124,13 @@ export default function ContactPage() {
value={formData.email} value={formData.email}
onChange={handleChange} onChange={handleChange}
placeholder="votre@email.com" placeholder="votre@email.com"
className="w-full px-4 py-3 border-2 border-[#e5e4dc] rounded-lg focus:outline-none focus:ring-2 focus:ring-[#d4a574] focus:border-[#d4a574]" className="w-full px-4 py-3 border-2 border-beige-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
/> />
</div> </div>
{/* Sujet */} {/* Sujet */}
<div> <div>
<label htmlFor="subject" className="block text-sm font-semibold text-[#5a5a4e] mb-2"> <label htmlFor="subject" className="block text-sm font-semibold text-gray-700 mb-2">
Sujet <span className="text-red-500">*</span> Sujet <span className="text-red-500">*</span>
</label> </label>
<select <select
@ -139,7 +139,7 @@ export default function ContactPage() {
required required
value={formData.subject} value={formData.subject}
onChange={handleChange} onChange={handleChange}
className="w-full px-4 py-3 border-2 border-[#e5e4dc] rounded-lg focus:outline-none focus:ring-2 focus:ring-[#d4a574] focus:border-[#d4a574] bg-white" className="w-full px-4 py-3 border-2 border-beige-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500 bg-white"
> >
<option value="">Sélectionnez un sujet</option> <option value="">Sélectionnez un sujet</option>
<option value="jeu-concours">Question sur le jeu-concours</option> <option value="jeu-concours">Question sur le jeu-concours</option>
@ -152,7 +152,7 @@ export default function ContactPage() {
{/* Message */} {/* Message */}
<div> <div>
<label htmlFor="message" className="block text-sm font-semibold text-[#5a5a4e] mb-2"> <label htmlFor="message" className="block text-sm font-semibold text-gray-700 mb-2">
Message <span className="text-red-500">*</span> Message <span className="text-red-500">*</span>
</label> </label>
<textarea <textarea
@ -163,7 +163,7 @@ export default function ContactPage() {
onChange={handleChange} onChange={handleChange}
placeholder="Décrivez votre demande en détail..." placeholder="Décrivez votre demande en détail..."
rows={6} rows={6}
className="w-full px-4 py-3 border-2 border-[#e5e4dc] rounded-lg focus:outline-none focus:ring-2 focus:ring-[#d4a574] focus:border-[#d4a574] resize-none" className="w-full px-4 py-3 border-2 border-beige-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500 resize-none"
/> />
</div> </div>
@ -176,11 +176,11 @@ export default function ContactPage() {
required required
checked={formData.acceptPolicy} checked={formData.acceptPolicy}
onChange={handleCheckboxChange} onChange={handleCheckboxChange}
className="mt-1 w-5 h-5 text-[#d4a574] border-[#e5e4dc] rounded focus:ring-2 focus:ring-[#d4a574]" className="mt-1 w-5 h-5 text-primary-500 border-beige-300 rounded focus:ring-2 focus:ring-primary-500"
/> />
<label htmlFor="acceptPolicy" className="text-sm text-[#5a5a4e] select-none cursor-pointer"> <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{' '} J'accepte que mes données soient collectées et traitées conformément à la{' '}
<Link href="/privacy" className="text-[#d4a574] underline hover:text-[#c4956a]"> <Link href="/privacy" className="text-primary-500 underline hover:text-primary-600">
politique de confidentialité politique de confidentialité
</Link>{' '} </Link>{' '}
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
@ -192,7 +192,7 @@ export default function ContactPage() {
<button <button
type="submit" type="submit"
disabled={isSubmitting} disabled={isSubmitting}
className="w-full bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] disabled:from-gray-400 disabled:to-gray-500 text-white font-bold px-8 py-4 rounded-lg transition-all duration-300 shadow-lg hover:shadow-[0_0_20px_rgba(212,165,116,0.6)] hover:scale-105" className="w-full bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 disabled:from-gray-400 disabled:to-gray-500 text-white font-bold px-8 py-4 rounded-lg transition-all duration-300 shadow-lg hover:shadow-[0_0_20px_rgba(11,96,41,0.4)] hover:scale-105"
> >
{isSubmitting ? "Envoi en cours..." : "Envoyer le message"} {isSubmitting ? "Envoi en cours..." : "Envoyer le message"}
</button> </button>
@ -205,20 +205,20 @@ export default function ContactPage() {
<div className="space-y-6"> <div className="space-y-6">
{/* Nos coordonnées */} {/* Nos coordonnées */}
<div className="bg-white rounded-xl shadow-md p-8 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-8 border border-beige-300">
<h2 className="text-2xl font-bold text-[#5a5a4e] mb-6">Nos coordonnées</h2> <h2 className="text-2xl font-bold text-gray-800 mb-6">Nos coordonnées</h2>
<div className="space-y-6"> <div className="space-y-6">
{/* Siège social */} {/* Siège social */}
<div className="flex items-start gap-4"> <div className="flex items-start gap-4">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md flex-shrink-0">📍</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md flex-shrink-0">📍</div>
<div> <div>
<h3 className="font-semibold text-[#5a5a4e] mb-1">Siège social</h3> <h3 className="font-semibold text-gray-800 mb-1">Siège social</h3>
<a <a
href="https://www.google.com/maps/search/?api=1&query=18+Avenue+Thiers+06000+Nice+France" href="https://www.google.com/maps/search/?api=1&query=18+Avenue+Thiers+06000+Nice+France"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#8a8a7a] text-sm hover:text-[#d4a574] transition-colors block" className="text-gray-600 text-sm hover:text-primary-500 transition-colors block"
> >
Thé Tip Top<br /> Thé Tip Top<br />
18 Avenue Thiers<br /> 18 Avenue Thiers<br />
@ -229,11 +229,11 @@ export default function ContactPage() {
{/* Téléphone */} {/* Téléphone */}
<div className="flex items-start gap-4"> <div className="flex items-start gap-4">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md flex-shrink-0">📞</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md flex-shrink-0">📞</div>
<div> <div>
<h3 className="font-semibold text-[#5a5a4e] mb-1">Téléphone</h3> <h3 className="font-semibold text-gray-800 mb-1">Téléphone</h3>
<p className="text-[#8a8a7a] text-sm"> <p className="text-gray-600 text-sm">
<a href="tel:+33123456789" className="hover:text-[#d4a574] transition-colors"> <a href="tel:+33123456789" className="hover:text-primary-500 transition-colors">
+33 1 23 45 67 89 +33 1 23 45 67 89
</a><br /> </a><br />
<span className="text-xs">Du lundi au vendredi<br />9h00 - 18h00</span> <span className="text-xs">Du lundi au vendredi<br />9h00 - 18h00</span>
@ -243,12 +243,12 @@ export default function ContactPage() {
{/* Email */} {/* Email */}
<div className="flex items-start gap-4"> <div className="flex items-start gap-4">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md flex-shrink-0"></div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md flex-shrink-0"></div>
<div> <div>
<h3 className="font-semibold text-[#5a5a4e] mb-1">Email</h3> <h3 className="font-semibold text-gray-800 mb-1">Email</h3>
<div className="text-[#8a8a7a] text-sm space-y-1"> <div className="text-gray-600 text-sm space-y-1">
<p> <p>
<a href="mailto:thetiptopgr3@gmail.com" className="hover:text-[#d4a574] transition-colors"> <a href="mailto:thetiptopgr3@gmail.com" className="hover:text-primary-500 transition-colors">
thetiptopgr3@gmail.com thetiptopgr3@gmail.com
</a> </a>
</p> </p>
@ -258,10 +258,10 @@ export default function ContactPage() {
{/* Service client */} {/* Service client */}
<div className="flex items-start gap-4"> <div className="flex items-start gap-4">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md flex-shrink-0">🕐</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md flex-shrink-0">🕐</div>
<div> <div>
<h3 className="font-semibold text-[#5a5a4e] mb-1">Service client</h3> <h3 className="font-semibold text-gray-800 mb-1">Service client</h3>
<p className="text-[#8a8a7a] text-sm"> <p className="text-gray-600 text-sm">
Réponse sous 24h<br /> Réponse sous 24h<br />
Support multilingue<br /> Support multilingue<br />
Du lundi au samedi Du lundi au samedi
@ -272,8 +272,8 @@ export default function ContactPage() {
</div> </div>
{/* Google Maps */} {/* Google Maps */}
<div className="bg-white rounded-xl shadow-md p-4 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-4 border border-beige-300">
<h2 className="text-xl font-bold text-[#5a5a4e] mb-4">Nous trouver</h2> <h2 className="text-xl font-bold text-gray-800 mb-4">Nous trouver</h2>
<div className="rounded-lg overflow-hidden relative"> <div className="rounded-lg overflow-hidden relative">
<iframe <iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2884.5!2d7.2619!3d43.7102!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12cdd0106a852d31%3A0x40819a5fd979a70!2s18%20Av.%20Thiers%2C%2006000%20Nice%2C%20France!5e0!3m2!1sfr!2sfr!4v1700000000000!5m2!1sfr!2sfr" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2884.5!2d7.2619!3d43.7102!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12cdd0106a852d31%3A0x40819a5fd979a70!2s18%20Av.%20Thiers%2C%2006000%20Nice%2C%20France!5e0!3m2!1sfr!2sfr!4v1700000000000!5m2!1sfr!2sfr"
@ -292,15 +292,15 @@ export default function ContactPage() {
rel="noopener noreferrer" rel="noopener noreferrer"
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-10 group" className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-10 group"
> >
<span className="block w-6 h-6 bg-red-600 rounded-full border-2 border-white shadow-lg cursor-pointer hover:scale-125 transition-transform animate-pulse"></span> <span className="block w-6 h-6 bg-primary-500 rounded-full border-2 border-white shadow-lg cursor-pointer hover:scale-125 transition-transform animate-pulse"></span>
<span className="absolute -bottom-1 left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-[6px] border-r-[6px] border-t-[8px] border-l-transparent border-r-transparent border-t-red-600"></span> <span className="absolute -bottom-1 left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-[6px] border-r-[6px] border-t-[8px] border-l-transparent border-r-transparent border-t-primary-500"></span>
</a> </a>
</div> </div>
<a <a
href="https://www.google.com/maps/search/?api=1&query=18+Avenue+Thiers+06000+Nice+France" href="https://www.google.com/maps/search/?api=1&query=18+Avenue+Thiers+06000+Nice+France"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="mt-3 inline-flex items-center gap-2 text-sm text-[#d4a574] hover:text-[#c4956a] transition-colors" className="mt-3 inline-flex items-center gap-2 text-sm text-primary-500 hover:text-primary-600 transition-colors"
> >
Ouvrir dans Google Maps Ouvrir dans Google Maps
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@ -318,17 +318,17 @@ export default function ContactPage() {
<section className="py-12"> <section className="py-12">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto"> <div className="max-w-4xl mx-auto">
<div className="bg-gradient-to-r from-[#d4a574]/10 to-[#c4956a]/10 rounded-xl p-8 border-l-4 border-[#d4a574] shadow-lg"> <div className="bg-gradient-to-r from-primary-50 to-primary-100 rounded-xl p-8 border-l-4 border-primary-500 shadow-lg">
<div className="flex items-start gap-4"> <div className="flex items-start gap-4">
<div className="w-16 h-16 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-3xl shadow-md flex-shrink-0">💡</div> <div className="w-16 h-16 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-3xl shadow-md flex-shrink-0">💡</div>
<div className="flex-1"> <div className="flex-1">
<h3 className="text-xl font-bold text-[#5a5a4e] mb-2">Avant de nous contacter</h3> <h3 className="text-xl font-bold text-gray-800 mb-2">Avant de nous contacter</h3>
<p className="text-[#5a5a4e] mb-4"> <p className="text-gray-700 mb-4">
Consultez notre FAQ, vous y trouverez peut-être la réponse à votre question ! Consultez notre FAQ, vous y trouverez peut-être la réponse à votre question !
</p> </p>
<Link <Link
href="/faq" href="/faq"
className="inline-flex items-center justify-center bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold px-6 py-3 rounded-lg transition-all duration-300 shadow-lg hover:scale-105" className="inline-flex items-center justify-center bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-3 rounded-lg transition-all duration-300 shadow-lg hover:scale-105"
> >
Voir la FAQ Voir la FAQ
</Link> </Link>

View File

@ -43,7 +43,7 @@ export default function CookiesPage() {
return ( return (
<div className="py-12"> <div className="py-12">
<div className="max-w-4xl mx-auto"> <div className="max-w-4xl mx-auto">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-8 text-center"> <h1 className="text-4xl md:text-5xl font-bold text-primary-300 mb-8 text-center">
Gestion des cookies Gestion des cookies
</h1> </h1>
@ -290,8 +290,8 @@ export default function CookiesPage() {
<CardContent> <CardContent>
<p className="text-gray-700"> <p className="text-gray-700">
Pour toute question concernant les cookies :{" "} Pour toute question concernant les cookies :{" "}
<a href="mailto:contact@thetiptop.fr" className="text-primary-600 hover:text-primary-700 underline"> <a href="mailto:thetiptopgr3@gmail.com" className="text-primary-600 hover:text-primary-700 underline">
contact@thetiptop.fr thetiptopgr3@gmail.com
</a> </a>
</p> </p>
</CardContent> </CardContent>

View File

@ -101,7 +101,7 @@ export default function FAQContent() {
<section className="bg-gradient-to-r from-white to-[#faf9f5] py-12 border-b-2 border-[#e5e4dc]"> <section className="bg-gradient-to-r from-white to-[#faf9f5] py-12 border-b-2 border-[#e5e4dc]">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto text-center"> <div className="max-w-4xl mx-auto text-center">
<h1 className="text-4xl md:text-5xl font-bold text-[#5a5a4e] mb-4"> <h1 className="text-4xl md:text-5xl font-bold text-primary-300 mb-4">
Questions fréquentes Questions fréquentes
</h1> </h1>
<p className="text-lg text-[#8a8a7a]"> <p className="text-lg text-[#8a8a7a]">

View File

@ -89,23 +89,23 @@ export default function HistoriquePage() {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0] py-8"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100 py-8">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="mb-8"> <div className="mb-8">
<h1 className="text-4xl font-bold text-[#5a5a4e] mb-2 flex items-center gap-3"> <h1 className="text-4xl font-bold text-gray-800 mb-2 flex items-center gap-3">
<Calendar className="w-10 h-10 text-[#d4a574]" /> <Calendar className="w-10 h-10 text-primary-500" />
Historique de mes participations Historique de mes participations
</h1> </h1>
<p className="text-[#8a8a7a]"> <p className="text-gray-600">
Consultez l'historique complet de vos participations et gains Consultez l'historique complet de vos participations et gains
</p> </p>
</div> </div>
<div className="grid md:grid-cols-4 gap-6 mb-8"> <div className="grid md:grid-cols-4 gap-6 mb-8">
<div className="bg-white rounded-xl shadow-md p-6 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 border border-beige-300">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-[#8a8a7a] mb-2">Total</p> <p className="text-sm font-medium text-gray-600 mb-2">Total</p>
<p className="text-4xl font-bold text-blue-600">{stats.total}</p> <p className="text-4xl font-bold text-blue-600">{stats.total}</p>
</div> </div>
<div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center"> <div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center">
@ -116,38 +116,38 @@ export default function HistoriquePage() {
</div> </div>
</div> </div>
<div className="bg-white rounded-xl shadow-md p-6 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 border border-beige-300">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-[#8a8a7a] mb-2">Réclamés</p> <p className="text-sm font-medium text-gray-600 mb-2">Réclamés</p>
<p className="text-4xl font-bold text-green-600">{stats.claimed}</p> <p className="text-4xl font-bold text-primary-600">{stats.claimed}</p>
</div> </div>
<div className="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center"> <div className="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center">
<svg className="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg> </svg>
</div> </div>
</div> </div>
</div> </div>
<div className="bg-white rounded-xl shadow-md p-6 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 border border-beige-300">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-[#8a8a7a] mb-2">En attente</p> <p className="text-sm font-medium text-gray-600 mb-2">En attente</p>
<p className="text-4xl font-bold text-yellow-600">{stats.pending}</p> <p className="text-4xl font-bold text-secondary-600">{stats.pending}</p>
</div> </div>
<div className="w-16 h-16 bg-yellow-100 rounded-full flex items-center justify-center"> <div className="w-16 h-16 bg-secondary-100 rounded-full flex items-center justify-center">
<svg className="w-8 h-8 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-8 h-8 text-secondary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg> </svg>
</div> </div>
</div> </div>
</div> </div>
<div className="bg-white rounded-xl shadow-md p-6 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 border border-beige-300">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-[#8a8a7a] mb-2">Rejetés</p> <p className="text-sm font-medium text-gray-600 mb-2">Rejetés</p>
<p className="text-4xl font-bold text-red-600">{stats.rejected}</p> <p className="text-4xl font-bold text-red-600">{stats.rejected}</p>
</div> </div>
<div className="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center"> <div className="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center">
@ -159,17 +159,17 @@ export default function HistoriquePage() {
</div> </div>
</div> </div>
<div className="bg-white rounded-xl shadow-md p-6 mb-6 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 mb-6 border border-beige-300">
<div className="flex flex-col md:flex-row gap-4"> <div className="flex flex-col md:flex-row gap-4">
<div className="flex-1"> <div className="flex-1">
<div className="relative"> <div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-[#8a8a7a] w-5 h-5" /> <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 w-5 h-5" />
<input <input
type="text" type="text"
placeholder="Rechercher par code ticket..." placeholder="Rechercher par code ticket..."
value={searchQuery} value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)} onChange={(e) => setSearchQuery(e.target.value)}
className="w-full pl-10 pr-4 py-3 border-2 border-[#e5e4dc] rounded-lg focus:ring-2 focus:ring-[#d4a574] focus:border-[#d4a574] focus:outline-none" className="w-full pl-10 pr-4 py-3 border-2 border-beige-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 focus:outline-none"
/> />
</div> </div>
</div> </div>
@ -179,8 +179,8 @@ export default function HistoriquePage() {
onClick={() => setFilter('ALL')} onClick={() => setFilter('ALL')}
className={`px-4 py-2 rounded-lg font-semibold transition-all ${ className={`px-4 py-2 rounded-lg font-semibold transition-all ${
filter === 'ALL' filter === 'ALL'
? 'bg-gradient-to-r from-[#d4a574] to-[#c4956a] text-white shadow-lg' ? 'bg-gradient-to-r from-primary-500 to-primary-600 text-white shadow-lg'
: 'bg-[#f5f5f0] text-[#5a5a4e] hover:bg-[#e5e4dc]' : 'bg-beige-100 text-gray-700 hover:bg-beige-200'
}`} }`}
> >
Tous ({tickets.length}) Tous ({tickets.length})
@ -189,8 +189,8 @@ export default function HistoriquePage() {
onClick={() => setFilter('CLAIMED')} onClick={() => setFilter('CLAIMED')}
className={`px-4 py-2 rounded-lg font-semibold transition-all ${ className={`px-4 py-2 rounded-lg font-semibold transition-all ${
filter === 'CLAIMED' filter === 'CLAIMED'
? 'bg-green-600 text-white shadow-lg' ? 'bg-primary-600 text-white shadow-lg'
: 'bg-[#f5f5f0] text-[#5a5a4e] hover:bg-[#e5e4dc]' : 'bg-beige-100 text-gray-700 hover:bg-beige-200'
}`} }`}
> >
Réclamés ({stats.claimed}) Réclamés ({stats.claimed})
@ -199,8 +199,8 @@ export default function HistoriquePage() {
onClick={() => setFilter('PENDING')} onClick={() => setFilter('PENDING')}
className={`px-4 py-2 rounded-lg font-semibold transition-all ${ className={`px-4 py-2 rounded-lg font-semibold transition-all ${
filter === 'PENDING' filter === 'PENDING'
? 'bg-yellow-600 text-white shadow-lg' ? 'bg-secondary-600 text-white shadow-lg'
: 'bg-[#f5f5f0] text-[#5a5a4e] hover:bg-[#e5e4dc]' : 'bg-beige-100 text-gray-700 hover:bg-beige-200'
}`} }`}
> >
En attente ({stats.pending}) En attente ({stats.pending})
@ -210,7 +210,7 @@ export default function HistoriquePage() {
className={`px-4 py-2 rounded-lg font-semibold transition-all ${ className={`px-4 py-2 rounded-lg font-semibold transition-all ${
filter === 'REJECTED' filter === 'REJECTED'
? 'bg-red-600 text-white shadow-lg' ? 'bg-red-600 text-white shadow-lg'
: 'bg-[#f5f5f0] text-[#5a5a4e] hover:bg-[#e5e4dc]' : 'bg-beige-100 text-gray-700 hover:bg-beige-200'
}`} }`}
> >
Rejetés ({stats.rejected}) Rejetés ({stats.rejected})
@ -219,15 +219,15 @@ export default function HistoriquePage() {
</div> </div>
</div> </div>
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<div className="px-6 py-4 border-b border-[#e5e4dc]"> <div className="px-6 py-4 border-b border-beige-300">
<h2 className="text-xl font-bold text-[#5a5a4e]">Tous mes tickets ({filteredTickets.length})</h2> <h2 className="text-xl font-bold text-gray-800">Tous mes tickets ({filteredTickets.length})</h2>
</div> </div>
<div className="p-6"> <div className="p-6">
{filteredTickets.length === 0 ? ( {filteredTickets.length === 0 ? (
<div className="text-center py-12"> <div className="text-center py-12">
<div className="text-6xl mb-4">🎲</div> <div className="text-6xl mb-4">🎲</div>
<p className="text-[#8a8a7a] mb-4"> <p className="text-gray-600 mb-4">
{searchQuery || filter !== 'ALL' {searchQuery || filter !== 'ALL'
? 'Aucun ticket trouvé avec ces filtres' ? 'Aucun ticket trouvé avec ces filtres'
: 'Vous n\'avez pas encore participé au jeu'} : 'Vous n\'avez pas encore participé au jeu'}
@ -235,7 +235,7 @@ export default function HistoriquePage() {
{!searchQuery && filter === 'ALL' && ( {!searchQuery && filter === 'ALL' && (
<button <button
onClick={() => router.push(ROUTES.GAME)} onClick={() => router.push(ROUTES.GAME)}
className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300" className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300"
> >
Jouer maintenant Jouer maintenant
</button> </button>
@ -245,25 +245,25 @@ export default function HistoriquePage() {
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table className="min-w-full"> <table className="min-w-full">
<thead> <thead>
<tr className="border-b border-[#e5e4dc]"> <tr className="border-b border-beige-300">
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider">
Code Ticket Code Ticket
</th> </th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider">
Gain Gain
</th> </th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider">
Statut Statut
</th> </th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider">
Date de participation Date de participation
</th> </th>
<th className="px-6 py-3 text-left text-xs font-semibold text-[#5a5a4e] uppercase tracking-wider"> <th className="px-6 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider">
Date de réclamation Date de réclamation
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody className="divide-y divide-[#e5e4dc]"> <tbody className="divide-y divide-beige-200">
{filteredTickets.map((ticket) => ( {filteredTickets.map((ticket) => (
<TicketTableRow key={ticket.id} ticket={ticket} showClaimedDate /> <TicketTableRow key={ticket.id} ticket={ticket} showClaimedDate />
))} ))}

View File

@ -17,9 +17,9 @@ import Link from "next/link";
const PRIZES = [ const PRIZES = [
{ type: 'INFUSEUR', name: 'Infuseur à thé', color: 'bg-blue-100 text-blue-800' }, { type: 'INFUSEUR', name: 'Infuseur à thé', color: 'bg-blue-100 text-blue-800' },
{ type: 'THE_SIGNATURE', name: 'Thé signature 100g', color: 'bg-green-100 text-green-800' }, { type: 'THE_SIGNATURE', name: 'Thé signature 100g', color: 'bg-primary-100 text-primary-800' },
{ type: 'COFFRET_DECOUVERTE', name: 'Coffret découverte 39€', color: 'bg-purple-100 text-purple-800' }, { type: 'COFFRET_DECOUVERTE', name: 'Coffret découverte 39€', color: 'bg-purple-100 text-purple-800' },
{ type: 'COFFRET_PRESTIGE', name: 'Coffret prestige 69€', color: 'bg-amber-100 text-amber-800' }, { type: 'COFFRET_PRESTIGE', name: 'Coffret prestige 69€', color: 'bg-secondary-200 text-secondary-800' },
{ type: 'THE_GRATUIT', name: 'Thé gratuit en magasin', color: 'bg-pink-100 text-pink-800' }, { type: 'THE_GRATUIT', name: 'Thé gratuit en magasin', color: 'bg-pink-100 text-pink-800' },
]; ];
@ -110,28 +110,28 @@ export default function JeuxPage() {
: null; : null;
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0] py-8"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100 py-8">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
{/* Formulaire Section */} {/* Formulaire Section */}
<section className="mb-16"> <section className="mb-16">
<div className="max-w-2xl mx-auto"> <div className="max-w-2xl mx-auto">
<div className="bg-white rounded-xl shadow-2xl overflow-hidden border-2 border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-2xl overflow-hidden border-2 border-beige-300">
<div className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] px-6 py-6 shadow-lg"> <div className="bg-gradient-to-r from-primary-500 to-primary-600 px-6 py-6 shadow-lg">
<h1 className="text-center text-3xl md:text-4xl font-bold text-white"> <h1 className="text-center text-3xl md:text-4xl font-bold text-white">
🎁 Jouez maintenant ! Jouez maintenant !
</h1> </h1>
</div> </div>
<div className="p-8"> <div className="p-8">
<div className="mb-6 text-center"> <div className="mb-6 text-center">
<p className="text-[#5a5a4e] text-lg"> <p className="text-beige-800 text-lg">
Bonjour <span className="font-bold text-[#d4a574]">{user?.firstName}</span>, Bonjour <span className="font-bold text-primary-500">{user?.firstName}</span>,
entrez le code de 10 caractères présent sur votre ticket de caisse entrez le code de 10 caractères présent sur votre ticket de caisse
</p> </p>
</div> </div>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6"> <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
<div> <div>
<label htmlFor="ticketCode" className="block text-sm font-semibold text-[#5a5a4e] mb-2"> <label htmlFor="ticketCode" className="block text-sm font-semibold text-beige-800 mb-2">
Code du ticket Code du ticket
</label> </label>
<input <input
@ -139,7 +139,7 @@ export default function JeuxPage() {
type="text" type="text"
placeholder="TTP2025ABC" placeholder="TTP2025ABC"
{...register("ticketCode")} {...register("ticketCode")}
className="w-full px-6 py-4 text-center text-2xl font-mono font-bold uppercase border-2 border-[#e5e4dc] rounded-lg focus:outline-none focus:ring-2 focus:ring-[#d4a574] focus:border-[#d4a574] tracking-widest bg-white shadow-inner" className="w-full px-6 py-4 text-center text-2xl font-mono font-bold uppercase border-2 border-beige-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500 tracking-widest bg-white shadow-inner"
maxLength={10} maxLength={10}
/> />
{errors.ticketCode && ( {errors.ticketCode && (
@ -158,7 +158,7 @@ export default function JeuxPage() {
</Link> </Link>
</div> </div>
)} )}
<p className="mt-2 text-sm text-[#8a8a7a] text-center"> <p className="mt-2 text-sm text-beige-600 text-center">
Format: TTP2025ABC (10 caractères) Format: TTP2025ABC (10 caractères)
</p> </p>
</div> </div>
@ -167,20 +167,20 @@ export default function JeuxPage() {
<button <button
type="submit" type="submit"
disabled={isPlaying} disabled={isPlaying}
className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] disabled:from-gray-400 disabled:to-gray-500 text-white font-bold px-12 py-4 text-lg rounded-lg transition-all duration-300 shadow-lg hover:shadow-[0_0_20px_rgba(212,165,116,0.6)] hover:scale-105" className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 disabled:from-gray-400 disabled:to-gray-500 text-white font-bold px-12 py-4 text-lg rounded-lg transition-all duration-300 shadow-lg hover:shadow-[0_0_20px_rgba(11,96,41,0.4)] hover:scale-105"
> >
{isPlaying ? "Vérification en cours..." : "🎲 Tenter ma chance !"} {isPlaying ? "Vérification en cours..." : "Tenter ma chance !"}
</button> </button>
</div> </div>
</form> </form>
<div className="mt-6 p-4 bg-gradient-to-r from-[#d4a574]/10 to-[#c4956a]/10 border-l-4 border-[#d4a574] rounded-lg shadow-md"> <div className="mt-6 p-4 bg-gradient-to-r from-primary-50 to-primary-100 border-l-4 border-primary-500 rounded-lg shadow-md">
<p className="text-sm text-[#5a5a4e] font-semibold mb-2"> <p className="text-sm text-beige-800 font-semibold mb-2">
💡 Bon à savoir : Bon à savoir :
</p> </p>
<ul className="text-sm text-[#5a5a4e] space-y-1 list-disc list-inside"> <ul className="text-sm text-beige-800 space-y-1 list-disc list-inside">
<li>Chaque code ne peut être utilisé qu'une seule fois</li> <li>Chaque code ne peut être utilisé qu'une seule fois</li>
<li>Consultez vos tickets sur la page <Link href={ROUTES.HISTORY} className="underline font-medium hover:text-[#d4a574] transition-colors">Mes gains</Link></li> <li>Consultez vos tickets sur la page <Link href={ROUTES.HISTORY} className="underline font-medium hover:text-primary-500 transition-colors">Mes gains</Link></li>
</ul> </ul>
</div> </div>
</div> </div>
@ -260,8 +260,8 @@ export default function JeuxPage() {
</div> </div>
{/* Loading Animation */} {/* Loading Animation */}
<div className="flex items-center gap-2 text-[#5a5a4e]"> <div className="flex items-center gap-2 text-beige-800">
<div className="animate-spin rounded-full h-6 w-6 border-b-2 border-[#d4a574]"></div> <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-primary-500"></div>
<span className="font-medium">Tirage en cours...</span> <span className="font-medium">Tirage en cours...</span>
</div> </div>
</div> </div>
@ -323,13 +323,13 @@ export default function JeuxPage() {
<div className="flex gap-3 justify-center"> <div className="flex gap-3 justify-center">
<button <button
onClick={closeModal} onClick={closeModal}
className="border-2 border-[#e5e4dc] hover:bg-[#f5f5f0] text-[#5a5a4e] font-bold px-6 py-3 rounded-lg transition-all" className="border-2 border-beige-300 hover:bg-beige-100 text-beige-800 font-bold px-6 py-3 rounded-lg transition-all"
> >
Fermer Fermer
</button> </button>
<button <button
onClick={() => router.push(ROUTES.HISTORY)} onClick={() => router.push(ROUTES.HISTORY)}
className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold px-6 py-3 rounded-lg transition-all duration-300 shadow-lg hover:shadow-[0_0_20px_rgba(212,165,116,0.6)]" className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-3 rounded-lg transition-all duration-300 shadow-lg hover:shadow-[0_0_20px_rgba(11,96,41,0.4)]"
> >
Voir mes gains Voir mes gains
</button> </button>

View File

@ -5,7 +5,10 @@ import { Toaster } from "react-hot-toast";
import LayoutClient from "./layout-client"; import LayoutClient from "./layout-client";
import { Providers } from "./providers"; import { Providers } from "./providers";
// Google Analytics 4
const GA_TRACKING_ID = "G-E272LVVQRD"; const GA_TRACKING_ID = "G-E272LVVQRD";
// Google Tag Manager
const GTM_ID = "GTM-WN8H6RTC";
export const metadata: Metadata = { export const metadata: Metadata = {
metadataBase: new URL(process.env.NEXT_PUBLIC_FRONTEND_URL || 'https://dsp5-archi-o24a-15m-g3.fr'), metadataBase: new URL(process.env.NEXT_PUBLIC_FRONTEND_URL || 'https://dsp5-archi-o24a-15m-g3.fr'),
@ -42,20 +45,45 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return ( return (
<html lang="fr"> <html lang="fr">
<head> <head>
{/* Google Tag Manager - must load first */}
<Script id="google-tag-manager" strategy="beforeInteractive">
{`
(function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start': new Date().getTime(), event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),
dl = l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-WN8H6RTC');
`}
</Script>
{/* Google Analytics 4 */}
<Script <Script
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`} src="https://www.googletagmanager.com/gtag/js?id=G-E272LVVQRD"
strategy="afterInteractive" strategy="beforeInteractive"
/> />
<Script id="google-analytics" strategy="afterInteractive"> <Script id="google-analytics" strategy="beforeInteractive">
{` {`
window.dataLayer = window.dataLayer || []; window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);} function gtag(){dataLayer.push(arguments);}
gtag('js', new Date()); gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}'); gtag('config', 'G-E272LVVQRD');
`} `}
</Script> </Script>
</head> </head>
<body className="min-h-screen flex flex-col bg-gray-50"> <body className="min-h-screen flex flex-col bg-gray-50">
{/* Google Tag Manager (noscript) */}
<noscript>
<iframe
src="https://www.googletagmanager.com/ns.html?id=GTM-WN8H6RTC"
height="0"
width="0"
style={{ display: 'none', visibility: 'hidden' }}
/>
</noscript>
<Providers> <Providers>
<LayoutClient>{children}</LayoutClient> <LayoutClient>{children}</LayoutClient>
</Providers> </Providers>

View File

@ -8,17 +8,17 @@ export const metadata: Metadata = {
export default function LegalPage() { export default function LegalPage() {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0] py-12 px-4"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100 py-12 px-4">
<div className="max-w-4xl mx-auto bg-white rounded-xl shadow-lg border border-[#e5e4dc] p-8"> <div className="max-w-4xl mx-auto bg-white rounded-xl shadow-lg border border-beige-300 p-8">
<h1 className="text-3xl font-bold text-[#5a5a4e] mb-6"> <h1 className="text-4xl md:text-5xl font-bold text-primary-500 mb-6">
Mentions légales Informations légales
</h1> </h1>
<p className="text-sm text-[#8a8a7a] mb-8"> <p className="text-sm text-gray-600 mb-8">
Dernière mise à jour : 21 Novembre 2025 Dernière mise à jour : 21 Novembre 2025
</p> </p>
<div className="space-y-6 text-[#5a5a4e]"> <div className="space-y-6 text-gray-700">
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
1. Éditeur du site 1. Éditeur du site
</h2> </h2>
<ul className="list-none space-y-2 mt-3"> <ul className="list-none space-y-2 mt-3">
@ -34,7 +34,7 @@ export default function LegalPage() {
</ul> </ul>
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
2. Responsable de publication 2. Responsable de publication
</h2> </h2>
<p> <p>
@ -42,7 +42,7 @@ export default function LegalPage() {
</p> </p>
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
3. Conception et accompagnement digital 3. Conception et accompagnement digital
</h2> </h2>
<ul className="list-none space-y-2 mt-3"> <ul className="list-none space-y-2 mt-3">
@ -55,7 +55,7 @@ export default function LegalPage() {
</ul> </ul>
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
4. Hébergement 4. Hébergement
</h2> </h2>
<p>Le site est hébergé par : OVH Cloud www.ovhcloud.com </p> <p>Le site est hébergé par : OVH Cloud www.ovhcloud.com </p>
@ -63,7 +63,7 @@ export default function LegalPage() {
<p>Téléphone : +33 (0)9 72 10 10 07</p> <p>Téléphone : +33 (0)9 72 10 10 07</p>
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
5. Propriété intellectuelle 5. Propriété intellectuelle
</h2> </h2>
<p> <p>
@ -75,16 +75,16 @@ export default function LegalPage() {
</p> </p>
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
6. Protection des données personnelles 6. Protection des données personnelles
</h2> </h2>
<p> <p>
Les données collectées via le site sont traitées par Thé Tip Top SA conformément au Règlement Général sur la Protection des Données (RGPD). Les données collectées via le site sont traitées par Thé Tip Top SA conformément au Règlement Général sur la Protection des Données (RGPD).
Chaque utilisateur dispose d'un droit d'accès, de rectification et de suppression de ses données en adressant une demande à : <a href="mailto:contact@thetiptop.fr" className="text-[#d4a574] hover:text-[#c4956a] transition-colors">contact@thetiptop.fr</a> Chaque utilisateur dispose d'un droit d'accès, de rectification et de suppression de ses données en adressant une demande à : <a href="mailto:contact@thetiptop.fr" className="text-primary-500 hover:text-primary-600 transition-colors">contact@thetiptop.fr</a>
</p> </p>
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
7. Cookies 7. Cookies
</h2> </h2>
<p> <p>

View File

@ -96,13 +96,13 @@ export default function LoginPage() {
{/* Tabs */} {/* Tabs */}
<div className="flex border-b border-gray-200"> <div className="flex border-b border-gray-200">
<button className="flex-1 py-4 px-6 text-center font-bold text-gray-900 bg-white border-b-3 border-[#d4a574] shadow-[0_3px_8px_rgba(212,165,116,0.3)] relative"> <button className="flex-1 py-4 px-6 text-center font-bold text-gray-900 bg-white border-b-3 border-primary-500 shadow-[0_3px_8px_rgba(11,96,41,0.2)] relative">
<span className="relative z-10">Connexion</span> <span className="relative z-10">Connexion</span>
<div className="absolute bottom-0 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-[#d4a574] to-transparent"></div> <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-primary-500 to-transparent"></div>
</button> </button>
<Link <Link
href={ROUTES.REGISTER} href={ROUTES.REGISTER}
className="flex-1 py-4 px-6 text-center font-semibold text-gray-500 bg-gray-50 hover:bg-gradient-to-r hover:from-[#d4a574]/5 hover:to-[#c4956a]/5 hover:text-[#c4956a] transition-all duration-300 hover:shadow-inner" className="flex-1 py-4 px-6 text-center font-semibold text-gray-500 bg-gray-50 hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 hover:text-primary-600 transition-all duration-300 hover:shadow-inner"
> >
Inscription Inscription
</Link> </Link>
@ -124,7 +124,7 @@ export default function LoginPage() {
type="email" type="email"
placeholder="email" placeholder="email"
{...register("email")} {...register("email")}
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-[#d4a574] focus:border-transparent`} 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-primary-500 focus:border-transparent`}
/> />
{errors.email && ( {errors.email && (
<p className="mt-1 text-sm text-red-500">{errors.email.message}</p> <p className="mt-1 text-sm text-red-500">{errors.email.message}</p>
@ -142,7 +142,7 @@ export default function LoginPage() {
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
placeholder="mot de passe" placeholder="mot de passe"
{...register("password")} {...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-[#d4a574] focus:border-transparent pr-12`} 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-primary-500 focus:border-transparent pr-12`}
/> />
<button <button
type="button" type="button"
@ -170,7 +170,7 @@ export default function LoginPage() {
<button <button
type="submit" type="submit"
disabled={isSubmitting} disabled={isSubmitting}
className="w-full bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] disabled:bg-gray-400 disabled:from-gray-400 disabled:to-gray-400 text-white font-bold px-8 py-4 rounded-lg transition-all duration-300 hover:shadow-[0_0_25px_rgba(212,165,116,0.7)] hover:scale-[1.02] shadow-lg transform" className="w-full bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 disabled:bg-gray-400 disabled:from-gray-400 disabled:to-gray-400 text-white font-bold px-8 py-4 rounded-lg transition-all duration-300 hover:shadow-[0_0_25px_rgba(11,96,41,0.5)] hover:scale-[1.02] shadow-lg transform"
> >
{isSubmitting ? "Connexion..." : "Se connecter"} {isSubmitting ? "Connexion..." : "Se connecter"}
</button> </button>
@ -179,7 +179,7 @@ export default function LoginPage() {
<div className="text-center"> <div className="text-center">
<Link <Link
href="/forgot-password" href="/forgot-password"
className="text-sm text-[#5a5a4e] hover:text-[#d4a574] hover:underline transition-colors" className="text-sm text-beige-800 hover:text-primary-500 hover:underline transition-colors"
> >
Mot de passe oublié ? Mot de passe oublié ?
</Link> </Link>

View File

@ -19,15 +19,15 @@ const PRIZES = [
export default function LotsPage() { export default function LotsPage() {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0]"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100">
{/* Hero Section */} {/* Hero Section */}
<section className="bg-gradient-to-r from-white to-[#faf9f5] py-12 border-b-2 border-[#e5e4dc]"> <section className="bg-gradient-to-r from-white to-beige-50 py-12 border-b-2 border-beige-300">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto text-center"> <div className="max-w-4xl mx-auto text-center">
<h1 className="text-4xl md:text-5xl font-bold text-[#5a5a4e] mb-4"> <h1 className="text-4xl md:text-5xl font-bold text-primary-300 mb-4">
Lots à gagner Lots à gagner
</h1> </h1>
<p className="text-lg text-[#8a8a7a]"> <p className="text-lg text-gray-600">
Découvrez tous les magnifiques prix de notre jeu-concours. Avec 100% de gagnants garantis, Découvrez tous les magnifiques prix de notre jeu-concours. Avec 100% de gagnants garantis,
chaque participant repart avec un lot ! chaque participant repart avec un lot !
</p> </p>
@ -39,7 +39,7 @@ export default function LotsPage() {
<section className="py-8"> <section className="py-8">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto"> <div className="max-w-5xl mx-auto">
<div className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] rounded-2xl p-8 shadow-2xl border-2 border-[#e5e4dc]"> <div className="bg-gradient-to-r from-primary-500 to-primary-600 rounded-2xl p-8 shadow-2xl border-2 border-primary-400">
<div className="flex flex-col md:flex-row items-center gap-6"> <div className="flex flex-col md:flex-row items-center gap-6">
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<div className="w-32 h-32 bg-white rounded-lg flex items-center justify-center p-3 shadow-md"> <div className="w-32 h-32 bg-white rounded-lg flex items-center justify-center p-3 shadow-md">
@ -53,7 +53,7 @@ export default function LotsPage() {
</div> </div>
</div> </div>
<div className="flex-1 text-center md:text-left"> <div className="flex-1 text-center md:text-left">
<div className="inline-block bg-white text-[#d4a574] text-xs font-bold px-3 py-1 rounded-full mb-2 shadow-md"> <div className="inline-block bg-white text-primary-500 text-xs font-bold px-3 py-1 rounded-full mb-2 shadow-md">
GRAND PRIX FINAL GRAND PRIX FINAL
</div> </div>
<h2 className="text-3xl md:text-4xl font-bold text-white mb-2"> <h2 className="text-3xl md:text-4xl font-bold text-white mb-2">
@ -88,7 +88,7 @@ export default function LotsPage() {
{/* CTA Section */} {/* CTA Section */}
<section className="py-16"> <section className="py-16">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto bg-gradient-to-r from-[#d4a574] to-[#c4956a] rounded-2xl shadow-2xl p-12 text-center text-white border-2 border-[#e5e4dc]"> <div className="max-w-4xl mx-auto bg-gradient-to-r from-primary-500 to-primary-600 rounded-2xl shadow-2xl p-12 text-center text-white border-2 border-primary-400">
<h2 className="text-3xl md:text-4xl font-bold mb-4"> <h2 className="text-3xl md:text-4xl font-bold mb-4">
Prêt à découvrir votre lot ? Prêt à découvrir votre lot ?
</h2> </h2>
@ -97,7 +97,7 @@ export default function LotsPage() {
tentez votre chance ! Avec 100% de gagnants, vous ne pouvez que gagner. tentez votre chance ! Avec 100% de gagnants, vous ne pouvez que gagner.
</p> </p>
<Link href="/register"> <Link href="/register">
<button className="bg-white text-[#d4a574] hover:bg-[#f5f5f0] font-bold text-lg px-12 py-4 rounded-lg shadow-xl transition-all duration-300 hover:scale-105"> <button className="bg-white text-primary-500 hover:bg-beige-50 font-bold text-lg px-12 py-4 rounded-lg shadow-xl transition-all duration-300 hover:scale-105">
Participer maintenant Participer maintenant
</button> </button>
</Link> </Link>

View File

@ -28,7 +28,7 @@ export default function NotFound() {
</div> </div>
{/* Text content */} {/* Text content */}
<h1 className="text-4xl md:text-5xl font-bold text-[#5a5a4e] mb-4"> <h1 className="text-4xl md:text-5xl font-bold text-primary-300 mb-4">
Oups ! Page introuvable Oups ! Page introuvable
</h1> </h1>
<p className="text-lg text-[#8a8a7a] mb-8 max-w-md mx-auto"> <p className="text-lg text-[#8a8a7a] mb-8 max-w-md mx-auto">

View File

@ -51,31 +51,33 @@ export default function HomePage() {
<TeaIconsBackground animationKey={animationKey} /> <TeaIconsBackground animationKey={animationKey} />
{/* Hero Section - Bannière principale */} {/* Hero Section - Bannière principale */}
<section className="relative min-h-screen flex items-center justify-center overflow-hidden"> <section className="relative min-h-screen flex items-center justify-center overflow-hidden pt-20 md:pt-0">
<div className="w-full relative z-10"> <div className="w-full relative z-10">
<div className="w-full text-center px-4"> <div className="w-full text-center px-4">
<h1 className="text-5xl md:text-6xl lg:text-7xl font-bold text-[#d4a574] mb-8 leading-tight drop-shadow-sm tracking-wide"> <h1 className="text-3xl sm:text-4xl md:text-6xl lg:text-7xl font-bold text-primary-500 mb-4 md:mb-6 leading-tight drop-shadow-sm tracking-wide">
Jeu Concours - Thé Tip Top Jeu Concours - Thé Tip Top
</h1> </h1>
<p className="text-5xl md:text-6xl lg:text-7xl font-semibold text-[#6a6a5e] mb-10 leading-relaxed tracking-wide"> <p className="text-xl sm:text-2xl md:text-5xl lg:text-6xl font-semibold text-primary-300 mb-4 md:mb-6 leading-snug md:leading-relaxed tracking-wide">
Célébrons l'ouverture de notre 10<sup>ème</sup> boutique à <span className="text-[#d4a574]">Nice</span> Célébrons l'ouverture de notre 10<sup>ème</sup> boutique à <span className="text-primary-500 font-bold">Nice</span>
</p> </p>
<p className="text-xl md:text-2xl lg:text-3xl text-[#7a7a6e] mb-16 leading-relaxed tracking-wide"> <p className="text-base sm:text-lg md:text-2xl lg:text-3xl text-gray-500 mb-8 md:mb-10 leading-relaxed tracking-wide px-2">
Participez à notre concours - 100% des participants gagnent un lot ! Participez à notre concours - 100% des participants gagnent un lot !
</p> </p>
<div className="flex flex-col sm:flex-row gap-4 justify-center px-4"> {/* Bouton principal */}
<div className="flex flex-col gap-4 justify-center items-center px-4">
<Link href={isAuthenticated ? ROUTES.GAME : "/register"}> <Link href={isAuthenticated ? ROUTES.GAME : "/register"}>
<div className="relative inline-block"> <div className="relative inline-block">
{/* Anneau qui pulse autour du bouton */} {/* Anneau qui pulse autour du bouton */}
<span className="absolute inset-0 rounded-full border-4 border-[#d4a574] animate-ping opacity-60"></span> <span className="absolute inset-0 rounded-full border-4 border-primary-500 animate-ping opacity-60"></span>
<button className="relative bg-[#d4a574] hover:bg-[#c4956a] text-white font-bold text-xl md:text-2xl px-16 py-6 md:px-20 md:py-7 rounded-full shadow-[0_0_25px_rgba(212,165,116,0.8)] hover:shadow-[0_0_40px_rgba(212,165,116,1)] transition-all duration-300 hover:scale-105"> <button className="relative bg-primary-500 hover:bg-primary-600 text-white font-bold text-lg sm:text-xl md:text-2xl px-10 py-4 sm:px-16 sm:py-6 md:px-20 md:py-7 rounded-full shadow-[0_0_25px_rgba(11,96,41,0.6)] hover:shadow-[0_0_40px_rgba(11,96,41,0.8)] transition-all duration-300 hover:scale-105">
Jouer maintenant Jouer maintenant
</button> </button>
</div> </div>
</Link> </Link>
</div> </div>
</div> </div>
</div> </div>
@ -104,7 +106,7 @@ export default function HomePage() {
<section className="py-20 bg-white/60 backdrop-blur-sm"> <section className="py-20 bg-white/60 backdrop-blur-sm">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto"> <div className="max-w-5xl mx-auto">
<h2 className="text-4xl md:text-5xl font-bold text-center text-gray-900 mb-4"> <h2 className="text-4xl md:text-5xl font-bold text-center text-primary-300 mb-4">
Comment participer? Comment participer?
</h2> </h2>
<p className="text-center text-gray-600 mb-16 text-lg max-w-2xl mx-auto"> <p className="text-center text-gray-600 mb-16 text-lg max-w-2xl mx-auto">
@ -114,11 +116,11 @@ export default function HomePage() {
<div className="grid md:grid-cols-3 gap-12"> <div className="grid md:grid-cols-3 gap-12">
{/* Step 1 */} {/* Step 1 */}
<div className="text-center relative"> <div className="text-center relative">
<div className="absolute top-0 right-0 w-8 h-8 bg-[#1a4d2e] text-white rounded-full flex items-center justify-center font-bold text-sm"> <div className="absolute top-0 right-0 w-8 h-8 bg-primary-500 text-white rounded-full flex items-center justify-center font-bold text-sm">
1 1
</div> </div>
<div className="bg-gradient-to-br from-[#fef3c7] to-[#fde68a] w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg"> <div className="bg-gradient-to-br from-primary-100 to-primary-200 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg">
<svg className="w-10 h-10 text-[#1a4d2e]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-10 h-10 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg> </svg>
</div> </div>
@ -130,27 +132,27 @@ export default function HomePage() {
{/* Step 2 */} {/* Step 2 */}
<div className="text-center relative"> <div className="text-center relative">
<div className="absolute top-0 right-0 w-8 h-8 bg-[#1a4d2e] text-white rounded-full flex items-center justify-center font-bold text-sm"> <div className="absolute top-0 right-0 w-8 h-8 bg-primary-500 text-white rounded-full flex items-center justify-center font-bold text-sm">
2 2
</div> </div>
<div className="bg-gradient-to-br from-[#fef3c7] to-[#fde68a] w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg"> <div className="bg-gradient-to-br from-primary-100 to-primary-200 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg">
<svg className="w-10 h-10 text-[#1a4d2e]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-10 h-10 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z" />
</svg> </svg>
</div> </div>
<h3 className="text-2xl font-bold mb-3 text-gray-900">Entrez votre code</h3> <h3 className="text-2xl font-bold mb-3 text-gray-900">Entrez votre code</h3>
<p className="text-gray-600 leading-relaxed"> <p className="text-gray-600 leading-relaxed">
Saisissez le code à 10 caractères de votre ticket d'achat à 49 Saisissez le code à 10 caractères de votre ticket
</p> </p>
</div> </div>
{/* Step 3 */} {/* Step 3 */}
<div className="text-center relative"> <div className="text-center relative">
<div className="absolute top-0 right-0 w-8 h-8 bg-[#1a4d2e] text-white rounded-full flex items-center justify-center font-bold text-sm"> <div className="absolute top-0 right-0 w-8 h-8 bg-primary-500 text-white rounded-full flex items-center justify-center font-bold text-sm">
3 3
</div> </div>
<div className="bg-gradient-to-br from-[#fef3c7] to-[#fde68a] w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg"> <div className="bg-gradient-to-br from-primary-100 to-primary-200 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6 shadow-lg">
<svg className="w-10 h-10 text-[#1a4d2e]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-10 h-10 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" />
</svg> </svg>
</div> </div>
@ -168,7 +170,7 @@ export default function HomePage() {
<section className="py-20 bg-transparent"> <section className="py-20 bg-transparent">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-6xl mx-auto"> <div className="max-w-6xl mx-auto">
<h2 className="text-4xl md:text-5xl font-bold text-center text-gray-900 mb-4"> <h2 className="text-4xl md:text-5xl font-bold text-center text-primary-300 mb-4">
Lots à gagner Lots à gagner
</h2> </h2>
<p className="text-center text-gray-600 mb-16 text-lg max-w-3xl mx-auto"> <p className="text-center text-gray-600 mb-16 text-lg max-w-3xl mx-auto">
@ -186,7 +188,7 @@ export default function HomePage() {
<Button <Button
variant="outline" variant="outline"
size="lg" size="lg"
className="border-2 border-[#1a4d2e] text-[#1a4d2e] hover:bg-[#1a4d2e] hover:text-white font-semibold px-8" className="border-2 border-primary-500 text-primary-500 hover:bg-primary-500 hover:text-white font-semibold px-8"
> >
Voir tous les lots Voir tous les lots
<svg className="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">

View File

@ -7,19 +7,19 @@ export const metadata: Metadata = {
export default function PrivacyPage() { export default function PrivacyPage() {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0] py-12 px-4"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100 py-12 px-4">
<div className="max-w-4xl mx-auto bg-white rounded-xl shadow-lg border border-[#e5e4dc] p-8"> <div className="max-w-4xl mx-auto bg-white rounded-xl shadow-lg border border-beige-300 p-8">
<h1 className="text-3xl font-bold text-[#5a5a4e] mb-6"> <h1 className="text-3xl font-bold text-gray-800 mb-6">
Politique de confidentialité Politique de confidentialité
</h1> </h1>
<p className="text-sm text-[#8a8a7a] mb-8"> <p className="text-sm text-gray-600 mb-8">
Dernière mise à jour : 17 janvier 2025 Dernière mise à jour : 17 janvier 2025
</p> </p>
<div className="space-y-6 text-[#5a5a4e]"> <div className="space-y-6 text-gray-700">
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
1. Introduction 1. Introduction
</h2> </h2>
<p> <p>
@ -30,7 +30,7 @@ export default function PrivacyPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
2. Données collectées 2. Données collectées
</h2> </h2>
<p className="mb-2">Nous collectons les informations suivantes :</p> <p className="mb-2">Nous collectons les informations suivantes :</p>
@ -44,7 +44,7 @@ export default function PrivacyPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
3. Utilisation des données 3. Utilisation des données
</h2> </h2>
<p className="mb-2">Vos données sont utilisées pour :</p> <p className="mb-2">Vos données sont utilisées pour :</p>
@ -58,7 +58,7 @@ export default function PrivacyPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
4. Vos droits (RGPD) 4. Vos droits (RGPD)
</h2> </h2>
<p className="mb-2">Conformément au RGPD, vous disposez des droits suivants :</p> <p className="mb-2">Conformément au RGPD, vous disposez des droits suivants :</p>
@ -69,12 +69,12 @@ export default function PrivacyPage() {
<li><strong>Droit d'opposition :</strong> vous opposer au traitement de vos données</li> <li><strong>Droit d'opposition :</strong> vous opposer au traitement de vos données</li>
</ul> </ul>
<p className="mt-3"> <p className="mt-3">
Pour exercer ces droits, contactez-nous à : <a href="mailto:privacy@thetiptop.fr" className="text-[#d4a574] hover:text-[#c4956a] transition-colors">privacy@thetiptop.fr</a> Pour exercer ces droits, contactez-nous à : <a href="mailto:privacy@thetiptop.fr" className="text-primary-500 hover:text-primary-600 transition-colors">privacy@thetiptop.fr</a>
</p> </p>
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
5. Contact 5. Contact
</h2> </h2>
<p> <p>
@ -82,16 +82,16 @@ export default function PrivacyPage() {
vous pouvez nous contacter : vous pouvez nous contacter :
</p> </p>
<ul className="list-none space-y-2 mt-3"> <ul className="list-none space-y-2 mt-3">
<li><strong>Email :</strong> <a href="mailto:privacy@thetiptop.fr" className="text-[#d4a574] hover:text-[#c4956a] transition-colors">privacy@thetiptop.fr</a></li> <li><strong>Email :</strong> <a href="mailto:privacy@thetiptop.fr" className="text-primary-500 hover:text-primary-600 transition-colors">privacy@thetiptop.fr</a></li>
<li><strong>Adresse :</strong> 18 Avenue Thiers, 06000 Nice, France</li> <li><strong>Adresse :</strong> 18 Avenue Thiers, 06000 Nice, France</li>
</ul> </ul>
</section> </section>
</div> </div>
<div className="mt-8 pt-6 border-t border-[#e5e4dc]"> <div className="mt-8 pt-6 border-t border-beige-300">
<a <a
href="/" href="/"
className="inline-flex items-center gap-2 text-[#d4a574] hover:text-[#c4956a] font-medium transition-colors group" className="inline-flex items-center gap-2 text-primary-500 hover:text-primary-600 font-medium transition-colors group"
> >
<svg className="w-5 h-5 group-hover:-translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 group-hover:-translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />

View File

@ -113,48 +113,48 @@ export default function ProfilePage() {
}; };
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0] py-8"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100 py-8">
<div className="container mx-auto px-4 max-w-4xl"> <div className="container mx-auto px-4 max-w-4xl">
<h1 className="text-4xl font-bold text-[#5a5a4e] mb-8">Mon profil</h1> <h1 className="text-4xl font-bold text-gray-800 mb-8">Mon profil</h1>
<div className="grid md:grid-cols-3 gap-6"> <div className="grid md:grid-cols-3 gap-6">
{/* Profile Info Card */} {/* Profile Info Card */}
<div className="md:col-span-2"> <div className="md:col-span-2">
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<div className="px-6 py-4 border-b border-[#e5e4dc]"> <div className="px-6 py-4 border-b border-beige-300">
<h2 className="text-xl font-bold text-[#5a5a4e]">Informations personnelles</h2> <h2 className="text-xl font-bold text-gray-800">Informations personnelles</h2>
</div> </div>
<div className="p-6"> <div className="p-6">
{!isEditing ? ( {!isEditing ? (
<div className="space-y-4"> <div className="space-y-4">
<div> <div>
<label className="text-sm font-medium text-[#8a8a7a]"> <label className="text-sm font-medium text-gray-600">
Prénom Prénom
</label> </label>
<p className="text-lg text-[#5a5a4e]">{user.firstName}</p> <p className="text-lg text-gray-800">{user.firstName}</p>
</div> </div>
<div> <div>
<label className="text-sm font-medium text-[#8a8a7a]"> <label className="text-sm font-medium text-gray-600">
Nom Nom
</label> </label>
<p className="text-lg text-[#5a5a4e]">{user.lastName}</p> <p className="text-lg text-gray-800">{user.lastName}</p>
</div> </div>
<div> <div>
<label className="text-sm font-medium text-[#8a8a7a]"> <label className="text-sm font-medium text-gray-600">
Email Email
</label> </label>
<p className="text-lg text-[#5a5a4e]">{user.email}</p> <p className="text-lg text-gray-800">{user.email}</p>
</div> </div>
<div> <div>
<label className="text-sm font-medium text-[#8a8a7a]"> <label className="text-sm font-medium text-gray-600">
Téléphone Téléphone
</label> </label>
<p className="text-lg text-[#5a5a4e]"> <p className="text-lg text-gray-800">
{user.phone || "Non renseigné"} {user.phone || "Non renseigné"}
</p> </p>
</div> </div>
<div> <div>
<label className="text-sm font-medium text-[#8a8a7a]"> <label className="text-sm font-medium text-gray-600">
Rôle Rôle
</label> </label>
<div className="mt-1"> <div className="mt-1">
@ -166,7 +166,7 @@ export default function ProfilePage() {
<div className="pt-4 flex flex-wrap gap-3"> <div className="pt-4 flex flex-wrap gap-3">
<button <button
onClick={() => setIsEditing(true)} onClick={() => setIsEditing(true)}
className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300" className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300"
> >
Modifier mes informations Modifier mes informations
</button> </button>
@ -215,7 +215,7 @@ export default function ProfilePage() {
<button <button
type="submit" type="submit"
disabled={isSubmitting} disabled={isSubmitting}
className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] disabled:bg-gray-400 text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300" className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 disabled:bg-gray-400 text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300"
> >
{isSubmitting ? "Enregistrement..." : "Enregistrer"} {isSubmitting ? "Enregistrement..." : "Enregistrer"}
</button> </button>
@ -223,7 +223,7 @@ export default function ProfilePage() {
type="button" type="button"
onClick={handleCancel} onClick={handleCancel}
disabled={isSubmitting} disabled={isSubmitting}
className="border-2 border-[#e5e4dc] hover:bg-[#f5f5f0] text-[#5a5a4e] font-bold px-6 py-3 rounded-lg transition-all" className="border-2 border-beige-300 hover:bg-beige-100 text-gray-700 font-bold px-6 py-3 rounded-lg transition-all"
> >
Annuler Annuler
</button> </button>
@ -236,16 +236,16 @@ export default function ProfilePage() {
{/* Account Status Card */} {/* Account Status Card */}
<div> <div>
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<div className="px-6 py-4 border-b border-[#e5e4dc]"> <div className="px-6 py-4 border-b border-beige-300">
<h2 className="text-xl font-bold text-[#5a5a4e]">Statut du compte</h2> <h2 className="text-xl font-bold text-gray-800">Statut du compte</h2>
</div> </div>
<div className="p-6 space-y-4"> <div className="p-6 space-y-4">
<div> <div>
<label className="text-sm font-medium text-[#8a8a7a]"> <label className="text-sm font-medium text-gray-600">
Membre depuis Membre depuis
</label> </label>
<p className="text-sm text-[#5a5a4e] mt-1"> <p className="text-sm text-gray-800 mt-1">
{formatDate(user.createdAt)} {formatDate(user.createdAt)}
</p> </p>
</div> </div>
@ -253,22 +253,22 @@ export default function ProfilePage() {
</div> </div>
{/* Quick Actions Card */} {/* Quick Actions Card */}
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc] mt-6"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300 mt-6">
<div className="px-6 py-4 border-b border-[#e5e4dc]"> <div className="px-6 py-4 border-b border-beige-300">
<h2 className="text-xl font-bold text-[#5a5a4e]">Actions rapides</h2> <h2 className="text-xl font-bold text-gray-800">Actions rapides</h2>
</div> </div>
<div className="p-6 space-y-2"> <div className="p-6 space-y-2">
{user.role === "CLIENT" && ( {user.role === "CLIENT" && (
<> <>
<button <button
onClick={() => router.push(ROUTES.GAME)} onClick={() => router.push(ROUTES.GAME)}
className="w-full bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300" className="w-full bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-3 rounded-lg transition-all shadow-lg hover:scale-105 duration-300"
> >
Jouer Jouer
</button> </button>
<button <button
onClick={() => router.push(ROUTES.HISTORY)} onClick={() => router.push(ROUTES.HISTORY)}
className="w-full border-2 border-[#d4a574] text-[#d4a574] hover:bg-[#d4a574] hover:text-white font-bold px-6 py-3 rounded-lg transition-all" className="w-full border-2 border-primary-500 text-primary-500 hover:bg-primary-500 hover:text-white font-bold px-6 py-3 rounded-lg transition-all"
> >
Historique Historique
</button> </button>
@ -277,7 +277,7 @@ export default function ProfilePage() {
{user.role === "EMPLOYEE" && ( {user.role === "EMPLOYEE" && (
<button <button
onClick={() => router.push(ROUTES.EMPLOYEE_DASHBOARD)} onClick={() => router.push(ROUTES.EMPLOYEE_DASHBOARD)}
className="w-full border-2 border-[#d4a574] text-[#d4a574] hover:bg-[#d4a574] hover:text-white font-bold px-6 py-3 rounded-lg transition-all" className="w-full border-2 border-primary-500 text-primary-500 hover:bg-primary-500 hover:text-white font-bold px-6 py-3 rounded-lg transition-all"
> >
Tableau de bord Tableau de bord
</button> </button>
@ -285,7 +285,7 @@ export default function ProfilePage() {
{user.role === "ADMIN" && ( {user.role === "ADMIN" && (
<button <button
onClick={() => router.push(ROUTES.ADMIN_DASHBOARD)} onClick={() => router.push(ROUTES.ADMIN_DASHBOARD)}
className="w-full border-2 border-[#d4a574] text-[#d4a574] hover:bg-[#d4a574] hover:text-white font-bold px-6 py-3 rounded-lg transition-all" className="w-full border-2 border-primary-500 text-primary-500 hover:bg-primary-500 hover:text-white font-bold px-6 py-3 rounded-lg transition-all"
> >
Administration Administration
</button> </button>

View File

@ -7,6 +7,7 @@ import { registerSchema, RegisterFormData } from "@/lib/validations";
import Link from "next/link"; import Link from "next/link";
import TeaIconsBackground from "@/components/TeaIconsBackground"; import TeaIconsBackground from "@/components/TeaIconsBackground";
import { ROUTES, API_BASE_URL, API_ENDPOINTS } from "@/utils/constants"; import { ROUTES, API_BASE_URL, API_ENDPOINTS } from "@/utils/constants";
import { isValidEmail } from "@/utils/helpers";
import ReCAPTCHA from "react-google-recaptcha"; import ReCAPTCHA from "react-google-recaptcha";
export default function RegisterPage() { export default function RegisterPage() {
@ -42,9 +43,7 @@ export default function RegisterPage() {
// Vérifier si l'email existe déjà // Vérifier si l'email existe déjà
const checkEmail = async (email: string) => { const checkEmail = async (email: string) => {
// Regex sécurisée contre ReDoS avec limite de longueur if (!email || !isValidEmail(email)) {
const isValidEmail = email && email.length <= 254 && /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(email);
if (!isValidEmail) {
setEmailStatus({ checking: false, exists: null, valid: null, message: '' }); setEmailStatus({ checking: false, exists: null, valid: null, message: '' });
return; return;
} }
@ -118,13 +117,13 @@ export default function RegisterPage() {
<div className="flex border-b border-gray-200"> <div className="flex border-b border-gray-200">
<Link <Link
href={ROUTES.LOGIN} href={ROUTES.LOGIN}
className="flex-1 py-4 px-6 text-center font-semibold text-gray-500 bg-gray-50 hover:bg-gradient-to-r hover:from-[#d4a574]/5 hover:to-[#c4956a]/5 hover:text-[#c4956a] transition-all duration-300 hover:shadow-inner" className="flex-1 py-4 px-6 text-center font-semibold text-gray-500 bg-gray-50 hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 hover:text-primary-600 transition-all duration-300 hover:shadow-inner"
> >
Connexion Connexion
</Link> </Link>
<button className="flex-1 py-4 px-6 text-center font-bold text-gray-900 bg-white border-b-3 border-[#d4a574] shadow-[0_3px_8px_rgba(212,165,116,0.3)] relative"> <button className="flex-1 py-4 px-6 text-center font-bold text-gray-900 bg-white border-b-3 border-primary-500 shadow-[0_3px_8px_rgba(11,96,41,0.2)] relative">
<span className="relative z-10">Inscription</span> <span className="relative z-10">Inscription</span>
<div className="absolute bottom-0 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-[#d4a574] to-transparent"></div> <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-primary-500 to-transparent"></div>
</button> </button>
</div> </div>
@ -145,7 +144,7 @@ export default function RegisterPage() {
type="text" type="text"
placeholder="prénom" placeholder="prénom"
{...register("firstName")} {...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-[#d4a574] focus:border-transparent`} 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-primary-500 focus:border-transparent`}
/> />
{errors.firstName && ( {errors.firstName && (
<p className="mt-1 text-sm text-red-500">{errors.firstName.message}</p> <p className="mt-1 text-sm text-red-500">{errors.firstName.message}</p>
@ -161,7 +160,7 @@ export default function RegisterPage() {
type="text" type="text"
placeholder="nom" placeholder="nom"
{...register("lastName")} {...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-[#d4a574] focus:border-transparent`} 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-primary-500 focus:border-transparent`}
/> />
{errors.lastName && ( {errors.lastName && (
<p className="mt-1 text-sm text-red-500">{errors.lastName.message}</p> <p className="mt-1 text-sm text-red-500">{errors.lastName.message}</p>
@ -185,9 +184,9 @@ export default function RegisterPage() {
errors.email || emailStatus.exists errors.email || emailStatus.exists
? 'border-red-500' ? 'border-red-500'
: emailStatus.valid : emailStatus.valid
? 'border-green-500' ? 'border-primary-500'
: 'border-gray-300' : 'border-gray-300'
} rounded-lg focus:outline-none focus:ring-2 focus:ring-[#d4a574] focus:border-transparent pr-10`} } rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent pr-10`}
/> />
{/* Status icon */} {/* Status icon */}
{emailStatus.checking && ( {emailStatus.checking && (
@ -200,7 +199,7 @@ export default function RegisterPage() {
)} )}
{!emailStatus.checking && emailStatus.valid && ( {!emailStatus.checking && emailStatus.valid && (
<div className="absolute right-3 top-1/2 -translate-y-1/2"> <div className="absolute right-3 top-1/2 -translate-y-1/2">
<svg className="h-5 w-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="h-5 w-5 text-primary-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg> </svg>
</div> </div>
@ -217,7 +216,7 @@ export default function RegisterPage() {
<p className="mt-1 text-sm text-red-500">{errors.email.message}</p> <p className="mt-1 text-sm text-red-500">{errors.email.message}</p>
)} )}
{!errors.email && emailStatus.message && ( {!errors.email && emailStatus.message && (
<p className={`mt-1 text-sm ${emailStatus.exists ? 'text-red-500' : emailStatus.valid ? 'text-green-600' : 'text-gray-500'}`}> <p className={`mt-1 text-sm ${emailStatus.exists ? 'text-red-500' : emailStatus.valid ? 'text-primary-600' : 'text-gray-500'}`}>
{emailStatus.message} {emailStatus.message}
</p> </p>
)} )}
@ -233,7 +232,7 @@ export default function RegisterPage() {
type="tel" type="tel"
placeholder="téléphone" placeholder="téléphone"
{...register("phone")} {...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-[#d4a574] focus:border-transparent`} 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-primary-500 focus:border-transparent`}
/> />
<p className="mt-1 text-xs text-gray-500">Optionnel - Format: 06 12 34 56 78</p> <p className="mt-1 text-xs text-gray-500">Optionnel - Format: 06 12 34 56 78</p>
{errors.phone && ( {errors.phone && (
@ -252,7 +251,7 @@ export default function RegisterPage() {
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
placeholder="mot de passe" placeholder="mot de passe"
{...register("password")} {...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-[#d4a574] focus:border-transparent pr-12`} 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-primary-500 focus:border-transparent pr-12`}
/> />
<button <button
type="button" type="button"
@ -288,7 +287,7 @@ export default function RegisterPage() {
type={showConfirmPassword ? "text" : "password"} type={showConfirmPassword ? "text" : "password"}
placeholder="confirmer mot de passe" placeholder="confirmer mot de passe"
{...register("confirmPassword")} {...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-[#d4a574] focus:border-transparent pr-12`} 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-primary-500 focus:border-transparent pr-12`}
/> />
<button <button
type="button" type="button"
@ -318,15 +317,15 @@ export default function RegisterPage() {
id="terms" id="terms"
type="checkbox" type="checkbox"
required required
className="mt-1 w-5 h-5 text-[#d4a574] border-gray-300 rounded focus:ring-2 focus:ring-[#d4a574]" className="mt-1 w-5 h-5 text-primary-500 border-gray-300 rounded focus:ring-2 focus:ring-primary-500"
/> />
<label htmlFor="terms" className="text-sm text-gray-700 select-none cursor-pointer"> <label htmlFor="terms" className="text-sm text-gray-700 select-none cursor-pointer">
J'accepte les{' '} J'accepte les{' '}
<Link href="/terms" className="text-[#5a5a4e] underline hover:text-[#d4a574]"> <Link href="/terms" className="text-beige-800 underline hover:text-primary-500">
conditions d'utilisation conditions d'utilisation
</Link>{' '} </Link>{' '}
et la{' '} et la{' '}
<Link href="/privacy" className="text-[#5a5a4e] underline hover:text-[#d4a574]"> <Link href="/privacy" className="text-beige-800 underline hover:text-primary-500">
politique de confidentialité politique de confidentialité
</Link>{' '} </Link>{' '}
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
@ -350,7 +349,7 @@ export default function RegisterPage() {
<button <button
type="submit" type="submit"
disabled={isSubmitting} disabled={isSubmitting}
className="w-full bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] disabled:bg-gray-400 disabled:from-gray-400 disabled:to-gray-400 text-white font-bold px-8 py-4 rounded-lg transition-all duration-300 hover:shadow-[0_0_25px_rgba(212,165,116,0.7)] hover:scale-[1.02] shadow-lg transform" className="w-full bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 disabled:bg-gray-400 disabled:from-gray-400 disabled:to-gray-400 text-white font-bold px-8 py-4 rounded-lg transition-all duration-300 hover:shadow-[0_0_25px_rgba(11,96,41,0.5)] hover:scale-[1.02] shadow-lg transform"
> >
{isSubmitting ? "Inscription..." : "S'inscrire"} {isSubmitting ? "Inscription..." : "S'inscrire"}
</button> </button>

View File

@ -11,15 +11,15 @@ export default function RulesPage() {
}; };
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0]"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100">
{/* Hero Section */} {/* Hero Section */}
<section className="bg-gradient-to-r from-white to-[#faf9f5] py-12 border-b-2 border-[#e5e4dc]"> <section className="bg-gradient-to-r from-white to-beige-50 py-12 border-b-2 border-beige-300">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto text-center"> <div className="max-w-4xl mx-auto text-center">
<h1 className="text-4xl md:text-5xl font-bold text-[#5a5a4e] mb-4"> <h1 className="text-4xl md:text-5xl font-bold text-primary-300 mb-4">
Règlement du jeu-concours Règlement du jeu-concours
</h1> </h1>
<p className="text-lg text-[#8a8a7a]"> <p className="text-lg text-gray-600">
Toutes les conditions de participation à notre grand jeu-concours "Thé Tip Top" Toutes les conditions de participation à notre grand jeu-concours "Thé Tip Top"
pour l'ouverture de notre 10e boutique. pour l'ouverture de notre 10e boutique.
</p> </p>
@ -31,36 +31,36 @@ export default function RulesPage() {
<section className="py-8"> <section className="py-8">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto"> <div className="max-w-4xl mx-auto">
<div className="bg-white rounded-xl shadow-md p-6 mb-8 border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md p-6 mb-8 border border-beige-300">
<div className="flex items-center gap-2 mb-6"> <div className="flex items-center gap-2 mb-6">
<span className="text-2xl">📋</span> <span className="text-2xl">📋</span>
<h2 className="text-2xl font-bold text-[#5a5a4e]">Résumé du jeu-concours</h2> <h2 className="text-2xl font-bold text-gray-800">Résumé du jeu-concours</h2>
</div> </div>
<div className="grid md:grid-cols-3 gap-4"> <div className="grid md:grid-cols-3 gap-4">
{/* 100% gagnants */} {/* 100% gagnants */}
<div className="bg-gradient-to-br from-[#d4a574]/10 to-[#c4956a]/10 rounded-lg p-6 text-center border border-[#d4a574]/20 hover:shadow-lg transition-shadow"> <div className="bg-gradient-to-br from-primary-50 to-primary-100 rounded-lg p-6 text-center border border-primary-200 hover:shadow-lg transition-shadow">
<div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-3xl shadow-lg">🎯</div> <div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-3xl shadow-lg">🎯</div>
<div className="text-2xl font-bold text-[#5a5a4e] mb-2">100% gagnants</div> <div className="text-2xl font-bold text-gray-800 mb-2">100% gagnants</div>
<p className="text-sm text-[#8a8a7a]"> <p className="text-sm text-gray-600">
Chaque participant repart avec un lot garanti Chaque participant repart avec un lot garanti
</p> </p>
</div> </div>
{/* 30 + 60 jours */} {/* 30 + 60 jours */}
<div className="bg-gradient-to-br from-[#d4a574]/10 to-[#c4956a]/10 rounded-lg p-6 text-center border border-[#d4a574]/20 hover:shadow-lg transition-shadow"> <div className="bg-gradient-to-br from-primary-50 to-primary-100 rounded-lg p-6 text-center border border-primary-200 hover:shadow-lg transition-shadow">
<div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-3xl shadow-lg">🔄</div> <div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-3xl shadow-lg">🔄</div>
<div className="text-2xl font-bold text-[#5a5a4e] mb-2">30 + 60 jours</div> <div className="text-2xl font-bold text-gray-800 mb-2">30 + 60 jours</div>
<p className="text-sm text-[#8a8a7a]"> <p className="text-sm text-gray-600">
Validation tickets (30j) + récupération lots (60j) Validation tickets (30j) + récupération lots (60j)
</p> </p>
</div> </div>
{/* Grand prix 360€ */} {/* Grand prix 360€ */}
<div className="bg-gradient-to-br from-[#d4a574]/10 to-[#c4956a]/10 rounded-lg p-6 text-center border border-[#d4a574]/20 hover:shadow-lg transition-shadow"> <div className="bg-gradient-to-br from-primary-50 to-primary-100 rounded-lg p-6 text-center border border-primary-200 hover:shadow-lg transition-shadow">
<div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-3xl shadow-lg">🏆</div> <div className="w-16 h-16 mx-auto mb-4 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-3xl shadow-lg">🏆</div>
<div className="text-2xl font-bold text-[#5a5a4e] mb-2">Grand prix 360</div> <div className="text-2xl font-bold text-gray-800 mb-2">Grand prix 360</div>
<p className="text-sm text-[#8a8a7a]"> <p className="text-sm text-gray-600">
Tirage final sous contrôle d'huissier Tirage final sous contrôle d'huissier
</p> </p>
</div> </div>
@ -76,17 +76,17 @@ export default function RulesPage() {
<div className="max-w-4xl mx-auto space-y-4"> <div className="max-w-4xl mx-auto space-y-4">
{/* Section 1 - Conditions de participation */} {/* Section 1 - Conditions de participation */}
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<button <button
onClick={() => toggleSection(1)} onClick={() => toggleSection(1)}
className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-[#d4a574]/5 hover:to-[#c4956a]/5 transition-colors" className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 transition-colors"
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md">📋</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md">📋</div>
<h3 className="text-xl font-bold text-[#5a5a4e]">1. Conditions de participation</h3> <h3 className="text-xl font-bold text-gray-800">1. Conditions de participation</h3>
</div> </div>
<svg <svg
className={`w-6 h-6 text-[#8a8a7a] transition-transform ${openSection === 1 ? 'rotate-180' : ''}`} className={`w-6 h-6 text-gray-600 transition-transform ${openSection === 1 ? 'rotate-180' : ''}`}
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -95,24 +95,24 @@ export default function RulesPage() {
</svg> </svg>
</button> </button>
{openSection === 1 && ( {openSection === 1 && (
<div className="px-6 pb-6 space-y-4 text-[#5a5a4e]"> <div className="px-6 pb-6 space-y-4 text-gray-800">
<p>Le concours est ouvert à toute personne majeure résidant en France métropolitaine ayant effectué un achat d'un montant minimum de 49€ TTC. Pour participer, le participant doit entrer un code unique obtenu lors d'un achat ou d'une opération marketing. </p> <p>Le concours est ouvert à toute personne majeure résidant en France métropolitaine ayant effectué un achat d'un montant minimum de 49€ TTC. Pour participer, le participant doit entrer un code unique obtenu lors d'un achat ou d'une opération marketing. </p>
</div> </div>
)} )}
</div> </div>
{/* Section 2 - Codes de participation */} {/* Section 2 - Codes de participation */}
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<button <button
onClick={() => toggleSection(2)} onClick={() => toggleSection(2)}
className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-[#d4a574]/5 hover:to-[#c4956a]/5 transition-colors" className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 transition-colors"
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md">🎫</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md">🎫</div>
<h3 className="text-xl font-bold text-[#5a5a4e]">2. Codes de participation</h3> <h3 className="text-xl font-bold text-gray-800">2. Codes de participation</h3>
</div> </div>
<svg <svg
className={`w-6 h-6 text-[#8a8a7a] transition-transform ${openSection === 2 ? 'rotate-180' : ''}`} className={`w-6 h-6 text-gray-600 transition-transform ${openSection === 2 ? 'rotate-180' : ''}`}
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -121,7 +121,7 @@ export default function RulesPage() {
</svg> </svg>
</button> </button>
{openSection === 2 && ( {openSection === 2 && (
<div className="px-6 pb-6 space-y-4 text-[#5a5a4e]"> <div className="px-6 pb-6 space-y-4 text-gray-800">
<p>Pour participer au jeu, le participant doit :</p> <p>Pour participer au jeu, le participant doit :</p>
<ol className="list-decimal list-inside space-y-2 ml-4"> <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>Effectuer un achat de minimum 49 dans une boutique Thé Tip Top participante</li>
@ -131,26 +131,26 @@ export default function RulesPage() {
<li>Saisir le code figurant sur son ticket dans l'espace dédié</li> <li>Saisir le code figurant sur son ticket dans l'espace dédié</li>
<li>Découvrir instantanément son gain</li> <li>Découvrir instantanément son gain</li>
</ol> </ol>
<div className="bg-gradient-to-r from-[#d4a574]/10 to-[#c4956a]/10 border-l-4 border-[#d4a574] p-4 mt-4 rounded"> <div className="bg-gradient-to-r from-primary-50 to-primary-100 border-l-4 border-primary-500 p-4 mt-4 rounded">
<p className="font-semibold text-[#5a5a4e]"> Important</p> <p className="font-semibold text-gray-800"> Important</p>
<p className="text-[#5a5a4e]">Chaque code ne peut être utilisé qu'une seule fois. Toute tentative de fraude entraînera l'exclusion du participant.</p> <p className="text-gray-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> </div>
)} )}
</div> </div>
{/* Section 3 - Calendrier et délais */} {/* Section 3 - Calendrier et délais */}
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<button <button
onClick={() => toggleSection(3)} onClick={() => toggleSection(3)}
className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-[#d4a574]/5 hover:to-[#c4956a]/5 transition-colors" className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 transition-colors"
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md">🎁</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md">🎁</div>
<h3 className="text-xl font-bold text-[#5a5a4e]">3. Lots à gagner</h3> <h3 className="text-xl font-bold text-gray-800">3. Lots à gagner</h3>
</div> </div>
<svg <svg
className={`w-6 h-6 text-[#8a8a7a] transition-transform ${openSection === 3 ? 'rotate-180' : ''}`} className={`w-6 h-6 text-gray-600 transition-transform ${openSection === 3 ? 'rotate-180' : ''}`}
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -159,7 +159,7 @@ export default function RulesPage() {
</svg> </svg>
</button> </button>
{openSection === 3 && ( {openSection === 3 && (
<div className="px-6 pb-6 space-y-4 text-[#5a5a4e]"> <div className="px-6 pb-6 space-y-4 text-gray-800">
<div> <div>
<p className="font-semibold mb-2">Voici ce que tu peux gagner :</p> <p className="font-semibold mb-2">Voici ce que tu peux gagner :</p>
</div> </div>
@ -177,17 +177,17 @@ export default function RulesPage() {
</div> </div>
{/* Section 4 - Tirage final Grand Prix */} {/* Section 4 - Tirage final Grand Prix */}
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<button <button
onClick={() => toggleSection(4)} onClick={() => toggleSection(4)}
className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-[#d4a574]/5 hover:to-[#c4956a]/5 transition-colors" className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 transition-colors"
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md">🏆</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md">🏆</div>
<h3 className="text-xl font-bold text-[#5a5a4e]">4. Tirage final - Grand Prix</h3> <h3 className="text-xl font-bold text-gray-800">4. Tirage final - Grand Prix</h3>
</div> </div>
<svg <svg
className={`w-6 h-6 text-[#8a8a7a] transition-transform ${openSection === 4 ? 'rotate-180' : ''}`} className={`w-6 h-6 text-gray-600 transition-transform ${openSection === 4 ? 'rotate-180' : ''}`}
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -196,7 +196,7 @@ export default function RulesPage() {
</svg> </svg>
</button> </button>
{openSection === 4 && ( {openSection === 4 && (
<div className="px-6 pb-6 space-y-4 text-[#5a5a4e]"> <div className="px-6 pb-6 space-y-4 text-gray-800">
<p className="font-semibold text-xl">Grand Prix : 1 an de thé offert (valeur 360)</p> <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> <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> <div>
@ -211,26 +211,26 @@ export default function RulesPage() {
<p>Le gagnant recevra Un an de thé d'une valeur de 360 !</p> <p>Le gagnant recevra Un an de thé d'une valeur de 360 !</p>
</div> </div>
<div className="bg-gradient-to-r from-[#d4a574]/10 to-[#c4956a]/10 border-l-4 border-[#d4a574] p-4 mt-4 rounded"> <div className="bg-gradient-to-r from-primary-50 to-primary-100 border-l-4 border-primary-500 p-4 mt-4 rounded">
<p className="font-semibold text-[#5a5a4e]">🎁 Information</p> <p className="font-semibold text-gray-800">🎁 Information</p>
<p className="text-[#5a5a4e]">Le gagnant sera contacté par email et par téléphone dans les 48h suivant le tirage.</p> <p className="text-gray-800">Le gagnant sera contacté par email et par téléphone dans les 48h suivant le tirage.</p>
</div> </div>
</div> </div>
)} )}
</div> </div>
{/* Section 5 - Retrait des lots */} {/* Section 5 - Retrait des lots */}
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<button <button
onClick={() => toggleSection(5)} onClick={() => toggleSection(5)}
className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-[#d4a574]/5 hover:to-[#c4956a]/5 transition-colors" className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 transition-colors"
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md">🎁</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md">🎁</div>
<h3 className="text-xl font-bold text-[#5a5a4e]">5. Retrait des lots</h3> <h3 className="text-xl font-bold text-gray-800">5. Retrait des lots</h3>
</div> </div>
<svg <svg
className={`w-6 h-6 text-[#8a8a7a] transition-transform ${openSection === 5 ? 'rotate-180' : ''}`} className={`w-6 h-6 text-gray-600 transition-transform ${openSection === 5 ? 'rotate-180' : ''}`}
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -239,7 +239,7 @@ export default function RulesPage() {
</svg> </svg>
</button> </button>
{openSection === 5 && ( {openSection === 5 && (
<div className="px-6 pb-6 space-y-4 text-[#5a5a4e]"> <div className="px-6 pb-6 space-y-4 text-gray-800">
<p>Les lots doivent être réclamés dans un délai de <strong>60 jours</strong> (du 1er décembre 2025 au 31 janvier 2026).</p> <p>Les lots doivent être réclamés dans un délai de <strong>60 jours</strong> (du 1er décembre 2025 au 31 janvier 2026).</p>
<div> <div>
<p className="font-semibold mb-2">Modalités de remise :</p> <p className="font-semibold mb-2">Modalités de remise :</p>
@ -258,17 +258,17 @@ export default function RulesPage() {
</div> </div>
{/* Section 6 - Protection des données */} {/* Section 6 - Protection des données */}
<div className="bg-white rounded-xl shadow-md overflow-hidden border border-[#e5e4dc]"> <div className="bg-white rounded-xl shadow-md overflow-hidden border border-beige-300">
<button <button
onClick={() => toggleSection(6)} onClick={() => toggleSection(6)}
className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-[#d4a574]/5 hover:to-[#c4956a]/5 transition-colors" className="w-full flex items-center justify-between p-6 text-left hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 transition-colors"
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center text-xl shadow-md">🔒</div> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center text-xl shadow-md">🔒</div>
<h3 className="text-xl font-bold text-[#5a5a4e]">6. Protection des données personnelles</h3> <h3 className="text-xl font-bold text-gray-800">6. Protection des données personnelles</h3>
</div> </div>
<svg <svg
className={`w-6 h-6 text-[#8a8a7a] transition-transform ${openSection === 6 ? 'rotate-180' : ''}`} className={`w-6 h-6 text-gray-600 transition-transform ${openSection === 6 ? 'rotate-180' : ''}`}
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -277,7 +277,7 @@ export default function RulesPage() {
</svg> </svg>
</button> </button>
{openSection === 6 && ( {openSection === 6 && (
<div className="px-6 pb-6 space-y-4 text-[#5a5a4e]"> <div className="px-6 pb-6 space-y-4 text-gray-800">
<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> <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> <div>
<p className="font-semibold mb-2">Vos droits :</p> <p className="font-semibold mb-2">Vos droits :</p>
@ -289,8 +289,8 @@ export default function RulesPage() {
<li>Droit à la portabilité des données</li> <li>Droit à la portabilité des données</li>
</ul> </ul>
</div> </div>
<p>Pour exercer vos droits, contactez-nous à : <a href="mailto:contact@thetiptop.fr" className="text-[#d4a574] underline hover:text-[#c4956a]">contact@thetiptop.fr</a></p> <p>Pour exercer vos droits, contactez-nous à : <a href="mailto:contact@thetiptop.fr" className="text-primary-500 underline hover:text-primary-600">contact@thetiptop.fr</a></p>
<p>Pour plus d'informations, consultez notre <a href="/privacy" className="text-[#d4a574] underline hover:text-[#c4956a]">Politique de confidentialité</a>.</p> <p>Pour plus d'informations, consultez notre <a href="/privacy" className="text-primary-500 underline hover:text-primary-600">Politique de confidentialité</a>.</p>
</div> </div>
)} )}
</div> </div>
@ -300,39 +300,39 @@ export default function RulesPage() {
</section> </section>
{/* Informations légales Section */} {/* Informations légales Section */}
<section className="py-16 bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0]"> <section className="py-16 bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-5xl mx-auto"> <div className="max-w-5xl mx-auto">
<div className="text-center mb-8"> <div className="text-center mb-8">
<h2 className="text-3xl font-bold text-[#5a5a4e] mb-2">Informations légales</h2> <h2 className="text-3xl font-bold text-gray-800 mb-2">Informations légales</h2>
<p className="text-[#8a8a7a]">Détails officiels du jeu-concours</p> <p className="text-gray-600">Détails officiels du jeu-concours</p>
</div> </div>
<div className="grid md:grid-cols-2 gap-6 mb-6"> <div className="grid md:grid-cols-2 gap-6 mb-6">
{/* Organisateur */} {/* Organisateur */}
<div className="bg-white rounded-xl shadow-lg p-6 border-2 border-[#e5e4dc] hover:shadow-xl transition-shadow"> <div className="bg-white rounded-xl shadow-lg p-6 border-2 border-beige-300 hover:shadow-xl transition-shadow">
<div className="flex items-center gap-3 mb-4"> <div className="flex items-center gap-3 mb-4">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center shadow-md"> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center shadow-md">
<span className="text-xl">🏢</span> <span className="text-xl">🏢</span>
</div> </div>
<h3 className="text-xl font-bold text-[#5a5a4e]">Organisateur</h3> <h3 className="text-xl font-bold text-gray-800">Organisateur</h3>
</div> </div>
<div className="space-y-2 text-[#5a5a4e]"> <div className="space-y-2 text-gray-800">
<p className="font-semibold">Thé Tip Top</p> <p className="font-semibold">Thé Tip Top</p>
<p className="text-sm">18 rue Léon Frot, 75011 Paris</p> <p className="text-sm">18 rue Léon Frot, 75011 Paris</p>
<p className="text-sm text-[#8a8a7a]">SIRET : 901 234 567 00015</p> <p className="text-sm text-gray-600">SIRET : 901 234 567 00015</p>
</div> </div>
</div> </div>
{/* Huissier */} {/* Huissier */}
<div className="bg-white rounded-xl shadow-lg p-6 border-2 border-[#e5e4dc] hover:shadow-xl transition-shadow"> <div className="bg-white rounded-xl shadow-lg p-6 border-2 border-beige-300 hover:shadow-xl transition-shadow">
<div className="flex items-center gap-3 mb-4"> <div className="flex items-center gap-3 mb-4">
<div className="w-12 h-12 bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full flex items-center justify-center shadow-md"> <div className="w-12 h-12 bg-gradient-to-br from-primary-500 to-primary-600 rounded-full flex items-center justify-center shadow-md">
<span className="text-xl"></span> <span className="text-xl"></span>
</div> </div>
<h3 className="text-xl font-bold text-[#5a5a4e]">Huissier</h3> <h3 className="text-xl font-bold text-gray-800">Huissier</h3>
</div> </div>
<div className="space-y-2 text-[#5a5a4e]"> <div className="space-y-2 text-gray-800">
<p className="font-semibold">Maître Arnaud Rick</p> <p className="font-semibold">Maître Arnaud Rick</p>
<p className="text-sm">Office Notarial de Paris</p> <p className="text-sm">Office Notarial de Paris</p>
<p className="text-sm">456 Rue de la Justice, 75002 Paris, France</p> <p className="text-sm">456 Rue de la Justice, 75002 Paris, France</p>
@ -341,7 +341,7 @@ export default function RulesPage() {
</div> </div>
{/* Note légale */} {/* Note légale */}
<div className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] rounded-xl shadow-lg p-6 text-white text-center"> <div className="bg-gradient-to-r from-primary-500 to-primary-600 rounded-xl shadow-lg p-6 text-white text-center">
<div className="flex items-center justify-center gap-2 mb-3"> <div className="flex items-center justify-center gap-2 mb-3">
<span className="text-2xl">📜</span> <span className="text-2xl">📜</span>
<h3 className="text-lg font-semibold">Note légale</h3> <h3 className="text-lg font-semibold">Note légale</h3>

View File

@ -7,19 +7,19 @@ export const metadata: Metadata = {
export default function TermsPage() { export default function TermsPage() {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0] py-12 px-4"> <div className="min-h-screen bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100 py-12 px-4">
<div className="max-w-4xl mx-auto bg-white rounded-xl shadow-lg border border-[#e5e4dc] p-8"> <div className="max-w-4xl mx-auto bg-white rounded-xl shadow-lg border border-beige-300 p-8">
<h1 className="text-3xl font-bold text-[#5a5a4e] mb-6"> <h1 className="text-3xl font-bold text-gray-800 mb-6">
Conditions d'utilisation Conditions d'utilisation
</h1> </h1>
<p className="text-sm text-[#8a8a7a] mb-8"> <p className="text-sm text-gray-600 mb-8">
Dernière mise à jour : 17 janvier 2025 Dernière mise à jour : 17 janvier 2025
</p> </p>
<div className="space-y-6 text-[#5a5a4e]"> <div className="space-y-6 text-gray-700">
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
1. Présentation 1. Présentation
</h2> </h2>
<p> <p>
@ -30,7 +30,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
2. Objet du jeu-concours 2. Objet du jeu-concours
</h2> </h2>
<p> <p>
@ -41,7 +41,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
3. Conditions de participation 3. Conditions de participation
</h2> </h2>
<ul className="list-disc pl-6 space-y-2"> <ul className="list-disc pl-6 space-y-2">
@ -54,7 +54,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
4. Modalités de participation 4. Modalités de participation
</h2> </h2>
<p className="mb-2">Pour participer :</p> <p className="mb-2">Pour participer :</p>
@ -67,7 +67,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
5. Lots à gagner 5. Lots à gagner
</h2> </h2>
<p className="mb-2">Les lots suivants sont disponibles :</p> <p className="mb-2">Les lots suivants sont disponibles :</p>
@ -82,7 +82,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
6. Récupération des lots 6. Récupération des lots
</h2> </h2>
<p> <p>
@ -93,7 +93,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
7. Limitation de responsabilité 7. Limitation de responsabilité
</h2> </h2>
<p> <p>
@ -104,7 +104,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
8. Propriété intellectuelle 8. Propriété intellectuelle
</h2> </h2>
<p> <p>
@ -116,7 +116,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
9. Modification des conditions 9. Modification des conditions
</h2> </h2>
<p> <p>
@ -127,7 +127,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
10. Droit applicable et juridiction 10. Droit applicable et juridiction
</h2> </h2>
<p> <p>
@ -138,7 +138,7 @@ export default function TermsPage() {
</section> </section>
<section> <section>
<h2 className="text-2xl font-semibold text-[#5a5a4e] mb-3"> <h2 className="text-2xl font-semibold text-gray-800 mb-3">
11. Contact 11. Contact
</h2> </h2>
<p> <p>
@ -146,17 +146,17 @@ export default function TermsPage() {
nous contacter : nous contacter :
</p> </p>
<ul className="list-none space-y-2 mt-3"> <ul className="list-none space-y-2 mt-3">
<li><strong>Email :</strong> <a href="mailto:contact@thetiptop.fr" className="text-[#d4a574] hover:text-[#c4956a] transition-colors">contact@thetiptop.fr</a></li> <li><strong>Email :</strong> <a href="mailto:contact@thetiptop.fr" className="text-primary-500 hover:text-primary-600 transition-colors">contact@thetiptop.fr</a></li>
<li><strong>Adresse :</strong> 18 Avenue Thiers, 06000 Nice, France</li> <li><strong>Adresse :</strong> 18 Avenue Thiers, 06000 Nice, France</li>
<li><strong>Téléphone :</strong> +33 4 93 00 00 00</li> <li><strong>Téléphone :</strong> +33 4 93 00 00 00</li>
</ul> </ul>
</section> </section>
</div> </div>
<div className="mt-8 pt-6 border-t border-[#e5e4dc]"> <div className="mt-8 pt-6 border-t border-beige-300">
<a <a
href="/" href="/"
className="inline-flex items-center gap-2 text-[#d4a574] hover:text-[#c4956a] font-medium transition-colors group" className="inline-flex items-center gap-2 text-primary-500 hover:text-primary-600 font-medium transition-colors group"
> >
<svg className="w-5 h-5 group-hover:-translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 group-hover:-translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />

View File

@ -30,16 +30,16 @@ export default function AboutContest({
<div className="grid md:grid-cols-2 gap-16 items-center"> <div className="grid md:grid-cols-2 gap-16 items-center">
{/* Texte */} {/* Texte */}
<div className="order-2 md:order-1 space-y-6"> <div className="order-2 md:order-1 space-y-6">
<h2 className="text-4xl md:text-5xl font-bold text-[#5a5a4e] leading-tight"> <h2 className="text-4xl md:text-5xl font-bold text-primary-500 leading-tight">
Jeu Concours Thé Tip Top Jeu Concours Thé Tip Top
<span className="block text-3xl md:text-4xl text-[#d4a574] mt-2"> <span className="block text-3xl md:text-4xl text-primary-300 mt-2">
Boutique Premium à Nice Boutique Premium à Nice
</span> </span>
</h2> </h2>
<div className="space-y-4 text-lg text-gray-700"> <div className="space-y-4 text-lg text-gray-700">
<p className="leading-relaxed"> <p className="leading-relaxed">
Bienvenue dans notre grand jeu-concours <span className="font-semibold text-[#5a5a4e]">Thé Tip Top</span> organisé à l'occasion de l'ouverture de notre <span className="font-semibold text-[#d4a574]">10ème boutique</span> de thé premium à Nice. Bienvenue dans notre grand jeu-concours <span className="font-semibold text-gray-800">Thé Tip Top</span> organisé à l'occasion de l'ouverture de notre <span className="font-semibold text-primary-500">10ème boutique</span> de thé premium à Nice.
</p> </p>
<p className="leading-relaxed"> <p className="leading-relaxed">
Nous vous offrons la chance de gagner des produits exceptionnels : thés bio, accessoires exclusifs et bien plus encore. Nous vous offrons la chance de gagner des produits exceptionnels : thés bio, accessoires exclusifs et bien plus encore.
@ -47,16 +47,16 @@ export default function AboutContest({
<p className="leading-relaxed"> <p className="leading-relaxed">
Participez facilement en quelques clics et tentez votre chance parmi nos lots prestigieux. Participez facilement en quelques clics et tentez votre chance parmi nos lots prestigieux.
</p> </p>
<div className="bg-gradient-to-r from-[#d4a574]/10 to-[#c4956a]/10 border-l-4 border-[#d4a574] p-4 rounded-r-lg"> <div className="bg-gradient-to-r from-primary-50 to-primary-100 border-l-4 border-primary-500 p-4 rounded-r-lg">
<p className="font-semibold text-[#5a5a4e] text-xl"> <p className="font-semibold text-gray-800 text-xl">
100% de tickets gagnants ! Chaque participation vous offre la garantie de repartir avec un cadeau. 100% de tickets gagnants ! Chaque participation vous offre la garantie de repartir avec un cadeau.
</p> </p>
</div> </div>
</div> </div>
<div className="flex flex-col sm:flex-row gap-4 pt-4"> <div className="flex flex-col sm:flex-row gap-4 pt-4">
<Link href="/register"> <Link href="/register">
<button className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold text-lg px-8 py-4 rounded-lg transition-all duration-300 hover:shadow-[0_0_25px_rgba(212,165,116,0.7)] hover:scale-105 shadow-lg flex items-center justify-center gap-2"> <button className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold text-lg px-8 py-4 rounded-lg transition-all duration-300 hover:shadow-[0_0_25px_rgba(11,96,41,0.5)] hover:scale-105 shadow-lg flex items-center justify-center gap-2">
En savoir plus En savoir plus
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 7l5 5m0 0l-5 5m5-5H6" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 7l5 5m0 0l-5 5m5-5H6" />

View File

@ -27,15 +27,15 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
const variants = { const variants = {
primary: primary:
"bg-[#d4a574] text-white hover:bg-[#c4956a] focus:ring-[#d4a574] shadow-md hover:shadow-lg", "bg-primary-500 text-white hover:bg-primary-600 focus:ring-primary-500 shadow-md hover:shadow-lg",
secondary: secondary:
"bg-white text-[#5a5a4e] hover:bg-[#d4a574] hover:text-white focus:ring-[#d4a574] border border-[#e5e4dc] shadow-sm", "bg-white text-gray-700 hover:bg-primary-500 hover:text-white focus:ring-primary-500 border border-gray-300 shadow-sm",
outline: outline:
"border-2 border-[#d4a574] text-[#d4a574] hover:bg-[#d4a574] hover:text-white focus:ring-[#d4a574] shadow-sm", "border-2 border-primary-500 text-primary-500 hover:bg-primary-500 hover:text-white focus:ring-primary-500 shadow-sm",
danger: danger:
"bg-red-600 text-white hover:bg-red-700 focus:ring-red-500 shadow-md", "bg-red-600 text-white hover:bg-red-700 focus:ring-red-500 shadow-md",
success: success:
"bg-[#1a4d2e] text-white hover:bg-[#2d5a3d] focus:ring-[#1a4d2e] shadow-md hover:shadow-lg", "bg-primary-600 text-white hover:bg-primary-700 focus:ring-primary-600 shadow-md hover:shadow-lg",
}; };
const sizes = { const sizes = {

View File

@ -27,16 +27,16 @@ export default function CookieConsent() {
if (!showBanner) return null; if (!showBanner) return null;
return ( return (
<div className="fixed bottom-0 left-0 right-0 z-50 bg-gradient-to-r from-[#f5f5f0] to-[#faf9f5] shadow-2xl border-t-4 border-[#d4a574]"> <div className="fixed bottom-0 left-0 right-0 z-50 bg-gradient-to-r from-beige-100 to-beige-50 shadow-2xl border-t-4 border-primary-500">
<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"> <div className="flex flex-col md:flex-row items-center justify-between gap-4">
{/* Message */} {/* Message */}
<div className="flex-1 text-center md:text-left"> <div className="flex-1 text-center md:text-left">
<p className="text-sm md:text-base text-[#5a5a4e]"> <p className="text-sm md:text-base text-gray-700">
🍪 Ce site utilise des cookies pour améliorer votre expérience de navigation et analyser notre trafic.{' '} Ce site utilise des cookies pour améliorer votre expérience de navigation et analyser notre trafic.{' '}
<Link <Link
href="/cookies" href="/cookies"
className="text-[#d4a574] hover:text-[#c4956a] underline transition-colors font-semibold" className="text-primary-500 hover:text-primary-600 underline transition-colors font-semibold"
> >
En savoir plus En savoir plus
</Link> </Link>
@ -47,13 +47,13 @@ export default function CookieConsent() {
<div className="flex gap-3 flex-shrink-0"> <div className="flex gap-3 flex-shrink-0">
<button <button
onClick={handleReject} onClick={handleReject}
className="px-6 py-2.5 bg-white border-2 border-[#e5e4dc] hover:border-[#d4a574] text-[#5a5a4e] hover:text-[#d4a574] rounded-lg transition-all duration-300 text-sm font-semibold" className="px-6 py-2.5 bg-white border-2 border-beige-300 hover:border-primary-500 text-gray-700 hover:text-primary-500 rounded-lg transition-all duration-300 text-sm font-semibold"
> >
Refuser Refuser
</button> </button>
<button <button
onClick={handleAccept} onClick={handleAccept}
className="px-6 py-2.5 bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white rounded-lg transition-all duration-300 shadow-lg hover:shadow-xl text-sm font-semibold" className="px-6 py-2.5 bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white rounded-lg transition-all duration-300 shadow-lg hover:shadow-xl text-sm font-semibold"
> >
Accepter tous les cookies Accepter tous les cookies
</button> </button>

View File

@ -40,7 +40,7 @@ export default function Footer() {
}; };
return ( return (
<footer className="bg-gradient-to-br from-[#f5f5f0] via-[#faf9f5] to-[#f5f5f0] text-[#5a5a4e] border-t-2 border-[#e5e4dc]"> <footer className="bg-gradient-to-br from-beige-100 via-beige-50 to-beige-100 text-beige-800 border-t-2 border-beige-300">
{/* Main Footer */} {/* Main Footer */}
<div className="container mx-auto px-4 py-12"> <div className="container mx-auto px-4 py-12">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
@ -49,7 +49,7 @@ export default function Footer() {
<div className="mb-4"> <div className="mb-4">
<Logo variant="default" size="md" showText={true} /> <Logo variant="default" size="md" showText={true} />
</div> </div>
<p className="text-sm text-[#8a8a7a] mb-4"> <p className="text-sm text-beige-600 mb-4">
Découvrez nos thés premium bio et artisanaux. Participez à notre grand Découvrez nos thés premium bio et artisanaux. Participez à notre grand
jeu-concours 100% gagnant et tentez de remporter nos magnifiques lots ! jeu-concours 100% gagnant et tentez de remporter nos magnifiques lots !
</p> </p>
@ -58,7 +58,7 @@ export default function Footer() {
href="https://www.facebook.com/profile.php?id=61584261567579" href="https://www.facebook.com/profile.php?id=61584261567579"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-beige-600 hover:text-primary-500 transition-colors"
aria-label="Facebook" aria-label="Facebook"
> >
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
@ -69,7 +69,7 @@ export default function Footer() {
href="https://www.instagram.com/thetiptopgr3/" href="https://www.instagram.com/thetiptopgr3/"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-beige-600 hover:text-primary-500 transition-colors"
aria-label="Instagram" aria-label="Instagram"
> >
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
@ -80,7 +80,7 @@ export default function Footer() {
href="https://www.pinterest.com/The_Tip_Top_/" href="https://www.pinterest.com/The_Tip_Top_/"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-beige-600 hover:text-primary-500 transition-colors"
aria-label="Pinterest" aria-label="Pinterest"
> >
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
@ -92,14 +92,14 @@ export default function Footer() {
{/* Quick Links */} {/* Quick Links */}
<div> <div>
<h3 className="text-lg font-semibold text-[#d4a574] mb-4"> <h3 className="text-lg font-semibold text-primary-500 mb-4">
NAVIGATION NAVIGATION
</h3> </h3>
<ul className="space-y-2"> <ul className="space-y-2">
<li> <li>
<Link <Link
href={ROUTES.HOME} href={ROUTES.HOME}
className="text-sm text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-sm text-beige-600 hover:text-primary-500 transition-colors"
> >
Accueil Accueil
</Link> </Link>
@ -107,7 +107,7 @@ export default function Footer() {
<li> <li>
<Link <Link
href={isAuthenticated ? ROUTES.GAME : ROUTES.REGISTER} href={isAuthenticated ? ROUTES.GAME : ROUTES.REGISTER}
className="text-sm text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-sm text-beige-600 hover:text-primary-500 transition-colors"
> >
Participer au jeu Participer au jeu
</Link> </Link>
@ -115,7 +115,7 @@ export default function Footer() {
<li> <li>
<Link <Link
href="/contact" href="/contact"
className="text-sm text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-sm text-beige-600 hover:text-primary-500 transition-colors"
> >
Contact Contact
</Link> </Link>
@ -123,7 +123,7 @@ export default function Footer() {
<li> <li>
<Link <Link
href="/faq" href="/faq"
className="text-sm text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-sm text-beige-600 hover:text-primary-500 transition-colors"
> >
FAQ FAQ
</Link> </Link>
@ -133,12 +133,12 @@ export default function Footer() {
{/* Legal */} {/* Legal */}
<div> <div>
<h3 className="text-lg font-semibold text-[#d4a574] mb-4">LÉGAL</h3> <h3 className="text-lg font-semibold text-primary-500 mb-4">LÉGAL</h3>
<ul className="space-y-2"> <ul className="space-y-2">
<li> <li>
<Link <Link
href="/terms" href="/terms"
className="text-sm text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-sm text-beige-600 hover:text-primary-500 transition-colors"
> >
Conditions d'utilisation Conditions d'utilisation
</Link> </Link>
@ -146,7 +146,7 @@ export default function Footer() {
<li> <li>
<Link <Link
href="/privacy" href="/privacy"
className="text-sm text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-sm text-beige-600 hover:text-primary-500 transition-colors"
> >
Politique de confidentialité Politique de confidentialité
</Link> </Link>
@ -154,7 +154,7 @@ export default function Footer() {
<li> <li>
<Link <Link
href="/rules" href="/rules"
className="text-sm text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-sm text-beige-600 hover:text-primary-500 transition-colors"
> >
Règlement du jeu Règlement du jeu
</Link> </Link>
@ -162,7 +162,7 @@ export default function Footer() {
<li> <li>
<Link <Link
href="/legal" href="/legal"
className="text-sm text-[#8a8a7a] hover:text-[#d4a574] transition-colors" className="text-sm text-beige-600 hover:text-primary-500 transition-colors"
> >
Mentions légales Mentions légales
</Link> </Link>
@ -172,8 +172,8 @@ export default function Footer() {
{/* Newsletter */} {/* Newsletter */}
<div> <div>
<h3 className="text-lg font-semibold text-[#d4a574] mb-4">NEWSLETTER</h3> <h3 className="text-lg font-semibold text-primary-500 mb-4">NEWSLETTER</h3>
<p className="text-sm text-[#8a8a7a] mb-4"> <p className="text-sm text-beige-600 mb-4">
Inscrivez-vous pour recevoir nos offres exclusives et nouveautés ! Inscrivez-vous pour recevoir nos offres exclusives et nouveautés !
</p> </p>
<form onSubmit={handleNewsletterSubmit} className="space-y-3"> <form onSubmit={handleNewsletterSubmit} className="space-y-3">
@ -183,42 +183,42 @@ export default function Footer() {
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
placeholder="Votre email" placeholder="Votre email"
className="w-full px-4 py-2 text-sm border border-[#e5e4dc] rounded-lg focus:outline-none focus:ring-2 focus:ring-[#d4a574] focus:border-transparent bg-white text-[#5a5a4e] placeholder-[#a0a098]" className="w-full px-4 py-2 text-sm border border-beige-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent bg-white text-beige-800 placeholder-beige-500"
disabled={isLoading} disabled={isLoading}
/> />
</div> </div>
<button <button
type="submit" type="submit"
disabled={isLoading} disabled={isLoading}
className="w-full px-4 py-2 text-sm font-medium text-white bg-[#d4a574] rounded-lg hover:bg-[#c49563] transition-colors disabled:opacity-50 disabled:cursor-not-allowed" className="w-full px-4 py-2 text-sm font-medium text-white bg-primary-500 rounded-lg hover:bg-primary-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
> >
{isLoading ? 'Inscription...' : "S'inscrire"} {isLoading ? 'Inscription...' : "S'inscrire"}
</button> </button>
{message && ( {message && (
<p <p
className={`text-xs ${ className={`text-xs ${
message.type === 'success' ? 'text-green-600' : 'text-red-600' message.type === 'success' ? 'text-primary-600' : 'text-red-600'
}`} }`}
> >
{message.text} {message.text}
</p> </p>
)} )}
</form> </form>
<div className="mt-4 pt-4 border-t border-[#e5e4dc]"> <div className="mt-4 pt-4 border-t border-beige-300">
<p className="text-xs text-[#8a8a7a] flex items-center gap-1"> <p className="text-xs text-beige-600 flex items-center gap-1">
<span></span> <span></span>
<a <a
href="mailto:thetiptopgr3@gmail.com" href="mailto:thetiptopgr3@gmail.com"
className="hover:text-[#d4a574] transition-colors" className="hover:text-primary-500 transition-colors"
> >
thetiptopgr3@gmail.com thetiptopgr3@gmail.com
</a> </a>
</p> </p>
<p className="text-xs text-[#8a8a7a] mt-1 flex items-center gap-1"> <p className="text-xs text-beige-600 mt-1 flex items-center gap-1">
<span>📞</span> <span>📞</span>
<a <a
href="tel:+33123456789" href="tel:+33123456789"
className="hover:text-[#d4a574] transition-colors" className="hover:text-primary-500 transition-colors"
> >
01 23 45 67 89 01 23 45 67 89
</a> </a>
@ -229,11 +229,11 @@ export default function Footer() {
</div> </div>
{/* Bottom Bar */} {/* Bottom Bar */}
<div className="border-t border-[#e5e4dc]"> <div className="border-t border-beige-300">
<div className="container mx-auto px-4 py-6"> <div className="container mx-auto px-4 py-6">
<div className="flex items-center justify-center text-sm"> <div className="flex items-center justify-center text-sm">
<p className="text-[#8a8a7a]"> <p className="text-beige-600">
© {currentYear} Tous droits réservés. <span className="text-[#a0a098] text-xs">Site étudiant</span> © {currentYear} Tous droits réservés. <span className="text-beige-500 text-xs">Site étudiant</span>
</p> </p>
</div> </div>
</div> </div>

View File

@ -4,10 +4,10 @@ export default function GamePeriod() {
return ( return (
<div className="grid md:grid-cols-2 gap-8 mt-8"> <div className="grid md:grid-cols-2 gap-8 mt-8">
{/* Période de validation des tickets */} {/* Période de validation des tickets */}
<div className="bg-gradient-to-br from-white to-[#fffbeb] rounded-3xl shadow-xl p-10 border-2 border-[#f59e0b] hover:shadow-2xl hover:scale-[1.02] transition-all duration-300"> <div className="bg-gradient-to-br from-white to-secondary-50 rounded-3xl shadow-xl p-10 border-2 border-secondary-400 hover:shadow-2xl hover:scale-[1.02] transition-all duration-300">
<div className="flex flex-col items-center text-center"> <div className="flex flex-col items-center text-center">
<div className="bg-gradient-to-br from-[#fef3c7] to-[#fde68a] rounded-full p-6 mb-6 shadow-lg"> <div className="bg-gradient-to-br from-secondary-100 to-secondary-200 rounded-full p-6 mb-6 shadow-lg">
<svg className="w-12 h-12 text-[#f59e0b]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-12 h-12 text-secondary-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z" />
</svg> </svg>
</div> </div>
@ -15,20 +15,20 @@ export default function GamePeriod() {
<p className="text-lg text-gray-600 mb-6"> <p className="text-lg text-gray-600 mb-6">
Achetez et validez votre code de participation Achetez et validez votre code de participation
</p> </p>
<div className="bg-[#f59e0b]/10 rounded-2xl px-6 py-4 w-full"> <div className="bg-secondary-100 rounded-2xl px-6 py-4 w-full">
<p className="text-lg font-bold text-[#b45309]"> <p className="text-lg font-bold text-secondary-700">
Du 1 décembre 2025 au 31 décembre 2025 Du 1 décembre 2025 au 31 décembre 2025
</p> </p>
<p className="text-[#f59e0b] font-semibold mt-1">30 jours</p> <p className="text-secondary-500 font-semibold mt-1">30 jours</p>
</div> </div>
</div> </div>
</div> </div>
{/* Période de récupération des lots */} {/* Période de récupération des lots */}
<div className="bg-gradient-to-br from-white to-[#ecfdf5] rounded-3xl shadow-xl p-10 border-2 border-[#1a4d2e] hover:shadow-2xl hover:scale-[1.02] transition-all duration-300"> <div className="bg-gradient-to-br from-white to-primary-50 rounded-3xl shadow-xl p-10 border-2 border-primary-500 hover:shadow-2xl hover:scale-[1.02] transition-all duration-300">
<div className="flex flex-col items-center text-center"> <div className="flex flex-col items-center text-center">
<div className="bg-gradient-to-br from-[#d1fae5] to-[#a7f3d0] rounded-full p-6 mb-6 shadow-lg"> <div className="bg-gradient-to-br from-primary-100 to-primary-200 rounded-full p-6 mb-6 shadow-lg">
<svg className="w-12 h-12 text-[#1a4d2e]" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-12 h-12 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" />
</svg> </svg>
</div> </div>
@ -36,11 +36,11 @@ export default function GamePeriod() {
<p className="text-lg text-gray-600 mb-6"> <p className="text-lg text-gray-600 mb-6">
Récupérez vos lots gagnés en boutique Récupérez vos lots gagnés en boutique
</p> </p>
<div className="bg-[#1a4d2e]/10 rounded-2xl px-6 py-4 w-full"> <div className="bg-primary-50 rounded-2xl px-6 py-4 w-full">
<p className="text-lg font-bold text-[#1a4d2e]"> <p className="text-lg font-bold text-primary-700">
Du 1 décembre 2025 au 31 janvier 2026 Du 1 décembre 2025 au 31 janvier 2026
</p> </p>
<p className="text-[#22c55e] font-semibold mt-1">60 jours</p> <p className="text-primary-500 font-semibold mt-1">60 jours</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -18,10 +18,10 @@ export default function GrandPrize({
}; };
return ( return (
<div className="bg-gradient-to-br from-[#fff8e8] via-[#fff4d9] to-[#ffefc4] rounded-3xl shadow-2xl p-10 md:p-12 border-3 border-[#d4a574] mt-10 hover:shadow-3xl transition-all duration-300"> <div className="bg-gradient-to-br from-secondary-50 via-secondary-100 to-secondary-200 rounded-3xl shadow-2xl p-10 md:p-12 border-3 border-secondary-400 mt-10 hover:shadow-3xl transition-all duration-300">
<div className="flex flex-col items-center text-center"> <div className="flex flex-col items-center text-center">
{/* Icône trophée */} {/* Icône trophée */}
<div className="bg-gradient-to-br from-[#d4a574] to-[#c4956a] rounded-full p-6 mb-6 shadow-xl"> <div className="bg-gradient-to-br from-secondary-400 to-secondary-500 rounded-full p-6 mb-6 shadow-xl">
<svg className="w-16 h-16 text-white" fill="currentColor" viewBox="0 0 20 20"> <svg className="w-16 h-16 text-white" fill="currentColor" viewBox="0 0 20 20">
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" /> <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
</svg> </svg>
@ -34,16 +34,16 @@ export default function GrandPrize({
{/* Prix principal */} {/* Prix principal */}
<div className="bg-white/80 backdrop-blur-sm rounded-2xl px-8 py-6 mb-6 shadow-lg"> <div className="bg-white/80 backdrop-blur-sm rounded-2xl px-8 py-6 mb-6 shadow-lg">
<p className="text-2xl md:text-3xl font-bold text-[#d4a574] mb-2"> <p className="text-2xl md:text-3xl font-bold text-primary-500 mb-2">
1 an de thé offert 1 an de thé offert
</p> </p>
<p className="text-xl text-[#8b6f47] font-semibold"> <p className="text-xl text-secondary-600 font-semibold">
d'une valeur de {prizeAmount} d'une valeur de {prizeAmount}
</p> </p>
</div> </div>
{/* Description */} {/* Description */}
<p className="text-lg md:text-xl text-[#5a5a4e] mb-8 max-w-2xl leading-relaxed"> <p className="text-lg md:text-xl text-gray-700 mb-8 max-w-2xl leading-relaxed">
Le grand prix du tirage final : une année complète de thé premium Le grand prix du tirage final : une année complète de thé premium
</p> </p>
@ -51,27 +51,27 @@ export default function GrandPrize({
<div className="grid md:grid-cols-2 gap-4 w-full max-w-xl"> <div className="grid md:grid-cols-2 gap-4 w-full max-w-xl">
{drawDate && ( {drawDate && (
<div className="bg-white/70 backdrop-blur-sm rounded-2xl p-5 flex items-center gap-4 shadow-md"> <div className="bg-white/70 backdrop-blur-sm rounded-2xl p-5 flex items-center gap-4 shadow-md">
<div className="bg-[#d4a574]/20 rounded-full p-3"> <div className="bg-primary-100 rounded-full p-3">
<svg className="w-6 h-6 text-[#d4a574]" fill="currentColor" viewBox="0 0 20 20"> <svg className="w-6 h-6 text-primary-500" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clipRule="evenodd" /> <path fillRule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clipRule="evenodd" />
</svg> </svg>
</div> </div>
<div className="text-left"> <div className="text-left">
<p className="text-sm text-[#8a8a7a] font-medium">Tirage au sort</p> <p className="text-sm text-gray-500 font-medium">Tirage au sort</p>
<p className="text-lg font-bold text-[#5a5a4e]">{formatDate(drawDate)}</p> <p className="text-lg font-bold text-gray-700">{formatDate(drawDate)}</p>
</div> </div>
</div> </div>
)} )}
<div className="bg-white/70 backdrop-blur-sm rounded-2xl p-5 flex items-center gap-4 shadow-md"> <div className="bg-white/70 backdrop-blur-sm rounded-2xl p-5 flex items-center gap-4 shadow-md">
<div className="bg-[#d4a574]/20 rounded-full p-3"> <div className="bg-primary-100 rounded-full p-3">
<svg className="w-6 h-6 text-[#d4a574]" fill="currentColor" viewBox="0 0 20 20"> <svg className="w-6 h-6 text-primary-500" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" /> <path fillRule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg> </svg>
</div> </div>
<div className="text-left"> <div className="text-left">
<p className="text-sm text-[#8a8a7a] font-medium">Certification</p> <p className="text-sm text-gray-500 font-medium">Certification</p>
<p className="text-lg font-bold text-[#5a5a4e]">Contrôle d'huissier</p> <p className="text-lg font-bold text-gray-700">Contrôle d'huissier</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -44,7 +44,7 @@ export default function Header() {
}; };
return ( return (
<header className="bg-gradient-to-r from-[#f5f5f0] to-[#faf9f5] sticky top-0 z-50 shadow-lg border-b-2 border-[#e5e4dc]"> <header className="bg-gradient-to-r from-beige-100 to-beige-50 sticky top-0 z-50 shadow-lg border-b-2 border-beige-300">
{/* Main Header */} {/* Main Header */}
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="flex items-center justify-between h-18 gap-4"> <div className="flex items-center justify-between h-18 gap-4">
@ -57,40 +57,40 @@ export default function Header() {
<nav className="hidden md:flex items-center gap-6 flex-shrink-0"> <nav className="hidden md:flex items-center gap-6 flex-shrink-0">
<Link <Link
href={ROUTES.HOME} href={ROUTES.HOME}
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors" className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
> >
Accueil Accueil
</Link> </Link>
<Link <Link
href={ROUTES.LOTS} href={ROUTES.LOTS}
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors" className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
> >
Lots à gagner Lots à gagner
</Link> </Link>
<Link <Link
href="/rules" href="/rules"
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors" className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
> >
Règlement Règlement
</Link> </Link>
<Link <Link
href="/about" href="/about"
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors" className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
> >
À propos À propos
</Link> </Link>
<Link <Link
href="/contact" href="/contact"
className="text-[#5a5a4e] hover:text-[#d4a574] font-medium transition-colors" className="text-gray-700 hover:text-primary-500 font-medium transition-colors"
> >
Contact Contact
</Link> </Link>
{/* Participer with Dropdown - Doré Button */} {/* Participer with Dropdown - Green Button */}
{isAuthenticated ? ( {isAuthenticated ? (
<Link <Link
href={ROUTES.GAME} href={ROUTES.GAME}
className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold px-6 py-2 rounded-lg transition-all duration-300 hover:shadow-[0_0_20px_rgba(212,165,116,0.6)] shadow-lg whitespace-nowrap" className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-2 rounded-lg transition-all duration-300 hover:shadow-[0_0_20px_rgba(11,96,41,0.4)] shadow-lg whitespace-nowrap"
> >
Participer Participer
</Link> </Link>
@ -98,7 +98,7 @@ export default function Header() {
<div className="relative" ref={dropdownRef}> <div className="relative" ref={dropdownRef}>
<button <button
onClick={() => setIsParticiperDropdownOpen(!isParticiperDropdownOpen)} onClick={() => setIsParticiperDropdownOpen(!isParticiperDropdownOpen)}
className="bg-gradient-to-r from-[#d4a574] to-[#c4956a] hover:from-[#e5b685] hover:to-[#d4a574] text-white font-bold px-6 py-2 rounded-lg transition-all duration-300 hover:shadow-[0_0_20px_rgba(212,165,116,0.6)] shadow-lg flex items-center justify-center gap-2 whitespace-nowrap" className="bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-400 hover:to-primary-500 text-white font-bold px-6 py-2 rounded-lg transition-all duration-300 hover:shadow-[0_0_20px_rgba(11,96,41,0.4)] shadow-lg flex items-center justify-center gap-2 whitespace-nowrap"
> >
Participer Participer
<svg <svg
@ -112,20 +112,20 @@ export default function Header() {
</button> </button>
{isParticiperDropdownOpen && ( {isParticiperDropdownOpen && (
<div className="absolute right-0 mt-2 w-56 bg-white rounded-xl shadow-2xl border-2 border-[#d4a574]/30 py-2 z-50 animate-fadeIn overflow-hidden"> <div className="absolute right-0 mt-2 w-56 bg-white rounded-xl shadow-2xl border-2 border-primary-200 py-2 z-50 animate-fadeIn overflow-hidden">
<Link <Link
href={ROUTES.LOGIN} href={ROUTES.LOGIN}
onClick={() => setIsParticiperDropdownOpen(false)} onClick={() => setIsParticiperDropdownOpen(false)}
className="block px-4 py-3 text-gray-700 hover:bg-gradient-to-r hover:from-[#d4a574]/10 hover:to-[#c4956a]/10 hover:text-[#c4956a] transition-all duration-300 hover:pl-6 hover:shadow-inner" className="block px-4 py-3 text-gray-700 hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 hover:text-primary-600 transition-all duration-300 hover:pl-6 hover:shadow-inner"
> >
<span className="font-bold block">Connexion</span> <span className="font-bold block">Connexion</span>
<p className="text-xs text-gray-500 mt-0.5">J'ai déjà un compte</p> <p className="text-xs text-gray-500 mt-0.5">J'ai déjà un compte</p>
</Link> </Link>
<div className="border-t border-[#d4a574]/20 my-1"></div> <div className="border-t border-primary-100 my-1"></div>
<Link <Link
href={ROUTES.REGISTER} href={ROUTES.REGISTER}
onClick={() => setIsParticiperDropdownOpen(false)} onClick={() => setIsParticiperDropdownOpen(false)}
className="block px-4 py-3 text-gray-700 hover:bg-gradient-to-r hover:from-[#d4a574]/10 hover:to-[#c4956a]/10 hover:text-[#c4956a] transition-all duration-300 hover:pl-6 hover:shadow-inner" className="block px-4 py-3 text-gray-700 hover:bg-gradient-to-r hover:from-primary-50 hover:to-primary-100 hover:text-primary-600 transition-all duration-300 hover:pl-6 hover:shadow-inner"
> >
<span className="font-bold block">Inscription</span> <span className="font-bold block">Inscription</span>
<p className="text-xs text-gray-500 mt-0.5">Créer un nouveau compte</p> <p className="text-xs text-gray-500 mt-0.5">Créer un nouveau compte</p>
@ -141,13 +141,13 @@ export default function Header() {
{isAuthenticated && ( {isAuthenticated && (
<> <>
<Link href={getDashboardRoute()}> <Link href={getDashboardRoute()}>
<div className="flex flex-col items-start bg-gradient-to-br from-white to-[#faf9f5] text-[#5a5a4e] hover:shadow-lg px-4 py-2.5 rounded-xl transition-all border-2 border-[#e5e4dc] hover:border-[#d4a574] group min-w-0 flex-shrink-0"> <div className="flex flex-col items-start bg-gradient-to-br from-white to-beige-100 text-beige-800 hover:shadow-lg px-4 py-2.5 rounded-xl transition-all border-2 border-beige-300 hover:border-primary-400 group min-w-0 flex-shrink-0">
<span className="text-sm font-bold group-hover:text-[#d4a574] transition-colors whitespace-nowrap overflow-hidden text-ellipsis max-w-[200px]">{user?.firstName} {user?.lastName}</span> <span className="text-sm font-bold group-hover:text-primary-500 transition-colors whitespace-nowrap overflow-hidden text-ellipsis max-w-[200px]">{user?.firstName} {user?.lastName}</span>
<span className="text-xs text-[#8a8a7a] whitespace-nowrap overflow-hidden text-ellipsis max-w-[200px]">{user?.email}</span> <span className="text-xs text-beige-600 whitespace-nowrap overflow-hidden text-ellipsis max-w-[200px]">{user?.email}</span>
</div> </div>
</Link> </Link>
<Link href={ROUTES.PROFILE}> <Link href={ROUTES.PROFILE}>
<button className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-[#d4a574] hover:to-[#c4956a] text-[#5a5a4e] hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-[#e5e4dc] hover:border-[#d4a574] hover:shadow-lg whitespace-nowrap"> <button className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-primary-500 hover:to-primary-600 text-beige-800 hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-beige-300 hover:border-primary-500 hover:shadow-lg whitespace-nowrap">
<svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg> </svg>
@ -156,7 +156,7 @@ export default function Header() {
</Link> </Link>
{user?.role === 'CLIENT' && ( {user?.role === 'CLIENT' && (
<Link href={ROUTES.HISTORY}> <Link href={ROUTES.HISTORY}>
<button className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-[#d4a574] hover:to-[#c4956a] text-[#5a5a4e] hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-[#e5e4dc] hover:border-[#d4a574] hover:shadow-lg whitespace-nowrap"> <button className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-primary-500 hover:to-primary-600 text-beige-800 hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-beige-300 hover:border-primary-500 hover:shadow-lg whitespace-nowrap">
<svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" />
</svg> </svg>
@ -166,7 +166,7 @@ export default function Header() {
)} )}
<button <button
onClick={logout} onClick={logout}
className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-red-500 hover:to-red-600 text-[#5a5a4e] hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-[#e5e4dc] hover:border-red-500 hover:shadow-lg whitespace-nowrap" className="flex items-center justify-center gap-2 bg-white hover:bg-gradient-to-r hover:from-red-500 hover:to-red-600 text-beige-800 hover:text-white font-semibold px-5 py-2.5 rounded-xl transition-all duration-300 border-2 border-beige-300 hover:border-red-500 hover:shadow-lg whitespace-nowrap"
> >
<svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
@ -180,7 +180,7 @@ export default function Header() {
{/* Mobile Menu Button */} {/* Mobile Menu Button */}
<button <button
onClick={toggleMobileMenu} onClick={toggleMobileMenu}
className="md:hidden p-2 text-[#5a5a4e] hover:text-[#d4a574] focus:outline-none" className="md:hidden p-2 text-beige-800 hover:text-primary-500 focus:outline-none"
aria-label="Toggle menu" aria-label="Toggle menu"
> >
{isMobileMenuOpen ? ( {isMobileMenuOpen ? (
@ -217,104 +217,60 @@ export default function Header() {
{/* Mobile Menu */} {/* Mobile Menu */}
{isMobileMenuOpen && ( {isMobileMenuOpen && (
<div className="md:hidden py-4 border-t border-gray-200 animate-fadeIn"> <div className="md:hidden py-4 border-t border-beige-300 animate-fadeIn">
<nav className="flex flex-col gap-3"> <nav className="flex flex-col gap-3">
<Link <Link
href={ROUTES.HOME} href={ROUTES.HOME}
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors" className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
Accueil Accueil
</Link> </Link>
<Link <Link
href={ROUTES.GAME} href={ROUTES.GAME}
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors" className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
Jeu Jeu
</Link> </Link>
<Link <Link
href={ROUTES.LOTS} href={ROUTES.LOTS}
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors" className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
Lots Lots
</Link> </Link>
<Link <Link
href="/about" href="/about"
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors" className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
À propos À propos
</Link> </Link>
<Link <Link
href="/contact" href="/contact"
className="text-gray-700 hover:text-primary-600 font-medium py-2 transition-colors" className="text-beige-800 hover:text-primary-500 font-medium py-2 transition-colors"
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
Contact Contact
</Link> </Link>
{/* Participer Mobile - Green Button */} {/* Participer Mobile - Green Button */}
{isAuthenticated ? (
<Link <Link
href={ROUTES.GAME} href={isAuthenticated ? ROUTES.GAME : ROUTES.REGISTER}
className="bg-green-600 hover:bg-green-700 text-white font-semibold px-4 py-3 rounded-lg transition-all hover:shadow-lg text-center block whitespace-nowrap" className="bg-primary-500 hover:bg-primary-600 text-white font-semibold px-4 py-3 rounded-lg transition-all hover:shadow-lg text-center block whitespace-nowrap"
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
🎯 Participer Participer
</Link> </Link>
) : (
<div>
<button
onClick={() => setIsParticiperDropdownOpen(!isParticiperDropdownOpen)}
className="bg-green-600 hover:bg-green-700 text-white font-semibold px-4 py-3 rounded-lg transition-all hover:shadow-lg flex items-center justify-center gap-2 w-full whitespace-nowrap"
>
🎯 Participer
<svg
className={`w-4 h-4 flex-shrink-0 transition-transform ${isParticiperDropdownOpen ? '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>
{isParticiperDropdownOpen && (
<div className="mt-2 space-y-2 animate-fadeIn bg-green-50 rounded-lg p-3">
<Link
href={ROUTES.LOGIN}
onClick={() => {
setIsMobileMenuOpen(false);
setIsParticiperDropdownOpen(false);
}}
className="block text-green-800 hover:text-green-900 font-medium py-2 px-3 bg-white rounded-md hover:bg-green-100 transition-colors"
>
Connexion
</Link>
<Link
href={ROUTES.REGISTER}
onClick={() => {
setIsMobileMenuOpen(false);
setIsParticiperDropdownOpen(false);
}}
className="block text-green-800 hover:text-green-900 font-medium py-2 px-3 bg-white rounded-md hover:bg-green-100 transition-colors"
>
Inscription
</Link>
</div>
)}
</div>
)}
{isAuthenticated && ( {isAuthenticated && (
<div className="border-t border-white/20 pt-3 mt-3 space-y-2"> <div className="border-t border-beige-300 pt-3 mt-3 space-y-2">
<Link <Link
href={getDashboardRoute()} href={getDashboardRoute()}
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
<button className="w-full flex flex-col items-center bg-white text-[#1a4d2e] hover:bg-[#f59e0b] hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap"> <button className="w-full flex flex-col items-center bg-white text-primary-700 hover:bg-secondary-400 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap">
<span className="text-sm">{user?.firstName} {user?.lastName}</span> <span className="text-sm">{user?.firstName} {user?.lastName}</span>
<span className="text-xs font-normal opacity-80">{user?.email}</span> <span className="text-xs font-normal opacity-80">{user?.email}</span>
</button> </button>
@ -323,7 +279,7 @@ export default function Header() {
href={ROUTES.PROFILE} href={ROUTES.PROFILE}
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
<button className="w-full flex items-center justify-center gap-2 bg-white text-[#1a4d2e] hover:bg-[#f59e0b] hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap"> <button className="w-full flex items-center justify-center gap-2 bg-white text-primary-700 hover:bg-secondary-400 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap">
Profil Profil
</button> </button>
</Link> </Link>
@ -332,7 +288,7 @@ export default function Header() {
href={ROUTES.HISTORY} href={ROUTES.HISTORY}
onClick={() => setIsMobileMenuOpen(false)} onClick={() => setIsMobileMenuOpen(false)}
> >
<button className="w-full flex items-center justify-center gap-2 bg-white text-[#1a4d2e] hover:bg-[#f59e0b] hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap"> <button className="w-full flex items-center justify-center gap-2 bg-white text-primary-700 hover:bg-secondary-400 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap">
Mes gains Mes gains
</button> </button>
</Link> </Link>
@ -342,7 +298,7 @@ export default function Header() {
logout(); logout();
setIsMobileMenuOpen(false); setIsMobileMenuOpen(false);
}} }}
className="w-full flex items-center justify-center gap-2 bg-white text-[#1a4d2e] hover:bg-red-600 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap" className="w-full flex items-center justify-center gap-2 bg-white text-primary-700 hover:bg-red-600 hover:text-white font-semibold px-4 py-3 rounded-lg transition-all whitespace-nowrap"
> >
Déconnexion Déconnexion
</button> </button>

View File

@ -27,7 +27,7 @@ export const PrizeCard: React.FC<PrizeCardProps> = ({
<div <div
className={cn( className={cn(
'bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow overflow-hidden h-full flex flex-col', 'bg-white rounded-xl shadow-md hover:shadow-xl transition-shadow overflow-hidden h-full flex flex-col',
isGrandPrix ? 'border-2 border-[#d4a574]' : 'border border-[#e5e4dc]', isGrandPrix ? 'border-2 border-primary-500' : 'border border-beige-300',
className className
)} )}
> >
@ -35,8 +35,8 @@ export const PrizeCard: React.FC<PrizeCardProps> = ({
className={cn( className={cn(
'aspect-square flex items-center justify-center p-2', 'aspect-square flex items-center justify-center p-2',
isGrandPrix isGrandPrix
? 'bg-gradient-to-br from-[#d4a574]/10 to-[#c4956a]/10' ? 'bg-gradient-to-br from-primary-50 to-primary-100'
: 'bg-gradient-to-br from-[#faf9f5] to-[#f5f5f0]' : 'bg-gradient-to-br from-beige-50 to-beige-100'
)} )}
> >
<Image <Image
@ -52,14 +52,14 @@ export const PrizeCard: React.FC<PrizeCardProps> = ({
className={cn( className={cn(
'inline-block text-sm font-bold px-3 py-1 rounded-full mb-3', 'inline-block text-sm font-bold px-3 py-1 rounded-full mb-3',
isGrandPrix isGrandPrix
? 'bg-gradient-to-r from-[#d4a574] to-[#c4956a] text-white shadow-md' ? 'bg-gradient-to-r from-primary-500 to-primary-600 text-white shadow-md'
: 'bg-gradient-to-r from-[#d4a574]/20 to-[#c4956a]/20 text-[#c4956a]' : 'bg-gradient-to-r from-primary-100 to-primary-200 text-primary-600'
)} )}
> >
{badge} {badge}
</div> </div>
<h3 className="text-xl font-bold text-[#5a5a4e] mb-2">{title}</h3> <h3 className="text-xl font-bold text-gray-800 mb-2">{title}</h3>
<p className="text-[#8a8a7a] text-sm mb-4">{description}</p> <p className="text-gray-600 text-sm mb-4">{description}</p>
</div> </div>
</div> </div>
); );

View File

@ -7,35 +7,51 @@ module.exports = {
theme: { theme: {
extend: { extend: {
colors: { colors: {
// Palette basée sur #0B6029 (Forest Green) - WCAG AA compliant
primary: { primary: {
50: '#f0fdf4', 50: '#E8F5EC', // Très clair pour backgrounds
100: '#dcfce7', 100: '#C6E7D0', // Clair
200: '#bbf7d0', 200: '#9ED5AF', //
300: '#86efac', 300: '#6FC085', //
400: '#4ade80', 400: '#3FA85B', //
500: '#22c55e', 500: '#0B6029', // Couleur principale (votre couleur)
600: '#16a34a', 600: '#0A5525', // Plus foncé
700: '#15803d', 700: '#084A20', //
800: '#166534', 800: '#063E1A', //
900: '#14532d', 900: '#042E13', // Très foncé
}, },
secondary: { secondary: {
50: '#fef3c7', // Or/Doré complémentaire - contraste 4.5:1+ sur blanc
100: '#fef08a', 50: '#FDF8E8',
200: '#fde047', 100: '#FAF0CC',
300: '#facc15', 200: '#F5E299',
400: '#eab308', 300: '#EFD366',
500: '#ca8a04', 400: '#E8C333',
600: '#a16207', 500: '#A68B2C', // Principal - bon contraste sur blanc
700: '#854d0e', 600: '#8A7324',
800: '#713f12', 700: '#6E5B1C',
900: '#422006', 800: '#524415',
900: '#362D0E',
},
// Beige pour backgrounds - excellent contraste avec primary
beige: {
50: '#FEFDFB',
100: '#FAF8F5', // Background principal
200: '#F5F0E8',
300: '#EBE4D8',
400: '#DED4C4',
500: '#C9BBAA',
600: '#A69882',
700: '#7D705F',
800: '#544B3F',
900: '#2B2620',
}, },
logo: { logo: {
brown: '#694633', brown: '#694633',
gold: '#C1C333', gold: '#C1C333',
lightGold: '#C5C04B', lightGold: '#C5C04B',
darkBrown: '#5a3a29', darkBrown: '#5a3a29',
forestGreen: '#0B6029',
}, },
}, },
fontFamily: { fontFamily: {

View File

@ -187,6 +187,8 @@ export interface AdminStatistics {
users: { users: {
total: number; total: number;
clients: number; clients: number;
activeClients: number;
inactiveClients: number;
employees: number; employees: number;
admins: number; admins: number;
verifiedEmails: number; verifiedEmails: number;

View File

@ -66,7 +66,7 @@ export const PRIZE_CONFIG = {
THE_SIGNATURE: { THE_SIGNATURE: {
name: 'Thé signature 100g', name: 'Thé signature 100g',
description: 'Notre thé signature premium 100g', description: 'Notre thé signature premium 100g',
color: 'bg-green-100 text-green-800', color: 'bg-primary-100 text-primary-800',
icon: '🍵', icon: '🍵',
value: 25, value: 25,
}, },
@ -80,7 +80,7 @@ export const PRIZE_CONFIG = {
COFFRET_PRESTIGE: { COFFRET_PRESTIGE: {
name: 'Coffret prestige 69€', name: 'Coffret prestige 69€',
description: 'Un coffret prestige d\'exception', description: 'Un coffret prestige d\'exception',
color: 'bg-amber-100 text-amber-800', color: 'bg-secondary-200 text-secondary-800',
icon: '🏆', icon: '🏆',
value: 69, value: 69,
}, },
@ -202,7 +202,7 @@ export const TICKET_STATUS_LABELS = {
// Ticket Status Colors // Ticket Status Colors
export const TICKET_STATUS_COLORS = { export const TICKET_STATUS_COLORS = {
PENDING: 'bg-yellow-100 text-yellow-800', PENDING: 'bg-secondary-100 text-secondary-800',
CLAIMED: 'bg-green-100 text-green-800', CLAIMED: 'bg-primary-100 text-primary-800',
REJECTED: 'bg-red-100 text-red-800', REJECTED: 'bg-red-100 text-red-800',
} as const; } as const;

View File

@ -6,10 +6,10 @@
// Status colors for badges and indicators // Status colors for badges and indicators
export const STATUS_COLORS = { export const STATUS_COLORS = {
PENDING: 'bg-yellow-100 text-yellow-800', PENDING: 'bg-secondary-100 text-secondary-800',
CLAIMED: 'bg-green-100 text-green-800', CLAIMED: 'bg-primary-100 text-primary-800',
REJECTED: 'bg-red-100 text-red-800', REJECTED: 'bg-red-100 text-red-800',
ACTIVE: 'bg-green-100 text-green-800', ACTIVE: 'bg-primary-100 text-primary-800',
INACTIVE: 'bg-gray-100 text-gray-800', INACTIVE: 'bg-gray-100 text-gray-800',
EXPIRED: 'bg-red-100 text-red-800', EXPIRED: 'bg-red-100 text-red-800',
} as const; } as const;
@ -17,23 +17,23 @@ export const STATUS_COLORS = {
// Badge color variants // Badge color variants
export const BADGE_COLORS = { export const BADGE_COLORS = {
info: 'bg-blue-100 text-blue-800', info: 'bg-blue-100 text-blue-800',
success: 'bg-green-100 text-green-800', success: 'bg-primary-100 text-primary-800',
warning: 'bg-yellow-100 text-yellow-800', warning: 'bg-secondary-100 text-secondary-800',
error: 'bg-red-100 text-red-800', error: 'bg-red-100 text-red-800',
purple: 'bg-purple-100 text-purple-800', purple: 'bg-purple-100 text-purple-800',
pink: 'bg-pink-100 text-pink-800', pink: 'bg-pink-100 text-pink-800',
amber: 'bg-amber-100 text-amber-800', amber: 'bg-secondary-200 text-secondary-800',
gray: 'bg-gray-100 text-gray-800', gray: 'bg-gray-100 text-gray-800',
} as const; } as const;
// Button style variants // Button style variants
export const BUTTON_STYLES = { export const BUTTON_STYLES = {
primary: 'bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition-all duration-300', primary: 'bg-primary-500 text-white px-6 py-2 rounded-lg hover:bg-primary-600 transition-all duration-300',
secondary: 'bg-gray-600 text-white px-6 py-2 rounded-lg hover:bg-gray-700 transition-all duration-300', secondary: 'bg-secondary-500 text-white px-6 py-2 rounded-lg hover:bg-secondary-600 transition-all duration-300',
success: 'bg-green-600 text-white px-6 py-2 rounded-lg hover:bg-green-700 transition-all duration-300', success: 'bg-primary-500 text-white px-6 py-2 rounded-lg hover:bg-primary-600 transition-all duration-300',
danger: 'bg-red-600 text-white px-6 py-2 rounded-lg hover:bg-red-700 transition-all duration-300', danger: 'bg-red-600 text-white px-6 py-2 rounded-lg hover:bg-red-700 transition-all duration-300',
warning: 'bg-yellow-600 text-white px-6 py-2 rounded-lg hover:bg-yellow-700 transition-all duration-300', warning: 'bg-secondary-400 text-white px-6 py-2 rounded-lg hover:bg-secondary-500 transition-all duration-300',
outline: 'border border-blue-600 text-blue-600 px-6 py-2 rounded-lg hover:bg-blue-50 transition-all duration-300', outline: 'border border-primary-500 text-primary-500 px-6 py-2 rounded-lg hover:bg-primary-50 transition-all duration-300',
ghost: 'text-gray-600 px-6 py-2 rounded-lg hover:bg-gray-100 transition-all duration-300', ghost: 'text-gray-600 px-6 py-2 rounded-lg hover:bg-gray-100 transition-all duration-300',
} as const; } as const;
@ -79,7 +79,7 @@ export function getInputStyle(hasError: boolean): string {
export const ROLE_COLORS = { export const ROLE_COLORS = {
ADMIN: 'bg-red-100 text-red-800', ADMIN: 'bg-red-100 text-red-800',
EMPLOYEE: 'bg-blue-100 text-blue-800', EMPLOYEE: 'bg-blue-100 text-blue-800',
CLIENT: 'bg-green-100 text-green-800', CLIENT: 'bg-primary-100 text-primary-800',
} as const; } as const;
export function getRoleColor(role: string): string { export function getRoleColor(role: string): string {
@ -90,9 +90,9 @@ export function getRoleColor(role: string): string {
// Prize type colors (from constants.ts PRIZE_CONFIG) // Prize type colors (from constants.ts PRIZE_CONFIG)
export const PRIZE_COLORS = { export const PRIZE_COLORS = {
INFUSEUR: 'bg-blue-100 text-blue-800', INFUSEUR: 'bg-blue-100 text-blue-800',
THE_SIGNATURE: 'bg-green-100 text-green-800', THE_SIGNATURE: 'bg-primary-100 text-primary-800',
COFFRET_DECOUVERTE: 'bg-purple-100 text-purple-800', COFFRET_DECOUVERTE: 'bg-purple-100 text-purple-800',
COFFRET_PRESTIGE: 'bg-amber-100 text-amber-800', COFFRET_PRESTIGE: 'bg-secondary-200 text-secondary-800',
THE_GRATUIT: 'bg-pink-100 text-pink-800', THE_GRATUIT: 'bg-pink-100 text-pink-800',
} as const; } as const;