import React, { useState, useEffect, useRef } from 'react' import { Link } from 'react-router-dom' import { Sparkles, Bot, Shield, Zap, ArrowRight, Check, MessageSquare, Upload, Play, ChevronRight, Star, Cpu, Menu, X, Users, CalendarDays, Megaphone, TrendingUp, Inbox, } from 'lucide-react' // ─── Translations ────────────────────────────────────────────────────────────── const TRANSLATIONS = { fr: { nav: { marketplace: 'Marché', pricing: 'Tarifs', features: 'Fonctionnalités', signin: 'Connexion', cta: 'Commencer gratuitement', }, hero: { badge: "La plateforme IA qui gère vos interactions clients", h1a: 'Une plateforme pour chatter, réserver,', h1b: 'et conclure des ventes', p: "Créez des chatbots RAG à partir de vos documents. Ajoutez le chat en direct, la capture de leads, la prise de rendez-vous et les campagnes Telegram — tout en un seul endroit.", cta1: 'Commencer gratuitement', cta2: 'Explorer le marché', sub: 'Sans carte bancaire · Gratuit pour toujours · Installation en 2 min', badge1: 'Lead Capturé', badge2: 'Rendez-vous Confirmé', }, stats: { chatbots: 'Chatbots Créés', companies: 'Entreprises', messages: 'Messages Traités', uptime: 'Disponibilité', }, features: { badge: 'Fonctionnalités', h2: 'Tout pour gérer vos relations clients', p: "Du chatbot IA à l'agent en direct, pipeline de leads, rendez-vous et campagnes — une plateforme, zéro intégration.", items: [ { title: 'Chatbots RAG', desc: 'Importez des PDF, DOCX et CSV. Votre chatbot répond à partir de votre contenu avec des sources citées.' }, { title: 'Boîte de réception en direct', desc: "Prenez en charge n'importe quelle conversation en temps réel. Répondez en tant qu'agent et suivez chaque interaction." }, { title: 'CRM de leads', desc: "Le chatbot capture les leads automatiquement. Gérez le pipeline : Nouveau → Contacté → Qualifié → Conclu." }, { title: 'Prise de rendez-vous', desc: "Définissez vos horaires et durées de créneaux. Le bot partage un lien de réservation et les clients choisissent en ligne." }, { title: 'Campagnes Telegram', desc: "Diffusez des messages ciblés à tous vos abonnés Telegram en un clic. Suivez les taux de livraison." }, { title: 'Analyse des lacunes', desc: "Voyez quelles questions le bot n'a pas su répondre. Ajoutez le contenu manquant et comblezles lacunes rapidement." }, ], }, howItWorks: { badge: 'Comment ça marche', h2: 'Des documents à une suite métier complète', steps: [ { title: 'Importer & Entraîner', desc: 'Déposez vos PDF, DOCX, CSV ou Excel. Le moteur RAG indexe votre contenu et votre chatbot est prêt en quelques minutes.' }, { title: 'Déployer & Capturer', desc: 'Publiez sur votre site web ou Telegram. Le bot gère les conversations, capture les leads et partage votre lien de réservation automatiquement.' }, { title: 'Gérer & Croître', desc: "Rejoignez les conversations en direct, travaillez votre pipeline de leads, confirmez les rendez-vous et diffusez des campagnes — depuis une seule boîte de réception." }, ], }, widget: { badge: 'Fonctionnalité Agence', h2: 'Une ligne de code.\nVotre chatbot, partout.', p: "Collez un simple script et votre chatbot est en ligne — sur n'importe quel site, n'importe quel framework. Aucune dépendance, aucune étape de build. Compatible WordPress, Webflow, Shopify, HTML brut, et plus.", bullets: [ "Intégrez dans n'importe quelle page HTML — aucun framework requis", "Le widget se charge de façon asynchrone, zéro impact sur la vitesse", "Stylé pour correspondre à votre marque", "L'ID du chatbot garde vos données complètement isolées", ], status: 'Widget chargé · 0 dépendances', }, workflow: { badge: 'Suite Complète', h2: 'Tout en un seul endroit — fini les outils éparpillés', p: "La plupart des entreprises utilisent un chatbot, un CRM, un outil de réservation et une app de diffusion séparément. Contexta remplace les quatre — construit autour de votre chatbot IA.", bullets: [ "Prenez en charge n'importe quelle conversation en tant qu'agent", 'Faites avancer les leads dans votre pipeline en un clic', 'Les clients réservent des créneaux directement depuis le chat', 'Diffusez à tous vos abonnés Telegram en une fois', ], inbox: { title: 'Boîte de réception', badge: "Agent en charge", msg: '"Bonjour, j\'ai besoin d\'aide avec ma commande #4821..."' }, leads: { title: 'Pipeline Leads', statuses: ['Nouveau', 'Contacté', 'Qualifié', 'Conclu'] }, booking: { title: 'Nouveau Rendez-vous', badge: 'Confirmé', detail: 'Alice Martin · Jeu 12 Juin · 10h00' }, campaign: { title: "Campagne Soldes d'Été", badge: 'Envoyé', detail: '482 / 500 livrés · Telegram' }, }, testimonials: { badge: 'Témoignages', h2: 'Aimé par les entreprises', items: [ { quote: "Notre chatbot prend désormais des rendez-vous directement depuis les conversations. Les clients choisissent un créneau et nous recevons une notification — plus d'emails aller-retour.", name: 'Sarah Chen', role: 'Propriétaire', company: 'Chen Physio Clinic' }, { quote: "La boîte de réception en direct change tout. On laisse l'IA gérer 80% des questions et on intervient seulement quand c'est nécessaire. Notre temps de réponse a été divisé par deux.", name: 'Marcus Johnson', role: 'Responsable Support', company: 'MedAssist' }, { quote: "Nous envoyons des campagnes Telegram à nos abonnés chaque semaine. Contexta a remplacé trois outils séparés — chatbot, CRM et diffusion — à une fraction du coût.", name: 'Elena Kowalski', role: 'Responsable Marketing', company: 'DataBridge' }, ], }, pricing: { h2: 'Gratuit pour démarrer, évoluez à votre rythme', p: "Chaque plan inclut le créateur de chatbots. Débloquez le chat en direct, la réservation et les campagnes quand vous êtes prêt.", seeAll: 'Voir la comparaison complète', plans: { free: { name: 'Gratuit', features: ['1 chatbot publié', 'Modèle Llama 3.3 70B', '100 conversations/mois', 'Boîte de réception lecture seule', 'Leads en lecture seule'], cta: 'Commencer' }, starter: { name: 'Starter', features: ['3 chatbots publiés', 'Tous les modèles Fireworks AI', '1 500 conversations/mois', 'Chat en direct + réponses agent', 'CRM complet', 'Rendez-vous (1 chatbot)', '3 campagnes/mois · 500 destinataires', 'Canal Telegram'], cta: 'Démarrer Starter' }, business: { name: 'Business', popular: 'Populaire', features: ['10 chatbots publiés', 'GPT-4o · Claude · Gemini', '5 000 conversations/mois', 'Réservations illimitées', 'Campagnes illimitées · 5k destinataires', 'Analyse des lacunes', 'Supprimer le badge "Propulsé par"'], cta: 'Démarrer Business' }, agency: { name: 'Agence', features: ['Chatbots illimités', 'Tous les modèles', '20 000 conversations/mois', 'Destinataires illimités', 'Export de code', 'Prêt pour le white-label'], cta: 'Démarrer Agence' }, }, }, cta: { h2: 'Votre suite IA, prête en quelques minutes', p: "Des centaines d'entreprises utilisent Contexta pour automatiser le chat, capturer des leads, réserver des rendez-vous et lancer des campagnes.", cta1: 'Commencer gratuitement', cta2: 'Explorer le marché', }, footer: { copyright: '© 2025 Contexta. Fait avec ❤️ pour les créateurs.' }, chat: [ { role: 'user', text: 'Quelle est votre politique de retour ?' }, { role: 'bot', text: "D'après vos documents, nous offrons une politique de retour de 30 jours pour tous les articles en état d'origine. Les remboursements sont traités sous 5 à 7 jours ouvrables." }, { role: 'user', text: 'Puis-je retourner des articles soldés ?' }, { role: 'bot', text: "Selon la section 4.2 de votre politique, les articles soldés peuvent être échangés sous 14 jours mais ne sont pas éligibles au remboursement. Souhaitez-vous en savoir plus ?" }, ], chatLabel: 'Support Bot', chatOnline: 'En ligne', chatPlaceholder: 'Écrire un message...', }, en: { nav: { marketplace: 'Marketplace', pricing: 'Pricing', features: 'Features', signin: 'Sign in', cta: 'Get started free', }, hero: { badge: 'The AI platform that runs your customer interactions', h1a: 'One platform to chat, book,', h1b: 'and close deals', p: 'Build RAG-powered chatbots from your documents. Then add live chat, lead capture, appointment booking, and Telegram campaigns — all in one place.', cta1: 'Start for free', cta2: 'Explore marketplace', sub: 'No credit card required · Free forever · 2min setup', badge1: 'Lead Captured', badge2: 'Booking Confirmed', }, stats: { chatbots: 'Chatbots Created', companies: 'Companies', messages: 'Messages Processed', uptime: 'Uptime', }, features: { badge: 'Features', h2: 'Everything to run your customer relationships', p: 'From AI chatbot to live agent, lead pipeline, appointments, and broadcast campaigns — one platform, zero integrations.', items: [ { title: 'RAG-Powered Chatbots', desc: 'Upload PDFs, DOCX, and CSV files. Your chatbot answers from your actual content with source citations.' }, { title: 'Live Chat Inbox', desc: 'Take over any conversation in real time. Reply as an agent, resolve tickets, and track every interaction.' }, { title: 'Lead CRM', desc: 'Chatbot captures leads automatically. You manage the pipeline: New → Contacted → Qualified → Closed.' }, { title: 'Appointment Booking', desc: 'Set business hours and slot durations. The bot shares a booking link and customers pick a slot online.' }, { title: 'Telegram Campaigns', desc: 'Broadcast targeted messages to all your Telegram subscribers in one click. Track delivery counts.' }, { title: 'Knowledge Gap Insights', desc: "See which questions your bot couldn't answer. Add the missing content and close the gaps fast." }, ], }, howItWorks: { badge: 'How It Works', h2: 'From documents to full business suite', steps: [ { title: 'Upload & Train', desc: 'Drop your PDFs, DOCX, CSV, or Excel files. The RAG engine indexes your content and your chatbot is ready in minutes.' }, { title: 'Deploy & Capture', desc: 'Publish to your website or Telegram. The bot handles conversations, captures leads, and shares your booking link automatically.' }, { title: 'Manage & Grow', desc: 'Jump into live conversations, work your lead pipeline, confirm appointments, and broadcast campaigns — all from one inbox.' }, ], }, widget: { badge: 'Agency Feature', h2: 'One line of code.\nYour chatbot, anywhere.', p: 'Paste a single script tag and your chatbot is live — on any website, any framework. No dependencies, no build step. Works with WordPress, Webflow, Shopify, raw HTML, anything.', bullets: [ 'Drop it into any HTML page — no framework needed', 'Widget loads asynchronously, zero impact on page speed', 'Styled to match your brand out of the box', 'Chatbot ID keeps your data completely isolated', ], status: 'Chatbot widget loaded · 0 dependencies', }, workflow: { badge: 'Full Business Suite', h2: 'Everything in one place — no juggling tools', p: 'Most businesses use a chatbot, a CRM, a booking tool, and a broadcast app separately. Contexta replaces all four — built around your AI chatbot so everything stays connected.', bullets: [ 'Take over any conversation as a live agent', 'Move leads through your pipeline with one click', 'Customers book slots directly from chat', 'Broadcast to all Telegram subscribers at once', ], inbox: { title: 'Live Inbox', badge: 'Agent handling', msg: '"Hi, I need help with my order #4821..."' }, leads: { title: 'Lead Pipeline', statuses: ['New', 'Contacted', 'Qualified', 'Closed'] }, booking: { title: 'New Booking', badge: 'Confirmed', detail: 'Alice Martin · Thu Jun 12 · 10:00 AM' }, campaign: { title: 'Summer Sale Campaign', badge: 'Sent', detail: '482 / 500 delivered · Telegram' }, }, testimonials: { badge: 'Testimonials', h2: 'Loved by businesses', items: [ { quote: 'Our chatbot now books appointments directly from conversations. Clients pick a slot and we get a notification — no back-and-forth emails anymore.', name: 'Sarah Chen', role: 'Owner', company: 'Chen Physio Clinic' }, { quote: 'The live inbox is a game changer. We let the AI handle 80% of questions and jump in only when it matters. Our response time dropped by half.', name: 'Marcus Johnson', role: 'Head of Support', company: 'MedAssist' }, { quote: 'We run Telegram campaigns to our subscribers every week. Contexta replaced three separate tools — chatbot, CRM, and broadcast — at a fraction of the cost.', name: 'Elena Kowalski', role: 'Marketing Lead', company: 'DataBridge' }, ], }, pricing: { h2: 'Start free, scale as you grow', p: "Every plan includes the chatbot builder. Unlock live chat, booking, and campaigns when you're ready.", seeAll: 'See full feature comparison', plans: { free: { name: 'Free', features: ['1 published chatbot', 'Llama 3.3 70B model', '100 conversations/mo', 'Read-only inbox', 'View-only leads'], cta: 'Get started' }, starter: { name: 'Starter', features: ['3 published chatbots', 'All Fireworks AI models', '1,500 conversations/mo', 'Live chat + agent replies', 'Full lead CRM', 'Appointments (1 chatbot)', '3 campaigns/mo · 500 recipients', 'Telegram channel'], cta: 'Start Starter' }, business: { name: 'Business', popular: 'Popular', features: ['10 published chatbots', 'GPT-4o · Claude · Gemini', '5,000 conversations/mo', 'Unlimited booking chatbots', 'Unlimited campaigns · 5k recipients', 'Knowledge gap suggestions', 'Remove "Powered by" badge'], cta: 'Start Business' }, agency: { name: 'Agency', features: ['Unlimited chatbots', 'All models', '20,000 conversations/mo', 'Unlimited recipients', 'Code export', 'White-label ready'], cta: 'Start Agency' }, }, }, cta: { h2: 'Your AI business suite, ready in minutes', p: 'Join hundreds of businesses using Contexta to automate chat, capture leads, book appointments, and run campaigns.', cta1: 'Get started for free', cta2: 'Explore marketplace', }, footer: { copyright: '© 2025 Contexta. Built with ❤️ for builders.' }, chat: [ { role: 'user', text: 'What are your return policies?' }, { role: 'bot', text: 'Based on your company documents, we offer a 30-day return policy for all items in original condition. Refunds are processed within 5-7 business days.' }, { role: 'user', text: 'Can I return sale items?' }, { role: 'bot', text: 'According to Section 4.2 of your policy, sale items can be exchanged within 14 days but are not eligible for refunds. Would you like to know more?' }, ], chatLabel: 'Support Bot', chatOnline: 'Online', chatPlaceholder: 'Type a message...', }, } type Lang = keyof typeof TRANSLATIONS // ─── Intersection Observer Hook ──────────────────────────────────────────────── function useInView(options?: IntersectionObserverInit) { const ref = useRef(null) const [isInView, setIsInView] = useState(false) useEffect(() => { const el = ref.current if (!el) return const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) setIsInView(true) }, { threshold: 0.15, ...options } ) observer.observe(el) return () => observer.disconnect() // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return { ref, isInView } } // ─── Animated Counter ────────────────────────────────────────────────────────── const AnimatedCounter: React.FC<{ end: number; suffix?: string; label: string; isInView: boolean }> = ({ end, suffix = '', label, isInView }) => { const [count, setCount] = useState(0) useEffect(() => { if (!isInView) return let start = 0 const duration = 2000 const increment = end / (duration / 16) const timer = setInterval(() => { start += increment if (start >= end) { setCount(end); clearInterval(timer) } else setCount(Math.floor(start)) }, 16) return () => clearInterval(timer) }, [isInView, end]) return (
{count.toLocaleString()}{suffix}

