Skip to content

feat(nav): THI-341 sidebar épurée + menu avatar GitHub-style pour le secondaire#371

Merged
thierryvm merged 3 commits into
mainfrom
feat/THI-341-nav-mobile-avatar-menu
Jun 4, 2026
Merged

feat(nav): THI-341 sidebar épurée + menu avatar GitHub-style pour le secondaire#371
thierryvm merged 3 commits into
mainfrom
feat/THI-341-nav-mobile-avatar-menu

Conversation

@thierryvm

Copy link
Copy Markdown
Owner

THI-341 — Refonte nav mobile (signalement @Thierry, ticket support 21f3df1e)

Bug corrigé : sur iPhone, la sidebar (drawer) écrasait les modules/leçons (zone flex-1 minuscule sous une nav shrink-0 surchargée de Mes outils + Compte & aide).

Solution (ta vision GitHub-style, Option Sidebar PURE) : tout le secondaire passe dans un menu avatar ; la sidebar se concentre sur l'essentiel.

Changements

  • UserMenu : variant card (sidebar) évolue en menu avatar — trigger row (avatar+nom+sync) → dropdown vers le haut avec les items secondaires + Mon profil + Se déconnecter. Réutilise le dropdown custom React+Tailwind existant (variant compact) — CSP-safe, 0 style inline, pas de Radix (cohérent décision THI-320). Mode invité préservé + lien Paramètres IA ajouté (accès BYOK invité, le menu avatar n'existe pas pour les invités).
  • Sidebar : nav = Tableau de bord + Référence + Modules + switch OS (intact). Le secondaire (Mes outils role-gated + Paramètres IA + Aide & feedback + Mes signalements) → secondaryItems passés au UserMenu. Role-gating reste côté Sidebar (RBAC un seul endroit), UserMenu reste « dumb » (sécurité).
  • −112 lignes nettes (le refactor simplifie).

Gates — tous passés

  • ui-auditor : H1 aria-haspopup="menu" + M1 tabIndex={-1} focus-trap + M2 test corrigé. CSP-safe confirmé (0 Radix, 0 inline style).
  • mobile-responsive-auditor : F-01 trigger 44px + F-02 dropdown overflow-y-auto max-h (anti-clip petit écran/large-text) + F-03 items 44px.
  • feature-dev:code-reviewer : fix(progress): real-time sidebar sync via React Context #1 displayName défensif (email vide). Mergeable.

Voie A empirique (Chrome MCP, compte test super_admin + invité, 390px)

Check Résultat
Sidebar épurée (Mes outils/Compte & aide retirés)
Menu avatar — 8 items role-gated, dropdown ↑
Trigger 54px · items 44px (touch targets)
Dropdown overflow-y: auto, pas de clip, fits viewport
aria-haspopup="menu"
Mode invité : Paramètres IA + Se connecter, pas de menu
Overflow horizontal page 0

Desktop : préservé (mobile-auditor §11 — LessonPage split + sidebar lg:static intacts ; composant viewport-agnostic). 2058 tests pass + auth 16/16.

🤖 Generated with Claude Code

thierryvm and others added 3 commits June 4, 2026 15:28
Fix the reported mobile bug (modules unreachable, sidebar overcrowded on iPhone):
move ALL secondary nav into the avatar menu so the sidebar focuses on the
essentials (Tableau de bord + Référence + Modules + OS switch — untouched).

- UserMenu: `card` variant (sidebar) evolves into an avatar menu — trigger row
  (avatar+name+sync) → dropdown opening UPWARD (bottom-full) with the secondary
  items + Mon profil + Se déconnecter. `compact` (landing) preserved + now also
  renders secondaryItems. Reuses the existing CSP-safe custom dropdown (no Radix,
  zero inline styles — same reason as the THI-320 native <select>).
- New prop `secondaryItems` (role-gated by the CALLER = Sidebar/RBAC; UserMenu
  stays "dumb" — no permission logic in the display component = security).
- Sidebar: removed "Mes outils" (collapsible) + "Compte & aide" from the vertical
  nav → passed as secondaryItems to UserMenu (Mes classes/institution/admin
  role-gated + Paramètres IA + Aide & feedback [modal] + Mes signalements).
- Guest access to Paramètres IA (BYOK, anonymous-friendly) preserved via a link in
  the "Mode invité" block (the avatar menu doesn't render for guests).
- auth.test rewritten for the new card-as-menu behavior + secondaryItems coverage.

2058 tests pass, type-check + lint clean. Voie A (guest + logged-in, desktop +
mobile 390px) + gates to follow. THI-341.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- a11y H1: aria-haspopup "true" → "menu" (WAI-ARIA 1.2: "true" aliases listbox;
  the popup is role="menu") on both triggers.
- a11y M1: tabIndex={-1} on both popover containers (useFocusTrap contract).
- mobile F-01: card trigger min-h-11 (44px touch target).
- mobile F-02: dropdown overflow-y-auto + max-h-[min(440px,calc(100dvh-200px))]
  instead of overflow-hidden → no top-clip on small viewport / large-text for
  super_admin (9 items); scrolls instead.
- mobile F-03: dropdown items py-2.5 → py-3 (44px touch targets).
- test: adapted the card sign-out test to the real dropdown behavior (handleSignOut
  closes the menu first → item unmounts), not the assumed "disabled" state.

auth 16/16, type-check + lint clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…de-reviewer)

Pre-existing edge case surfaced by code-review: `displayName[0].toUpperCase()`
crashed if `user.email === ''` (the `??` chain kept the empty string). Use `||`
so '' falls through to 'Utilisateur', and guard `initials` with `?? 'U'`. THI-341.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
terminal-learning Building Building Preview Jun 4, 2026 1:41pm

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @thierryvm, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@thierryvm thierryvm merged commit 3687203 into main Jun 4, 2026
4 checks passed
@thierryvm thierryvm deleted the feat/THI-341-nav-mobile-avatar-menu branch June 4, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant