// sections.jsx — Mission, Features, Journey, Destinations, Operators, Vision const { useState: sUseState, useEffect: sUseEffect, useRef: sUseRef } = React; // ---------- PHONE MOCKUP ---------- function PhoneMockup({ children, style = {}, rotate = 0 }) { return (
{children}
); } function PhoneSearchScreen() { const stories = [ { label: "Réduction", grad: "linear-gradient(135deg, #fca5a5, #dc2626)", icon: "🎁" }, { label: "Nouveautés", grad: "linear-gradient(135deg, #fcd34d, #f59e0b)", icon: "✨" }, { label: "Destinations", grad: "linear-gradient(135deg, #93c5fd, #2563eb)", icon: "🌍" }, { label: "Annonces", grad: "linear-gradient(135deg, #fda4af, #e11d48)", icon: "📣" }, ]; return (
{/* Status bar */}
09:41
{/* Top bar: search + icons */}
5
{/* Stories */}
{stories.map((s, i) => (
{s.icon}
{s.label}
))}
{/* Greeting */}
N
Bonjour NAPON YAHASINE 👋
Réservez votre prochain voyage
{/* Search card */}
Recherche rapide
Compagnies
{/* Tabs */}
Aller simple
Aller-retour
{/* Fields */} {[ { label: "D'où partez-vous ?", value: "Choisir la ville de départ", c: "#f59e0b", muted: true }, { label: "Où allez-vous ?", value: "Choisir la ville d'arrivée", c: "#16a34a", muted: true }, ].map((r, i) => (
{r.label}
{r.value}
))}
Quand partez-vous ?
jj/mm/aaaa
📅
Combien de passagers ?
1 passager
Rechercher des trajets
ⓘ Besoin d'aide pour réserver ?
{/* Bottom nav */}
); } function PhoneBottomNav({ active = "home" }) { const items = [ { id: "home", label: "Accueil", icon: (c) => }, { id: "gps", label: "GPS", icon: (c) => }, { id: "fab" }, { id: "support", label: "Support", icon: (c) => }, { id: "profile", label: "Profil", icon: (c) => }, ]; return (
{items.map((it, i) => { if (it.id === "fab") { return (
); } const color = active === it.id ? "#dc2626" : "#9ca3af"; return (
{it.icon(color)} {it.label}
); })}
); } function PhoneSeatScreen() { // Grid: columns A B | aisle | C D, rows 1..11 const cols = ["A", "B", "C", "D"]; const rows = 11; const unavailable = new Set(["B2", "C1", "D3", "A7", "D6"]); const selected = new Set(["B5"]); const reserving = new Set(["C7"]); return (
{/* Status bar */}
09:41
{/* Progress header: Étape 2 sur 4 */}
Étape 2 sur 4 Choisir la place
{/* Tricolor progress */}
{/* Tricolor banner */}
Retour aux trajets
Choisissez votre place
Ouagadougou → Bobo-Dioulasso
{/* Seat grid card */}
{/* Column labels with aisle */}
{cols.slice(0,2).map(c =>
{c}
)}
{cols.slice(2).map(c =>
{c}
)}
{Array.from({ length: rows }).map((_, rIdx) => { const r = rIdx + 1; return (
{[0,1,-1,2,3].map((colIdx, i) => { if (colIdx === -1) return
; const seat = `${cols[colIdx]}${r}`; const isUnavail = unavailable.has(seat); const isSel = selected.has(seat); const isRes = reserving.has(seat); let bg = "#fff", color = "#374151", border = "1px solid #d1d5db"; if (isUnavail) { bg = "#f3f4f6"; color = "#d1d5db"; border = "1px solid #e5e7eb"; } if (isSel) { bg = "#16a34a"; color = "#fff"; border = "1px solid #16a34a"; } if (isRes) { bg = "#fef3c7"; color = "#d97706"; border = "1px solid #fde68a"; } return (
{seat}
); })}
); })}
{/* Legend */}
Légende :
Disponible
Sélectionné
Occupé
En réservation
{/* Continuer CTA fixed above bottom nav */}
Continuer vers le paiement
); } function PhoneTicketScreen() { return (
VOTRE BILLET
De
Ouaga
À
Bobo
Date
26 avril
Départ
14:30
Siège
5, 8
{/* Fake QR */}
{Array.from({ length: 64 }).map((_, i) => { const x = i % 8, y = Math.floor(i / 8); const filled = (i * 37 + 13) % 3 !== 0 || (x === 0 && y === 0) || (x === 7 && y === 0) || (x === 0 && y === 7); return filled ? : null; })}
Aïcha Sawadogo
FT-2604-A8B9C2
✓ Confirmé
Disponible hors-ligne · PDF · SMS
); } // ---------- My Tickets list screen ---------- function PhoneTicketsListScreen() { const tickets = [ { co: "STAF", code: "ST7H851940", from: "Ouagadougou", to: "Bobo-Dioulasso", dep: "07:05", arr: "13:05", date: "05/12/2025", seat: "A12", status: "Actif" }, { co: "Rakiéta", code: "RK9K1234AB", from: "Ouagadougou", to: "Bobo-Dioulasso", dep: "09:05", arr: "14:55", date: "02/12/2025", seat: "B05", status: "Embarqué" }, { co: "TSR Voyages", code: "TS5M5432EF", from: "Ouagadougou", to: "Koudougou", dep: "15:30", arr: "17:10", date: "15/11/2025", seat: "D10", status: "Actif" }, ]; const statusColor = (s) => s === "Actif" ? { bg: "#dcfce7", fg: "#15803d" } : s === "Embarqué" ? { bg: "#dbeafe", fg: "#1d4ed8" } : { bg: "#f3f4f6", fg: "#6b7280" }; return (
{/* Status bar */}
09:41
{/* Header tricolor banner */}
Mes billets
{/* Search */}
Rechercher par compagnie...
{/* Data sync card */}
Données
Source : en ligne
Dernière sync : 23/04/2026 23:17
Synchroniser
{/* Tabs */}
{[ { l: "Actifs (2)", active: true }, { l: "Embarqués (1)" }, { l: "Annulés (1)" }, { l: "Expirés (10)" }, ].map((t, i) => (
{t.l}
))}
{/* Tickets list */}
{tickets.map((tk, i) => { const sc = statusColor(tk.status); return (
🚌
{tk.co}
{tk.code}
{tk.status}
{tk.dep}
{tk.from}
{tk.arr}
{tk.to}
🗓 {tk.date} Siège {tk.seat}
); })}
); } Object.assign(window, { PhoneTicketsListScreen }); // ---------- DIORAMA 3D — scène de voyage immersive ---------- function Diorama3D() { const y = sUseState ? 0 : 0; const scrollY = useScrollY(); // Parallax per layer return (
{/* Sky gradient with late-afternoon atmosphere */}
{/* Sun disk */}
{/* Heat shimmer horizon */}
{/* Distant mountains (far plane) */} {/* Mid hills */} {/* Baobabs mid-ground */}
{[ { left: "8%", scale: .6, z: -1 }, { left: "18%", scale: .4, z: -1.5 }, { left: "78%", scale: .55, z: -1 }, { left: "88%", scale: .45, z: -1.3 }, ].map((b, i) => ( ))}
{/* Road stretching to vanishing point */}
{/* Aerial route line (replaces bus) — premium, sobre */} {/* Glow underneath */} {/* Crisp route line */} {/* Origin & destination pins */} {/* Travelling light bead */} {/* Route tag overlays */}
OUAGADOUGOU · 14:30
BOBO-DIOULASSO · 19:45
365 KM · CLIMATISÉ · WIFI · PREMIUM
{/* Subtle grain */}
); } // ---------- MISSION ---------- function Mission({ t }) { return (
{t.mission.eyebrow}