{label}

) } // ─── Floating Chat Preview ───────────────────────────────────────────────────── const FloatingChatPreview: React.FC<{ conversation: { role: string; text: string }[] label: string online: string placeholder: string }> = ({ conversation, label, online, placeholder }) => { const [messages, setMessages] = useState<{ role: string; text: string }[]>([]) const [isTyping, setIsTyping] = useState(false) const [step, setStep] = useState(0) useEffect(() => { setMessages([]) setStep(0) }, [conversation]) useEffect(() => { if (step >= conversation.length) { const timeout = setTimeout(() => { setMessages([]); setStep(0) }, 4000) return () => clearTimeout(timeout) } const timeout = setTimeout(() => { if (conversation[step].role === 'bot') { setIsTyping(true) setTimeout(() => { setIsTyping(false) setMessages(prev => [...prev, conversation[step]]) setStep(s => s + 1) }, 1500) } else { setMessages(prev => [...prev, conversation[step]]) setStep(s => s + 1) } }, step === 0 ? 1500 : 1000) return () => clearTimeout(timeout) }, [step, conversation]) return (

{label}

{online}
{messages.map((msg, i) => (
{msg.text}
))} {isTyping && (
)}
{placeholder}
) } // ─── Feature Card ────────────────────────────────────────────────────────────── const FeatureCard: React.FC<{ icon: React.ReactNode title: string desc: string color: string delay: number isInView: boolean }> = ({ icon, title, desc, color, delay, isInView }) => (
{icon}

