// Klyvio — ReportTabs v4 // Niveau 2 : taux de récupération sourcés (McKinsey, MIT Sloan) sous les hypothèses // Niveau 3 : BeforeAfter sectoriel — étapes adaptées selon le secteur du dirigeant // ───────────────────────────────────────────────────────────── // PAIN POINTS // ───────────────────────────────────────────────────────────── function PainPoints({ data }) { const sevCfg = { high: { label: "Critique", bg: "var(--danger-dim)", color: "var(--danger)", border: "rgba(239,68,68,0.25)" }, med: { label: "Important", bg: "var(--warn-dim)", color: "var(--warn)", border: "rgba(245,158,11,0.25)" }, low: { label: "À surveiller", bg: "var(--accent-dim)", color: "var(--gray)", border: "var(--border)" }, }; const dims = window.KLYVIO_DIMENSIONS; const critiques = data.pains.filter(p => p.severity === "high").length; const introText = critiques > 0 ? `${data.pains.length} points identifiés à partir de vos réponses — dont ${critiques} critique${critiques > 1 ? "s" : ""} à traiter en priorité.` : `${data.pains.length} points identifiés à partir de vos réponses. Classés par niveau de criticité.`; return (
Diagnostic

Ce qui vous freine aujourd'hui.

{introText}

{data.pains.map((p, i) => { const cfg = sevCfg[p.severity]; const dim = dims.find(d => d.id === p.dim); return (
{cfg.label} {dim?.short || dim?.label}

{p.title}

{p.desc}

Impact : {p.impact}
); })}
Bonne nouvelle
Chacun de ces points a une solution concrète dans la roadmap. Commencez par les quick wins pour engranger rapidement des résultats visibles.
); } // ───────────────────────────────────────────────────────────── // AUTOMATIONS — niveau 3 : BeforeAfter sectoriel // ───────────────────────────────────────────────────────────── function Automations({ data }) { const [selected, setSelected] = useState(data.autos[0]?.id); const current = data.autos.find(a => a.id === selected) || data.autos[0]; const sector = data.sector || "services"; return (
Processus automatisables

{data.autos.length} opportunités priorisées.

Classement par impact décroissant selon vos réponses. Cliquez une ligne pour voir le détail et l'avant/après.

{data.autos.map((a) => { const active = a.id === selected; return ( ); })}
Automatisation {current.priority}

{current.label}

{current.desc}