{t.mission.title}

{t.mission.problem}

→ {t.mission.solution}

{t.mission.solutionText}

{t.mission.badges.map((b, i) => ( {b} ))}
{/* Photo réelle d'un intérieur de car premium — incarne directement l'expérience de voyage. Plus parlante qu'un diorama illustratif. */}
Intérieur d'un car premium FasoTravel
Le confort à bord Sièges premium · Climatisation · WiFi · Espace
); } // ---------- FEATURES ---------- // La section porte la démo interactive principale : la vraie app FasoTravel // embarquée dans un cadre téléphone, entourée de cartes "features" qui // expliquent ce que l'utilisateur peut faire dans l'app. // Plus de PhoneMockup illustratif (cyclage faux écrans SVG) — remplacé par // MobileDemoFrame (iframe vers mobile-demo/?demo=1). function Features({ t, onNotify }) { const lang = (window.FT_T === window.FT_I18N?.fr) ? "fr" : "en"; return (
{t.features.eyebrow}

{t.features.title}

{lang === "fr" ? "Cliquez à l'intérieur du téléphone — c'est l'application réelle, en mode démo. Vous pouvez réellement réserver un billet." : "Tap inside the phone — it's the actual app in demo mode. You can really book a ticket."}

{/* Left features (3 premières) */}
{t.features.list.slice(0, 3).map((f, i) => (
0{i+1}

{f.t}

{f.d}

))}
{/* Démo iframe au centre — la vraie app Mobile */}
{/* Right features (3 suivantes) */}
{t.features.list.slice(3).map((f, i) => (
0{i+4}

{f.t}

{f.d}

))}
); } // ---------- JOURNEY ---------- function Journey({ t }) { return (
{t.journey.eyebrow}

{t.journey.title}

{t.journey.steps.map((s, i) => (
{s.n}

{s.t}

{s.d}

))}
); } Object.assign(window, { PhoneMockup, PhoneSearchScreen, PhoneSeatScreen, PhoneTicketScreen, Mission, Features, Journey, Diorama3D });