{title}

{desc}

) // ─── How It Works Step ───────────────────────────────────────────────────────── const Step: React.FC<{ num: number icon: React.ReactNode title: string desc: string isInView: boolean delay: number }> = ({ num, icon, title, desc, isInView, delay }) => (
{icon}
{num}

{title}

{desc}

) // ─── Testimonial Card ────────────────────────────────────────────────────────── const TestimonialCard: React.FC<{ quote: string name: string role: string company: string isInView: boolean delay: number }> = ({ quote, name, role, company, isInView, delay }) => (
{[...Array(5)].map((_, i) => ( ))}

"{quote}"

{name[0]}

{name}

{role} · {company}

) // ═══════════════════════════════════════════════════════════════════════════════ // LANDING PAGE // ═══════════════════════════════════════════════════════════════════════════════ export const LandingPage: React.FC = () => { const [lang, setLang] = useState('fr') const [mobileMenuOpen, setMobileMenuOpen] = useState(false) const [scrolled, setScrolled] = useState(false) const t = TRANSLATIONS[lang] const { ref: featuresRef, isInView: featuresInView } = useInView() const { ref: howItWorksRef, isInView: howItWorksInView } = useInView() const { ref: statsRef, isInView: statsInView } = useInView() const { ref: testimonialsRef, isInView: testimonialsInView } = useInView() const { ref: pricingRef, isInView: pricingInView } = useInView() const { ref: ctaRef, isInView: ctaInView } = useInView() useEffect(() => { const handleScroll = () => setScrolled(window.scrollY > 20) window.addEventListener('scroll', handleScroll, { passive: true }) return () => window.removeEventListener('scroll', handleScroll) }, []) const FEATURE_ICONS = [ { icon: , color: 'bg-blue-100 text-blue-600' }, { icon: , color: 'bg-sky-100 text-sky-600' }, { icon: , color: 'bg-green-100 text-green-600' }, { icon: , color: 'bg-orange-100 text-orange-600' }, { icon: , color: 'bg-purple-100 text-purple-600' }, { icon: , color: 'bg-rose-100 text-rose-600' }, ] const LEAD_COLORS = ['bg-gray-100 text-gray-600', 'bg-blue-100 text-blue-600', 'bg-yellow-100 text-yellow-700', 'bg-green-100 text-green-700'] return (
{/* ── Navigation ── */} {/* ── Hero ── */}
{t.hero.badge}