{current.result && (
{current.result}
)}
Avant → après
{/* Niveau 3 — BeforeAfter sectoriel */}
); } function MiniStat({ label, value, highlight }) { return (
{label}
{value}
); } // ───────────────────────────────────────────────────────────── // BEFORE/AFTER — niveau 3 : adapté par secteur // ───────────────────────────────────────────────────────────── // Structure : BEFORE_AFTER[autoId][sector] = { before: {steps, time}, after: {steps, time} } // Fallback : [autoId].default si le secteur n'est pas défini const BEFORE_AFTER = { mail: { default: { before: { steps: ["Lire l'email", "Chercher les éléments de contexte", "Rédiger une réponse", "Relire et envoyer"], time: "12–15 min" }, after: { steps: ["L'agent propose une réponse contextualisée", "Vous relisez et ajustez en 1 min", "Envoi en 1 clic"], time: "3–4 min" }, }, btp: { before: { steps: ["Lire la demande client ou fournisseur", "Vérifier l'avancement du chantier", "Rédiger la réponse", "Envoyer"], time: "15–20 min" }, after: { steps: ["L'agent détecte le chantier concerné", "Propose une réponse avec le contexte chantier", "Vous validez et envoyez"], time: "3–5 min" }, }, health: { before: { steps: ["Lire la demande patient ou mutuelle", "Vérifier le dossier", "Rédiger la réponse", "Classer"], time: "10–15 min" }, after: { steps: ["L'agent identifie le type de demande", "Propose une réponse conforme", "Vous validez et classez automatiquement"], time: "2–3 min" }, }, industry: { before: { steps: ["Lire la demande fournisseur ou client", "Vérifier le planning de production", "Rédiger la réponse", "Envoyer"], time: "12–18 min" }, after: { steps: ["L'agent consulte le planning en temps réel", "Propose une réponse avec délais actualisés", "Vous validez"], time: "3–4 min" }, }, }, devis: { default: { before: { steps: ["Extraire le besoin client", "Chercher les tarifs en vigueur", "Remplir un modèle", "Valider et envoyer"], time: "25–35 min" }, after: { steps: ["L'email client est analysé automatiquement", "Le devis est pré-rempli", "Vous validez ou ajustez et envoyez"], time: "5–8 min" }, }, btp: { before: { steps: ["Lire le cahier des charges", "Calculer les métrés manuellement", "Appliquer les tarifs", "Rédiger et envoyer"], time: "2–4 h" }, after: { steps: ["L'agent extrait les métrés du document", "Applique votre grille tarifaire", "Vous vérifiez et signez"], time: "20–30 min" }, }, services: { before: { steps: ["Analyser le besoin exprimé", "Chercher des missions similaires", "Rédiger la proposition", "Chiffrer et envoyer"], time: "1–2 h" }, after: { steps: ["L'agent analyse le brief", "Génère une proposition à partir de vos modèles", "Vous ajustez et envoyez"], time: "15–25 min" }, }, health: { before: { steps: ["Identifier les actes concernés", "Vérifier la nomenclature", "Rédiger le devis patient", "Transmettre"], time: "15–20 min" }, after: { steps: ["L'agent identifie les actes et codes", "Génère le devis conforme", "Vous validez et transmettez"], time: "3–5 min" }, }, }, support: { default: { before: { steps: ["Lire la demande", "Chercher dans la doc interne", "Rédiger une réponse", "Transférer si complexe"], time: "8–12 min" }, after: { steps: ["L'agent répond instantanément 24h/24", "Escalade automatique si cas complexe", "Vous ne traitez que les exceptions"], time: "2–3 min (manuel)" }, }, commerce: { before: { steps: ["Lire la question client (stock, livraison…)", "Vérifier dans l'ERP", "Répondre par email ou téléphone"], time: "8–15 min" }, after: { steps: ["L'agent consulte le stock en temps réel", "Répond instantanément au client", "Escalade si réclamation complexe"], time: "< 1 min (automatique)" }, }, health: { before: { steps: ["Décrocher le téléphone", "Identifier le patient", "Répondre à la question", "Mettre à jour le dossier"], time: "5–10 min" }, after: { steps: ["L'agent répond aux questions fréquentes (horaires, RDV, résultats)", "Transfère les urgences à une secrétaire", "Dossier mis à jour automatiquement"], time: "< 1 min (automatique)" }, }, }, report: { default: { before: { steps: ["Collecter les chiffres dans plusieurs outils", "Copier/coller dans un tableau", "Mettre en forme", "Commenter et diffuser"], time: "2–4 h/sem" }, after: { steps: ["Données agrégées automatiquement", "Synthèse rédigée par l'agent", "Vous validez et diffusez"], time: "15–30 min/sem" }, }, industry: { before: { steps: ["Collecter les données de production", "Calculer les indicateurs qualité et délais", "Mettre en forme le rapport", "Diffuser à la direction"], time: "3–5 h/sem" }, after: { steps: ["L'agent agrège les données machines et production", "Calcule automatiquement les KPIs", "Envoie le rapport à la direction chaque lundi matin"], time: "0 min (automatique)" }, }, btp: { before: { steps: ["Collecter l'avancement de chaque chantier", "Calculer les marges", "Rédiger le rapport de direction", "Diffuser"], time: "4–6 h/sem" }, after: { steps: ["L'agent collecte les données chantier en temps réel", "Calcule les marges et alertes de dépassement", "Diffuse le rapport automatiquement"], time: "0 min (automatique)" }, }, }, agenda: { default: { before: { steps: ["Vérifier les disponibilités de chacun", "Envoyer des créneaux par email", "Attendre les retours", "Ressaisir dans le calendrier"], time: "30–60 min/sem" }, after: { steps: ["L'agent trouve les créneaux disponibles", "Invitations envoyées automatiquement", "Comptes-rendus rédigés après la réunion"], time: "5–10 min/sem" }, }, health: { before: { steps: ["Gérer les appels de prise de RDV", "Vérifier les disponibilités des praticiens", "Confirmer par téléphone ou SMS"], time: "2–3 h/jour" }, after: { steps: ["L'agent gère les prises de RDV en ligne et par téléphone", "Synchronise automatiquement les agendas", "Envoie les rappels patients automatiquement"], time: "15 min/jour (supervison)" }, }, btp: { before: { steps: ["Coordonner les plannings des équipes de chantier", "Gérer les conflits de ressources", "Communiquer les planning par téléphone"], time: "1–2 h/jour" }, after: { steps: ["L'agent optimise les plannings selon les contraintes", "Notifie les équipes automatiquement", "Alerte sur les conflits de ressources"], time: "15–20 min/jour" }, }, }, content: { default: { before: { steps: ["Trouver l'angle et le message", "Rédiger", "Trouver des visuels", "Publier et suivre"], time: "1–2 h/post" }, after: { steps: ["Un brief court suffit", "L'agent produit un draft complet", "Vous ajustez et publiez"], time: "15–25 min/post" }, }, commerce: { before: { steps: ["Préparer les fiches produits", "Rédiger les descriptions", "Créer les posts promotionnels", "Planifier et publier"], time: "2–3 h/semaine" }, after: { steps: ["L'agent génère les fiches produits depuis votre catalogue", "Rédige les posts selon votre charte", "Planifie et publie automatiquement"], time: "20–30 min/semaine" }, }, services: { before: { steps: ["Définir le sujet et l'angle", "Rédiger l'article ou le post LinkedIn", "Relire et corriger", "Publier et répondre aux commentaires"], time: "2–4 h/post" }, after: { steps: ["Brief en 5 min sur votre expertise", "L'agent rédige un post ou article structuré", "Vous ajustez le ton et publiez"], time: "20–30 min/post" }, }, }, docs: { default: { before: { steps: ["Chercher dans ses emails", "Chercher dans les dossiers partagés", "Demander à un collègue", "Ressaisir si introuvable"], time: "15–30 min/recherche" }, after: { steps: ["Vous posez votre question en langage naturel", "La réponse arrive en quelques secondes", "Source indiquée pour vérification"], time: "< 1 min" }, }, btp: { before: { steps: ["Chercher le bon plan ou CCTP", "Appeler le conducteur de travaux", "Retrouver la bonne version du document", "Transmettre"], time: "20–40 min/recherche" }, after: { steps: ["Vous demandez 'plan R+2 chantier Dupont'", "L'agent retrouve le bon document en quelques secondes", "Version et date confirmées automatiquement"], time: "< 1 min" }, }, health: { before: { steps: ["Chercher le protocole ou la procédure", "Demander à un collègue senior", "Vérifier la dernière version", "Appliquer"], time: "10–20 min/recherche" }, after: { steps: ["Vous demandez le protocole en langage naturel", "L'agent retrouve la version en vigueur", "Source et date de mise à jour affichées"], time: "< 1 min" }, }, }, }; function BeforeAfter({ auto, sector }) { const autoData = BEFORE_AFTER[auto.id]; if (!autoData) { return (
Avant
Processus entièrement manuel
Après
L'agent automatise les étapes répétitives
); } // Priorité : secteur spécifique → default const { before, after } = autoData[sector] || autoData.default; return (
Avant · {before.time}
    {before.steps.map((s, i) =>
  1. {s}
  2. )}
