/* global React, Icon */
const { useState: useStateH } = React;

// ==================== HELP / USER GUIDE ====================
function Help({ t, lang }) {
  const [section, setSection] = useStateH("start");

  const SECTIONS = [
    { k: "start",    fr: "Démarrage",          en: "Getting started",   icon: "zap" },
    { k: "modules",  fr: "Les modules",        en: "Modules",           icon: "folder" },
    { k: "actions",  fr: "Actions clés",       en: "Key actions",       icon: "plus" },
    { k: "mobile",   fr: "Collecte mobile",    en: "Mobile collection", icon: "smartphone" },
    { k: "workflow", fr: "Workflow validation",en: "Approval workflow", icon: "shieldCheck" },
    { k: "admin",    fr: "Administration",     en: "Administration",    icon: "users" },
    { k: "faq",      fr: "FAQ",                en: "FAQ",               icon: "info" },
    { k: "contact",  fr: "Support & contact",  en: "Support & contact", icon: "message" },
  ];

  return (
    <div className="page">
      <div className="page-header">
        <div className="page-eyebrow">{lang === "fr" ? "AIDE & DOCUMENTATION" : "HELP & DOCUMENTATION"}</div>
        <div className="page-header-row">
          <div>
            <h1 className="page-title">{lang === "fr" ? "Guide d'utilisation MELR" : "MELR User Guide"}</h1>
            <div className="page-sub">
              {lang === "fr"
                ? "Tout ce qu'il faut savoir pour utiliser la plateforme : démarrage, modules, actions courantes, workflow et FAQ."
                : "Everything you need to know to use the platform: getting started, modules, common actions, workflow and FAQ."}
            </div>
          </div>
          <div className="page-header-actions">
            <button className="btn sm" onClick={() => window.open("/USER_GUIDE.md", "_blank")}>
              <Icon.download /> {lang === "fr" ? "Version Markdown" : "Markdown version"}
            </button>
          </div>
        </div>
      </div>

      <div className="page-body" style={{ display: "grid", gridTemplateColumns: "220px 1fr", gap: 18 }}>
        {/* Sidebar nav for help sections */}
        <div className="card" style={{ padding: 8, height: "fit-content", position: "sticky", top: 8 }}>
          {SECTIONS.map((s) => {
            const Ic = Icon[s.icon] || Icon.info;
            const active = section === s.k;
            return (
              <button key={s.k}
                onClick={() => setSection(s.k)}
                className={"btn sm" + (active ? " primary" : " ghost")}
                style={{ width: "100%", justifyContent: "flex-start", marginBottom: 4, padding: "6px 10px" }}>
                <Ic /> <span style={{ marginLeft: 6 }}>{lang === "fr" ? s.fr : s.en}</span>
              </button>
            );
          })}
        </div>

        {/* Content area */}
        <div className="card" style={{ padding: 24, maxWidth: 820 }}>
          {section === "start"    && <HelpStart lang={lang} />}
          {section === "modules"  && <HelpModules lang={lang} />}
          {section === "actions"  && <HelpActions lang={lang} />}
          {section === "mobile"   && <HelpMobile lang={lang} />}
          {section === "workflow" && <HelpWorkflow lang={lang} />}
          {section === "admin"    && <HelpAdmin lang={lang} />}
          {section === "faq"      && <HelpFAQ lang={lang} />}
          {section === "contact"  && <HelpContact lang={lang} />}
        </div>
      </div>
    </div>
  );
}

// ============================================================
// Reusable building blocks for the help content
// ============================================================

function HelpH({ children }) { return <h2 style={{ marginTop: 0, fontSize: 20, fontWeight: 600 }}>{children}</h2>; }
function HelpSubH({ children }) { return <h3 style={{ marginTop: 22, fontSize: 15, fontWeight: 600 }}>{children}</h3>; }
function HelpP({ children, style }) { return <p style={{ lineHeight: 1.55, marginTop: 8, ...style }}>{children}</p>; }
function HelpList({ items }) {
  return (
    <ul style={{ marginTop: 8, paddingLeft: 18, lineHeight: 1.7 }}>
      {items.map((it, i) => <li key={i}>{it}</li>)}
    </ul>
  );
}
function HelpKey({ children }) {
  return <code style={{ background: "var(--bg-sunken, #f3f4f6)", padding: "1px 6px", borderRadius: 4, fontSize: 12, fontFamily: "ui-monospace, monospace" }}>{children}</code>;
}
function HelpNote({ tone, children }) {
  const colors = {
    info:    { bg: "#eef2ff", b: "#6366f1", c: "#3730a3" },
    warn:    { bg: "#fef3c7", b: "#d97706", c: "#92400e" },
    success: { bg: "#dcfce7", b: "#16a34a", c: "#166534" },
    danger:  { bg: "#fee2e2", b: "#dc2626", c: "#991b1b" },
  };
  const c = colors[tone || "info"];
  return (
    <div style={{ background: c.bg, borderLeft: `3px solid ${c.b}`, color: c.c, padding: "10px 14px", borderRadius: 6, marginTop: 12, fontSize: 13 }}>
      {children}
    </div>
  );
}

// ============================================================
// Section contents
// ============================================================

function HelpStart({ lang }) {
  if (lang === "fr") return (
    <div>
      <HelpH>Démarrage en 4 étapes</HelpH>
      <HelpP>
        MELR est une plateforme de suivi-évaluation multi-secteurs : projets, indicateurs, sites,
        baseline, planification, audits SAT et DVT, ex-ante, reporting, apprentissage et collecte
        de données mobile — le tout connecté à une base de données avec mises à jour en temps réel.
      </HelpP>

      <HelpSubH>1. Se connecter</HelpSubH>
      <HelpP>
        Le panneau d'authentification (déplaçable, par défaut en bas à droite) vous permet de vous
        connecter ou de créer un compte. Si vous venez de vous inscrire, attendez qu'un
        administrateur vous ajoute à une organisation pour voir les données.
      </HelpP>

      <HelpSubH>2. Explorer le portefeuille</HelpSubH>
      <HelpP>
        Le menu de gauche regroupe tous les modules : commencez par <b>Tableau de bord</b> pour
        une vue d'ensemble, puis <b>Programmes</b> pour la hiérarchie et <b>Projets</b> pour le détail.
        Chaque module a sa propre couleur dans la sidebar pour repérage rapide.
      </HelpP>

      <HelpSubH>3. Ajouter vos données</HelpSubH>
      <HelpP>
        Chaque écran propose un bouton <HelpKey>+ Nouveau X</HelpKey> en haut à droite pour créer
        un projet, un site, un indicateur ou saisir une valeur. Les changements sont visibles
        immédiatement par tous les utilisateurs connectés (badge <span style={{ color: "#dc2626" }}>● Live</span>).
      </HelpP>

      <HelpSubH>4. Installer l'app sur votre téléphone (optionnel)</HelpSubH>
      <HelpP>
        MELR est une PWA installable. Sur <b>Android / Chrome</b>, ouvrez l'app et cliquez
        « Installer l'app » (visible sur <b>Collecte de données</b>) — ou utilisez l'invite native
        du navigateur. Sur <b>iPhone / iPad (Safari)</b>, faites <b>Partager → Sur l'écran d'accueil</b>.
        L'icône lance directement la <b>Collecte de données</b> en mode plein écran ; le tableau de
        bord reste accessible via le raccourci long-press de l'icône ou en cliquant « Bureau » dans
        la barre supérieure.
      </HelpP>

      <HelpNote tone="info">
        Vous ne voyez pas vos données ? Vérifiez avec votre administrateur que votre profil est
        bien rattaché à une organisation.
      </HelpNote>
    </div>
  );
  return (
    <div>
      <HelpH>4-step quick start</HelpH>
      <HelpP>MELR is a multi-sector M&E platform: projects, indicators, sites, baseline, planning, SAT &amp; DVT audits, ex-ante, reporting, learning and mobile data collection — connected to a database with real-time updates.</HelpP>
      <HelpSubH>1. Sign in</HelpSubH>
      <HelpP>The authentication panel (draggable, bottom-right by default) lets you sign in or sign up. New users wait for an admin to add them to an organization before they can see data.</HelpP>
      <HelpSubH>2. Browse the portfolio</HelpSubH>
      <HelpP>The left menu groups all modules: start with <b>Dashboard</b>, then <b>Programmes</b> for the hierarchy and <b>Projects</b> for detail. Each module has its own colour in the sidebar for quick spotting.</HelpP>
      <HelpSubH>3. Add your data</HelpSubH>
      <HelpP>Each screen has a <HelpKey>+ New X</HelpKey> button at the top right. Changes are visible to everyone via the <span style={{ color: "#dc2626" }}>● Live</span> badge.</HelpP>
      <HelpSubH>4. Install on your phone (optional)</HelpSubH>
      <HelpP>MELR is an installable PWA. On <b>Android / Chrome</b>, open the app and tap "Install app" (visible on <b>Data Collection</b>) — or accept the native browser prompt. On <b>iPhone / iPad (Safari)</b>, use <b>Share → Add to Home Screen</b>. The icon launches straight into <b>Data Collection</b> in full screen; the dashboard stays one long-press away on the icon or via "Desktop" in the top bar.</HelpP>
      <HelpNote tone="info">No data visible? Ask an admin to assign your profile to an organization.</HelpNote>
    </div>
  );
}