{t.hero.h1a}{' '} {t.hero.h1b}

{t.hero.p}

{t.hero.cta1} {t.hero.cta2}

{t.hero.sub}

{t.hero.badge1}
{t.hero.badge2}
{/* ── Stats ── */}
{/* ── Features ── */}
{t.features.badge}

{t.features.h2}

{t.features.p}

{t.features.items.map((f, i) => ( ))}
{/* ── How It Works ── */}
{t.howItWorks.badge}

{t.howItWorks.h2}

{[ { icon: }, { icon: }, { icon: }, ].map((s, i) => ( ))}
{/* ── Widget Embed Highlight ── */}
{t.widget.badge}

{t.widget.h2}

{t.widget.p}

{t.widget.bullets.map(text => (
{text}
))}
index.html
                    
                      {``}
                      {'\n'}
                      {`
                      {'\n'}
                      {'  '}
                      {'src'}
                      {'='}
                      {`"https://app.contexta.ai/widget.js"`}
                      {'\n'}
                      {'  '}
                      {'data-chatbot'}
                      {'='}
                      {`"your-chatbot-id"`}
                      {'\n'}
                      {'>'}
                      {''}
                    
                  
{t.widget.status}
{/* ── Business Workflow Highlight ── */}

{t.workflow.inbox.title}

{t.workflow.inbox.badge}

{t.workflow.inbox.msg}

{t.workflow.leads.title}

{t.workflow.leads.statuses.map((label, i) => (

{[12, 7, 4, 9][i]}

{label}

))}

{t.workflow.booking.title}

{t.workflow.booking.badge}

{t.workflow.booking.detail}

{t.workflow.campaign.title}

{t.workflow.campaign.badge}

{t.workflow.campaign.detail}

{t.workflow.badge}

{t.workflow.h2}

{t.workflow.p}

{[ { icon: }, { icon: }, { icon: }, { icon: }, ].map(({ icon }, i) => (
{icon}
{t.workflow.bullets[i]}
))}
{/* ── Testimonials ── */}
{t.testimonials.badge}

{t.testimonials.h2}

{t.testimonials.items.map((item, i) => ( ))}
{/* ── Pricing Teaser ── */}

{t.pricing.h2}

{t.pricing.p}

{/* Free */}

{t.pricing.plans.free.name}

$0 /mo
    {t.pricing.plans.free.features.map(f => (
  • {f}
  • ))}
{t.pricing.plans.free.cta}
{/* Starter */}

{t.pricing.plans.starter.name}

$19 /mo
    {t.pricing.plans.starter.features.map(f => (
  • {f}
  • ))}
{t.pricing.plans.starter.cta}
{/* Business */}
{t.pricing.plans.business.popular}

{t.pricing.plans.business.name}

$49 /mo
    {t.pricing.plans.business.features.map(f => (
  • {f}
  • ))}
{t.pricing.plans.business.cta}
{/* Agency */}

{t.pricing.plans.agency.name}

$99 /mo
    {t.pricing.plans.agency.features.map(f => (
  • {f}
  • ))}
{t.pricing.plans.agency.cta}
{t.pricing.seeAll}
{/* ── CTA ── */}

{t.cta.h2}

{t.cta.p}

{t.cta.cta1} {t.cta.cta2}
{/* ── Footer ── */}
) }