Après · {after.time}
    {after.steps.map((s, i) =>
  1. {s}
  2. )}
); } // ───────────────────────────────────────────────────────────── // ROI SIMULATOR — niveau 2 : taux sourcés McKinsey/MIT Sloan // ───────────────────────────────────────────────────────────── function ROISimulator({ data, answers, simHoursPct, setSimHoursPct, simStaffPct, setSimStaffPct }) { const hFactor = simHoursPct / 100; const sFactor = simStaffPct / 100; const adjusted = data.autos.map(a => ({ ...a, annualHours: Math.round(a.annualHours * hFactor * sFactor), annualGain: Math.round(a.annualGain * hFactor * sFactor), })); const totalGain = adjusted.reduce((s, a) => s + a.annualGain, 0); const totalHours = adjusted.reduce((s, a) => s + a.annualHours, 0); const invest = data.roi.totalInvest; const net = totalGain - invest; const payback = totalGain > 0 ? Math.max(0.5, Math.round((invest / (totalGain / 12)) * 10) / 10) : 999; const nominalGain = data.roi.totalGain; const scenarios = [ { label: "Conservateur", gain: Math.round(nominalGain * 0.50), desc: "50% des heures réellement récupérées, adoption partielle" }, { label: "Nominal", gain: nominalGain, desc: "Hypothèses de base issues de vos réponses", nominal: true }, { label: "Optimiste", gain: Math.round(nominalGain * 1.30), desc: "Adoption rapide + réinvestissement du temps en croissance" }, ]; const roiDetail = data.roiDetail; const sliderStyle = (val, min, max) => ({ width: "100%", height: 6, appearance: "none", background: `linear-gradient(to right, var(--accent) 0%, var(--accent) ${(val - min) / (max - min) * 100}%, var(--gray-dim) ${(val - min) / (max - min) * 100}%)`, borderRadius: 999, cursor: "pointer", outline: "none", }); return (
Simulateur ROI