function HelpModules({ lang }) {
  const modules = lang === "fr" ? [
    { n: "Tableau de bord", d: "KPIs portefeuille, breakdown par secteur, liste des projets, alertes consolidées." },
    { n: "Programmes", d: "Hiérarchie programmes → projets, Gantt consolidé, création / édition de programmes, mémo d'activités." },
    { n: "Projets", d: "Liste filtrable du portefeuille, création / édition, badge programme parent, devise affichée selon le réglage global." },
    { n: "Détail projet", d: "Drill-down sur un projet : sites, indicateurs, équipe, Gantt, bouton « Avancement »." },
    { n: "Évaluation ex ante", d: "Dossiers complets : identification, intrants, scénarios, calendrier, CAPEX/OPEX, recettes, financement, dette, P&L, cash-flow, parties prenantes, finances publiques, multicritères, institutionnel, sensibilité. Indicateurs économiques (VAN, TRI, DSCR) et décision GO / NO-GO. Export Word." },
    { n: "Baseline", d: "Carte Leaflet des sites GPS · onglets CRUD : Acteurs, Infrastructure, Comptes d'exploitation, Problèmes identifiés. Création de sites depuis l'UI." },
    { n: "Planification (Gantt)", d: "Phases et actions par projet avec progression, génération depuis un template, dépendances simples." },
    { n: "Indicateurs · Définition", d: "Catalogue org-wide des indicateurs : Code · Nom FR/EN · Origine (Institution) · Niveau · fiches PIRS multilingues (PDF/Word/Excel). Import Excel. Admin uniquement." },
    { n: "Indicateurs · Suivi", d: "Liste filtrable, onglets actifs (Cadre logique / Outputs / Outcomes / Impact / Context), création depuis le catalogue ou en saisie manuelle, scoring PEFA (A · B+ · B · …), saisie multi-sites groupée, édition/suppression par les admins." },
    { n: "Audit système (SAT)", d: "Méthode REFT Africa : 100 normes sur 8 domaines, scoring 0/1/2 (E : 0/5/10), plan d'action. Import / export Excel, Word, PDF. Soumission au workflow de validation." },
    { n: "Audit des données (DVT)", d: "Vérification M1/M2/M3 (déclaré vs vérifié, variance ±5%) et plan d'amélioration des données. Import / export. Soumission au workflow." },
    { n: "Synthèse audits", d: "Tableau consolidé SAT + DVT à travers le portefeuille : radar moyenné par domaine, KPIs, classement par projet, comparaison historique." },
    { n: "Reporting", d: "Rapports périodiques, génération automatique de graphiques, export Word (docx) et Excel (xlsx) intégré." },
    { n: "Apprentissage", d: "Questions d'apprentissage, capitalisation, preuves associées par projet." },
    { n: "Collecte de données", d: "Saisie mobile offline-first · formulaires à schémas dynamiques (text/number/date/bool/select/photo/signature) · GPS · file d'attente locale (auto-sync) · installable PWA Android et iOS · route mobile-only plein écran (?mobile=1)." },
    { n: "Validation (Workflow)", d: "Flux d'approbation multi-étapes avec assignation par étape, templates configurables par type d'objet, actions groupées, pièces jointes, discussion avec @mention, timeline en temps réel." },
    { n: "Notifications", d: "Alertes en direct, KPIs (non lus, par sévérité), déclencheurs automatiques (SAT priorité, DVT variance, étape workflow, @mention), filtres et marquage comme lu." },
    { n: "Constructeur de formulaires", d: "Création / édition visuelle des formulaires sans SQL · 8 types de champ (text, number, date, bool, select, matrix, photo, signature) · restriction par agent · export Excel par formulaire (saisies + URLs signées des pièces jointes). Admin uniquement." },
    { n: "Aide & support", d: "Ce guide · formulaire de bug/suggestion (tickets) · panneau d'administration des tickets pour les admins · coordonnées de l'équipe." },
    { n: "Gestion des Organisations", d: "Réservée aux super-administrateurs de la plateforme : créer, modifier, archiver ou supprimer les organisations. Compte des membres et des projets par organisation. La suppression d'une organisation est confirmée par un retype de son identifiant pour éviter les fausses manipulations." },
    { n: "Administration", d: "Organisation & rôles (matrice rôles × permissions en temps réel), gestion des membres, affectations agents → projets, paramètres (organisation, profil, apparence, liens). Visible aux administrateurs de l'organisation." },
  ] : [
    { n: "Dashboard", d: "Portfolio KPIs, sector breakdown, project list, consolidated alerts." },
    { n: "Programmes", d: "Programmes → projects hierarchy, consolidated Gantt, create / edit programmes, activity feed." },
    { n: "Projects", d: "Portfolio list with filters, create / edit, parent-programme badge, currency follows the global setting." },
    { n: "Project detail", d: "Drill-down: sites, indicators, team, Gantt, Progress button." },
    { n: "Ex-ante appraisal", d: "Full dossier: identification, inputs, scenarios, calendar, CAPEX/OPEX, revenue, financing, debt, P&L, cash-flow, stakeholders, public finance, multi-criteria, institutional, sensitivity. Economic indicators (NPV, IRR, DSCR) and GO / NO-GO decision. Word export." },
    { n: "Baseline", d: "Leaflet site map · CRUD tabs: Stakeholders, Infrastructure, Operating accounts, Issues. Create sites from the UI." },
    { n: "Planning (Gantt)", d: "Phases and actions per project with progress, template generation, simple dependencies." },
    { n: "Indicators · Definitions", d: "Org-wide indicator catalogue: Code · Name FR/EN · Origin (Institution) · Level · multilingual PIRS sheets (PDF/Word/Excel). Excel import. Admin only." },
    { n: "Indicators · Tracking", d: "Filterable list, active tabs (Logframe / Outputs / Outcomes / Impact / Context), create from catalogue or manual entry, PEFA scoring (A · B+ · B · …), multi-site batch entry, admin edit/delete." },
    { n: "M&E system audit (SAT)", d: "REFT Africa methodology: 100 norms across 8 domains, 0/1/2 scoring (E: 0/5/10), action plan. Excel / Word / PDF import / export. Submits to validation workflow." },
    { n: "Data audit (DVT)", d: "M1/M2/M3 verification (reported vs verified, ±5% variance) and data-improvement plan. Import / export. Submits to workflow." },
    { n: "Audit dashboard", d: "Consolidated SAT + DVT view across the portfolio: aggregate radar per domain, KPIs, per-project ranking, historical comparison." },
    { n: "Reporting", d: "Periodic reports, auto-generated charts, integrated Word (docx) and Excel (xlsx) export." },
    { n: "Learning", d: "Learning questions, capitalisation, evidence per project." },
    { n: "Data Collection", d: "Offline-first mobile entry · schema-driven forms (text/number/date/bool/select/photo/signature) · GPS · local queue (auto-sync) · installable PWA on Android and iOS · full-screen mobile-only route (?mobile=1)." },
    { n: "Workflow", d: "Multi-step approval with per-step assignment, configurable templates by object type, bulk actions, file attachments, @mention discussion, real-time timeline." },
    { n: "Notifications", d: "Live alerts, KPIs (unread, by severity), auto-triggers (SAT priority, DVT variance, workflow step, @mention), filters and mark-as-read." },
    { n: "Form builder", d: "Visual creation / editing of forms without SQL · 8 field types (text, number, date, bool, select, matrix, photo, signature) · per-agent restriction · per-form Excel export (submissions + signed attachment URLs). Admin only." },
    { n: "Help & support", d: "This guide · bug/suggestion ticket form · admin ticket triage panel · team contact details." },
    { n: "Organization Management", d: "Super-administrator only: create, edit, archive or delete organizations platform-wide. Member + project counts per org. Deletion guarded by typing the organization's short identifier — prevents accidents." },
    { n: "Administration", d: "Organization & roles (live roles × permissions matrix), member management, agent → project assignments, settings (org, profile, appearance, links). Visible to organization administrators." },
  ];
  return (
    <div>
      <HelpH>{lang === "fr" ? "Les modules" : "Modules"}</HelpH>
      <HelpP>{lang === "fr"
        ? "Chaque module est accessible depuis le menu de gauche, code-couleur par bloc. Les écrans en lecture seule s'enrichissent automatiquement quand vous y ajoutez des données via les autres modules CRUD."
        : "Each module is accessible from the left menu, colour-coded per block. Read-only screens fill in automatically as you add data from the CRUD modules."}
      </HelpP>
      <div style={{ marginTop: 12, display: "grid", gap: 10 }}>
        {modules.map((m, i) => (
          <div key={i} style={{ display: "grid", gridTemplateColumns: "200px 1fr", gap: 12, padding: "8px 0", borderTop: i === 0 ? "none" : "1px solid var(--line-faint)" }}>
            <div style={{ fontWeight: 600 }}>{m.n}</div>
            <div className="text-faint">{m.d}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function HelpActions({ lang }) {
  if (lang === "fr") return (
    <div>
      <HelpH>Actions courantes</HelpH>

      <HelpSubH>Créer un projet</HelpSubH>
      <HelpList items={[
        <>Naviguer sur <b>Projets</b></>,
        <>Cliquer <HelpKey>+ Nouveau projet</HelpKey> en haut à droite</>,
        <>Remplir code, nom, secteur, budget</>,
        <>Le projet apparaît immédiatement dans la liste, et sur le Dashboard</>,
      ]} />

      <HelpSubH>Créer un site</HelpSubH>
      <HelpList items={[
        <>Naviguer sur <b>Baseline</b></>,
        <>Cliquer <HelpKey>+ Nouveau site</HelpKey></>,
        <>Choisir le projet de rattachement, saisir nom, type, coordonnées GPS (lat/lng)</>,
        <>Le marqueur apparaît sur la carte Leaflet</>,
      ]} />

      <HelpSubH>Créer un indicateur</HelpSubH>
      <HelpList items={[
        <>Naviguer sur <b>Suivi des indicateurs</b></>,
        <>Cliquer <HelpKey>+ Nouvel indicateur</HelpKey></>,
        <>Saisir code, nom, niveau (output/outcome/impact), unité, baseline, cible, fréquence</>,
      ]} />

      <HelpSubH>Saisir une valeur d'indicateur</HelpSubH>
      <HelpList items={[
        <>Sur la liste des indicateurs, cliquer <HelpKey>+ Valeur</HelpKey> à côté de l'indicateur live</>,
        <>Saisir la période (trimestre par défaut), la valeur, un commentaire optionnel</>,
        <>La sparkline s'étend automatiquement et le statut (ok / warn / risk) est calculé par rapport à la cible</>,
      ]} />

      <HelpSubH>Modifier l'avancement d'un projet</HelpSubH>
      <HelpList items={[
        <>Cliquer sur un projet live → onglet Vue d'ensemble</>,
        <>Bouton <HelpKey>Avancement</HelpKey> dans les actions du header → saisir 0-100</>,
      ]} />

      <HelpSubH>Faire un audit système (SAT)</HelpSubH>
      <HelpList items={[
        <>Naviguer sur <b>Audit système (SAT)</b> et choisir un projet</>,
        <>Cliquer <HelpKey>+ Nouvelle évaluation</HelpKey> → saisir titre, période, équipe</>,
        <>Répondre aux <b>100 normes</b> réparties sur 8 domaines (score 0/1/2 ; le domaine E utilise 0/5/10)</>,
        <>L'onglet <b>Plan d'action</b> permet de créer des actions correctives liées aux normes en écart</>,
        <>Export Excel / Word / PDF via le menu <HelpKey>Exporter</HelpKey> en haut à droite</>,
        <>Bouton <HelpKey>Soumettre pour validation</HelpKey> → l'évaluation entre dans le workflow d'approbation selon le template <b>SAT</b></>,
      ]} />

      <HelpSubH>Faire un audit des données (DVT)</HelpSubH>
      <HelpList items={[
        <>Naviguer sur <b>Audit des données (DVT)</b> et choisir un projet</>,
        <>Cliquer <HelpKey>+ Nouvel audit</HelpKey></>,
        <>Onglet <b>Vérification</b> : pour chaque indicateur retenu, comparer M1 (déclaré) / M2 (carnet) / M3 (terrain). La variance ±5% déclenche un drapeau orange</>,
        <>Onglet <b>Amélioration</b> : actions correctives (responsable, échéance, statut)</>,
        <>Import / export Excel pour préparer hors ligne · soumission au workflow possible</>,
      ]} />

      <HelpSubH>Saisir une donnée terrain (mobile)</HelpSubH>
      <HelpList items={[
        <>Sur le téléphone, ouvrir l'app installée (ou l'URL avec <HelpKey>?mobile=1</HelpKey>)</>,
        <>Choisir un formulaire dans la liste d'accueil</>,
        <>Accepter la demande de géolocalisation pour attacher le GPS</>,
        <>Sélectionner un site et remplir les champs (photo, signature inclus si le schéma les contient)</>,
        <>Cliquer <HelpKey>Continuer</HelpKey> → <em>Récap</em> → <HelpKey>Envoyer</HelpKey></>,
        <>Hors-ligne : la saisie est mise en file locale et synchronisée automatiquement au retour du réseau</>,
      ]} />

      <HelpSubH>Soumettre un item au workflow d'approbation</HelpSubH>
      <HelpList items={[
        <>Depuis SAT, DVT ou Reporting : bouton <HelpKey>Soumettre pour validation</HelpKey></>,
        <>L'app cherche le <em>template</em> actif pour ce type d'objet (par défaut 2 étapes : Revue → Approbation finale)</>,
        <>L'item apparaît dans <b>Workflow</b> avec un assigné, un SLA et la chaîne d'étapes</>,
      ]} />

      <HelpSubH>Générer un rapport périodique</HelpSubH>
      <HelpList items={[
        <>Naviguer sur <b>Reporting</b></>,
        <>Choisir un projet, une période, un modèle</>,
        <>Cliquer <HelpKey>Générer</HelpKey> : les graphiques sont produits automatiquement</>,
        <>Export Word (<HelpKey>.docx</HelpKey>) ou Excel (<HelpKey>.xlsx</HelpKey>) via les boutons en haut à droite</>,
      ]} />

      <HelpSubH>Faire une évaluation ex ante</HelpSubH>
      <HelpList items={[
        <>Naviguer sur <b>Évaluation ex ante</b> → bouton <HelpKey>+ Nouveau dossier</HelpKey></>,
        <>Remplir les sections séquentiellement (sommaire à gauche) : identification, intrants, scénarios, calendrier, CAPEX/OPEX, recettes, financement, dette, P&L, cash-flow, etc.</>,
        <>Les indicateurs économiques (VAN, TRI, DSCR) se recalculent en direct</>,
        <>La carte <b>Décision</b> affiche un statut GO / NO-GO selon les seuils définis</>,
        <>Export Word complet du dossier via <HelpKey>Exporter en Word</HelpKey></>,
      ]} />

      <HelpSubH>Changer la devise affichée</HelpSubH>
      <HelpList items={[
        <>Dans la barre supérieure, cliquer le widget devise (par défaut EUR)</>,
        <>Choisir parmi EUR / FCFA / USD / GBP / CHF / CAD, ou éditer les taux personnalisés</>,
        <>Tous les montants du portefeuille sont reconvertis instantanément</>,
      ]} />
    </div>
  );
  return (
    <div>
      <HelpH>Common actions</HelpH>
      <HelpSubH>Create a project</HelpSubH>
      <HelpList items={[
        "Go to Projects",
        "Click + New project (top right)",
        "Fill in code, name, sector, budget",
        "The project appears immediately in the list and on the Dashboard",
      ]} />
      <HelpSubH>Create a site</HelpSubH>
      <HelpList items={[
        "Go to Baseline",
        "Click + New site",
        "Pick the parent project, fill name, kind, GPS coords",
        "The marker appears on the Leaflet map",
      ]} />
      <HelpSubH>Create an indicator</HelpSubH>
      <HelpList items={[
        "Go to Indicators tracking",
        "Click + New indicator",
        "Fill code, name, level, unit, baseline, target, frequency",
      ]} />
      <HelpSubH>Add an indicator value</HelpSubH>
      <HelpList items={[
        "On the indicators list, click + Value next to a live indicator",
        "Fill the period, value and optional comment",
        "The sparkline grows and status is auto-derived from the target",
      ]} />
      <HelpSubH>Update project progress</HelpSubH>
      <HelpList items={[
        "Open a live project → Overview tab",
        "Click Progress button in the header → enter 0-100",
      ]} />

      <HelpSubH>Run a system audit (SAT)</HelpSubH>
      <HelpList items={[
        "Go to System audit (SAT) and pick a project",
        "Click + New evaluation → fill title, period, team",
        "Answer the 100 norms across 8 domains (score 0/1/2; domain E uses 0/5/10)",
        "The Action plan tab lets you create corrective actions linked to flagged norms",
        "Excel / Word / PDF export from the Export menu in the top right",
        <>Click <HelpKey>Submit for validation</HelpKey> → the evaluation enters the approval workflow using the <b>SAT</b> template</>,
      ]} />

      <HelpSubH>Run a data audit (DVT)</HelpSubH>
      <HelpList items={[
        "Go to Data audit (DVT) and pick a project",
        "Click + New audit",
        "Verification tab: for each retained indicator, compare M1 (reported) / M2 (registers) / M3 (field). ±5% variance flags an orange warning",
        "Improvement tab: corrective actions (owner, due date, status)",
        "Excel import / export for offline prep; workflow submission supported",
      ]} />

      <HelpSubH>Capture a field entry (mobile)</HelpSubH>
      <HelpList items={[
        <>On your phone, open the installed app (or the URL with <HelpKey>?mobile=1</HelpKey>)</>,
        "Pick a form from the home list",
        "Accept the geolocation prompt to attach GPS",
        "Select a site and fill in the fields (photo, signature included if defined in the schema)",
        <>Tap <HelpKey>Continue</HelpKey> → <em>Review</em> → <HelpKey>Submit</HelpKey></>,
        "Offline: the entry is locally queued and auto-syncs when the network returns",
      ]} />

      <HelpSubH>Submit an item to the approval workflow</HelpSubH>
      <HelpList items={[
        <>From SAT, DVT or Reporting: click <HelpKey>Submit for validation</HelpKey></>,
        "The app looks up the active template for that object type (default 2 steps: Review → Final approval)",
        "The item lands in Workflow with an assignee, an SLA, and the step chain",
      ]} />

      <HelpSubH>Generate a periodic report</HelpSubH>
      <HelpList items={[
        "Go to Reporting",
        "Pick a project, a period, a template",
        <>Click <HelpKey>Generate</HelpKey>: charts are produced automatically</>,
        <>Word (<HelpKey>.docx</HelpKey>) or Excel (<HelpKey>.xlsx</HelpKey>) export via the buttons in the top right</>,
      ]} />

      <HelpSubH>Run an ex-ante appraisal</HelpSubH>
      <HelpList items={[
        <>Go to Ex-ante appraisal → click <HelpKey>+ New dossier</HelpKey></>,
        "Fill the sections in sequence (left-hand summary): identification, inputs, scenarios, calendar, CAPEX/OPEX, revenue, financing, debt, P&L, cash-flow, etc.",
        "Economic indicators (NPV, IRR, DSCR) recalculate live",
        "The Decision card shows GO / NO-GO based on configured thresholds",
        <>Full dossier Word export via <HelpKey>Export to Word</HelpKey></>,
      ]} />

      <HelpSubH>Change the displayed currency</HelpSubH>
      <HelpList items={[
        "In the top bar, click the currency widget (default EUR)",
        "Pick EUR / XOF / USD / GBP / CHF / CAD, or edit custom rates",
        "All portfolio amounts re-convert instantly",
      ]} />
    </div>
  );
}

function HelpWorkflow({ lang }) {
  if (lang === "fr") return (
    <div>
      <HelpH>Workflow d'approbation</HelpH>
      <HelpP>
        L'écran <b>Validation</b> centralise toutes les demandes d'approbation : évaluations SAT,
        audits DVT, rapports, dossiers ex-ante, mises à jour d'indicateurs. Chaque item passe par
        une chaîne d'approbateurs <b>multi-étapes</b> définie par son <em>template</em>, avec
        assignation explicite à chaque étape et historique complet.
      </HelpP>

      <HelpSubH>Anatomie d'un item</HelpSubH>
      <HelpList items={[
        <><b>Type d'objet</b> (<b>SAT</b>, <b>DQA</b>, <b>Rapport</b>, etc.)</>,
        <><b>Étape courante</b> et nombre total d'étapes (ex. « 2/3 »)</>,
        <><b>Assigné</b> de l'étape courante — c'est le seul qui peut faire avancer ou renvoyer</>,
        <><b>SLA</b> (jours) et date d'échéance ; les items en retard sont surlignés</>,
        <><b>Live / Demo</b> : seuls les items LIVE viennent de la base de données et peuvent être modifiés</>,
      ]} />

      <HelpSubH>Les actions sur une étape</HelpSubH>
      <HelpList items={[
        <><b>💬 Commenter</b> — ajouter un message dans la discussion (visible en temps réel par tous)</>,
        <><b>📎 Pièce jointe</b> — bouton « Pièce » dans la barre de discussion ; le fichier est stocké dans le bucket privé <HelpKey>validation-attachments</HelpKey></>,
        <><b>@mention</b> — taper <HelpKey>@</HelpKey> dans la discussion pour invoquer un membre ; il reçoit une notification automatique</>,
        <><b>👥 Déléguer</b> — transférer l'assignation de l'étape courante à un autre membre</>,
        <><b>⚠️ Renvoyer</b> — refuser : l'item revient à l'étape précédente avec votre motif</>,
        <><b>✅ Approuver</b> — valider l'étape courante. Si c'était la dernière, l'item passe à l'état <em>approuvé</em> final ; sinon, l'étape suivante s'active et son assigné est notifié</>,
      ]} />

      <HelpSubH>Action groupée</HelpSubH>
      <HelpP>
        Bouton <HelpKey>Action groupée</HelpKey> dans la barre d'outils → cocher plusieurs items
        dans la liste de gauche → appliquer en un clic : approuver tout, renvoyer tout, ou
        ré-assigner. Pratique pour les approbateurs traitant un lot de rapports en fin de période.
      </HelpP>

      <HelpSubH>Templates configurables</HelpSubH>
      <HelpP>
        Bouton <HelpKey>Configurer flux</HelpKey> → ouverture du modal templates. Un template se
        définit par <b>type d'objet</b> et contient :
      </HelpP>
      <HelpList items={[
        <>Une liste ordonnée d'<b>étapes</b> (nom, rôle attendu, SLA en jours)</>,
        <>Un <b>SLA global</b> et une cadence de rappel</>,
        <>Un drapeau <b>actif</b> — un seul template actif par type d'objet à la fois</>,
      ]} />
      <HelpP>
        Les nouvelles soumissions de ce type d'objet utilisent automatiquement le template actif.
        Les items déjà en cours conservent leur chaîne d'origine.
      </HelpP>

      <HelpSubH>Notifications déclenchées</HelpSubH>
      <HelpP>
        Le système crée automatiquement une notification quand : (a) un item vous est assigné,
        (b) vous êtes mentionné dans une discussion, (c) une norme SAT marquée priorité, (d) un
        écart DVT supérieur à ±5%. Les notifications sont visibles dans l'onglet <b>Notifications</b>
        et la cloche en haut à droite.
      </HelpP>

      <HelpSubH>Audit trail</HelpSubH>
      <HelpP>
        Chaque action est enregistrée dans <HelpKey>validation_actions</HelpKey> avec identité,
        horodatage, étape, type d'action et note. La timeline en bas du détail de l'item liste
        tout en direct (realtime), accessible par tous les membres de l'organisation.
      </HelpP>
    </div>
  );
  return (
    <div>
      <HelpH>Approval workflow</HelpH>
      <HelpP>
        The <b>Workflow</b> screen centralises every approval request: SAT evaluations, DVT audits,
        reports, ex-ante dossiers, indicator updates. Each item runs through a <b>multi-step</b>
        approval chain defined by its <em>template</em>, with explicit per-step assignment and full
        audit history.
      </HelpP>

      <HelpSubH>Anatomy of an item</HelpSubH>
      <HelpList items={[
        <><b>Object type</b> (<b>SAT</b>, <b>DQA</b>, <b>Rapport</b>, etc.)</>,
        <><b>Current step</b> and total step count (e.g. "2/3")</>,
        <><b>Assignee</b> of the current step — only they can advance or send back</>,
        <><b>SLA</b> (days) and due date; overdue items are highlighted</>,
        <><b>Live / Demo</b>: only LIVE items come from the database and are editable</>,
      ]} />

      <HelpSubH>Actions on a step</HelpSubH>
      <HelpList items={[
        <><b>💬 Comment</b> — add a message to the discussion (visible to everyone in real time)</>,
        <><b>📎 Attachment</b> — "Attach" button in the discussion bar; file lands in the private <HelpKey>validation-attachments</HelpKey> bucket</>,
        <><b>@mention</b> — type <HelpKey>@</HelpKey> in the discussion to call out a member; they get a notification</>,
        <><b>👥 Delegate</b> — pass the current-step assignment to another member</>,
        <><b>⚠️ Send back</b> — reject: the item returns to the previous step with your reason</>,
        <><b>✅ Approve</b> — validate the current step. If it was the last one, the item flips to <em>approved</em>; otherwise the next step opens and its assignee is notified</>,
      ]} />

      <HelpSubH>Bulk action</HelpSubH>
      <HelpP>
        <HelpKey>Bulk action</HelpKey> button in the toolbar → tick several items in the left list →
        apply at once: approve all, send back all, or reassign. Useful for approvers clearing a
        batch of period-end reports.
      </HelpP>

      <HelpSubH>Configurable templates</HelpSubH>
      <HelpP>
        <HelpKey>Configure flow</HelpKey> button → opens the templates modal. A template is keyed
        by <b>object type</b> and carries:
      </HelpP>
      <HelpList items={[
        <>An ordered list of <b>steps</b> (name, expected role, SLA in days)</>,
        <>A <b>global SLA</b> and reminder cadence</>,
        <>An <b>active</b> flag — only one active template per object type at a time</>,
      ]} />
      <HelpP>
        New submissions of that object type automatically use the active template. In-flight items
        keep their original chain.
      </HelpP>

      <HelpSubH>Triggered notifications</HelpSubH>
      <HelpP>
        A notification is created automatically when: (a) an item is assigned to you, (b) you're
        @mentioned, (c) a SAT norm is flagged priority, (d) a DVT variance exceeds ±5%. Notifications
        show up in the <b>Notifications</b> screen and in the bell badge.
      </HelpP>

      <HelpSubH>Audit trail</HelpSubH>
      <HelpP>
        Every action is recorded in <HelpKey>validation_actions</HelpKey> with identity, timestamp,
        step, action type and note. The timeline at the bottom of the item detail lists everything
        live (realtime), accessible to all members of the organization.
      </HelpP>
    </div>
  );
}

function HelpMobile({ lang }) {
  if (lang === "fr") return (
    <div>
      <HelpH>Collecte de données mobile</HelpH>
      <HelpP>
        Le module <b>Collecte de données</b> est conçu pour les agents terrain : saisie hors-ligne,
        synchronisation différée, photo, signature et géolocalisation. Il fonctionne directement
        dans le navigateur du téléphone et s'installe en PWA pour un usage natif.
      </HelpP>

      <HelpSubH>Installer l'app sur votre téléphone</HelpSubH>
      <HelpList items={[
        <><b>Android / Chrome</b> : ouvrir l'URL → menu ⋮ → <em>Installer l'application</em>. Ou, sur l'écran « Collecte de données », cliquer <HelpKey>Installer l'app</HelpKey>.</>,
        <><b>iPhone / iPad (Safari)</b> : ouvrir l'URL dans <b>Safari</b> (pas Chrome ni Edge sur iOS) → bouton Partager <span style={{ fontFamily: "ui-sans-serif" }}>□↑</span> → <em>Sur l'écran d'accueil</em> → Ajouter.</>,
        <>L'icône MELR apparaît sur l'écran d'accueil et lance directement <b>Collecte de données</b> en plein écran.</>,
      ]} />
      <HelpNote tone="info">
        Sur iOS, seul <b>Safari</b> sait installer une PWA. Chrome et Edge sur iPhone afficheront
        l'app mais sans installer le raccourci sur l'écran d'accueil.
      </HelpNote>

      <HelpSubH>Route mobile plein écran</HelpSubH>
      <HelpP>
        Que vous soyez sur téléphone ou sur ordinateur, l'URL <HelpKey>?mobile=1</HelpKey> bascule
        l'app en mode mobile plein écran (pas de sidebar, pas de cadre Android, juste les écrans
        Accueil → Formulaire → Récap). Le bouton <HelpKey>Bureau</HelpKey> dans la barre supérieure
        permet de revenir au mode tableau de bord.
      </HelpP>

      <HelpSubH>Saisir une donnée</HelpSubH>
      <HelpList items={[
        <>Sur la page d'accueil, choisir un <b>formulaire</b> dans la liste (issus de la base de données).</>,
        <>Si l'agent est affecté à <b>plusieurs projets</b>, un sélecteur « Projet » apparaît au-dessus de la liste. Avec un seul projet, la liste est filtrée automatiquement, pas de sélecteur.</>,
        <>Le GPS est demandé en arrière-plan ; les coordonnées s'attachent automatiquement à la saisie si l'utilisateur accepte.</>,
        <>Sélectionner un <b>site</b> (obligatoire) et remplir les champs définis par le schéma : texte, nombre, date, booléen, liste, matrice, <b>photo</b> ou <b>signature</b>.</>,
        <>Cliquer <HelpKey>Continuer</HelpKey> → écran <em>Récap</em> → <HelpKey>Envoyer</HelpKey>. Une notification confirme l'envoi.</>,
      ]} />

      <HelpSubH>Mes saisies</HelpSubH>
      <HelpP>
        L'icône <Icon.fileText className="sm" /> en haut à droite de l'écran d'accueil ouvre la
        vue <b>Mes saisies</b>. Elle combine en une seule liste:
      </HelpP>
      <HelpList items={[
        <>Les saisies déjà <b>synchronisées</b> avec la base de données (avec badge vert « ✓ Envoyé »).</>,
        <>Les saisies <b>en file locale</b> en attente de synchro (badge ambre « 📥 En file »).</>,
        <>Les saisies en cours de validation (« À valider »).</>,
      ]} />
      <HelpP>
        Tapez une ligne pour <b>développer le détail</b> : code du formulaire, date de capture,
        taille, et tous les champs saisis (avec aperçu des pièces jointes et coordonnées GPS si
        présentes). Limité aux 40 plus récentes pour rester rapide sur le téléphone.
      </HelpP>
      <HelpP>
        Le badge rouge sur l'icône indique le nombre total de saisies (serveur + queue locale).</HelpP>

      <HelpSubH>Photos et signatures</HelpSubH>
      <HelpList items={[
        <><b>Photo</b> : ouvre directement l'appareil photo arrière du téléphone si disponible. La vignette s'affiche dans le formulaire avec boutons « Reprendre » / « Effacer ».</>,
        <><b>Signature</b> : un cadre dessinable au doigt ou stylet. Bouton « Effacer » pour recommencer.</>,
        <>Les fichiers sont stockés dans un bucket privé de stockage scopé à votre organisation. Les URLs signées sont générées à la demande pour la consultation.</>,
      ]} />

      <HelpSubH>Hors-ligne et synchronisation</HelpSubH>
      <HelpP>
        Le système essaie <b>toujours d'envoyer immédiatement</b> au serveur. Il bascule en file
        locale uniquement en cas de <b>vraie erreur réseau</b> (timeout, pas de connexion). Les
        erreurs de permission (RLS) ne sont jamais mises en queue silencieusement : un message
        rouge précise la raison pour que vous sachiez quoi corriger.
      </HelpP>
      <HelpList items={[
        <>Saisie envoyée avec succès → toast vert « ✓ Saisie envoyée ».</>,
        <>Erreur réseau → la saisie est mise en file locale, toast ambre « 📥 Saisie mise en file locale ». Photos et signatures incluses (stockées en base64 dans le navigateur).</>,
        <>Erreur de permission (vous ne pouvez pas soumettre ce formulaire / ce projet) → toast rouge avec le message du serveur.</>,
        <>Pastille <span className="pill amber dot">N</span> dans la barre supérieure : nombre de saisies en attente locale.</>,
        <>Bouton <HelpKey>Sync</HelpKey> dans la barre (apparaît quand il y a des saisies en attente) : force la tentative immédiate. Le résultat s'affiche dans une banderole sous la barre, avec la première erreur concrète si une saisie reste bloquée.</>,
        <>Auto-flush : dès que le réseau revient, la file se vide silencieusement en arrière-plan.</>,
      ]} />

      <HelpSubH>Pastille ADMIN</HelpSubH>
      <HelpP>
        Si la pastille violette <span style={{ background: "#7c3aed", color: "white", padding: "1px 6px", borderRadius: 999, fontSize: 10, fontWeight: 700 }}>ADMIN</span>
        {" "}apparaît dans la barre supérieure du mode mobile, votre compte a la permission
        <b>administrateur</b> et <b>voit TOUS les formulaires de l'organisation</b>
        — indépendamment des affectations projet/agent. C'est par design pour la supervision,
        mais ça peut prêter à confusion quand on teste des restrictions. Pour valider le filtrage
        des agents de terrain, connectez-vous avec un compte qui n'a <em>pas</em> ce rôle.
      </HelpP>

      <HelpSubH>Configurer un formulaire (côté administrateur)</HelpSubH>
      <HelpP>
        Un formulaire de collecte est composé de plusieurs <b>champs</b> de types différents
        (texte libre, nombre, date, oui/non, liste déroulante, tableau, photo, signature).
        Vous le construisez visuellement depuis <b>Administration → Formulaires</b> grâce au
        constructeur de formulaires — voir la section <b>« Administration »</b> de cette aide
        pour le détail des étapes. Le champ <b>« Site »</b> est ajouté automatiquement par
        l'application mobile : pas besoin de le déclarer manuellement.
      </HelpP>

      <HelpNote tone="warn">
        L'iPhone exige que la permission <b>Localisation</b> soit accordée à Safari (Réglages →
        Safari → Localisation) pour que le GPS attache lat/lng aux saisies.
      </HelpNote>
    </div>
  );
  return (
    <div>
      <HelpH>Mobile data collection</HelpH>
      <HelpP>
        The <b>Data Collection</b> module is built for field agents: offline capture, deferred
        sync, photo, signature and geolocation. It runs in the phone browser and installs as a
        PWA for a native-app feel.
      </HelpP>

      <HelpSubH>Install on your phone</HelpSubH>
      <HelpList items={[
        <><b>Android / Chrome</b>: open the URL → ⋮ menu → <em>Install app</em>. Or, on the Data Collection screen, tap <HelpKey>Install app</HelpKey>.</>,
        <><b>iPhone / iPad (Safari)</b>: open the URL in <b>Safari</b> (not Chrome or Edge on iOS) → Share <span style={{ fontFamily: "ui-sans-serif" }}>□↑</span> → <em>Add to Home Screen</em> → Add.</>,
        <>The MELR icon appears on the home screen and launches straight into <b>Data Collection</b> full-screen.</>,
      ]} />
      <HelpNote tone="info">
        On iOS, only <b>Safari</b> can install a PWA. Chrome and Edge on iPhone will run the app
        but can't pin a home-screen shortcut.
      </HelpNote>

      <HelpSubH>Mobile full-screen route</HelpSubH>
      <HelpP>
        On phone or desktop, the URL <HelpKey>?mobile=1</HelpKey> switches the app to full-screen
        mobile (no sidebar, no Android frame, just Home → Form → Review). The
        <HelpKey>Desktop</HelpKey> button in the top bar returns to the dashboard.
      </HelpP>

      <HelpSubH>Submit an entry</HelpSubH>
      <HelpList items={[
        <>On the home screen, pick a <b>form</b> from the list (loaded from the database).</>,
        <>If the agent is assigned to <b>multiple projects</b>, a "Project" picker appears above the list. With a single project the list is auto-filtered, no picker shown.</>,
        <>GPS is requested in the background; coordinates auto-attach to the entry if the user grants permission.</>,
        <>Select a <b>site</b> (required) and fill in the fields defined by the schema: text, number, date, boolean, select, matrix, <b>photo</b> or <b>signature</b>.</>,
        <>Tap <HelpKey>Continue</HelpKey> → <em>Review</em> screen → <HelpKey>Submit</HelpKey>. A toast confirms the upload.</>,
      ]} />

      <HelpSubH>My submissions</HelpSubH>
      <HelpP>
        The <Icon.fileText className="sm" /> icon top-right of the home screen opens
        <b> My submissions</b>. It combines into one list:
      </HelpP>
      <HelpList items={[
        <>Submissions already <b>synced</b> to the database (green "✓ Sent" badge).</>,
        <>Submissions <b>locally queued</b> waiting for sync (amber "📥 Queued" badge).</>,
        <>Submissions in review ("Review").</>,
      ]} />
      <HelpP>
        Tap a row to <b>expand the detail</b>: form code, capture date, size, and every captured
        field (with attachment thumbnails and GPS coordinates when present). Limited to the 40
        most recent for phone performance.
      </HelpP>
      <HelpP>
        The red badge on the icon shows the total count (server + local queue).
      </HelpP>

      <HelpSubH>Photo &amp; signature</HelpSubH>
      <HelpList items={[
        <><b>Photo</b>: opens the phone's rear camera directly if available. Thumbnail with Retake / Clear buttons.</>,
        <><b>Signature</b>: a canvas you draw on with finger or stylus. Clear button to start over.</>,
        <>Files are stored in a private storage bucket scoped to your organization. Signed URLs are generated on demand for viewing.</>,
      ]} />

      <HelpSubH>Offline &amp; sync</HelpSubH>
      <HelpP>
        The system <b>always tries to send to the server immediately</b>. It falls back to the
        local queue only on a <b>real network error</b> (timeout, no connection). Permission
        errors (RLS) are never silently queued — a red toast surfaces the exact reason so you
        know what to fix.
      </HelpP>
      <HelpList items={[
        <>Submission sent → green toast "✓ Submission saved".</>,
        <>Network error → entry queued locally, amber toast "📥 Saved locally". Photos and signatures included (stored as base64 in the browser).</>,
        <>Permission error (you can't submit this form / this project) → red toast with the server message.</>,
        <><span className="pill amber dot">N</span> pill in the top bar: count of locally queued submissions.</>,
        <><HelpKey>Sync</HelpKey> button in the bar (appears when entries are pending): forces an immediate retry. The outcome shows in a banner under the bar, with the first concrete error if any submission stays blocked.</>,
        <>Auto-flush: as soon as the network returns, the queue drains silently in the background.</>,
      ]} />

      <HelpSubH>ADMIN pill</HelpSubH>
      <HelpP>
        If the violet <span style={{ background: "#7c3aed", color: "white", padding: "1px 6px", borderRadius: 999, fontSize: 10, fontWeight: 700 }}>ADMIN</span>
        {" "}pill appears in the mobile top bar, your account has the
        <b>administrateur</b> permission and <b>sees ALL forms in the organization</b>
        — regardless of project/agent assignments. By design for supervision, but it can be
        confusing when testing restrictions. To validate field-agent filtering, sign in with an
        account that does <em>not</em> have that role.
      </HelpP>

      <HelpSubH>Configure a form (admin)</HelpSubH>
      <HelpP>
        A data-collection form is built from several <b>fields</b> of different types (free text,
        number, date, yes/no, dropdown, matrix, photo, signature). Build it visually from
        <b> Administration → Forms</b> with the visual form builder — see the
        <b> "Administration"</b> section of this help for the step-by-step. The <b>"Site"</b>
        field is auto-injected by the mobile app: no need to declare it manually.
      </HelpP>

      <HelpNote tone="warn">
        iPhone requires Safari to have <b>Location</b> permission (Settings → Safari → Location)
        for GPS to attach lat/lng to entries.
      </HelpNote>
    </div>
  );
}

function HelpAdmin({ lang }) {
  if (lang === "fr") return (
    <div>
      <HelpH>Administration</HelpH>

      <HelpNote tone="success">
        Toutes les actions d'administration courantes se font <b>directement dans
        l'interface</b> (Sidebar → Administration). L'envoi d'email (inscription, récupération
        de mot de passe, notifications, invitations) fonctionne dès la première installation.
      </HelpNote>

      <HelpSubH>Ajouter un nouveau membre à votre organisation</HelpSubH>
      <HelpP>
        Quand un nouveau collègue s'inscrit depuis le panneau de connexion (onglet
        « Créer un compte »), son compte est créé mais il n'est rattaché à aucune organisation
        par sécurité. Pour l'ajouter à la vôtre :
      </HelpP>
      <HelpList items={[
        <>Sidebar → <b>Organisation & rôles</b></>,
        <>Section « Inscrits en attente » → cliquer <b>« Ajouter à l'org »</b> sur la ligne du nouvel inscrit</>,
        <>Le membre apparaît immédiatement dans la liste « Membres de l'organisation »</>,
      ]} />

      <HelpSubH>Attribuer un rôle à un membre</HelpSubH>
      <HelpP>
        Dans <b>Organisation & rôles</b>, en face de chaque membre, utilisez le menu
        <HelpKey>+ rôle</HelpKey> pour ajouter un rôle. Les rôles disponibles se gèrent dans la
        matrice « Rôles × permissions » en haut de la page. À la première utilisation, cliquez
        sur <b>« Initialiser 5 rôles par défaut »</b> pour créer en un clic les rôles
        Administrateur, Chef de projet, Suivi & Évaluation, Agent de saisie et Bailleur, avec
        leurs permissions standards.
      </HelpP>
      <HelpP style={{ marginTop: 8 }}>
        Pour créer un rôle sur mesure adapté à votre organisation (par exemple
        « Coordinateur régional », « Responsable qualité données »), utilisez le bouton
        <b> « Nouveau rôle »</b>. Vous attribuez ensuite les permissions case par case dans la
        matrice.
      </HelpP>

      <HelpSubH>Retirer l'accès d'un membre</HelpSubH>
      <HelpP>
        Dans <b>Organisation & rôles</b>, cliquez sur le bouton <b>×</b> en bout de ligne du
        membre. Son compte est conservé (il peut toujours se connecter à la plateforme) mais il
        ne verra plus aucune donnée de votre organisation. Pour le réintégrer plus tard, il
        réapparaîtra automatiquement dans « Inscrits en attente ».
      </HelpP>

      <HelpSubH>Affecter des agents à un projet</HelpSubH>
      <HelpP>
        Par défaut, un nouveau membre de l'organisation ne voit <b>aucun formulaire de
        projet</b> sur mobile tant que vous ne l'avez pas affecté à un projet spécifique. C'est
        ce qui empêche chaque agent de voir tous les formulaires de toute l'organisation.
      </HelpP>
      <HelpList items={[
        <>Sidebar → <b>Organisation & rôles</b></>,
        <>Faire défiler jusqu'à la carte <b>« Affectations aux projets »</b> (sous la liste des membres).</>,
        <>Pour chaque membre, sélectionner les projets via le menu <b>+ projet</b>. Une pastille verte apparaît par projet affecté. Le × retire l'affectation.</>,
        <>Les changements sont instantanés — l'agent verra les nouveaux formulaires sur son mobile dès le prochain rafraîchissement, sans déconnexion.</>,
      ]} />
      <HelpNote tone="info">
        Les administrateurs voient tous les formulaires de leur organisation, peu importe les
        affectations. L'écran d'affectation sert uniquement à filtrer ce que voient les agents
        de saisie.
      </HelpNote>

      <HelpSubH>Créer ou modifier un formulaire de collecte</HelpSubH>
      <HelpP>
        L'application propose un <b>constructeur visuel</b> qui vous permet de créer un
        formulaire complet sans aucune compétence technique. Accessible dans
        <b> Administration → Formulaires</b>. Visible uniquement pour les administrateurs.
      </HelpP>
      <HelpList items={[
        <>Bouton <b>+ Nouveau formulaire</b> en haut à droite → ouvre l'éditeur.</>,
        <><b>Renseignements de base</b> : code court unique (par exemple CPN-01), nom en français (obligatoire), nom en anglais (optionnel), version (« v1 » par défaut), projet de rattachement, état actif ou inactif.</>,
        <><b>Champs du formulaire</b> : ajoutez, réordonnez (flèches ↑↓) ou supprimez chaque champ. Pour chacun : une clé technique (utilisée pour stocker la donnée), un libellé (ce que voit l'agent), et un type parmi 8 — texte, nombre, date, oui/non, liste déroulante, tableau, photo, signature.</>,
        <><b>Liste déroulante</b> : éditeur visuel ligne par ligne, libellé à gauche + valeur stockée à droite (auto-générée). Bouton <b>+ Option</b> pour ajouter une nouvelle valeur, flèches pour réordonner.</>,
        <>Cliquez sur <b>Enregistrer</b>. Le formulaire apparaît immédiatement sur le mobile des agents affectés au projet.</>,
      ]} />
      <HelpP>
        Le champ <b>« site »</b> est ajouté automatiquement par l'application mobile — vous n'avez
        pas à le créer. Les champs photo et signature fonctionnent dès la première configuration
        de la plateforme.
      </HelpP>

      <HelpSubH>Restreindre un formulaire à des agents précis</HelpSubH>
      <HelpP>
        Par défaut, tous les agents affectés à un projet voient tous les formulaires du projet.
        Pour aller plus loin (par exemple : seules les infirmières remplissent le formulaire
        CPN-01, seuls les vaccinateurs remplissent VAX-01) :
      </HelpP>
      <HelpList items={[
        <>Ouvrir le formulaire dans le constructeur (bouton <b>Modifier</b>).</>,
        <>Faire défiler jusqu'à la section <b>« Restriction par agent »</b> (visible uniquement après la première création du formulaire).</>,
        <>Cliquer sur les agents concernés pour les ajouter à la liste — chaque clic les ajoute ou les retire. La banderole verte confirme : « 🔒 Restriction active : seuls les N agent(s) sélectionné(s) verront ce formulaire. »</>,
        <>Cliquer <b>Enregistrer</b>. La banderole reste verte tant qu'au moins un agent est dans la liste.</>,
        <>Pour <b>retirer toute restriction</b> : cliquer sur tous les agents pour les désélectionner (la banderole redevient orange : « Aucune restriction active »). Enregistrer.</>,
      ]} />
      <HelpNote tone="warn">
        Une banderole <b>orange</b> signifie qu'aucune restriction n'est active : <b>tous les
        agents du projet</b> voient le formulaire. Une banderole <b>verte</b> avec un nombre
        signifie qu'une restriction est active. En cas de doute, vérifiez d'abord la couleur de
        la banderole.
      </HelpNote>
      <HelpP>
        Dans la liste des formulaires, la colonne <b>« Restriction »</b> affiche soit
        « 🔒 N » (pastille verte avec le nombre d'agents autorisés) soit « Tous » (pastille
        grise) — pratique pour auditer en un coup d'œil quels formulaires sont ouverts.
      </HelpP>

      <HelpSubH>Super-admin · Agir en tant qu'admin d'une autre organisation</HelpSubH>
      <HelpP>
        Sidebar → <b>Organisation & rôles</b>. Si vous êtes super-administrateur de la
        plateforme, un bandeau violet apparaît en haut de la page :
        <b> « 🛡 Mode super-admin · Agir en tant qu'admin de : [Org X] »</b>. Le menu
        déroulant liste toutes les organisations actives de la plateforme.
      </HelpP>
      <HelpList items={[
        <>Sélectionnez l'organisation cible → <b>tous les sous-panneaux</b> (matrice rôles, membres, affectations aux projets, inscrits en attente, invitations) opèrent maintenant sur cette organisation.</>,
        <>Ce mode ne change pas votre identité ni votre profil : vous restez membre de votre organisation d'origine. C'est juste un changement de contexte d'administration.</>,
        <>Le bandeau reste visible tant que vous êtes sur Organisation & rôles. Revenez à votre organisation d'origine en la re-sélectionnant dans le menu.</>,
      ]} />
      <HelpNote tone="info">
        Pour <b>créer ou transférer un projet</b> vers une autre organisation, vous n'avez pas
        besoin de basculer le contexte : utilisez directement les boutons sur la page Projets
        (voir ci-dessous).
      </HelpNote>

      <HelpSubH>Super-admin · Créer ou transférer un projet vers une autre organisation</HelpSubH>
      <HelpP>
        Sidebar → <b>Projets</b>. Trois actions super-admin sont disponibles sur chaque ligne
        de projet (visibles uniquement pour les super-administrateurs) :
      </HelpP>
      <HelpList items={[
        <><b>👤 Resp.</b> — désigner le chef de projet parmi les membres de l'organisation propriétaire du projet. Distinct des agents de saisie (voir ci-après).</>,
        <><b>🔁 Transférer</b> — déplacer le projet vers une autre organisation. Conséquences : le lien au programme parent est rompu (les programmes sont attachés à une organisation), le responsable du projet est effacé (à redéfinir dans la nouvelle organisation), les affectations des agents de l'ancienne organisation sont effacées. Les indicateurs, sites, saisies et audits du projet suivent automatiquement.</>,
        <><b>+ Nouveau projet</b> dans la barre d'actions ouvre un formulaire avec un menu <em>Organisation cible</em> en haut (visible super-admin uniquement) — choisir l'organisation de destination avant de créer.</>,
      ]} />
      <HelpNote tone="warn">
        Après transfert d'un projet, le champ <b>Responsable</b> est vide (l'ancien chef
        appartenait à l'ancienne organisation et ne peut plus piloter le projet). Cliquez sur
        <b> 👤 Resp.</b> sur la ligne du projet pour désigner un nouveau chef parmi les membres
        de la nouvelle organisation.
      </HelpNote>

      <HelpSubH>Super-admin · Transférer un programme entier vers une autre organisation</HelpSubH>
      <HelpP>
        Sidebar → <b>Programmes</b>. Sur la ligne de chaque programme, un bouton
        <b>🔁 Transférer</b> (visible super-admin uniquement) ouvre une fenêtre de confirmation.
        À la différence du transfert d'un seul projet, ici <em>le programme et TOUS ses projets
        déménagent ensemble</em> :
      </HelpP>
      <HelpList items={[
        <>Le lien <b>programme ↔ projets</b> est conservé : les projets restent attachés au programme.</>,
        <>Le <b>responsable</b> de CHAQUE projet est effacé — l'administrateur de la nouvelle organisation en désignera un par projet.</>,
        <>Les <b>affectations agents</b> sont effacées pour tous les projets du programme.</>,
        <>Les <b>indicateurs, sites, saisies et audits</b> suivent chacun leur projet automatiquement.</>,
        <>Les <b>définitions d'indicateurs</b> (catalogue partagé de l'organisation) NE sont PAS déplacées — elles restent dans l'organisation d'origine.</>,
      ]} />

      <HelpSubH>Trois concepts à ne pas confondre : Responsable, Agents, Restriction</HelpSubH>
      <HelpP>
        Trois mécanismes différents qu'il est facile de confondre :
      </HelpP>
      <HelpList items={[
        <><b>Responsable de projet</b> — UNE seule personne, le pilotage hiérarchique du projet. Désignée sur la page <b>Projets → 👤 Resp.</b></>,
        <><b>Agents affectés au projet</b> — plusieurs personnes autorisées à saisir des données terrain sur le projet. Définies dans <b>Organisation & rôles → Affectations aux projets</b>.</>,
        <><b>Restriction par formulaire</b> — un sous-ensemble des agents affectés qui peuvent remplir UN formulaire précis (par exemple : sur ce formulaire CPN-01, seules deux infirmières spécifiques). Définie dans <b>Formulaires → Modifier le formulaire → Restriction par agent</b>.</>,
      ]} />

      <HelpSubH>Onboarding · organisation choisie à l'inscription</HelpSubH>
      <HelpP>
        Quand un nouveau collègue crée son compte, il voit un menu déroulant
        <b> « Organisation à rejoindre »</b> pré-rempli avec la liste des organisations actives.
        Quand il valide son inscription :
      </HelpP>
      <HelpList items={[
        <>Son compte est créé et marqué « en attente » dans l'organisation qu'il a choisie.</>,
        <>L'administrateur de cette organisation le voit dans <b>« Inscrits en attente »</b> avec une pastille bleue « Demande : Nom de l'organisation ».</>,
        <>L'administrateur clique sur <b>« + Ajouter à l'org »</b> → le membre est officiellement rattaché et peut accéder aux données de l'organisation.</>,
        <>Côté administrateur classique : la liste des inscrits est filtrée à son organisation (un admin de l'organisation A ne voit pas les demandes pour l'organisation B). Côté super-administrateur : il voit toutes les demandes et peut surcharger via le menu organisation par ligne.</>,
      ]} />

      <HelpSubH>Appartenance à plusieurs organisations</HelpSubH>
      <HelpP>
        Un utilisateur peut appartenir à <b>plusieurs organisations</b> simultanément.
        Son organisation d'origine reste son <b>organisation principale</b> (« home org ») —
        celle par défaut quand il se connecte. Les organisations supplémentaires sont des
        appartenances secondaires.
      </HelpP>
      <HelpList items={[
        <><b>Sélecteur « 🏢 Organisation active »</b> dans la barre supérieure. Visible si l'utilisateur appartient à plus d'une organisation, ou s'il est super-administrateur (même avec une seule appartenance). Son choix est mémorisé dans le navigateur. Le badge <em>« home »</em> identifie l'organisation d'origine.</>,
        <><b>Raccourci super-admin « + Rejoindre une autre organisation »</b> : dans le menu déroulant du sélecteur cyan, en bas. Permet de s'ajouter en deux clics comme membre secondaire de n'importe quelle organisation. L'organisation active bascule automatiquement sur la nouvelle organisation après ajout.</>,
        <><b>Distinct du bandeau super-admin 🛡 « Agit sur »</b> : ce dernier est un mode temporaire pour administrer une autre organisation sans en être membre. L'organisation active, elle, est un choix utilisateur permanent parmi ses appartenances réelles.</>,
        <><b>Pour qu'un administrateur ajoute un membre existant</b> : Sidebar → <b>Organisation & rôles</b> → bouton <b>+ Membre existant</b> dans la carte « Membres ». Entrer l'email (la personne doit déjà avoir un compte sur la plateforme), choisir éventuellement un rôle. Son organisation d'origine reste inchangée.</>,
        <><b>Section « 🔗 Membres rattachés »</b> sous la liste des membres : liste les utilisateurs dont l'organisation d'origine est ailleurs mais qui ont une appartenance ici. Bouton × pour révoquer l'appartenance (l'utilisateur reste membre de son organisation d'origine).</>,
        <><b>Invitations par lien</b> : si l'utilisateur invité a déjà un compte sur la plateforme, l'invitation ajoute une appartenance secondaire (au lieu de remplacer son organisation d'origine). Si c'est un nouveau compte, le comportement est inchangé (l'organisation cible devient son organisation d'origine).</>,
        <><b>Écrans qui respectent l'organisation active</b> : Tableau de bord, Projets, Programmes, Indicateurs (Suivi et Définitions), Reporting, Audit Système S&E, Audit des Données, Workflow, Ex-ante. La liste des projets, indicateurs et dossiers est filtrée sur l'organisation active. Pour les écrans Audit Système et Audit des Données, le projet choisi est mémorisé entre vos sessions.</>,
      ]} />
      <HelpNote tone="info">
        Quand vous <b>créez quelque chose</b> (un nouveau projet, un indicateur, un formulaire),
        l'application utilise l'organisation active comme valeur par défaut. Vérifiez la
        pastille cyan en haut avant de créer pour éviter les erreurs.
      </HelpNote>

      <HelpSubH>Onboarding · invitations par lien</HelpSubH>
      <HelpP>
        Pour un onboarding sans phase d'attente, l'administrateur génère un lien d'invitation à
        usage unique. Si un email est renseigné, l'invitation est envoyée automatiquement au
        destinataire (le lien est aussi copié dans le presse-papier comme filet de sécurité).
        Sinon, l'administrateur partage le lien lui-même par le canal de son choix (WhatsApp,
        SMS, etc.).
      </HelpP>
      <HelpList items={[
        <><b>Côté administrateur</b> : Sidebar → <b>Organisation & rôles</b> → carte <b>« Invitations par lien »</b> → bouton <b>+ Inviter</b>.</>,
        <>Choix : <b>Email (envoi automatique)</b> — si renseigné, lien à usage unique pour ce compte ET email envoyé automatiquement au destinataire ; rôle attribué automatiquement quand la personne s'inscrit ; validité (24h / 3 jours / 7 jours / 30 jours).</>,
        <>Au save : (a) avec email → message vert <em>« ✉ Invitation envoyée à X (lien aussi copié) »</em> ; (b) sans email → message vert <em>« ✓ Lien copié dans le presse-papier »</em> à partager manuellement.</>,
        <><b>Côté futur membre</b> : il clique sur le lien → arrive sur le panneau d'authentification avec une banderole bleue « ✉ Invitation à rejoindre [Nom de l'organisation] » → s'inscrit (ou se connecte s'il a déjà un compte) → l'invitation est consommée automatiquement → il est directement membre de l'organisation, sans phase d'attente.</>,
        <>L'administrateur peut <b>révoquer</b> une invitation à tout moment (bouton ×). Les invitations utilisées et expirées restent visibles dans la liste pour audit.</>,
      ]} />
      <HelpNote tone="info">
        Les deux flux coexistent : « organisation choisie à l'inscription » pour les campagnes
        d'enrôlement large où vous ne savez pas qui va s'inscrire ; « invitations par lien »
        pour onboarder un collègue nommément, plus rapide et plus sûr.
      </HelpNote>

      <HelpSubH>Super-admin · Gérer les organisations de la plateforme</HelpSubH>
      <HelpP>
        Sidebar → <b>Administration → Gestion des Organisations</b>. Cette page est visible
        uniquement pour les super-administrateurs de la plateforme. Elle permet de créer,
        archiver, restaurer et supprimer des organisations.
      </HelpP>
      <HelpList items={[
        <>Bouton <b>+ Nouvelle organisation</b> → formulaire avec le nom, un identifiant court généré automatiquement, la langue par défaut, et une URL de logo (optionnel).</>,
        <>Pour chaque ligne : <b>Modifier</b>, <b>Archiver</b> ou <b>Restaurer</b> (réversible, l'organisation archivée est masquée par défaut), et <b>Supprimer</b> (irréversible, efface toutes les données de l'organisation).</>,
        <>La suppression d'une organisation demande une <b>confirmation tapée</b> de son identifiant pour éviter les fausses manipulations.</>,
        <>Une fois l'organisation créée, ajoutez le premier administrateur via <b>Organisation & rôles → Inscrits en attente</b> (la personne doit d'abord créer son compte depuis le panneau de connexion).</>,
      ]} />
      <HelpNote tone="warn">
        Le rôle <b>super-administrateur</b> est distinct de celui d'administrateur d'une
        organisation. Un administrateur classique gère son organisation ; un super-administrateur
        voit et gère toutes les organisations de la plateforme. Il existe toujours au moins
        deux super-administrateurs sur la plateforme (par sécurité, pour éviter de perdre
        l'accès).
      </HelpNote>

      <HelpSubH>Indicateurs · le catalogue partagé de l'organisation</HelpSubH>
      <HelpP>
        Sidebar → <b>Indicateurs → Définition des indicateurs</b>. Ce catalogue est partagé
        entre tous les projets de votre organisation. Au lieu de redéfinir le même indicateur
        sur chaque projet, vous le définissez UNE FOIS dans le catalogue, puis les chefs de
        projet le réutilisent. Chaque entrée porte :
      </HelpP>
      <HelpList items={[
        <>Un <b>code unique</b> (par exemple « SANT.CPN4 », « EDU.COMPL2ND », « PFM.PEFA17 ») — c'est ce code que les chefs de projet sélectionneront depuis « Code importé » lors de la création de leurs indicateurs.</>,
        <>Un <b>nom</b> en français et en anglais.</>,
        <>Une <b>institution d'origine</b> (par exemple OMS, UNESCO, USAID, votre propre organisation, PEFA…) pour tracer la provenance.</>,
        <>Un <b>niveau logframe</b> (Output, Outcome, Impact, Contextuel).</>,
        <>Un <b>type de mesure</b> : numérique (chiffres bruts) ou Score PEFA (lettres A à D).</>,
      ]} />
      <HelpP style={{ marginTop: 8 }}>
        Actions disponibles :
      </HelpP>
      <HelpList items={[
        <>Bouton <b>+ Nouvelle définition</b> → formulaire en deux temps : (1) saisir les renseignements de base et enregistrer ; (2) attacher les fiches PIRS multilingues.</>,
        <><b>Fiches PIRS multilingues</b> : pour chaque définition, vous attachez autant de fichiers que de langues nécessaires (FR / EN / ES / PT / AR ou neutre). Formats acceptés : PDF, Word, Excel. 10 Mo maximum par fichier. Les fichiers sont accessibles via des liens valables une heure (sécurité).</>,
        <>Bouton <b>Importer Excel</b> pour créer ou mettre à jour plusieurs définitions en une fois depuis un tableur. Colonnes attendues : Code, Nom (FR), Nom (EN), Origine, Niveau. Les lignes incomplètes sont ignorées.</>,
        <>Bouton <b>Exporter CSV</b> pour archiver le catalogue ou le partager en dehors de la plateforme.</>,
        <>La colonne <b>PIRS</b> de la liste affiche le nombre de fichiers attachés — cliquez pour ouvrir l'éditeur.</>,
      ]} />

      <HelpSubH>Indicateurs · types de mesure (numérique ou PEFA)</HelpSubH>
      <HelpP>
        Le champ <b>Type de mesure</b> de chaque définition détermine la façon dont les valeurs
        seront saisies dans le module Suivi :
      </HelpP>
      <HelpList items={[
        <><b>Numérique</b> (par défaut) — saisie en chiffres bruts pour la baseline, la cible et chaque valeur périodique. Unité libre (%, kg, FCFA, USD…).</>,
        <><b>Score PEFA</b> — saisie alphabétique selon l'échelle officielle : A (équivalent 4), B+ (3,5), B (3), C+ (2,5), C (2), D+ (1,5), D (1), ou NR (Non noté). Dans le module Suivi, baseline / cible / valeurs deviennent des menus déroulants par lettre, et la conversion numérique est faite automatiquement pour les graphiques et les barres de progression.</>,
      ]} />

      <HelpSubH>Indicateurs · créer un indicateur projet depuis le catalogue</HelpSubH>
      <HelpList items={[
        <>Sidebar → <b>Indicateurs → Suivi des indicateurs</b> → bouton <b>+ Nouvel indicateur</b>.</>,
        <>Premier champ <b>« Code importé »</b> : choisir une entrée du catalogue → le code, le nom et le niveau se pré-remplissent et se verrouillent. Le type de mesure (numérique ou PEFA) est aussi adopté depuis le catalogue.</>,
        <>Vous pouvez aussi laisser « Saisie manuelle » pour créer un code personnalisé (non lié au catalogue), mais c'est rarement recommandé.</>,
        <>Choisir le projet, l'unité, la baseline, la cible et la fréquence de mesure. Pour PEFA : baseline et cible sont des menus par lettre.</>,
      ]} />

      <HelpSubH>Indicateurs · modifier ou supprimer (administrateur)</HelpSubH>
      <HelpP>
        Sur chaque ligne d'indicateur, à côté du bouton « Valeur », les administrateurs voient
        deux boutons supplémentaires :
      </HelpP>
      <HelpList items={[
        <><b>✎ Modifier</b> — ouvre l'éditeur pré-rempli. Vous pouvez changer : nom (FR/EN), niveau, unité, baseline, cible, fréquence. Le code reste en lecture seule (pour renommer, supprimez + recréez).</>,
        <><b>× Supprimer</b> — confirmation explicite avec avertissement : toutes les valeurs saisies pour cet indicateur sont aussi supprimées (en cascade).</>,
      ]} />

      <HelpSubH>Indicateurs · saisie groupée sur plusieurs sites</HelpSubH>
      <HelpP>
        Dans le module Suivi des indicateurs, le bouton <b>Saisir</b> de la carte
        « Saisie multi-sites » ouvre un formulaire de saisie en lot :
      </HelpP>
      <HelpList items={[
        <>Choisir un indicateur dans le menu déroulant (liste filtrée aux indicateurs du projet courant).</>,
        <>Définir une période (par défaut, le trimestre en cours).</>,
        <>Un tableau apparaît avec une ligne par site du projet : Site (code + nom + région) + un champ valeur (numérique ou liste PEFA selon le type d'indicateur).</>,
        <>Les lignes laissées vides sont ignorées à l'enregistrement.</>,
        <>Cliquez sur <b>Enregistrer toutes les valeurs</b> → un message vert confirme le nombre de valeurs enregistrées.</>,
      ]} />

      <HelpSubH>Exporter les saisies d'un formulaire en Excel</HelpSubH>
      <HelpP>
        Sur la ligne de chaque formulaire dans <b>Administration → Formulaires</b>, cliquez sur
        le bouton <b>Exporter</b>. Un formulaire s'ouvre :
      </HelpP>
      <HelpList items={[
        <><b>Plage de dates</b> à exporter. Laisser vide pour tout exporter depuis le début.</>,
        <>Case <b>« Inclure les URLs des pièces jointes »</b> — cochée par défaut. Décochez-la pour un fichier plus léger sans la liste des photos/signatures.</>,
        <>Cliquez sur <b>Exporter</b> → téléchargement immédiat d'un fichier Excel nommé avec le code du formulaire et la date.</>,
      ]} />
      <HelpP>
        Le fichier Excel contient 3 onglets :
      </HelpP>
      <HelpList items={[
        <><b>Saisies</b> : une ligne par soumission, avec une colonne par champ du formulaire et toutes les métadonnées (identifiant, dates, site, agent, coordonnées GPS).</>,
        <><b>Pièces jointes</b> : liens directs pour télécharger les photos et signatures depuis Excel (valables 1 heure pour des raisons de sécurité).</>,
        <><b>Schéma</b> : la définition complète du formulaire au moment de l'export — le fichier est auto-documenté et peut être archivé seul.</>,
      ]} />

      <HelpSubH>Réinitialiser un mot de passe</HelpSubH>
      <HelpP>
        Sur le panneau de connexion, n'importe quel utilisateur peut cliquer sur
        <b> « Mot de passe oublié »</b> → un email de récupération lui est envoyé
        automatiquement. Si un membre ne le reçoit pas (boîte spam, email erroné), un
        administrateur peut déclencher manuellement le renvoi depuis la console d'administration
        de la plateforme.
      </HelpP>

      <HelpSubH>Personnaliser les flux d'approbation</HelpSubH>
      <HelpP>
        Sidebar → <b>Workflow</b> → bouton <b>« Configurer flux »</b>. Un modèle de flux se
        définit par type d'objet (évaluation SAT, audit qualité, rapport bailleur, etc.) avec
        une liste d'étapes ordonnée (par exemple : soumission → revue par le chef de projet →
        validation par le coordinateur S&E → approbation finale), un délai de traitement, et
        une fréquence de rappel automatique. Les soumissions ultérieures de ce type d'objet
        utilisent automatiquement le modèle actif.
      </HelpP>

      <HelpSubH>Traiter les tickets de support</HelpSubH>
      <HelpP>
        Les administrateurs voient un panneau <b>« Administration des tickets »</b> en bas de
        l'onglet « Support & contact ». Filtres Ouverts / Clôturés / Tous ; changement d'état
        (Nouveau → En revue → Résolu) ; priorité ; note de résolution visible par l'auteur du
        ticket.
      </HelpP>

      <HelpSubH>Modifier les paramètres de votre organisation</HelpSubH>
      <HelpP>
        Sidebar → <b>Administration → Paramètres</b> → carte « Organisation » : nom,
        identifiant court, URL du logo, langue par défaut. La même page permet aussi de modifier
        votre profil personnel et l'apparence de l'application (thème, couleur d'accent,
        densité d'affichage).
      </HelpP>
    </div>
  );
  return (
    <div>
      <HelpH>Administration</HelpH>

      <HelpNote tone="success">
        All routine admin tasks are now performed <b>directly in the UI</b> (Sidebar →
        Administration). An <b>email service</b> is configured: email sign-up, password recovery
        and email notifications all work.
      </HelpNote>

      <HelpSubH>Add a member to your organization</HelpSubH>
      <HelpP>
        New sign-ups (login screen → "Create account") get a profile but no organization by
        design. To add them:
      </HelpP>
      <HelpList items={[
        <>Sidebar → <b>Administration</b> → <b>Organization & roles</b></>,
        <>"Pending sign-ups" panel → click <b>"Add to org"</b></>,
        <>The member appears immediately in "Organization members"</>,
      ]} />

      <HelpSubH>Assign a role to a member</HelpSubH>
      <HelpP>
        In <b>Organization & roles</b>, next to each member, use the <HelpKey>+ role</HelpKey>
        dropdown. Available roles are managed in the "Roles × permissions" matrix above. On first
        use, click <b>"Seed 5 default roles"</b> to create Admin, Project lead, M&E, Field entry
        and Donor with their standard permissions.
      </HelpP>
      <HelpP style={{ marginTop: 8 }}>
        For custom roles (e.g. <em>data_steward</em>, <em>regional_lead</em>), use the
        <b> "New role"</b> button. Permissions are then toggled in the matrix.
      </HelpP>

      <HelpSubH>Revoke a member's access</HelpSubH>
      <HelpP>
        In <b>Organization & roles</b>, click the <HelpKey>×</HelpKey> at the end of the member's
        row. The account is preserved (the user can still log in) but no tenant data is visible.
        To re-add them, they'll reappear in "Pending sign-ups".
      </HelpP>

      <HelpSubH>Assign agents to a project</HelpSubH>
      <HelpP>
        By default a new org member sees <b>no project form</b> on mobile until you assign them
        to a specific project. This prevents every agent from seeing every form in the org.
      </HelpP>
      <HelpList items={[
        <>Sidebar → <b>Administration → Organization & roles</b></>,
        <>Scroll to the <b>"Project assignments"</b> card (below the members list).</>,
        <>For each member, pick projects via the <HelpKey>+ project</HelpKey> dropdown. A green pill appears per assigned project. The × removes the assignment.</>,
        <>Changes are realtime — the agent sees new forms on mobile immediately without reloading.</>,
      ]} />
      <HelpNote tone="info">
        Administrators see every form in their org regardless of assignments. This screen is
        used to filter non-admin agents.
      </HelpNote>

      <HelpSubH>Create or edit a form</HelpSubH>
      <HelpP>
        The visual builder avoids writing SQL. Reached in <b>Administration → Forms</b>.
        Visible only with the <b>administrateur</b> permission.
      </HelpP>
      <HelpList items={[
        <><HelpKey>+ New form</HelpKey> button top-right → opens the editor modal.</>,
        <><b>Metadata</b>: code (short, unique), French name (required), English name (optional), version ("v1" default), parent project, active/inactive.</>,
        <><b>Schema fields</b>: add / reorder (↑↓) / remove. Per field: a <em>key</em> (alphanumeric + underscore, e.g. <HelpKey>date_visit</HelpKey>), a display <em>label</em>, and a <em>type</em> among 8: text, number, date, yes/no, select, matrix, photo, signature.</>,
        <><b>Dropdown</b>: visual row-based editor, label on the left + stored value on the right (auto-derived from the label). <HelpKey>+ Option</HelpKey> to add, ↑↓× to reorder or delete.</>,
        <>Click <HelpKey>Save</HelpKey>. The form appears immediately on mobile for agents assigned to the project.</>,
      ]} />
      <HelpP>
        The <b>"site"</b> field is auto-injected by the mobile app — no need to add it to the
        schema. Photo and signature fields work as soon as the platform is initially configured.
      </HelpP>

      <HelpSubH>Restrict a form to specific agents</HelpSubH>
      <HelpP>
        By default every agent assigned to a form's project sees it. To narrow further (e.g.
        nurses fill CPN-01 only, vaccinators only VAX-01):
      </HelpP>
      <HelpList items={[
        <>Open the form in the builder (<HelpKey>Edit</HelpKey> button).</>,
        <>Scroll to the <b>"Restrict to specific agents"</b> section (visible only after the form is first created).</>,
        <>Click on the relevant agents to add them to the list — each click toggles. The green banner confirms "🔒 Restriction active: only the N selected agent(s) will see this form."</>,
        <>Click <HelpKey>Save</HelpKey>. The banner stays green as long as ≥1 agent is in the list.</>,
        <>To <b>lift the restriction</b>: deselect every agent (the banner turns amber, "No restriction active"). Save.</>,
      ]} />
      <HelpNote tone="warn">
        The <b>amber</b> banner means "0 restriction" so <b>everyone in the project sees</b> the
        form. The <b>green</b> banner with the count means restriction active. If you want to
        restrict and the agent still sees everything, check the banner colour first.
      </HelpNote>
      <HelpP>
        In the forms list, the <b>"Restriction"</b> column shows either "🔒 N" (green pill with
        the count of allowed agents) or "All" (faint pill) — useful for auditing which forms are
        open vs restricted at a glance.
      </HelpP>

      <HelpSubH>Super-admin · Acting as admin of another org</HelpSubH>
      <HelpP>
        Sidebar → <b>Organization & roles</b>. Holders of the
        <b>super-administrateur</b> permission see a violet banner above
        the matrix: <b>"🛡 Super-admin mode · Acting as admin of:
        [Org X]"</b>. The dropdown lists every active organization.
      </HelpP>
      <HelpList items={[
        <>Switch to the target org → <b>every sub-panel</b> (roles matrix, members, project assignments, pending sign-ups, invitations) operates on that org.</>,
        <>Acting-as doesn't change your identity or your profile: you remain a member of your home org. It's only an admin-context switch.</>,
        <>The banner stays visible while you're on Org & roles. Switch back to your home org by re-selecting it in the dropdown.</>,
      ]} />
      <HelpNote tone="info">
        To <b>create or transfer a project</b> for another org you don't need
        acting-as mode: use the dedicated buttons on the Projects page (below).
      </HelpNote>

      <HelpSubH>Super-admin · Create or transfer a project across orgs</HelpSubH>
      <HelpP>
        Sidebar → <b>Projects</b>. Three super-admin actions are available on
        every row (visible only with <b>super-administrateur</b>):
      </HelpP>
      <HelpList items={[
        <><b>👤 Lead</b> — set the project lead from the project's org members. Distinct from field agents (see below).</>,
        <><b>🔁 Transfer</b> — move the project to another organization. Consequences: the parent-programme link is dropped (programmes are org-scoped), the lead is reset to NULL (to be re-picked), existing agent assignments are wiped. Indicators, sites, submissions and audits follow the project.</>,
        <><b>+ New project</b> in the toolbar opens a modal with an <em>Target organization</em> dropdown at the top (visible only to super-admins) — pick the destination org before creating.</>,
      ]} />
      <HelpNote tone="warn">
        After transferring a project the <b>Lead</b> column is empty (the old
        lead belonged to the previous org). Click <b>👤 Lead</b> on the project
        to designate a new lead from the new org's members.
      </HelpNote>

      <HelpSubH>Super-admin · Transfer a whole programme to another org</HelpSubH>
      <HelpP>
        Sidebar → <b>Programmes</b>. On each programme row, a <b>🔁 Transfer</b>
        button (super-admin only) opens a confirmation modal. Unlike a
        single-project transfer, here <em>the programme AND all its projects move
        together</em>:
      </HelpP>
      <HelpList items={[
        <>The <b>programme ↔ projects</b> link is preserved (projects stay attached to the programme).</>,
        <>EACH project's <b>lead</b> is reset to NULL — the new org's admin will pick one per project.</>,
        <><b>Agent assignments</b> are wiped for every project in the programme.</>,
        <><b>Indicators, sites, submissions, audits</b> follow each project (natural FK cascade).</>,
        <><b>Indicator definitions</b> (the org catalogue) are NOT moved — they stay in the source org.</>,
      ]} />

      <HelpSubH>Distinct concepts: Lead, Agents, Restriction</HelpSubH>
      <HelpP>
        Three different mechanisms easily confused:
      </HelpP>
      <HelpList items={[
        <><b>Project lead</b> — ONE person, hierarchical ownership. Set in <b>Projects → 👤 Lead</b>.</>,
        <><b>Project-assigned agents</b> — N people allowed to submit field data on the project. Set in <b>Org & roles → Project assignments</b>.</>,
        <><b>Per-form restriction</b> — subset of those agents who can fill a specific form. Set in <b>Form Builder → edit form → Restrict to agents</b>.</>,
      ]} />

      <HelpSubH>Onboarding · org chosen at sign-up</HelpSubH>
      <HelpP>
        When creating an account, the new user sees an <b>"Organization to
        join"</b> dropdown populated with the list of active organizations.
        On submit:
      </HelpP>
      <HelpList items={[
        <>Their account is created and marked "pending" against the chosen organization.</>,
        <>The admin of the chosen org sees them under <b>"Pending sign-ups"</b> with a blue chip "Wants to join: Org Name".</>,
        <>Admin clicks "+ Add to org" → the user becomes an official member.</>,
        <>Regular admin: the pending list is filtered to their org (no cross-org leak). Super-admin: sees every request, can override via the per-row org picker.</>,
      ]} />

      <HelpSubH>Multi-organization membership</HelpSubH>
      <HelpP>
        A user can belong to <b>several organizations</b> at the same time. Their original
        organization stays as their <b>home org</b> — the default they land on at sign-in.
        Extra organizations are <em>secondary memberships</em>.
      </HelpP>
      <HelpList items={[
        <><b>'🏢 Active organization' switcher</b> in the topbar. Visible when the user has > 1 membership OR when they're a super-admin (even with a single membership). Persisted in the browser (localStorage). A <em>'home'</em> badge identifies the original org.</>,
        <><b>Super-admin '+ Join another organization' shortcut</b> (v1.10): at the bottom of the cyan selector's dropdown. Lets you self-add as a secondary member of any org in two clicks, without going through the violet pill + '+ Existing member' flow. The active org automatically switches to the freshly-joined one.</>,
        <><b>Distinct from the super-admin 🛡 'Acting on' pill</b>: the latter is a temporary admin override for managing another org without being a member. The active org is a permanent user choice among their real memberships.</>,
        <><b>For an admin to add an existing member</b>: Sidebar → <b>Organization & roles</b> → <HelpKey>+ Existing member</HelpKey> button in the Members card. Enter their email (they must already have an account), optionally pick a role. Their original org stays unchanged.</>,
        <><b>'🔗 Attached members' section</b> below the members list: lists users whose home org is elsewhere but who have a membership here. × button revokes the membership (the user stays in their home org).</>,
        <><b>Invitations</b>: if the invited user already has an account, the invitation adds a secondary membership (instead of replacing their home org). If it's a new account, the legacy behaviour applies (target org becomes their home).</>,
        <><b>Screens that honor the active org</b>: Dashboard, Projects, Programmes, Indicators (Tracking + Definitions), Reporting, Audit System, Audit Data, Workflow, Ex-ante. The list of projects / indicators / dossiers is filtered to the active org. For Audit System and Audit Data, the project you choose is remembered between sessions.</>,
      ]} />
      <HelpNote tone="info">
        For <b>writes</b> (create a project, capture an indicator value,
        etc.), the app uses the active org as the default. The user controls
        which org is active via the topbar selector.
      </HelpNote>
      <HelpSubH>Onboarding · invitation links</HelpSubH>
      <HelpP>
        For onboarding without a "pending" phase, the admin generates a
        single-use invitation link. If an email is set, the invitation is
        sent to the recipient automatically (the link is also copied to the
        clipboard as a safety net). Otherwise, the admin shares the link
        manually via any channel.
      </HelpP>
      <HelpList items={[
        <><b>Admin side</b>: Sidebar → <b>Organization & roles</b> → <b>"Invitation links"</b> card → <HelpKey>+ Invite</HelpKey> button.</>,
        <>Inputs: <b>Email (auto-send)</b> — if set, link is single-use for that account AND the email is auto-sent; auto-assigned role on redeem; validity (24h / 3d / 7d / 30d).</>,
        <>On save: (a) with email → green toast <em>"✉ Invitation sent to X (link also copied)"</em>; (b) without email → green toast <em>"✓ Link copied to clipboard"</em> for manual sharing.</>,
        <><b>Future member side</b>: they click → land on the auth panel with a blue banner "✉ Invitation to join Org Name" → sign up (or sign in if they already have an account) → the invitation is consumed automatically → they become a direct member, no pending phase.</>,
        <>Admin can <b>revoke</b> an invitation anytime (× button). Used and expired invitations stay visible in the list for audit.</>,
      ]} />
      <HelpNote tone="info">
        Both flows coexist. For agents who don't know the org before signup
        (broad enrolment campaign), the org-at-signup is enough. For inviting
        a named member, the invitation link is faster and safer.
      </HelpNote>

      <HelpSubH>Super-admin — manage organizations</HelpSubH>
      <HelpP>
        Sidebar → <b>Administration → Organization Management</b>. Visible only to accounts holding the
        <b>super-administrateur</b> permission. Creates, archives, restores and deletes
        organizations platform-wide.
      </HelpP>
      <HelpList items={[
        <><HelpKey>+ New organization</HelpKey> → modal Name + Slug (auto-derived) + Default locale + Logo URL (optional).</>,
        <>Per-row: <b>Edit</b>, <b>Archive / Restore</b> (reversible, hidden by default) and <b>Delete</b> (irreversible, cascade to every record).</>,
        <>Deletion requires a <b>typed confirmation</b> of the slug — prevents accidents.</>,
        <>After creation, add the first admin via <b>Organization & roles → Pending sign-ups</b> (they must first sign up from the auth panel).</>,
      ]} />
      <HelpNote tone="warn">
        The <b>super-administrator</b> role is distinct from a regular organization
        <b> administrator</b>. A regular admin manages THEIR own org; a super-administrator
        sees and manages EVERY organization on the platform. At least two super-administrators
        always exist (for safety, to avoid losing access).
      </HelpNote>

      <HelpSubH>Indicators — org-wide catalogue ("Indicator definitions")</HelpSubH>
      <HelpP>
        Sidebar → <b>Indicators → Indicator definitions</b>. Org-wide catalogue shared across
        every project. Each entry has a unique code (reusable as "Imported code" in Tracking), a
        FR/EN name, an origin institution (REFT Africa, WHO, USAID, PEFA…), a logframe level
        and a measurement type (numeric or PEFA).
      </HelpP>
      <HelpList items={[
        <><HelpKey>+ New definition</HelpKey> button → two-step modal: (1) metadata + Save; (2) attach the multilingual PIRS sheets.</>,
        <><b>Multilingual PIRS sheets</b>: any number of files per definition (FR / EN / ES / PT / AR / language-neutral). PDF, Word or Excel · 10 MB max per file. Stored in the private <HelpKey>indicator-pirs</HelpKey> bucket, scoped per organization.</>,
        <><HelpKey>Import Excel</HelpKey> bulk-upserts on (org, code). Recognized columns: <em>Code · Name (FR) · Name (EN) · Origin · Level</em> (FR/EN aliases tolerated). Rows missing Code or FR Name are skipped.</>,
        <><HelpKey>Export CSV</HelpKey> for auditing or Excel round-tripping.</>,
        <>The list's PIRS column shows <span className="pill green dot" style={{ fontSize: 10 }}>🗎 N</span> with the file count; click to open the editor.</>,
      ]} />

      <HelpSubH>Indicators — measurement types (numeric vs PEFA)</HelpSubH>
      <HelpP>
        The <b>Measurement type</b> field on a definition drives the entry UI in Tracking.
      </HelpP>
      <HelpList items={[
        <><b>Numeric</b> (default) — raw figures for baseline, target and values. Free-text unit (%, kg, USD…).</>,
        <><b>PEFA score</b> — alphabetic entry. Official De Renzio scale: A=4 · B+=3.5 · B=3 · C+=2.5 · C=2 · D+=1.5 · D=1 · NR=not rated. In Tracking, baseline / target / values become letter dropdowns; the converted numeric is computed automatically for sparklines and progress bars.</>,
      ]} />

      <HelpSubH>Indicators — create a project indicator from the catalogue</HelpSubH>
      <HelpList items={[
        <>Sidebar → <b>Indicators → Indicator tracking</b> → <HelpKey>+ New indicator</HelpKey>.</>,
        <>First field "<b>Imported code</b>": pick a catalogue entry → code, name and level auto-fill and lock (greyed background). The measurement type (numeric/PEFA) is also adopted from the catalogue.</>,
        <>Or leave "Manual entry" for a custom code (not linked to the catalogue).</>,
        <>Pick the project, unit, baseline, target, frequency. For PEFA: baseline and target are letter dropdowns.</>,
      ]} />

      <HelpSubH>Indicators — edit or delete (admin)</HelpSubH>
      <HelpP>
        On every indicator row, alongside the "Value" button, admins see two extra buttons
        (gated on the <b>administrateur</b> permission):
      </HelpP>
      <HelpList items={[
        <><b>✎ Edit</b> — pre-filled editor. Editable: FR/EN name, level, unit, baseline, target, frequency. The <em>code</em> stays read-only (to rename, delete + recreate).</>,
        <><b>× Delete</b> — explicit confirmation with cascade warning: every captured value goes too.</>,
      ]} />
      <HelpNote tone="info">
        At the DB layer, UPDATE and DELETE are guarded by RLS: only an account with
        <b>administrateur</b> can write/delete. UI hides the buttons, base rejects
        the requests — defense in depth.
      </HelpNote>

      <HelpSubH>Indicators — multi-site batch entry</HelpSubH>
      <HelpP>
        In Indicator tracking, the <HelpKey>Enter</HelpKey> button on the "Multi-site data
        entry" card opens a batch-entry modal:
      </HelpP>
      <HelpList items={[
        <>Pick an indicator from the dropdown (filtered to the current project's indicators).</>,
        <>Set a period (defaults to the current quarter).</>,
        <>Table with one row per project site: Site (code + name + region) + value field (numeric or PEFA dropdown depending on the indicator's measurement type).</>,
        <>Empty rows skipped on save.</>,
        <>Single <HelpKey>Save all values</HelpKey> button → one bulk INSERT → toast with the number of values stored.</>,
      ]} />

      <HelpSubH>Export submissions to Excel</HelpSubH>
      <HelpP>
        On each form's row in <b>Administration → Forms</b>, an <HelpKey>Export</HelpKey> button
        opens a modal:
      </HelpP>
      <HelpList items={[
        <><b>Date range</b> to export. Leave blank for everything since the beginning.</>,
        <><b>"Include attachment URLs"</b> checkbox — on by default. Uncheck for a lighter file without the attachments sheet.</>,
        <>Click <b>Export</b> → instant download of an Excel file named with the form code and the date.</>,
      ]} />
      <HelpP>
        The file has 3 sheets:
      </HelpP>
      <HelpList items={[
        <><b>Saisies</b>: one row per submission with one column per schema field + metadata (ID, dates, site, agent, GPS).</>,
        <><b>Pièces jointes</b>: signed URLs (1h) to download photos and signatures right from Excel. Also includes the permanent <em>storage path</em> for re-signing later via the API.</>,
        <><b>Schéma</b>: full form definition at export time — the file is self-documenting.</>,
      ]} />

      <HelpSubH>Reset a password</HelpSubH>
      <HelpP>
        On the login screen, any user can click <b>"Forgot password"</b> → a recovery email is
        sent automatically. If a member doesn't receive it (spam folder, wrong email), an
        administrator can trigger a manual resend from the platform admin console.
      </HelpP>

      <HelpSubH>Customize approval workflows</HelpSubH>
      <HelpP>
        Sidebar → <b>Workflow</b> → <b>"Configure flow"</b> button. A flow template is defined
        per object type (SAT evaluation, DQA audit, donor report, etc.) with an ordered list of
        steps (e.g. submission → review by the project lead → validation by the M&E coordinator
        → final approval), a processing deadline, and an automatic reminder cadence. Subsequent
        submissions of that object type use the active template automatically.
      </HelpP>

      <HelpSubH>Handle support tickets</HelpSubH>
      <HelpP>
        Administrators see a <b>"Tickets administration"</b> panel at the bottom of the
        "Support & contact" tab. Filters Open / Closed / All; state transitions (New → In
        review → Resolved); priority; resolution note visible to the ticket author.
      </HelpP>

      <HelpSubH>Edit organization settings</HelpSubH>
      <HelpP>
        Sidebar → <b>Administration → Settings</b> → "Organization" card: name, short
        identifier, logo URL, default language. The same page lets you edit your personal
        profile and the appearance of the application (theme, accent colour, layout density).
      </HelpP>
    </div>
  );
}

function HelpFAQ({ lang }) {
  const faq = lang === "fr" ? [
    { q: "Je ne vois aucune donnée après connexion.",
      a: "Votre profil n'est pas rattaché à une organisation. Demandez à votre administrateur de le faire (Administration → Organisation & rôles → onglet 'Inscrits en attente')." },
    { q: "Le badge 'Live' n'apparaît pas en haut des écrans.",
      a: "Les mises à jour en temps réel ne sont pas activées sur ce tableau côté serveur. Contactez l'administrateur de la plateforme." },
    { q: "Mon nouveau site n'apparaît pas sur la carte.",
      a: "Vérifiez que vous avez bien saisi la latitude et la longitude (en degrés décimaux). Sans coordonnées, le site apparaît seulement dans la liste à droite." },
    { q: "Je ne reçois pas l'email de confirmation après inscription.",
      a: "Un service email est configuré. Vérifiez vos spams. Si l'email tarde plus de quelques minutes, contactez l'admin via le formulaire de support (Aide → Support & contact)." },
    { q: "Mon item est marqué DEMO — pourquoi je ne peux pas l'approuver ?",
      a: "Les items DEMO sont des exemples codés dans l'app, ils n'existent pas dans la base de données. Pour un item modifiable, soumettez-en un depuis SAT, DVT ou Reporting via le bouton 'Soumettre pour validation'." },
    { q: "Comment installer MELR sur mon téléphone ?",
      a: "Android / Chrome : ouvrir l'app → menu ⋮ → 'Installer l'application'. Sur l'écran 'Collecte de données', un bouton 'Installer l'app' est aussi proposé. iPhone (Safari uniquement) : Partager → Sur l'écran d'accueil. L'icône se lance directement en mode collecte." },
    { q: "Mes saisies hors-ligne ne sont pas envoyées.",
      a: "Quand le réseau revient, la file se vide automatiquement. Si elle persiste : ouvrir Collecte de données en mode bureau et cliquer 'Synchroniser'. La pastille de la barre supérieure indique combien de saisies sont en attente locale." },
    { q: "Les photos ou signatures ne fonctionnent pas.",
      a: "Sur iPhone, l'accès à l'appareil photo demande l'autorisation Safari (Réglages → Safari → Caméra). Sur Android, l'autorisation s'accorde au premier usage via une popup. Si le problème persiste après autorisation, contacter le support via le formulaire intégré." },
    { q: "Safari iOS affiche 'Response served by service worker has redirections'.",
      a: "Bug iOS connu avec les service workers et les réponses redirigées. Le fix a été déployé (cleanResponse côté SW). Pour récupérer : supprimer + ré-ajouter l'icône MELR sur l'écran d'accueil, ou Réglages → Safari → Avancé → Données du site → supprimer 'melr'." },
    { q: "Comment passer en mode mobile depuis l'ordinateur ?",
      a: "Ajouter ?mobile=1 à la fin de l'URL, ou utiliser le raccourci 'Collecte' de l'icône PWA (long-press)." },
    { q: "Le GPS n'est pas attaché à mes saisies.",
      a: "Le navigateur doit avoir l'autorisation géolocalisation. Sur Chrome Android : icône cadenas dans la barre d'URL → Localisation. Sur iPhone : Réglages → Safari → Localisation → Autoriser." },
    { q: "Le panneau de connexion gêne ma vision.",
      a: "Le panneau est déplaçable : le saisir par sa barre supérieure pour le glisser. Il y a aussi un bouton de réduction. Sa position est mémorisée pour la prochaine session." },
    { q: "Le panneau d'administration des tickets n'apparaît pas.",
      a: "Il n'est visible qu'aux administrateurs. Vérifier dans Administration → Organisation & rôles que votre rôle a bien la permission « Gestion des utilisateurs ». Au premier lancement, cliquer sur « Initialiser 5 rôles par défaut » pour créer les rôles standards." },
    { q: "Mon agent voit tous les formulaires alors qu'il ne devrait en voir qu'un.",
      a: "Trois vérifications : (1) Le compte de l'agent n'est-il pas administrateur ? Une pastille violette « ADMIN » apparaît en haut du mode mobile quand le compte a les droits d'administration — les admins voient tout par design. (2) Ouvrir le formulaire dans Administration → Formulaires et vérifier la couleur de la banderole « Restriction par agent » — orange signifie « aucune restriction active ». (3) La colonne « Restriction » dans la liste des formulaires doit afficher « 🔒 N » (vert), pas « Tous ». Si elle dit « Tous », ouvrir le formulaire, sélectionner les agents autorisés, et enregistrer." },
    { q: "Mes saisies restent en file d'attente alors que je suis en ligne.",
      a: "Toucher le bouton « Sync » dans la barre mobile (apparaît dès qu'il y a une saisie en attente). Un message s'affiche : si c'est « X envoyée(s) », c'était un problème transitoire de réseau, c'est résolu. Si c'est « X bloquée(s) », la cause la plus fréquente est que l'agent n'est pas affecté au projet du formulaire. Solution : un administrateur va dans Organisation & rôles → Affectations aux projets et ajoute l'agent au projet." },
    { q: "Où retrouver mes saisies passées sur le téléphone ?",
      a: "Icône 'fichier' en haut à droite de l'écran d'accueil mobile (avec badge rouge indiquant le nombre total). Ouvre 'Mes saisies' : liste combinée des saisies serveur + queue locale, par ordre antéchronologique, avec détail expandable en tap." },
    { q: "Comment créer un nouveau formulaire ?",
      a: "Administration → Formulaires → bouton « + Nouveau formulaire ». Le constructeur visuel demande un code court, un nom (FR + EN), un projet de rattachement, puis vous propose un éditeur de champs (ajouter, réordonner, supprimer) avec 8 types : texte, nombre, date, oui/non, liste déroulante (avec éditeur d'options visuel), tableau, photo, signature. Accessible aux administrateurs uniquement." },
    { q: "Comment exporter les saisies d'un formulaire en Excel ?",
      a: "Administration → Formulaires → bouton 'Exporter' sur la ligne du formulaire. Choisir une plage de dates, cocher 'Inclure URLs pièces jointes', cliquer Exporter. Téléchargement immédiat d'un .xlsx avec 3 onglets (Saisies, Pièces jointes, Schéma). Les URLs des photos/signatures sont signées et valables 1 heure." },
    { q: "Comment ajouter une fiche PIRS dans une autre langue ?",
      a: "Indicateurs → Définition des indicateurs → Modifier la définition → section « Fiches PIRS multilingues » → mini-formulaire en bas (langue + libellé + fichier) → Ajouter. Autant de fichiers que de langues nécessaires. Chaque fichier reste disponible via un lien signé 1h." },
    { q: "Comment saisir un indicateur scoré PEFA (A, B+, etc.) ?",
      a: "Dans Définition des indicateurs, choisir « Score PEFA » dans le champ « Type de mesure ». Toutes les saisies suivantes (baseline, cible, valeurs périodiques) seront des dropdowns alphabétiques (A · B+ · B · C+ · C · D+ · D · NR). La conversion numérique (A=4, B+=3.5, B=3, C+=2.5, C=2, D+=1.5, D=1) est automatique et alimente sparklines et progress bars." },
    { q: "J'ai créé un indicateur avec une mauvaise baseline. Faut-il le supprimer et recréer ?",
      a: "Non, modifie-le directement. Dans Suivi des indicateurs, en tant qu'admin, le bouton ✎ apparaît à côté de « Valeur ». Modifie baseline, cible, nom, niveau, fréquence. Seul le code reste verrouillé (pour le renommer, il faut effectivement supprimer + recréer)." },
    { q: "Comment supprimer un indicateur déjà saisi ?",
      a: "Action administrateur uniquement. Dans Suivi des indicateurs → bouton × sur la ligne. Une confirmation explicite vous rappelle que toutes les valeurs saisies pour cet indicateur seront aussi supprimées (en cascade)." },
    { q: "Saisir la même valeur sur 10 sites un par un, c'est long.",
      a: "Utiliser la « Saisie multi-sites ». Suivi des indicateurs → carte « Saisie multi-sites » → bouton Saisir. Choisir l'indicateur + la période, remplir une valeur par site dans la table. Un seul Save → un INSERT bulk. Les lignes vides sont ignorées." },
    { q: "Comment inviter un nouveau membre par lien ?",
      a: "Sidebar → Organisation & rôles → carte « Invitations par lien » → bouton « + Inviter ». Renseigner un email (lien à usage unique pour ce compte ET envoi automatique de l'invitation à cette adresse) et un rôle pré-attribué, puis la validité (24h à 30j). Au save, le toast confirme l'envoi de l'email ; le lien est aussi copié dans le presse-papier en filet de sécurité. Le destinataire clique → s'inscrit → est rattaché à l'org sans phase d'attente. Si l'email est laissé vide : pas d'envoi, juste un lien à partager manuellement." },
    { q: "L'envoi automatique d'email ne marche pas, le message est orange.",
      a: "L'envoi peut être indisponible temporairement (service email non configuré ou en maintenance). Dans ce cas, l'invitation est quand même créée et le lien est copié dans votre presse-papier — il suffit de le coller dans un email manuel et de l'envoyer vous-même au destinataire. Contactez votre administrateur plateforme pour vérifier la configuration du service email." },
    { q: "Combien de temps un lien d'invitation reste-t-il valide ?",
      a: "Tu choisis à la création : 24h, 3 jours, 7 jours (recommandé) ou 30 jours. Passé ce délai, le lien affiche « Expirée » et ne peut plus être utilisé. Tu peux toujours en générer un nouveau ou révoquer manuellement via le bouton × dans la liste." },
    { q: "Pourquoi mon administrateur ne voit pas tous les inscrits en attente ?",
      a: "C'est par design depuis la version multi-organisations. Un administrateur classique ne voit que les inscrits qui ont choisi SON organisation au moment de leur inscription (ou ceux qui n'ont rien choisi). Le super-administrateur de la plateforme voit toutes les demandes, toutes organisations confondues, et peut les dispatcher via le menu organisation par ligne." },
    { q: "Comment ajouter une nouvelle organisation à la plateforme ?",
      a: "Action super-admin. Sidebar → Administration → Gestion des Organisations → bouton « + Nouvelle organisation ». Remplir Nom + Slug (auto-généré depuis le nom) + Langue par défaut + URL logo (optionnel) → Créer. Puis ajouter le premier admin de la nouvelle org via Organisation & rôles → Inscrits en attente (il doit d'abord créer son compte depuis le panneau de connexion)." },
    { q: "Comment supprimer une organisation ?",
      a: "Action super-admin, irréversible. Gestion des Organisations → bouton × rouge sur la ligne. Pour confirmer, il faut retaper le slug exact de l'org. Cascade définitive sur tous les projets, sites, indicateurs, formulaires, saisies, audits, rapports et profils membres de l'org. Préférer l'archivage si tu veux pouvoir revenir en arrière." },
    { q: "Quelle est la différence entre 'archiver' et 'supprimer' une organisation ?",
      a: "Archiver = réversible. L'org devient masquée par défaut dans la liste (case 'Inclure les archivées' pour la rendre visible). Toutes les données restent intactes en base, on peut restaurer à tout moment. Supprimer = définitif, cascade catastrophique sur toutes les données dépendantes. Préférer toujours archiver d'abord, supprimer uniquement quand on est certain." },
    { q: "Je suis administrateur mais je ne vois pas « Gestion des Organisations » dans la barre latérale.",
      a: "C'est normal. Cette entrée est réservée aux super-administrateurs de la plateforme — distincts des administrateurs d'une organisation. Un administrateur classique gère SON organisation ; un super-administrateur voit et gère toutes les organisations." },
    { q: "Comment désigner le chef d'un projet (responsable hiérarchique) ?",
      a: "Sidebar → Projets → bouton 👤 Resp. sur la ligne du projet. La fenêtre liste les membres de l'organisation propriétaire du projet — choisir une personne, Enregistrer. Le responsable est une UNE personne (le chef de projet) ; à distinguer des agents de saisie qui sont plusieurs et qui se gèrent dans Organisation & rôles." },
    { q: "Après transfert d'un projet, pourquoi le responsable est vide ?",
      a: "C'est volontaire. L'ancien responsable appartenait à l'organisation d'origine — il ne peut pas piloter un projet d'une autre organisation. Le transfert efface le responsable. Désignez un nouveau via Projets → 👤 Resp. en choisissant un membre de la nouvelle organisation." },
    { q: "Comment transférer un projet d'une organisation à une autre ?",
      a: "Action super-administrateur. Sidebar → Projets → bouton 🔁 Transférer sur la ligne. Choisir l'organisation cible, confirmer. Le projet change d'organisation. Conséquences listées dans la fenêtre : lien programme rompu, responsable effacé, affectations agents effacées. Les indicateurs, sites et saisies suivent le projet automatiquement." },
    { q: "Comment transférer un programme entier (avec tous ses projets) ?",
      a: "Action super-administrateur. Sidebar → Programmes → bouton 🔁 Transférer sur la ligne du programme. À la différence du transfert d'un seul projet, le programme et TOUS ses projets déménagent ensemble — le lien programme↔projets est préservé. Conséquences : le responsable de chaque projet est effacé, les affectations agents sont purgées pour tous les projets, les indicateurs/sites/saisies suivent leurs projets. Les définitions d'indicateurs (catalogue) restent dans l'organisation d'origine." },
    { q: "Quelle différence entre Responsable, Agents et Restriction par formulaire ?",
      a: "Trois concepts distincts. (1) Le responsable du projet = UNE personne, le chef du projet. Défini dans Projets → 👤 Resp. (2) Les agents affectés = plusieurs personnes autorisées à saisir des données terrain. Définis dans Organisation & rôles → Affectations aux projets. (3) La restriction par formulaire = un sous-ensemble des agents affectés qui peuvent remplir UN formulaire précis. Définie dans Formulaires → Modifier → Restriction par agent." },
    { q: "Comment appartenir à plusieurs organisations ?",
      a: "Trois scénarios. (1) Super-administrateur : auto-jointure → cliquer la pastille cyan 🏢 en haut → dans le menu, en bas, « + Rejoindre une autre organisation ». (2) Un administrateur de l'organisation cible vous ajoute via Organisation & rôles → bouton « + Membre existant ». (3) Vous recevez un lien d'invitation à cette organisation alors que vous êtes déjà inscrit : en cliquant le lien, vous gagnez une appartenance secondaire (votre organisation d'origine reste votre « home »). Dans les trois cas, le sélecteur cyan 🏢 vous permet ensuite de basculer entre vos organisations." },
    { q: "J'ai cliqué sur une autre organisation dans le sélecteur cyan, rien ne change.",
      a: "Le sélecteur cyan n'opère que sur vos appartenances réelles. Si vous n'avez qu'une seule appartenance (votre organisation d'origine), le sélecteur n'a pas d'autre choix à proposer. Pour ajouter une organisation : ouvrir le menu → bouton « + Rejoindre une autre organisation » en bas (super-administrateur uniquement). Sinon, demandez à un administrateur de l'organisation cible de vous ajouter en « Membre existant »." },
    { q: "Mes données d'audit (SAT / DQA) semblent avoir disparu.",
      a: "L'écran d'audit sélectionne automatiquement le premier projet de votre liste filtrée. Si vous appartenez à plusieurs organisations, ce premier projet peut avoir changé. Vérifiez le menu projet en haut de l'écran : votre ancien projet (par exemple « Modernisation du port ») doit y figurer. Sélectionnez-le manuellement, et l'écran retient votre choix pour les prochaines visites." },
    { q: "Quelle différence entre « org active » et « Agir en tant qu'admin de » ?",
      a: "Le sélecteur cyan 🏢 « Organisation active » (en haut) est votre choix personnel parmi vos appartenances réelles — il persiste entre sessions. Le pill violet 🛡 « Agit sur » (super-admin uniquement) est un override temporaire pour gérer une autre org sans en être membre. Les deux peuvent coexister mais ne servent pas le même cas d'usage." },
    { q: "Quand je quitte une org secondaire, est-ce que je perds mes données ?",
      a: "Non. Retirer une membership secondaire (bouton × dans « Membres rattachés ») supprime votre accès à cette org mais ne touche ni à votre profil ni à votre organisation d'origine. Si vous avez créé des projets/saisies dans cette org, ils restent là — leur propriétaire reste l'org, pas vous." },
    { q: "Comment administrer une autre organisation sans changer de compte ?",
      a: "Super-admin uniquement. Sidebar → Organisation & rôles → bandeau violet « 🛡 Mode super-admin · Agir en tant qu'admin de » → choisir l'org cible. Tous les sous-panneaux (matrice rôles, membres, affectations, inscrits, invitations) opèrent sur cette org. Votre identité ne change pas, seul le contexte d'administration." },
    { q: "Je viens d'être promu super-administrateur mais la liste « Gestion des Organisations » est toujours vide.",
      a: "Cause habituelle : il faut se déconnecter puis se reconnecter pour que votre session prenne en compte le nouveau rôle. Sans cette opération, votre ancienne session ne voit pas la nouvelle permission et la liste reste vide. Déconnexion / reconnexion suffit dans la grande majorité des cas." },
    { q: "Comment exporter mes données ?",
      a: "Par formulaire de collecte : Administration → Formulaires → bouton « Exporter » sur la ligne du formulaire (Excel avec 3 onglets : saisies, pièces jointes, schéma). Pour les modules SAT, DQA et Reporting : chaque module propose son propre bouton d'export en Excel / Word / PDF. Le catalogue d'indicateurs s'exporte aussi en CSV." },
  ] : [
    { q: "I see no data after login.", a: "Your profile has no organization. Ask an admin to assign one (Administration → Organization & roles → 'Pending sign-ups' tab)." },
    { q: "The 'Live' badge doesn't show.", a: "Real-time updates aren't enabled for this table on the server side. Contact the platform administrator." },
    { q: "My new site is not on the map.", a: "Make sure you entered latitude AND longitude as decimal degrees. Without coords, the site only appears in the right-hand list." },
    { q: "I'm not receiving the confirmation email after sign-up.", a: "An email service is configured. Check your spam folder. If the email is delayed by more than a few minutes, contact the admin through the support form (Help → Support & contact)." },
    { q: "My item is marked DEMO — why can't I approve it?", a: "DEMO items are app-coded examples, they don't exist in the database. For an editable item, submit one from SAT, DVT, or Reporting via the 'Submit for validation' button." },
    { q: "How do I install MELR on my phone?", a: "Android / Chrome: open the app → ⋮ menu → 'Install app'. The Data Collection screen also offers an 'Install app' button. iPhone (Safari only): Share → Add to Home Screen. The icon launches straight into Data Collection mode." },
    { q: "My offline entries aren't being sent.", a: "The queue drains automatically when the network returns. If it persists: open Data Collection in desktop mode and tap 'Sync'. The pill in the top bar shows how many entries are locally queued." },
    { q: "Photos or signatures don't work.", a: "On iPhone, camera access requires Safari permission (Settings → Safari → Camera). On Android, permission is granted on first use via a popup. If the problem persists after granting permission, contact support via the in-app form." },
    { q: "Safari iOS shows 'Response served by service worker has redirections'.", a: "Known iOS bug with service workers and redirected responses. The fix is deployed (cleanResponse in the SW). To recover: remove + re-add the MELR icon on the home screen, or Settings → Safari → Advanced → Website Data → delete 'melr'." },
    { q: "How do I switch to mobile mode from a desktop?", a: "Append ?mobile=1 to the URL, or use the 'Collecte' shortcut on the PWA icon (long-press)." },
    { q: "GPS is not attached to my entries.", a: "The browser must have geolocation permission. Chrome Android: lock icon in the URL bar → Location. iPhone: Settings → Safari → Location → Allow." },
    { q: "The auth panel obstructs my view.", a: "It's draggable — grab its header bar and move it. There's also a minimize button. Position is persisted across sessions." },
    { q: "The ticket administration panel doesn't show up.", a: "It's only visible to administrators. Check that your role has the 'User management' permission in Administration → Organization & roles. On first launch, click 'Seed 5 default roles' to create the standard roles." },
    { q: "My agent sees every form when they should only see one.", a: "Three checks: (1) Is the agent's account an administrator? A violet 'ADMIN' pill shows at the top of mobile mode when the account has admin rights — admins see everything by design. (2) Open the form in Administration → Forms and check the colour of the 'Restrict to agents' banner — amber means 'no active restriction'. (3) The 'Restriction' column in the forms list should show '🔒 N' (green), not 'All'. If it says 'All', open the form, select the allowed agents, and save." },
    { q: "My submissions stay queued even though I'm online.", a: "Tap the 'Sync' button in the mobile bar (visible whenever something is pending). A message appears: 'X sent' means a transient network glitch (resolved). 'X blocked: <message>' surfaces the database reason — often a missing RLS permission (the agent isn't assigned to the form's project). Fix in Org & roles → Project assignments → add the agent to the project." },
    { q: "Where do I find my past submissions on the phone?", a: "File icon top-right of the mobile home screen (red badge shows the total). Opens 'My submissions': combined list of server submissions + local queue, newest first, with expandable detail on tap." },
    { q: "How do I create a new form?", a: "Administration → Forms → '+ New form' button. The visual builder asks for a short code, a name (FR + EN), a parent project, and offers a fields editor (add, reorder, remove) covering 8 types: text, number, date, yes/no, dropdown (with visual options editor), matrix, photo, signature. Available to administrators only." },
    { q: "How do I export submissions to Excel?", a: "Administration → Forms → 'Export' button on the form's row. Pick a date range, tick 'Include attachment URLs', click Export. Immediate download of a .xlsx with 3 sheets (Saisies, Attachments, Schema). Photo/signature URLs are signed and valid for 1 hour." },
    { q: "How do I add a PIRS sheet in another language?", a: "Indicators → Indicator definitions → Edit the definition → 'Multilingual PIRS sheets' section → mini-form at the bottom (language + label + file) → Add. As many files as languages you need. Each is available via a 1h signed URL." },
    { q: "How do I capture a PEFA-scored indicator (A, B+, …)?", a: "In Indicator definitions, set 'Measurement type' to 'PEFA score'. All subsequent entries (baseline, target, periodic values) become alphabetic dropdowns (A · B+ · B · C+ · C · D+ · D · NR). Numeric conversion (A=4, B+=3.5, B=3, C+=2.5, C=2, D+=1.5, D=1) is automatic and powers sparklines + progress bars." },
    { q: "I created an indicator with the wrong baseline. Delete and recreate?", a: "No, edit it. In Indicator tracking, as admin, the ✎ button appears next to 'Value'. Edit baseline, target, name, level, frequency. Only the code stays locked (renaming the code requires delete + recreate)." },
    { q: "How do I delete an indicator that has values?", a: "Administrator-only action. In Indicator tracking → × button on the row. Explicit confirmation reminds you that every captured value for that indicator will also be deleted (in cascade)." },
    { q: "Capturing the same value across 10 sites one-by-one is tedious.", a: "Use 'Multi-site data entry'. Indicator tracking → 'Multi-site data entry' card → Enter button. Pick the indicator + period, fill one value per site in the table. Single Save → one bulk INSERT. Empty rows skipped." },
    { q: "How do I invite a new member by link?", a: "Sidebar → Organization & roles → 'Invitation links' card → '+ Invite' button. Set an email (single-use for that account AND auto-send the invitation to that address) and an auto-assigned role; pick validity (24h to 30d). On save, the toast confirms the email was sent; the link is also copied to clipboard as a safety net. The recipient clicks → signs up → is attached to the org with no pending phase. If the email is left empty: no auto-send, just a link to share manually." },
    { q: "Auto-send doesn't work — the toast is amber.", a: "The email service may be temporarily unavailable or not yet configured. In that case the invitation is still created and the link is copied to your clipboard — just paste it into a manual email and send it yourself. Contact your platform administrator to verify the email service configuration." },
    { q: "How long does an invitation link stay valid?", a: "You choose at creation: 24h, 3 days, 7 days (recommended) or 30 days. After that the link shows 'Expired' and can no longer be redeemed. You can always generate a new one or manually revoke from the list with the × button." },
    { q: "Why doesn't my admin see all pending sign-ups?", a: "By design since the multi-organization version. A regular admin only sees sign-ups who chose THEIR organization at signup (or who left it blank). The platform's super-administrator sees everything across all organizations and dispatches them via the per-row organization picker." },
    { q: "How do I add a new organization to the platform?", a: "Super-admin action. Sidebar → Administration → Organization Management → '+ New organization' button. Fill Name + Slug (auto-derived) + Default locale + Logo URL (optional) → Create. Then add the first admin via Organization & roles → Pending sign-ups (they must first sign up from the auth panel)." },
    { q: "How do I delete an organization?", a: "Super-admin action, irreversible. Organization Management → red × on the row. To confirm, retype the exact slug. Permanent cascade on every project, site, indicator, form, submission, audit, report and member profile. Prefer archiving if you may want to roll back." },
    { q: "What is the difference between archiving and deleting an organization?", a: "Archive = reversible. The org becomes hidden by default ('Include archived' to show it again). Data stays intact, restore anytime. Delete = permanent, catastrophic cascade on all dependent data. Prefer archive first, delete only when certain." },
    { q: "I'm an admin but I don't see 'Organization Management' in the sidebar.", a: "Expected. That entry is reserved for platform super-administrators — distinct from administrators of an organization. A regular admin manages THEIR organization; a super-administrator sees and manages every organization on the platform." },
    { q: "How do I designate a project lead?", a: "Sidebar → Projects → 👤 Lead button on the project row. The dialog lists the members of the organization that owns the project — pick one, Save. The lead is ONE person (the project's head); distinct from field agents, who are several and managed in Organization & roles." },
    { q: "Why is the Lead column empty after I transfer a project?", a: "By design. The previous lead belonged to the source organization — they can't lead a project in another organization. Transfer clears the lead. Designate a new one via Projects → 👤 Lead, picking a member of the new organization." },
    { q: "How do I transfer a project to another organization?", a: "Super-administrator action. Sidebar → Projects → 🔁 Transfer button on the row. Pick the target organization, confirm. The project changes organization. Consequences listed in the dialog: programme link dropped, lead cleared, agent assignments wiped. Indicators, sites and submissions follow the project automatically." },
    { q: "How do I transfer a whole programme (with all its projects)?", a: "Super-administrator action. Sidebar → Programmes → 🔁 Transfer button on the programme row. Unlike a single-project transfer, the programme AND all its projects move together — the programme↔projects link is preserved. Consequences: each project's lead is cleared, agent assignments are wiped for every project, indicators/sites/submissions follow their respective projects. Indicator definitions (the org catalogue) stay in the source organization." },
    { q: "What's the difference between Lead, Agents and Form restriction?", a: "Three distinct concepts. (1) Project lead = ONE person, the head of the project. Set in Projects → 👤 Lead. (2) Project-assigned agents = several people allowed to submit field data. Set in Organization & roles → Project assignments. (3) Per-form restriction = a subset of those agents who can fill ONE specific form. Set in Forms → Edit → Restrict to agents." },
    { q: "How can I belong to multiple organizations?", a: "Three paths. (1) [Super-admin] Self-join: click the cyan 🏢 pill in the topbar → at the bottom of the dropdown, '+ Join another organization' → pick the target org. (2) An admin of the target org adds you as 'Existing member' via Org & roles → + Existing member button. (3) You receive an invitation link to that org while already signed in: clicking it grants a secondary membership (your home org stays put). In all three cases the cyan 🏢 selector then offers your orgs to switch between them." },
    { q: "I clicked another org in the cyan selector but nothing changes.", a: "The cyan selector only operates on your REAL memberships. If you only have one membership (your home organization), the selector has no other choice to offer. To add an organization: open the dropdown → '+ Join another organization' button at the bottom (super-administrator only). Otherwise ask an administrator of the target organization to add you as 'Existing member'." },
    { q: "My audit (SAT / DQA) data appears to have disappeared.", a: "The audit screen auto-picks the first project in your filtered list. If you belong to several organizations, the first project may have shifted. Check the project dropdown at the top of the screen: your previous project should still be in the list. Pick it manually, and the screen remembers your choice across sessions." },
    { q: "What's the difference between 'Active org' and 'Acting as admin of'?", a: "The cyan 🏢 'Active organization' selector (topbar) is your personal pick among orgs you actually belong to — it persists across sessions. The violet 🛡 'Acting on' pill (super-admin only) is a temporary override to administer another org without being a member. Both can coexist but serve different purposes." },
    { q: "If I leave a secondary org, do I lose my data?", a: "No. Removing a secondary membership (× in 'Attached members') drops your access to that org but leaves your profile and home org untouched. Any projects/captures you created in that org stay there — the org owns them, not you." },
    { q: "How do I administer another organization without switching accounts?", a: "Super-admin only. Sidebar → Organization & roles → violet banner '🛡 Super-admin mode · Acting as admin of' → pick the target org. Every sub-panel (roles matrix, members, assignments, pending, invitations) operates on that org. Your identity doesn't change, only the admin context." },
    { q: "I ran the bootstrap but Organization Management is still empty.", a: "Three common causes: (1) you didn't sign out and sign back in after the grant — the JWT session keeps the old role, you must log out and log in again; (2) the bootstrap block didn't find your email (check the NOTICE output in SQL Editor) — your email in profiles may differ, try « select email from profiles where email ilike '%yourname%' »; (3) the organizations-super-admin.sql migration didn't run in full — rerun it (idempotent). Verify in SQL with « select public.is_super_admin_user() »: must return true." },
    { q: "How do I export my data?", a: "Per form: Administration → Forms → Export. SAT, DVT and Reporting export to Excel / Word / PDF via their own buttons. For raw admin export, database admin console → Table Editor → 'Export' (CSV)." },
  ];
  return (
    <div>
      <HelpH>FAQ</HelpH>
      <div style={{ marginTop: 12, display: "grid", gap: 14 }}>
        {faq.map((it, i) => (
          <div key={i}>
            <div style={{ fontWeight: 600, fontSize: 14 }}>Q. {it.q}</div>
            <div style={{ marginTop: 4, color: "var(--text-faint)" }}>{it.a}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function HelpContact({ lang }) {
  const t = (fr, en) => lang === "fr" ? fr : en;
  return (
    <div>
      <HelpH>{t("Support & contact", "Support & contact")}</HelpH>
      <HelpP>
        {t("L'application MELR est développée et maintenue par :", "MELR is developed and maintained by:")}
      </HelpP>
      <div style={{ lineHeight: 1.55, marginTop: 4 }}>
        <b>Baitir Ndoye, Ph.D.</b><br />
        Evaluator, AEA Member<br />
        Director of REFT Africa
      </div>
      <div style={{ lineHeight: 1.55, marginTop: 12 }}>
        <b>{t("Siège social", "Headquarters")} :</b><br />
        REFT Institute, Inc.<br />
        Centennial, CO, USA
      </div>

      <HelpSubH>{t("Coordonnées", "Contact details")}</HelpSubH>
      <HelpList items={[
        <>📧 Email{lang === "fr" ? " :" : ":"} <a href="mailto:it@reft-africa.org">it@reft-africa.org</a></>,
        <>📞 {t("Téléphone", "Phone")}{lang === "fr" ? " :" : ":"} <a href="tel:+221775418951">+221 77 541 8951</a></>,
        <>🌍 {t("Site web", "Website")}{lang === "fr" ? " :" : ":"} <a href="https://reft-africa.org" target="_blank" rel="noreferrer">reft-africa.org</a></>,
        <>📮 {t("Adresse", "Address")}{lang === "fr" ? " :" : ":"} BP 15570 Fann, Dakar, {t("Sénégal", "Senegal")}</>,
      ]} />

      <HelpSubH>{t("Signaler un bug ou suggérer une amélioration", "Report a bug or suggest an improvement")}</HelpSubH>
      <SupportTicketForm lang={lang} />

      <HelpSubH>{t("Mes tickets", "My tickets")}</HelpSubH>
      <SupportTicketList lang={lang} />

      <SupportAdminPanel lang={lang} />

      <HelpSubH>{t("Application", "Application")}</HelpSubH>
      <HelpList items={[
        <>URL{lang === "fr" ? " :" : ":"} <a href="https://melr.reft-africa.org" target="_blank" rel="noreferrer">melr.reft-africa.org</a></>,
      ]} />

      <HelpNote tone="success">
        {t("Version actuelle", "Current version")} : <b>1.12</b> · {new Date().toLocaleDateString(lang === "fr" ? "fr-FR" : "en-US")} · © Baitir Ndoye, Ph.D., REFT Africa
        <div style={{ marginTop: 6, fontSize: 11.5, opacity: 0.9 }}>
          {t(
            "Nouveau en v1.12 : raffinement visuel de l'interface. Les boutons se soulèvent légèrement au survol et affichent une bague de focus accessible au clavier. Les cartes prennent une ombre douce qui s'amplifie au survol. Les pastilles de statut (vert / orange / rouge / violet) ont une bordure plus nette. Les lignes des tableaux affichent une barre d'accent à gauche au survol. La sidebar marque l'élément actif d'une barre d'accent verticale et d'un léger dégradé. Les champs de saisie ont un halo de focus renforcé. Les cartes KPI gagnent un dégradé subtil et une bande d'accent en haut. Les modales s'ouvrent avec une animation 'spring' plus élégante. Bonus : nouveaux états vides élégants (icône + titre + message) et squelettes de chargement (shimmer). L'animation est désactivée automatiquement pour les utilisateurs qui ont activé 'réduire les animations' dans leur système. La fonctionnalité reste identique — seul l'aspect change.",
            "New in v1.12: visual refinement of the interface. Buttons gently lift on hover and show an accessible keyboard focus ring. Cards have a soft shadow that deepens on hover. Status pills (green / amber / red / violet) get cleaner borders. Table rows show a left accent bar on hover. The sidebar marks the active item with a vertical accent bar and a subtle gradient. Input fields gain a stronger focus halo. KPI cards get a subtle gradient and a top accent stripe. Modals open with a more elegant 'spring' animation. Bonus: new elegant empty states (icon + title + message) and shimmer skeleton loaders. Motion is disabled automatically for users who enabled 'reduce motion' in their OS settings. Functionality is unchanged — only the look-and-feel evolves."
          )}
        </div>
        <div style={{ marginTop: 6, fontSize: 11.5, opacity: 0.75 }}>
          {t(
            "v1.11 : aide réécrite pour être plus pédagogique. Toutes les références techniques aux produits tiers et aux mécanismes internes ont été retirées. L'aide se concentre désormais sur l'utilisation : comment faire telle action, où cliquer, ce qu'on voit à l'écran.",
            "v1.11: help fully rewritten with a teaching-first approach. All references to third-party products and internal mechanisms have been removed. The help now focuses on usage: how to do a given action, where to click, what to expect on screen."
          )}
        </div>
        <div style={{ marginTop: 4, fontSize: 11.5, opacity: 0.65 }}>
          {t(
            "v1.10 : sélecteur cyan d'organisation active visible pour un super-administrateur avec une seule appartenance, raccourci « + Rejoindre une autre organisation », écrans Audit / Workflow / Ex-ante respectent le contexte d'org active.",
            "v1.10: cyan active-org selector visible for a super-administrator with a single membership, '+ Join another organization' shortcut, Audit / Workflow / Ex-ante screens respect the active-org context."
          )}
        </div>
        <div style={{ marginTop: 4, fontSize: 11.5, opacity: 0.55 }}>
          {t(
            "v1.9 : appartenance à plusieurs organisations (sélecteur cyan d'organisation active, bouton « + Membre existant », acceptation d'invitation pour les utilisateurs existants).",
            "v1.9: multi-organization membership (cyan active-org selector, '+ Existing member' button, invitation redemption for existing users)."
          )}
        </div>
        <div style={{ marginTop: 4, fontSize: 11.5, opacity: 0.5 }}>
          {t(
            "v1.8 : envoi automatique des invitations par email · v1.7 : transfert de programme entier · v1.6 : workflow super-administrateur cross-organisation.",
            "v1.8: automatic invitation emails · v1.7: whole-programme transfer · v1.6: cross-organization super-admin workflow."
          )}
        </div>
      </HelpNote>
    </div>
  );
}

// Bug-report / suggestion form — persists to support_tickets via RLS
function SupportTicketForm({ lang }) {
  const t = (fr, en) => lang === "fr" ? fr : en;
  const [category, setCategory] = useStateH("bug");
  const [module, setModule]     = useStateH("");
  const [subject, setSubject]   = useStateH("");
  const [body, setBody]         = useStateH("");
  const [steps, setSteps]       = useStateH("");
  const [priority, setPriority] = useStateH("normal");
  const [busy, setBusy]         = useStateH(false);
  const [msg, setMsg]           = useStateH(null);

  const MODULES = [
    { v: "", label: t("— choisir un module —", "— pick a module —") },
    { v: "dashboard", label: t("Tableau de bord", "Dashboard") },
    { v: "programmes", label: t("Programmes", "Programmes") },
    { v: "projects", label: t("Projets", "Projects") },
    { v: "exante", label: t("Évaluation ex-ante", "Ex-ante appraisal") },
    { v: "baseline", label: "Baseline" },
    { v: "indicators", label: t("Indicateurs", "Indicators") },
    { v: "audit_system", label: t("Audit système (SAT)", "M&E system audit (SAT)") },
    { v: "audit_data", label: t("Audit des données (DVT)", "Data audit (DVT)") },
    { v: "audit_dashboard", label: t("Synthèse audits", "Audit dashboard") },
    { v: "reporting", label: "Reporting" },
    { v: "workflow", label: t("Workflow", "Workflow") },
    { v: "notifications", label: "Notifications" },
    { v: "mobile", label: t("Collecte de données (mobile)", "Data Collection (mobile)") },
    { v: "org", label: t("Organisation & rôles", "Org & roles") },
    { v: "settings", label: t("Paramètres", "Settings") },
    { v: "other", label: t("Autre", "Other") },
  ];

  const onSubmit = async (e) => {
    e.preventDefault();
    if (!subject.trim() || !body.trim()) {
      setMsg(t("Objet et description requis.", "Subject and description required."));
      return;
    }
    setBusy(true); setMsg(null);
    try {
      await window.melr.createSupportTicket({
        category, module: module || null,
        subject: subject.trim(), body: body.trim(),
        steps: steps.trim() || null, priority,
      });
      setSubject(""); setBody(""); setSteps(""); setModule("");
      setMsg(t("✓ Ticket créé. Suivi dans 'Mes tickets' ci-dessous.", "✓ Ticket created. Tracked in 'My tickets' below."));
      setTimeout(() => setMsg(null), 4000);
    } catch (err) { setMsg(err.message); }
    finally { setBusy(false); }
  };

  const inp = { width: "100%", padding: "8px 10px", borderRadius: 6, border: "1px solid var(--line)", fontSize: 13, background: "var(--bg, white)", color: "var(--text)", boxSizing: "border-box", fontFamily: "inherit" };
  const lbl = { display: "block", fontSize: 11, color: "var(--text-faint)", marginBottom: 4, textTransform: "uppercase", letterSpacing: "0.04em", marginTop: 10 };

  return (
    <form onSubmit={onSubmit} style={{ background: "var(--bg-sunken, #f9fafb)", padding: 14, borderRadius: 6, marginTop: 8 }}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 10 }}>
        <div>
          <label style={lbl}>{t("Catégorie", "Category")}</label>
          <select style={inp} value={category} onChange={(e) => setCategory(e.target.value)}>
            <option value="bug">{t("Bug", "Bug")}</option>
            <option value="suggestion">{t("Suggestion", "Suggestion")}</option>
            <option value="question">{t("Question", "Question")}</option>
          </select>
        </div>
        <div>
          <label style={lbl}>{t("Module concerné", "Module")}</label>
          <select style={inp} value={module} onChange={(e) => setModule(e.target.value)}>
            {MODULES.map((m) => <option key={m.v} value={m.v}>{m.label}</option>)}
          </select>
        </div>
        <div>
          <label style={lbl}>{t("Priorité", "Priority")}</label>
          <select style={inp} value={priority} onChange={(e) => setPriority(e.target.value)}>
            <option value="low">{t("Faible", "Low")}</option>
            <option value="normal">{t("Normale", "Normal")}</option>
            <option value="high">{t("Haute", "High")}</option>
          </select>
        </div>
      </div>

      <label style={lbl}>{t("Objet", "Subject")} *</label>
      <input style={inp} value={subject} onChange={(e) => setSubject(e.target.value)} maxLength={120}
        placeholder={t("Bouton 'Approuver' ne réagit pas dans Workflow", "'Approve' button unresponsive in Workflow")} />

      <label style={lbl}>{t("Description", "Description")} *</label>
      <textarea style={{ ...inp, minHeight: 90, resize: "vertical" }}
        value={body} onChange={(e) => setBody(e.target.value)}
        placeholder={t("Ce qui se passe et ce qui devrait se passer…", "What happens and what should happen…")} />

      <label style={lbl}>{t("Étapes pour reproduire (optionnel)", "Steps to reproduce (optional)")}</label>
      <textarea style={{ ...inp, minHeight: 60, resize: "vertical" }}
        value={steps} onChange={(e) => setSteps(e.target.value)}
        placeholder={t("1. Aller à… 2. Cliquer sur… 3. Observer…", "1. Go to… 2. Click on… 3. Observe…")} />

      {msg && (
        <div style={{ marginTop: 10, fontSize: 12, color: msg.startsWith("✓") ? "#15803d" : "#b91c1c" }}>{msg}</div>
      )}

      <div style={{ display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 12 }}>
        <button type="submit" className="btn sm primary" disabled={busy}>
          {busy ? "…" : t("Envoyer le ticket", "Submit ticket")}
        </button>
      </div>

      <div className="text-faint" style={{ fontSize: 11, marginTop: 8 }}>
        {t(
          "URL courante et user-agent sont joints automatiquement pour faciliter le diagnostic.",
          "Current URL and user-agent are auto-attached to help diagnosis."
        )}
      </div>
    </form>
  );
}

// Lists the user's tickets (or all org tickets if they have users.manage)
function SupportTicketList({ lang }) {
  const t = (fr, en) => lang === "fr" ? fr : en;
  const { data: tickets, loading } = window.melr.useSupportTickets();
  if (loading) {
    return <div className="text-faint" style={{ padding: 14, fontSize: 12 }}>{t("Chargement…", "Loading…")}</div>;
  }
  if (!tickets || tickets.length === 0) {
    return (
      <div className="text-faint" style={{ padding: 14, fontSize: 12.5, textAlign: "center" }}>
        {t("Aucun ticket pour le moment.", "No ticket yet.")}
      </div>
    );
  }
  const stateMeta = {
    new:       { fr: "Nouveau", en: "New", color: "#1d4ed8", bg: "#dbeafe" },
    in_review: { fr: "En revue", en: "In review", color: "#a16207", bg: "#fef3c7" },
    resolved:  { fr: "Résolu", en: "Resolved", color: "#15803d", bg: "#dcfce7" },
    wontfix:   { fr: "Non corrigé", en: "Wont fix", color: "#6b7280", bg: "#f3f4f6" },
  };
  const catLabel = (c) => c === "bug" ? "Bug" : c === "suggestion" ? t("Suggestion", "Suggestion") : t("Question", "Question");
  const prioLabel = (p) => p === "high" ? t("Haute", "High") : p === "low" ? t("Faible", "Low") : t("Normale", "Normal");
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 6, marginTop: 6 }}>
      {tickets.map((tk) => {
        const sm = stateMeta[tk.state] || stateMeta.new;
        return (
          <div key={tk.id} style={{
            display: "grid", gridTemplateColumns: "auto 1fr auto auto",
            gap: 10, alignItems: "center",
            padding: "10px 12px", border: "1px solid var(--line)", borderRadius: 6,
            background: "var(--bg-elev, white)",
          }}>
            <span style={{
              padding: "2px 8px", borderRadius: 999,
              background: sm.bg, color: sm.color,
              fontSize: 10.5, fontWeight: 700,
            }}>{lang === "fr" ? sm.fr : sm.en}</span>
            <div>
              <div style={{ fontWeight: 500, fontSize: 13 }}>{tk.subject}</div>
              <div className="text-faint" style={{ fontSize: 11, marginTop: 2 }}>
                {catLabel(tk.category)}
                {tk.module ? " · " + tk.module : ""}
                {" · "}{prioLabel(tk.priority)}
                {" · "}{new Date(tk.created_at).toLocaleString(lang === "fr" ? "fr-FR" : "en-US")}
              </div>
              {tk.resolution && (
                <div style={{ marginTop: 4, padding: "6px 8px", background: "#f0fdf4", borderRadius: 4, fontSize: 11.5, color: "#166534" }}>
                  <strong>{t("Résolution :", "Resolution:")}</strong> {tk.resolution}
                </div>
              )}
            </div>
            <span className="tag-mono" style={{ fontSize: 10 }} title={tk.id}>#{String(tk.id).slice(0, 6)}</span>
            <span style={{ fontSize: 11, color: "var(--text-faint)" }}>
              {tk.resolved_at
                ? "✓ " + new Date(tk.resolved_at).toLocaleDateString(lang === "fr" ? "fr-FR" : "en-US")
                : "—"}
            </span>
          </div>
        );
      })}
    </div>
  );
}

// Admin panel — only shown when the user has the 'users.manage' permission.
// Shows EVERY ticket in the org (RLS already grants admin SELECT) and lets
// admins change state, priority, and resolution inline.
function SupportAdminPanel({ lang }) {
  const t = (fr, en) => lang === "fr" ? fr : en;
  const { has, loading: permsLoading } = window.melr.useCurrentUserPermissions();
  const { data: tickets, loading } = window.melr.useSupportTickets();
  const [filter, setFilter] = useStateH("open");  // open | all | resolved | mine

  if (permsLoading) return null;
  if (!has("users.manage")) return null;  // hidden for non-admins

  // Filter
  let visible = tickets || [];
  if (filter === "open")     visible = visible.filter((t) => t.state === "new" || t.state === "in_review");
  if (filter === "resolved") visible = visible.filter((t) => t.state === "resolved" || t.state === "wontfix");

  const counts = {
    all:      tickets.length,
    open:     tickets.filter((t) => t.state === "new" || t.state === "in_review").length,
    resolved: tickets.filter((t) => t.state === "resolved" || t.state === "wontfix").length,
  };

  return (
    <>
      <HelpSubH>{t("Administration des tickets", "Tickets administration")}</HelpSubH>
      <HelpNote tone="info">
        {t(
          "Vous avez la permission users.manage : vous voyez et pouvez gérer tous les tickets de votre organisation.",
          "You have the users.manage permission: you can see and manage every ticket in your organization."
        )}
      </HelpNote>

      {/* Filter chips */}
      <div className="row gap-sm" style={{ marginTop: 12, flexWrap: "wrap" }}>
        {[
          { k: "open",     l: t("Ouverts", "Open"),       c: counts.open },
          { k: "resolved", l: t("Clôturés", "Closed"),    c: counts.resolved },
          { k: "all",      l: t("Tous", "All"),           c: counts.all },
        ].map((x) => (
          <button key={x.k}
            onClick={() => setFilter(x.k)}
            className={"btn sm " + (filter === x.k ? "primary" : "")}>
            {x.l} <span className="tag-mono" style={{ marginLeft: 4 }}>{x.c}</span>
          </button>
        ))}
      </div>

      <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 12 }}>
        {loading && (
          <div className="text-faint" style={{ padding: 14, fontSize: 12 }}>{t("Chargement…", "Loading…")}</div>
        )}
        {!loading && visible.length === 0 && (
          <div className="text-faint" style={{ padding: 14, fontSize: 12.5, textAlign: "center" }}>
            {t("Aucun ticket dans ce filtre.", "No ticket in this filter.")}
          </div>
        )}
        {visible.map((tk) => (
          <SupportAdminRow key={tk.id} ticket={tk} lang={lang} />
        ))}
      </div>
    </>
  );
}

