From f415f9cc48ec764601777fd2939d1fb6049dd395 Mon Sep 17 00:00:00 2001 From: Titoune09 Date: Fri, 24 Apr 2026 12:51:00 +0200 Subject: [PATCH 1/2] Refonte landing page en vitrine agence de voyage --- src/App.tsx | 441 ++++++++++++++++++++++------------------------------ 1 file changed, 182 insertions(+), 259 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 1bf0ed7..382b7c2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,305 +1,228 @@ -import { useMemo, useState } from 'react'; -import { AnimatePresence, motion } from 'framer-motion'; +import { motion } from 'framer-motion'; -const missions = [ - "Transforme ton cahier en magazine spatial en n'utilisant que ce qu'il y a dans ta trousse.", - 'Compose un haïku dramatique sur la leçon actuelle en trois emojis mentaux.', - 'Crée une mini bande-annonce dans ta tête pour un film inspiré de ce chapitre.', - 'Imagine une version rétro-futuriste de la classe et note trois éléments déco.', - 'Conçois un signal secret pour prévenir un camarade qu\'il est temps de sourire.', - 'Dresse l\'inventaire de ton sac comme si tu étais un explorateur temporel.', - 'Réécris la consigne entendue comme un slogan publicitaire mystérieux.', -]; - -const ambiances = [ - 'Ambiance agent secret feutré : tout bruit devient un indice sonore.', - 'Ambiance studio de création : chaque objet est un prototype en devenir.', - 'Ambiance capsule temporelle : tu rédiges pour le toi du futur.', - 'Ambiance festival minimaliste : les lumières néon sont imaginaires mais intenses.', - 'Ambiance café littéraire : les chuchotements deviennent des dialogues stylés.', -]; +type Destination = { + name: string; + vibe: string; + price: string; + image: string; +}; -const twists = [ - 'Ajoute une contrainte couleur (uniquement des tons glaciaux ou solaires).', - 'Insère un symbole secret qui n\'a de sens que pour toi.', - 'Tout doit pouvoir être raconté en trente secondes chrono.', - 'Imagine que tu dois présenter le résultat à un extraterrestre courtois.', - 'Inclue une référence subtile à ta chanson favorite du moment.', -]; +type Offer = { + title: string; + description: string; + badge: string; +}; -const microQuests = [ +const destinations: Destination[] = [ { - title: 'Flash-croquis', - duration: '2 min', - description: - 'Croque en cinq traits maximum ce qui se passe devant toi comme si c\'était une scène de théâtre.', + name: 'Bali, Indonésie', + vibe: 'Temples, jungle et hôtels intimistes', + price: 'Dès 1 490€', + image: + 'https://images.unsplash.com/photo-1537953773345-d172ccf13cf1?auto=format&fit=crop&w=1200&q=80', }, { - title: 'Cartographie secrète', - duration: '3 min', - description: 'Dessine un mini-plan de la classe et invente un surnom pour trois endroits.', + name: 'Kyoto, Japon', + vibe: 'Culture, ryokans et cerisiers en fleurs', + price: 'Dès 1 980€', + image: + 'https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e?auto=format&fit=crop&w=1200&q=80', }, { - title: 'Playlist silencieuse', - duration: '1 min', - description: 'Choisis la musique imaginaire parfaite pour le moment et écris-en trois adjectifs.', + name: 'Marrakech, Maroc', + vibe: 'Riad premium, désert et artisanat local', + price: 'Dès 890€', + image: + 'https://images.unsplash.com/photo-1597212618440-806262de4f6d?auto=format&fit=crop&w=1200&q=80', }, { - title: 'Emoji météo', - duration: '30 s', - description: 'Décris l\'ambiance générale avec deux emojis météo que tu garderais en mémoire.', - }, - { - title: 'Selfie mental', - duration: '2 min', - description: 'Imagine un selfie cinématique de toi ici et décris le décor en une phrase.', + name: 'Reykjavik, Islande', + vibe: 'Aurores boréales et roadtrip volcanique', + price: 'Dès 1 650€', + image: + 'https://images.unsplash.com/photo-1504893524553-b855bce32c67?auto=format&fit=crop&w=1200&q=80', }, ]; -const timeline = [ +const offers: Offer[] = [ + { + title: 'Voyage sur-mesure', + description: 'Itinéraire conçu selon vos envies, votre rythme et votre budget. Pas de package générique.', + badge: 'Signature', + }, { - label: 'Calibration', - detail: 'Observe la salle comme si tu faisais un repérage de scène.', - length: '1 min', + title: 'Lune de miel', + description: 'Expériences exclusives, hôtels d’exception et moments privés pensés pour marquer votre histoire.', + badge: 'Romance', }, { - label: 'Mission', - detail: 'Lance ton mix et note les premières idées qui débordent.', - length: '4 min', + title: 'Family first', + description: 'Programmes adaptés aux enfants, transferts fluides et activités qui plaisent à toute la famille.', + badge: 'Famille', }, { - label: 'Finition', - detail: 'Peaufine un détail qui fera sourire ton toi du futur.', - length: '3 min', + title: 'Évasion express', + description: 'City-break ou long week-end premium prêt à partir en quelques jours.', + badge: 'Last minute', }, ]; -type MissionMix = { - mission: string; - ambiance: string; - twist: string; -}; - -function pickAnother(items: T[], previous?: T) { - if (items.length === 1) return items[0]; - let candidate = items[Math.floor(Math.random() * items.length)]; - while (candidate === previous) { - candidate = items[Math.floor(Math.random() * items.length)]; - } - return candidate; -} +const stats = [ + { value: '12 000+', label: 'voyageurs accompagnés' }, + { value: '48', label: 'pays partenaires' }, + { value: '4.9/5', label: 'note moyenne clients' }, +]; -function createMix(previous?: MissionMix): MissionMix { - return { - mission: pickAnother(missions, previous?.mission), - ambiance: pickAnother(ambiances, previous?.ambiance), - twist: pickAnother(twists, previous?.twist), - }; -} +const steps = [ + { + title: 'Brief découverte', + text: 'On échange 20 minutes pour comprendre votre style de voyage et vos priorités.', + }, + { + title: 'Création de l’itinéraire', + text: 'Vous recevez une proposition élégante, claire et personnalisée.', + }, + { + title: 'Départ serein', + text: 'Documents, assistance et suivi en direct avant et pendant le séjour.', + }, +]; export default function App() { - const [mix, setMix] = useState(() => createMix()); - const [stepIndex, setStepIndex] = useState(0); - - const vibeCards = useMemo(() => microQuests.concat(microQuests.slice(0, 2)), []); - - const progress = ((stepIndex + 1) / timeline.length) * 100; - return (
-
-
-
+
+
-
-
-

Mode incognito

-

- Kit anti-ennui ultra discret pour transformer la classe en studio créatif. -

-

- Pas de jeux, pas besoin de bouger de ta chaise : juste des micro missions stylées à déclencher du bout des doigts. Mobile - first, iPad ready, imagination maximale. -

-
- -
-
-
-
-

Mix instantané

-

Ton brief secret

-
- setMix((previous) => createMix(previous))} - className="rounded-full bg-accent px-5 py-3 text-sm font-semibold text-night shadow-halo transition focus:outline-none focus:ring focus:ring-accent/40" - > - Remix éclair - +
+
+

Aetheria Travel

+

Agence de voyage premium

+
+ + Demander un devis + +
+ +
+
+ + + Voyagez mieux + +

+ Votre prochain voyage commence ici. +

+

+ Des séjours sur-mesure, visuellement inspirants et parfaitement organisés. Vous profitez, on gère le reste. +

+ +
    + {stats.map((item) => ( +
  • +
    {item.value}
    +

    {item.label}

    +
  • + ))} +
+
+ + + Voyage premium au bord de la mer + +
-
- - - Mission : {mix.mission} - - - - - Ambiance : {mix.ambiance} - - - - - Twist : {mix.twist} - - -
+
+
+

Des offres pensées pour chaque style

+

Simple, clair, haut de gamme. Toujours personnalisé.

- -
-
-
-

Timeline

-

Sprint créatif de 8 minutes

-
-
-

Étape {stepIndex + 1}

-

{timeline[stepIndex].length}

-
-
-
- -
-
- - -

{timeline[stepIndex].length}

-

{timeline[stepIndex].label}

-

{timeline[stepIndex].detail}

-
-
-
-
- setStepIndex((index) => (index - 1 + timeline.length) % timeline.length)} - className="w-full rounded-full border border-white/20 px-4 py-3 text-sm font-semibold text-chrome/80 transition hover:border-white/40 focus:outline-none focus:ring focus:ring-ember/30 sm:w-auto" - > - Étape précédente - - setStepIndex((index) => (index + 1) % timeline.length)} - className="w-full rounded-full bg-ember px-4 py-3 text-sm font-semibold text-night transition focus:outline-none focus:ring focus:ring-ember/30 sm:w-auto" - > - Prochaine étincelle - -
+
+ {offers.map((offer) => ( +
+ {offer.badge} +

{offer.title}

+

{offer.description}

+
+ ))}
-
-
-
-

Micro-quêtes

-

Scroll discret, idées XL

-
- Glisse latéralement ➜ +
+
+

Destinations qui donnent envie de partir

-
-
- {vibeCards.map((quest, index) => ( - -
- {quest.duration} - #{index + 1} -
-

{quest.title}

-

{quest.description}

-
- ))} -
+
+ {destinations.map((destination) => ( +
+ {destination.name} +
+

{destination.name}

+

{destination.vibe}

+

{destination.price}

+
+
+ ))}
-
-
-

Garde-fous

-

Règles d\'ultra discrétion

-
    -
  • • Tout reste silencieux : c\'est ton cinéma intérieur.
  • -
  • • Un carnet ou l\'app Notes suffit comme plateau de tournage.
  • -
  • • Chrono souple : tu peux couper ou relancer le mix quand tu veux.
  • -
  • • Bonus : partage la mission finale uniquement avec quelqu\'un qui saura apprécier.
  • -
-
- -
-

Upgrade

-

Si la séance dure plus longtemps

-
    -
  • • Assemble plusieurs missions pour créer un mini magazine clandestin.
  • -
  • • Écris une lettre à toi-même de demain en relatant ta meilleure trouvaille.
  • -
  • • Crée un classement des objets les plus dramatiques de la classe.
  • -
  • • Imagine une affiche de film inspirée du prof du jour (attention : respect total !).
  • -
+
+

Votre voyage en 3 étapes fluides

+
+ {steps.map((step, index) => ( +
+

Étape {index + 1}

+

{step.title}

+

{step.text}

+
+ ))}
-
-

- Glisse, griffonne, respire : c\'est ton laboratoire secret pour survivre aux heures longues. -

-

- Optimisé pour iPad et smartphones : tout se joue à un doigt, sans jamais attirer l\'attention. Quand tu veux revenir au - monde réel, il suffit de fermer l\'onglet. +

+

Parlons de votre prochain départ

+

+ Dites-nous vos envies (dates, budget, style), notre équipe vous répond avec une proposition personnalisée sous 24h.

-
-
+
+ + +