Ajustez les hypothèses, voyez le gain.

Calculé à partir de vos réponses — {roiDetail?.headcount || "?"} personnes · {roiDetail?.hoursLostWk || "?"} h/sem perdues · coût horaire moyen {formatEur(roiDetail?.hourlyCost || 0)}.

{!roiDetail?.smicAdjusted && !roiDetail?.hourlyFloored ? (

Le coût horaire est calculé sur la base de votre masse salariale déclarée, divisée par le nombre de salariés, 47 semaines travaillées et 35 h/semaine.

) : ( <>

Le coût horaire moyen est calculé à partir de la masse salariale annuelle, divisée par le nombre de salariés, 47 semaines travaillées et 35 h/semaine.

{roiDetail?.smicAdjusted && (
⚠️

La masse salariale déclarée est inférieure au SMIC chargé en vigueur (21 000 €/an par salarié). Le calcul a été automatiquement basé sur ce minimum légal.

)} {roiDetail?.hourlyFloored && !roiDetail?.smicAdjusted && (
⚠️

Le coût horaire calculé est inférieur au minimum observé en PME françaises. Il a été ajusté à 20 €/h pour refléter la réalité du marché.

)} )}
{/* 3 scénarios */}
{scenarios.map((sc, i) => { const netSc = sc.gain - invest; return (
{sc.label} {sc.nominal && "· Votre estimation"}
{formatEur(sc.gain)}
Gain brut annuel
= 0 ? "var(--success)" : "var(--danger)" }}> Net : {formatEur(netSc)}
{sc.desc}
); })}
{/* Disclaimer */}
Ces estimations représentent un potentiel, pas une garantie.{" "} Le gain réel dépend du taux d'adoption de vos équipes, de la qualité de vos données et de la vitesse de déploiement. Les heures récupérées peuvent être réinvesties en croissance ou en réduction de coûts selon votre priorité.
Affinez votre scénario
{[ { label: "Heures gagnées vs estimation", val: simHoursPct, set: setSimHoursPct, min: 40, max: 130, step: 5, marks: ["Conservateur", "Nominal", "Optimiste"] }, { label: "Taux d'adoption par les équipes", val: simStaffPct, set: setSimStaffPct, min: 30, max: 100, step: 5, marks: ["Pilote", "Partiel", "Total"] }, ].map((s, k) => (
{s.label}
{s.val}%
s.set(parseInt(e.target.value))} style={sliderStyle(s.val, s.min, s.max)} />
{s.marks.map(m => {m})}
))} {/* Niveau 2 — hypothèses avec sources McKinsey / MIT Sloan */} {roiDetail && (
Hypothèses de calcul
{[ { label: "Effectif", value: `${roiDetail.headcount} pers.` }, { label: "Heures perdues", value: `${roiDetail.hoursLostWk} h/sem/pers.` }, { label: "Taux de récup.", value: `${Math.round(roiDetail.recoveryRate * 100)}%` }, { label: "Coût horaire moy.", value: formatEur(roiDetail.hourlyCost) }, { label: "Offre recommandée", value: roiDetail.offerName || data.offer?.name || "—" }, ].map(h => (
{h.label} {h.value}
))} {/* Niveau 2 — sources des taux */}
Sources des taux de récupération :
Tâches administratives (45%) — McKinsey Global Institute, A Future That Works, 2017.
Emails et communication (35%) — MIT Sloan Management Review, AI at Work, 2023.
Reporting et consolidation (40%) — Bpifrance Le Lab, Baromètre IA PME, 2023.
Taux appliqués aux postes déclarés dans vos réponses.
)}
Gain net — scénario personnalisé
= 0 ? "var(--accent)" : "var(--danger)", marginBottom: 8, fontVariantNumeric: "tabular-nums" }}> {formatEur(net)}
{formatHours(totalHours)} économisées · Investissement {formatEur(invest)}
Investissement {formatEur(invest)} Net {formatEur(net)}
Retour sur invest.
{payback} mois
pour rentabiliser
{roiDetail?.offer?.name || data.offer?.name || `${data.tier === "starter" ? "1" : data.tier === "duo" ? "2" : "3"} agents autonomes`}
{formatEur(invest)} la 1ère année
puis {formatEur(roiDetail?.subscription || 0)}/an
Basé sur les automatisations les plus impactantes. Périmètre complet défini lors de votre entretien.
Par automatisation
{adjusted.map(a => (
{a.label}
{formatEur(a.annualGain)}
))}
); } // ───────────────────────────────────────────────────────────── // ROADMAP // ───────────────────────────────────────────────────────────── function Roadmap({ data }) { const profile = data?.profile; const isUrgent = profile?.id === "urgent"; return (
Plan d'action

