Espace adhérent : plus de barre latérale hors staff

Un adhérent voyait deux fois le même menu : la barre latérale ne portait chez
lui que la section « Côté adhérent » — Informations, Mon profil, Mes
promotions — et EspaceHeader rend déjà ces trois entrées en onglets sous le
bandeau. Un quart de l'écran pour une redite.

BackendShell branche donc sur isStaff : hors staff, il ne reste qu'un bandeau
de marque, aligné sur la colonne de contenu, et la page prend toute la
largeur. Le staff garde la barre, qui est chez lui la navigation principale et
le seul chemin vers son propre espace.

Le piège était sur téléphone : sous 1024px les actions du compte vivaient dans
le tiroir, pas dans l'entête. Sans tiroir, la déconnexion serait devenue
inatteignable — .backend-header--plain rétablit leur affichage à toutes les
largeurs, et un test le verrouille avec l'absence d'aside et de bouton de
tiroir dans la variante.

Vérifié au navigateur en 1440 et 390 px, adhérent et administrateur : aucune
barre ni bouton de tiroir côté adhérent, actions présentes aux deux largeurs,
aucun débordement horizontal ; les dix-sept entrées de l'administrateur et son
tiroir sont intacts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QsLjRAnuLwivqxCbM4WeP
This commit is contained in:
Claude committed 2026-09-15 06:47:10 +00:00
1 parent cc33cf5fbc
commit 2da125eca2
4 files changed
+162 -1

No files matched your search

+38 -1
View File
@@ -4,7 +4,7 @@ import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useState, type ReactNode } from "react";
import { BackendIcon, type BackendIconName } from "@/components/BackendIcons";
import { can, ROLE_LABELS } from "@/lib/rbac";
import { can, isStaff, ROLE_LABELS } from "@/lib/rbac";
import type { AppRole } from "@/types/next-auth";
import { doSignOut } from "./actions";
@@ -192,6 +192,43 @@ export function BackendShell({
</form>
);
/**
* Un adhérent n'a pas de barre latérale : elle ne porterait que la section
* « Côté adhérent », c'est-à-dire les trois entrées déjà présentes en onglets
* sous le bandeau de l'espace. Deux menus pour la même chose, dont un qui
* mange un quart de l'écran. Il ne reste donc qu'un bandeau de marque, et le
* contenu prend toute la largeur — recentré pour ne pas s'étirer.
*
* Le staff la garde : chez lui elle est la navigation principale, et
* « Côté adhérent » y est le seul chemin vers son propre espace.
*/
if (!isStaff(user.role)) {
return (
<div className="backend backend--plain" style={{ fontFamily: "'Public Sans',sans-serif", color: "#33291D" }}>
<header className="backend-header backend-header--plain">
<Link href="/backend/espace/informations" className="backend-brand">
<span className="backend-brand__mark">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src="/assets/logo.png" alt="Plein R" style={{ height: 34, width: "auto", display: "block" }} />
</span>
<span className="backend-brand__text">
<span className="font-display backend-brand__name">Plein R</span>
<span className="backend-brand__sub">Espace adhérent</span>
</span>
</Link>
<div className="backend-header__actions">
{siteLink}
{signOut}
</div>
</header>
{/* Le bandeau de l'espace porte déjà le nom et les onglets : répéter
ici le titre de la page ferait un troisième étage d'en-tête. */}
<div className="backend-content backend-content--plain">{children}</div>
</div>
);
}
return (
<div className="backend" style={{ fontFamily: "'Public Sans',sans-serif", color: "#33291D" }}>
{menuOpen && (
+75
View File
@@ -850,6 +850,81 @@ img {
min-width: 0;
}
/* ---- Backend sans barre latérale (espace adhérent) ----
Un adhérent n'a que les trois onglets de son espace : une barre latérale
les répéterait. `.backend` étant une rangée flex, la variante repasse en
bloc pour que l'entête et le contenu s'empilent simplement. */
.backend--plain {
display: block;
}
/* L'entête s'aligne sur la colonne de contenu : sans cela le logo collerait
au bord de l'écran pendant que le contenu reste centré. */
.backend-header--plain {
padding: 14px max(24px, calc((100% - 1040px) / 2));
}
.backend-brand {
display: flex;
align-items: center;
gap: 11px;
margin-right: auto;
min-width: 0;
text-decoration: none;
}
.backend-brand__mark {
display: inline-flex;
flex-shrink: 0;
padding: 5px;
border-radius: 11px;
background: #fff;
border: 1px solid #e6dcc6;
}
.backend-brand__text {
display: flex;
flex-direction: column;
line-height: 1.15;
min-width: 0;
}
.backend-brand__name {
font-size: 17px;
font-weight: 800;
color: var(--ink-strong);
}
.backend-brand__sub {
font-size: 11.5px;
color: var(--muted-3);
}
/* Sans barre latérale, il n'y a plus de tiroir où loger les actions sur
téléphone : elles restent dans l'entête à toutes les largeurs. */
.backend-header--plain .backend-header__actions {
display: flex;
}
.backend-content--plain {
width: 100%;
max-width: 1040px;
margin: 0 auto;
}
@media (max-width: 1024px) {
.backend-header--plain {
padding: 11px 16px;
}
.backend-content--plain {
max-width: none;
}
}
/* Le nom de marque s'efface avant les actions : le logo suffit à situer la
page, deux boutons tronqués ne servent à rien. */
@media (max-width: 560px) {
.backend-brand__text {
display: none;
}
.backend-header--plain .backend-action {
padding: 8px 11px;
font-size: 13px;
}
}
::-webkit-scrollbar {
width: 10px;
height: 10px;