// One row in the admin panel — collapsed by default, expands to show the
// editable controls and the original body / steps.
function SupportAdminRow({ ticket, lang }) {
  const t = (fr, en) => lang === "fr" ? fr : en;
  const [open, setOpen]       = useStateH(false);
  const [state, setState]     = useStateH(ticket.state);
  const [priority, setPriority] = useStateH(ticket.priority || "normal");
  const [resolution, setResolution] = useStateH(ticket.resolution || "");
  const [busy, setBusy]       = useStateH(false);
  const [msg, setMsg]         = useStateH(null);

  // Sync local state if the ticket changes underneath (realtime)
  React.useEffect(() => {
    setState(ticket.state);
    setPriority(ticket.priority || "normal");
    setResolution(ticket.resolution || "");
  }, [ticket.id, ticket.state, ticket.priority, ticket.resolution]);

  const onSave = async () => {
    setBusy(true); setMsg(null);
    try {
      await window.melr.updateSupportTicket(ticket.id, {
        state, priority,
        resolution: resolution.trim() || null,
      });
      setMsg(t("✓ Mis à jour.", "✓ Updated."));
      setTimeout(() => setMsg(null), 2500);
    } catch (e) { setMsg(e.message); }
    finally { setBusy(false); }
  };

  const stateMeta = {
    new:       { fr: "Nouveau", en: "New", color: "#1d4ed8", bg: "#dbeafe" },
    in_review: { fr: "En revue", en: "In review", color: "#a16207", bg: "#fef3c7" },
    resolved:  { fr: "Résolu", en: "Resolved", color: "#15803d", bg: "#dcfce7" },
    wontfix:   { fr: "Non corrigé", en: "Wont fix", color: "#6b7280", bg: "#f3f4f6" },
  }[ticket.state] || { fr: ticket.state, en: ticket.state, color: "#374151", bg: "#f3f4f6" };

  const catLabel = (c) => c === "bug" ? "Bug" : c === "suggestion" ? t("Suggestion", "Suggestion") : t("Question", "Question");
  const author = ticket.author ? (ticket.author.full_name || ticket.author.email) : "—";
  const inp = { width: "100%", padding: "6px 8px", borderRadius: 5, border: "1px solid var(--line)", fontSize: 12, background: "var(--bg, white)", color: "var(--text)", boxSizing: "border-box", fontFamily: "inherit" };

  return (
    <div style={{
      border: "1px solid var(--line)", borderRadius: 6,
      background: "var(--bg-elev, white)", overflow: "hidden",
    }}>
      <button onClick={() => setOpen((v) => !v)}
        style={{
          display: "grid", gridTemplateColumns: "auto 1fr auto auto",
          gap: 10, alignItems: "center", width: "100%", textAlign: "left",
          padding: "10px 12px", background: "transparent", border: 0, cursor: "pointer",
        }}>
        <span style={{
          padding: "2px 8px", borderRadius: 999,
          background: stateMeta.bg, color: stateMeta.color,
          fontSize: 10.5, fontWeight: 700,
        }}>{lang === "fr" ? stateMeta.fr : stateMeta.en}</span>
        <div>
          <div style={{ fontWeight: 500, fontSize: 13 }}>{ticket.subject}</div>
          <div className="text-faint" style={{ fontSize: 11, marginTop: 2 }}>
            {catLabel(ticket.category)}
            {ticket.module ? " · " + ticket.module : ""}
            {" · " + author}
            {" · " + new Date(ticket.created_at).toLocaleString(lang === "fr" ? "fr-FR" : "en-US")}
          </div>
        </div>
        <span className="tag-mono" style={{ fontSize: 10 }}>#{String(ticket.id).slice(0, 6)}</span>
        <span style={{ fontSize: 13, color: "var(--text-faint)" }}>{open ? "▾" : "▸"}</span>
      </button>

      {open && (
        <div style={{ padding: "0 12px 14px", borderTop: "1px solid var(--line-faint)" }}>
          {/* Body & steps from the user */}
          <div style={{ marginTop: 12 }}>
            <div className="text-faint" style={{ fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 4 }}>
              {t("Description", "Description")}
            </div>
            <div style={{ fontSize: 12.5, whiteSpace: "pre-wrap", padding: "6px 8px", background: "var(--bg-sunken, #f9fafb)", borderRadius: 4 }}>
              {ticket.body}
            </div>
          </div>
          {ticket.steps && (
            <div style={{ marginTop: 8 }}>
              <div className="text-faint" style={{ fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 4 }}>
                {t("Étapes de reproduction", "Steps to reproduce")}
              </div>
              <div style={{ fontSize: 12.5, whiteSpace: "pre-wrap", padding: "6px 8px", background: "var(--bg-sunken, #f9fafb)", borderRadius: 4 }}>
                {ticket.steps}
              </div>
            </div>
          )}
          {ticket.url && (
            <div style={{ marginTop: 8, fontSize: 11.5 }}>
              <span className="text-faint">{t("URL :", "URL:")} </span>
              <a href={ticket.url} target="_blank" rel="noreferrer" style={{ wordBreak: "break-all" }}>{ticket.url}</a>
            </div>
          )}

          {/* Admin controls */}
          <div style={{ marginTop: 14, padding: "10px 12px", background: "#eef2ff", borderRadius: 4 }}>
            <div className="text-faint" style={{ fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 6 }}>
              {t("Administration", "Administration")}
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
              <div>
                <label style={{ fontSize: 11, color: "#374151", display: "block", marginBottom: 2 }}>
                  {t("État", "State")}
                </label>
                <select style={inp} value={state} onChange={(e) => setState(e.target.value)}>
                  <option value="new">{t("Nouveau", "New")}</option>
                  <option value="in_review">{t("En revue", "In review")}</option>
                  <option value="resolved">{t("Résolu", "Resolved")}</option>
                  <option value="wontfix">{t("Non corrigé", "Wont fix")}</option>
                </select>
              </div>
              <div>
                <label style={{ fontSize: 11, color: "#374151", display: "block", marginBottom: 2 }}>
                  {t("Priorité", "Priority")}
                </label>
                <select style={inp} value={priority} onChange={(e) => setPriority(e.target.value)}>
                  <option value="low">{t("Faible", "Low")}</option>
                  <option value="normal">{t("Normale", "Normal")}</option>
                  <option value="high">{t("Haute", "High")}</option>
                </select>
              </div>
            </div>

            <label style={{ fontSize: 11, color: "#374151", display: "block", marginTop: 10, marginBottom: 2 }}>
              {t("Résolution / note pour l'auteur (optionnel)", "Resolution / note to the author (optional)")}
            </label>
            <textarea style={{ ...inp, minHeight: 50, resize: "vertical" }}
              value={resolution} onChange={(e) => setResolution(e.target.value)}
              placeholder={t("Corrigé dans la version 1.1, déployé le …", "Fixed in version 1.1, deployed on …")} />

            {msg && (
              <div style={{ marginTop: 8, fontSize: 12, color: msg.startsWith("✓") ? "#15803d" : "#b91c1c" }}>{msg}</div>
            )}

            <div style={{ display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 10 }}>
              <button className="btn sm primary" onClick={onSave} disabled={busy}>
                {busy ? "…" : t("Enregistrer", "Save")}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

window.Help = Help;
