import { useCallback, useEffect, useState } from 'react'; import styled from 'styled-components'; import DashboardPage from './components/DashboardPage'; import ChatInterface from './components/ChatInterface'; import BusinessShowcasePage from './components/PublicBusinessPage'; import LoginPage from './components/LoginPage'; import OnboardingFlow from './components/OnboardingFlow'; import SuccessPage from './components/SuccessPage'; import AboutPage from './components/AboutPage'; import FaqPage from './components/FaqPage'; import BlogPage from './components/BlogPage'; import SahelLogo from './components/SahelLogo'; import MarketingFooter from './components/layout/MarketingFooter'; import MarketingHeader from './components/layout/MarketingHeader'; import { ROUTES, loginUrl } from './lib/routes'; import { getSession } from './lib/session'; import { API_URL } from './config'; const AppContainer = styled.div` min-height: 100vh; background: #ffffff; color: #1c1b1b; font-family: 'Inter', system-ui, sans-serif; `; const Header = styled.header` position: sticky; top: 0; z-index: 20; display: flex; align-items: center; justify-content: space-between; min-height: 76px; padding: 0 clamp(18px, 5vw, 64px); background: rgba(255, 255, 255, 0.96); border-bottom: 0.5px solid #d9d6cc; backdrop-filter: blur(12px); `; const HeaderActions = styled.div` display: flex; align-items: center; gap: 12px; `; const Brand = styled.div` color: #185fa5; font-size: clamp(18px, 3vw, 22px); font-weight: 500; `; const HeaderNav = styled.nav` display: flex; align-items: center; gap: 18px; a { color: #414751; font-size: 14px; font-weight: 600; text-decoration: none; } @media (max-width: 720px) { a:not(.primary-link) { display: none; } } `; const PageTransition = styled.div` animation: page-in 420ms ease both; @keyframes page-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } } `; const Shell = styled.main` display: grid; grid-template-columns: minmax(280px, 380px) minmax(0, 1fr); gap: 24px; padding: 24px 32px; @media (max-width: 900px) { grid-template-columns: 1fr; padding: 16px; } `; const DashboardIntro = styled.section` display: grid; gap: 18px; padding: 24px 32px 0; @media (max-width: 900px) { padding: 18px 16px 0; } `; const DashboardHero = styled.div` display: grid; gap: 16px; padding: clamp(20px, 4vw, 34px); border: 0.5px solid #d9d6cc; border-radius: 8px; background: #f6f3f2; @media (min-width: 860px) { grid-template-columns: minmax(0, 1fr) auto; align-items: end; } `; const DashboardTitle = styled.h1` margin: 0; font-size: clamp(32px, 5vw, 54px); font-weight: 500; line-height: 1; `; const DashboardSubnav = styled.nav` display: flex; flex-wrap: wrap; gap: 8px; a { display: inline-flex; align-items: center; min-height: 36px; padding: 0 12px; border: 0.5px solid #c8c5bc; border-radius: 6px; background: #ffffff; color: #2f3540; font-size: 13px; font-weight: 700; text-decoration: none; } a:hover { border-color: #378add; color: #185fa5; } `; const WorkspaceHeader = styled.div` display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; `; const WorkspaceActions = styled.div` display: flex; flex-wrap: wrap; gap: 8px; `; const Panel = styled.section` background: #ffffff; border: 0.5px solid #d9d6cc; border-radius: 8px; padding: clamp(18px, 3vw, 28px); `; const PanelTitle = styled.h2` margin: 0 0 14px; font-size: clamp(24px, 4vw, 34px); font-weight: 500; `; const Form = styled.form` display: grid; gap: 12px; `; const Label = styled.label` display: grid; gap: 9px; color: #2f3540; font-size: 13px; font-weight: 600; text-transform: uppercase; `; const Input = styled.input` border: 0.5px solid #c8c5bc; border-radius: 6px; min-height: 58px; padding: 0 16px; background: #ffffff; color: #1c1b1b; font-size: 15px; &:focus { border-color: #378add; outline: none; } `; const TextArea = styled.textarea` min-height: 78px; border: 0.5px solid #c8c5bc; border-radius: 6px; padding: 14px 16px; font-size: 14px; resize: vertical; &:focus { border-color: #378add; outline: none; } `; const Button = styled.button` border: 0; border-radius: 6px; min-height: 46px; padding: 0 18px; background: #378add; color: white; font-weight: 700; cursor: pointer; transition: background 150ms ease, border-color 150ms ease; &:hover { background: #185fa5; } &:disabled { background: #9db6cc; cursor: not-allowed; } `; const SecondaryButton = styled(Button)` background: #ffffff; color: #1c1b1b; border: 0.5px solid #c8c5bc; &:hover { background: #f6f3f2; } `; const GhostButton = styled.button` border: 0.5px solid #c8c5bc; border-radius: 6px; min-height: 40px; padding: 0 12px; background: #ffffff; color: #17201b; font-weight: 700; cursor: pointer; `; const BusinessList = styled.div` display: grid; gap: 8px; margin-top: 18px; `; const BusinessButton = styled.button` border: 1px solid ${({ $active }) => ($active ? '#207a4c' : '#dfe7df')}; border-radius: 6px; padding: 10px; background: ${({ $active }) => ($active ? '#eef8f1' : '#ffffff')}; text-align: left; cursor: pointer; `; const LinkBox = styled.div` display: grid; gap: 8px; margin-bottom: 16px; padding: 12px; border-radius: 6px; background: #f8faf8; font-size: 14px; `; const EmbedCode = styled.pre` margin: 8px 0 0; padding: 12px; overflow-x: auto; border: 1px solid #dfe7df; border-radius: 6px; background: #17201b; color: #eef8f1; font-size: 12px; line-height: 1.5; `; const QrBox = styled.div` display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 14px; align-items: center; margin-bottom: 16px; padding: 12px; border-radius: 6px; background: #ffffff; border: 1px solid #dfe7df; @media (max-width: 560px) { grid-template-columns: 1fr; } `; const SmallButton = styled.button` border: 1px solid #c6ddce; border-radius: 6px; min-height: 36px; padding: 0 12px; background: #eef8f1; color: #207a4c; font-weight: 700; cursor: pointer; `; const Muted = styled.span` color: #617065; `; const StatsGrid = styled.div` display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 16px; @media (max-width: 560px) { grid-template-columns: 1fr; } `; const StatBox = styled.div` padding: 12px; border: 1px solid #dfe7df; border-radius: 6px; background: #f8faf8; `; const StatValue = styled.div` font-size: 28px; font-weight: 800; `; const RecentList = styled.div` display: grid; gap: 8px; margin-bottom: 16px; `; const RecentItem = styled.div` padding: 10px; border-radius: 6px; background: #f8faf8; border: 1px solid #e5ece5; font-size: 14px; `; const ItemMeta = styled.div` display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; color: #617065; font-size: 12px; `; const StatusText = styled.div` min-height: 18px; color: ${({ $error }) => ($error ? '#a13a2b' : '#207a4c')}; font-size: 13px; `; const ActionRow = styled.div` display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; `; const StatusBadge = styled.span` display: inline-flex; align-items: center; min-height: 22px; padding: 0 8px; border-radius: 999px; background: ${({ $status }) => $status === 'closed' ? '#eef0f2' : $status === 'contacted' ? '#eef8f1' : '#fff4df'}; color: ${({ $status }) => $status === 'closed' ? '#596168' : $status === 'contacted' ? '#207a4c' : '#8a5a00'}; font-size: 12px; font-weight: 700; `; const LanguageBadge = styled(StatusBadge)` background: ${({ $language }) => $language === 'ar' ? '#eef3ff' : $language === 'fr' ? '#fff4df' : '#eef8f1'}; color: ${({ $language }) => $language === 'ar' ? '#2f5faa' : $language === 'fr' ? '#8a5a00' : '#207a4c'}; `; const PublicShell = styled.main` max-width: 1180px; margin: 0 auto; padding: clamp(28px, 6vw, 72px) 18px; `; const PublicHero = styled.section` display: grid; gap: 18px; margin-bottom: 28px; padding: clamp(32px, 6vw, 72px) clamp(20px, 5vw, 48px); background: #185fa5; color: #e6f1fb; border-radius: 8px; overflow: hidden; `; const PublicTitle = styled.h1` margin: 0; max-width: 780px; font-size: clamp(48px, 9vw, 92px); font-weight: 500; line-height: 0.96; `; const PublicActions = styled.div` display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; `; const LinkButton = styled.a` display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 46px; padding: 0 18px; border-radius: 6px; background: #378add; color: white; font-weight: 700; text-decoration: none; transition: background 150ms ease, border-color 150ms ease; &:hover { background: #185fa5; } `; const SecondaryLink = styled(LinkButton)` background: #ffffff; color: #1c1b1b; border: 0.5px solid #c8c5bc; &:hover { background: #f6f3f2; } `; const LandingHero = styled.section` position: relative; display: grid; gap: 40px; min-height: calc(100svh - 76px); padding: clamp(44px, 7vw, 88px) clamp(18px, 5vw, 64px) 28px; overflow: hidden; @media (min-width: 980px) { grid-template-columns: minmax(0, 1.08fr) minmax(360px, 0.92fr); align-items: center; } `; const Eyebrow = styled.div` display: inline-flex; width: fit-content; align-items: center; gap: 8px; margin-bottom: 18px; padding: 7px 11px; border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 999px; background: #ffffff; color: #414751; font-size: 12px; font-weight: 700; `; const HeroTitle = styled.h1` max-width: 780px; margin: 0; font-size: clamp(48px, 10vw, 92px); font-weight: 500; line-height: 0.98; em { font-style: italic; } `; const HeroCopy = styled.p` max-width: 620px; margin: 20px 0 0; color: #414751; font-size: clamp(16px, 2.2vw, 20px); line-height: 1.65; `; const HeroActions = styled.div` display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; a { min-width: min(100%, 228px); } `; const ProductVisual = styled.div` display: grid; gap: 14px; `; const BrowserMock = styled.div` border: 0.5px solid #d9d6cc; border-radius: 8px; background: #ffffff; overflow: hidden; `; const BrowserBar = styled.div` display: flex; align-items: center; gap: 6px; height: 36px; padding: 0 12px; border-bottom: 0.5px solid #d9d6cc; background: #f6f3f2; span { width: 8px; height: 8px; border-radius: 50%; background: #b8c2cc; } `; const DashboardPreview = styled.div` display: grid; gap: 16px; padding: 18px; `; const ChartImage = styled.div` min-height: 210px; border-radius: 6px; border: 0.5px solid #d9d6cc; background: #f1efe8; position: relative; &::before { content: ''; position: absolute; inset: 36px 28px; border-left: 0.5px solid #b5d4f4; border-bottom: 0.5px solid #b5d4f4; } &::after { content: ''; position: absolute; left: 54px; right: 34px; bottom: 54px; height: 72px; background: #378add; clip-path: polygon(0 78%, 18% 58%, 38% 68%, 58% 30%, 78% 42%, 100% 8%, 100% 100%, 0 100%); opacity: 0.9; } `; const PreviewGrid = styled.div` display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; div { min-height: 76px; padding: 12px; border-radius: 6px; background: #f6f3f2; color: #185fa5; font-size: 26px; } span { display: block; margin-top: 6px; color: #717783; font-family: 'Inter', sans-serif; font-size: 11px; font-weight: 700; } `; const SectionBand = styled.section` padding: clamp(48px, 8vw, 92px) clamp(18px, 5vw, 64px); background: ${({ $tone }) => ($tone === 'warm' ? '#f1efe8' : '#ffffff')}; border-top: 0.5px solid #d9d6cc; `; const SectionInner = styled.div` max-width: 1180px; margin: 0 auto; `; const SectionTitle = styled.h2` max-width: 720px; margin: 0 0 16px; font-size: clamp(34px, 6vw, 58px); font-weight: 500; line-height: 1.05; `; const SectionLead = styled.p` max-width: 640px; margin: 0 0 32px; color: #414751; line-height: 1.7; `; const FeatureGrid = styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; `; const FeatureCard = styled.div` min-height: 190px; padding: 22px; border: 0.5px solid #d9d6cc; border-radius: 8px; background: #ffffff; transition: background 150ms ease, border-color 150ms ease; &:hover { border-color: #85b7eb; background: #f8fbff; } `; const IconBox = styled.div` display: grid; place-items: center; width: 44px; height: 44px; margin-bottom: 18px; border-radius: 6px; background: #e6f1fb; color: #185fa5; font-size: 22px; `; const StepsGrid = styled.div` display: grid; gap: 28px; @media (min-width: 900px) { grid-template-columns: minmax(0, 1fr) 420px; align-items: center; } `; const StepList = styled.div` display: grid; gap: 18px; `; const StepItem = styled.div` display: grid; grid-template-columns: 42px minmax(0, 1fr); gap: 16px; strong { display: block; margin-bottom: 5px; } p { margin: 0; color: #414751; line-height: 1.6; } `; const StepNumber = styled.div` display: grid; place-items: center; width: 36px; height: 36px; border: 0.5px solid #378add; border-radius: 6px; color: #185fa5; font-weight: 800; `; const QrPhoto = styled.div` aspect-ratio: 4 / 5; border-radius: 8px; border: 0.5px solid #d9d6cc; background: #ffffff; position: relative; &::before { content: ''; position: absolute; width: 46%; aspect-ratio: 1; left: 27%; top: 24%; background: #185fa5; border: 14px solid #f1efe8; outline: 0.5px solid #d9d6cc; } &::after { content: 'QR code partageable'; position: absolute; left: 0; right: 0; bottom: 24%; text-align: center; color: #414751; font-size: 13px; font-weight: 500; } `; const PricingGrid = styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; `; const PriceCard = styled.div` position: relative; padding: 24px; border: ${({ $featured }) => ($featured ? '2px solid #378add' : '0.5px solid #d9d6cc')}; border-radius: 8px; background: #ffffff; h3 { margin: 0 0 16px; color: ${({ $featured }) => ($featured ? '#185fa5' : '#414751')}; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; } strong { display: block; margin-bottom: 18px; font-size: 34px; font-weight: 500; } p { color: #414751; line-height: 1.7; } `; const PopularBadge = styled.div` position: absolute; top: 0; right: 0; padding: 5px 9px; background: #378add; color: #ffffff; font-size: 10px; font-weight: 800; text-transform: uppercase; `; const Footer = styled.footer` padding: 44px clamp(18px, 5vw, 64px); border-top: 0.5px solid #d9d6cc; background: #ffffff; `; const FooterInner = styled.div` display: grid; max-width: 1180px; margin: 0 auto; gap: 24px; @media (min-width: 760px) { grid-template-columns: 1fr auto auto; } a { color: #414751; text-decoration: none; } `; const MiniSiteGrid = styled.div` display: grid; gap: 28px; @media (min-width: 980px) { grid-template-columns: minmax(0, 0.85fr) minmax(360px, 0.65fr); align-items: start; } `; const InfoPills = styled.div` display: flex; flex-wrap: wrap; gap: 10px; `; const InfoPill = styled.span` display: inline-flex; align-items: center; gap: 7px; min-height: 38px; padding: 0 12px; border-radius: 6px; background: rgba(255, 255, 255, 0.82); color: #2f3540; font-weight: 700; `; const ConciergeCard = styled(Panel)` padding: 0; overflow: hidden; `; const ConciergeHeader = styled.div` display: flex; align-items: center; gap: 16px; padding: 24px; border-bottom: 0.5px solid #d9d6cc; `; const BotAvatar = styled.div` display: grid; place-items: center; width: 58px; height: 58px; border-radius: 8px; background: #378add; color: #ffffff; font-size: 26px; `; const PublicFooterLinks = styled.div` display: flex; flex-wrap: wrap; justify-content: center; gap: 28px; margin-top: 44px; color: #414751; `; function landingCta() { const session = getSession(); return session?.owner ? ROUTES.dashboard : loginUrl(ROUTES.onboarding); } function LandingPage() { useEffect(() => { const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add('opacity-100', 'translate-y-0'); entry.target.classList.remove('opacity-0', 'translate-y-8'); } }); }, { threshold: 0.05 } ); const sections = document.querySelectorAll('.reveal-section'); sections.forEach((section) => { section.classList.add('transition-all', 'duration-700', 'opacity-0', 'translate-y-8'); observer.observe(section); }); return () => { sections.forEach((section) => observer.unobserve(section)); }; }, []); return (
Transformez votre boutique locale en une puissance digitale. Gérez vos ventes avec l'IA, des mini-sites rapides et des QR codes intelligents.
{/* Key Stats */}Le chatbot RAG de Sahel.ai répond en Darija, Arabe, Français ou Anglais — avec une connaissance précise de votre inventaire et de vos prix.
Importez vos catalogues, menus ou fiches produits — l'IA apprend et répond avec vos vraies données.
Darija, Arabe, Français — le client parle sa langue, l'IA comprend et répond.
Un scan, une question, une commande. Le parcours client le plus court du Maroc.
L'IA qui connaît votre inventaire. Elle répond aux clients sur WhatsApp et sur votre site 24/7 avec une précision humaine.
Votre catalogue digital optimisé pour le mobile et le SEO local.
Lien direct entre votre boutique physique et votre inventaire digital.
Comprenez ce que vos clients achètent et pourquoi.
Importez vos produits via Excel ou simplement en prenant des photos.
Importez vos produits via Excel ou simplement en prenant des photos.
L'IA apprend vos prix et vos stocks pour répondre aux clients instantanément.
Partagez votre lien sur WhatsApp, Instagram ou affichez vos QR codes en magasin.
Partagez votre lien sur WhatsApp, Instagram ou affichez vos QR codes en magasin.
Pas de frais cachés. Annulez à tout moment.
Parfait pour démarrer votre digitalisation.
La solution complète pour les PME ambitieuses.
Plus de 500 commerces marocains utilisent déjà Sahel.ai pour booster leurs ventes.
Lancer mon commerceVotre demande de démonstration pour Sahel.ai a bien été reçue. Notre équipe vous contactera par email à {email} dans les plus brefs délais.
Pour une mise en place, une question commerciale ou un accompagnement personnalisé, n'hésitez pas à contacter l'équipe Sahel.ai.
> )}Dernière mise à jour : avril 2026 — Sahel.ai, développé dans le cadre d'un stage PFE à Minnova Consulting, Tinghir, Maroc.
Sahel.ai collecte uniquement les données nécessaires au fonctionnement de la plateforme :
Vos données sont utilisées exclusivement pour faire fonctionner votre chatbot, vous envoyer des notifications de service, améliorer les réponses de l'IA, et vous contacter en cas de problème technique. Sahel.ai ne vend jamais vos données à des tiers et n'utilise pas vos documents pour entraîner des modèles globaux.
Toutes les données sont stockées sur Supabase (serveurs en Europe) avec chiffrement en transit (HTTPS) et au repos. Les documents uploadés sont traités localement dans notre pipeline RAG et ne sont jamais transmis à des services tiers sans votre consentement. Votre clé API Groq n'est jamais exposée côté client.
Vos données de commerce sont conservées tant que votre compte est actif. Les logs de conversations sont conservés 90 jours glissants. Après suppression de votre compte, toutes vos données sont définitivement effacées sous 30 jours.
Conformément au RGPD et à la loi marocaine 09-08 sur la protection des données, vous avez le droit d'accéder à vos données, de les corriger, de les exporter ou de les supprimer à tout moment depuis votre dashboard ou en nous contactant à : contact@sahel.ai
Dernière mise à jour : avril 2026 — Sahel.ai, Minnova Consulting, Tinghir.
Les présentes Conditions Générales d'Utilisation (CGU) régissent l'accès et l'utilisation de la plateforme Sahel.ai, développée par MOUHAMED dans le cadre d'un stage PFE à Minnova Consulting, Tinghir. En utilisant Sahel.ai, vous acceptez sans réserve les présentes conditions.
Sahel.ai est une plateforme SaaS permettant aux commerces marocains de créer un chatbot IA personnalisé et un mini-site web à partir de leurs documents. Le service comprend : la création et l'hébergement d'un chatbot, la génération d'un mini-site public, un QR code téléchargeable et un tableau de bord analytique.
En utilisant Sahel.ai, vous vous engagez à :
Sahel.ai est fourni « en l'état » dans le cadre d'un projet étudiant. Nous ne garantissons pas une disponibilité 24h/24 ni l'exactitude absolue des réponses du chatbot. L'utilisateur est seul responsable des informations fournies dans ses documents et des réponses générées par son chatbot.
Le code source, le design et la marque Sahel.ai sont la propriété de leur auteur. Le contenu uploadé par les utilisateurs (documents, descriptions) reste leur propriété exclusive. Sahel.ai n'acquiert aucun droit sur vos données métier.
Vous pouvez supprimer votre compte et tous vos commerces à tout moment depuis votre dashboard. Sahel.ai se réserve le droit de suspendre un compte en cas de violation des présentes conditions, sans préavis.
Les présentes CGU sont soumises au droit marocain. En cas de litige, les tribunaux compétents sont ceux de Tinghir, Maroc.
Dernière mise à jour : avril 2026 — Sahel.ai.
Un cookie est un petit fichier texte stocké sur votre navigateur lors de votre visite. Sahel.ai utilise un nombre minimal de cookies, listés ci-dessous avec leur fonction exacte.
Cette page est en cours de finalisation. Pour toute question officielle, contactez l'équipe Sahel.ai et nous vous répondrons avec les informations adaptées à votre commerce.
> )}{business.description || 'Bienvenue. Posez une question a notre assistant IA pour obtenir des informations, disponibilites ou recommandations.'}
Des suggestions claires a partir de vos documents.
Les demandes sont enregistrees dans votre espace proprietaire.
Commerce introuvable.