Votre roadmap sur 12 mois.

{isUrgent ? "Votre situation permet de démarrer dès cette semaine — les quick wins ci-dessous sont activables sans prérequis technique." : "Trois phases, séquencées selon l'effort et l'impact. Chaque phase livre une valeur concrète avant la suivante."}

{data.roadmap.map((phase, idx) => (
PHASE {idx + 1}
{phase.title} {idx === 0 && isUrgent && ( ← À démarrer maintenant )}
{phase.phase}
{phase.items.map((it, i) => (
{it.label}
{it.kind === "auto" &&
{formatEur(it.annualGain)}/an · {it.applicableStaff} collab.
} {it.kind === "action" &&
Action organisationnelle · Effort {it.effort}/5
}
))}
))}
); } // ───────────────────────────────────────────────────────────── // BENCHMARK — sources réelles // ───────────────────────────────────────────────────────────── const SECTOR_DIM_OFFSETS = { services: { context: +4, org: +3, data: +2, processes: +1, usage: +6, readiness: +3, vision: +5 }, commerce: { context: +2, org: +1, data: -1, processes: +3, usage: +2, readiness: -1, vision: +1 }, industry: { context: -2, org: +2, data: -3, processes: +4, usage: -4, readiness: -2, vision: -3 }, health: { context: -4, org: -2, data: -5, processes: -3, usage: -6, readiness: -4, vision: -5 }, btp: { context: -5, org: -3, data: -6, processes: -2, usage: -8, readiness: -5, vision: -6 }, other: { context: 0, org: 0, data: 0, processes: 0, usage: 0, readiness: 0, vision: 0 }, }; const SECTOR_SOURCES = { services: "Bpifrance Le Lab — Baromètre IA PME 2023", commerce: "CCI France — Étude maturité numérique 2023", industry: "Symop / Bpifrance — Industrie du futur 2024", health: "FEHAP / ANAP — Maturité numérique secteur santé 2023", btp: "FNTP / FFB — Baromètre digital BTP 2023", other: "Bpifrance Le Lab — Baromètre IA PME 2023", }; function Benchmark({ data, company }) { const { percentile, sectorAvg, distribution } = data.bench; const offsets = SECTOR_DIM_OFFSETS[data.sector] || SECTOR_DIM_OFFSETS.other; const source = SECTOR_SOURCES[data.sector] || SECTOR_SOURCES.other; return (
Comparaison sectorielle

Où vous situez-vous ?

Votre position vs {data.sectorLabel} · Moyenne sectorielle issue de {source}.

Votre position
Top {100 - percentile}%
Vous êtes plus avancé·e que {percentile}% des PME de {data.sectorLabel}.
{distribution.buckets.map((v, i) => (
{i === distribution.userBucket && (
Vous · {data.global}
)}
))}
050100
Moyenne sectorielle : {source}
vs moyenne {data.sectorLabel}
{data.global}
vs
{sectorAvg}
moy. secteur
= sectorAvg ? "chip-success" : "chip-warn"}`} style={{ marginLeft: "auto" }}> = sectorAvg ? "trendUp" : "trendDown"} size={11} /> {data.global >= sectorAvg ? "+" : ""}{data.global - sectorAvg} pts
Dimensions vs secteur
{data.scores.map(s => { const sectorV = Math.max(0, Math.min(100, sectorAvg + (offsets[s.id] || 0))); const diff = Math.round(s.value - sectorV); return (
{s.label}
= 0 ? "var(--success)" : "var(--danger)" }}> {diff >= 0 ? "+" : ""}{diff}
); })}
); } Object.assign(window, { PainPoints, Automations, ROISimulator, Roadmap, Benchmark });