Responsive mobile / tablette / desktop

En-tête (onglets sur une seconde ligne en tablette, menu déroulant en
mobile), panneau d'affectation et fiche bénévole en tiroir par-dessus sous
lg: (plein écran en mobile), colonne des postes de la grille rétrécie,
liste des bénévoles réduite en mobile, écran « Postes & créneaux » empilé,
aperçu de l'éditeur de badges mis à l'échelle (glisser-déposer tactile),
ligne des types de paiement repliée, marges réduites — desktop inchangé.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AdamThomas
2026-10-27 18:05:16 +01:00
co-authored by Claude Opus 5.5
parent 0f904f5e3d
commit 85e841ae4a
13 changed files with 269 additions and 129 deletions
+28 -14
View File
@@ -571,8 +571,10 @@ function issueParams(issue: ImportIssue): Record<string, string | number> {
return out;
}
// Mobile : nom + cotisation seulement (téléphone, email et vœux restent sur
// la fiche) ; toutes les colonnes à partir de `md:`.
const LIST_COLUMNS =
'minmax(0,2fr) minmax(0,1.4fr) minmax(0,2fr) minmax(0,1.2fr) minmax(0,1.2fr)';
'grid-cols-[minmax(0,1fr)_auto] md:grid-cols-[minmax(0,2fr)_minmax(0,1.4fr)_minmax(0,2fr)_minmax(0,1.2fr)_minmax(0,1.2fr)]';
/** Résumé d'une ligne de la liste : mode de paiement (et mécénat), statut
* d'un paiement en ligne non abouti. */
@@ -677,7 +679,7 @@ export function ConfigVolunteers() {
return (
<div className="flex min-h-0 flex-1 items-stretch">
<div className="max-h-[calc(100vh-118px)] min-w-0 flex-1 overflow-auto p-4">
<div className="min-w-0 flex-1 p-3 sm:p-4 lg:max-h-[calc(100vh-118px)] lg:overflow-auto">
<div className="mb-[14px] flex flex-wrap items-stretch gap-3">
<div className="flex flex-1 flex-col justify-center gap-[10px] border-[3px] border-ink bg-paper p-[14px] shadow-brutal-lg">
<div>
@@ -757,13 +759,15 @@ export function ConfigVolunteers() {
) : (
<div className="border-[3px] border-ink bg-paper shadow-brutal-lg">
<div
className="grid gap-[10px] bg-ink px-[10px] py-[7px] font-display text-[9.5px] font-extrabold uppercase tracking-wide text-cream"
style={{ gridTemplateColumns: LIST_COLUMNS }}
className={cx(
'grid gap-[10px] bg-ink px-[10px] py-[7px] font-display text-[9.5px] font-extrabold uppercase tracking-wide text-cream',
LIST_COLUMNS,
)}
>
<span>{t('config.vol.colName')}</span>
<span>{t('config.vol.colPhone')}</span>
<span>{t('config.vol.colEmail')}</span>
<span>{t('config.vol.colWishes')}</span>
<span className="hidden md:block">{t('config.vol.colPhone')}</span>
<span className="hidden md:block">{t('config.vol.colEmail')}</span>
<span className="hidden md:block">{t('config.vol.colWishes')}</span>
<span>{t('config.vol.colFee')}</span>
</div>
{rows.map((volunteer) => {
@@ -774,10 +778,10 @@ export function ConfigVolunteers() {
type="button"
onClick={() => setSelectedId(volunteer.id)}
className={cx(
'grid w-full items-center gap-[10px] border-b border-sand-line px-[10px] py-[7px] text-left',
'grid w-full items-center gap-[10px] border-b border-sand-line px-[10px] py-[9px] text-left md:py-[7px]',
LIST_COLUMNS,
active ? 'bg-yellow' : 'hover:bg-cream',
)}
style={{ gridTemplateColumns: LIST_COLUMNS }}
>
<span className="flex min-w-0 items-center gap-[7px]">
<span className="flex h-6 w-6 flex-none items-center justify-center border-2 border-ink bg-paper font-display text-[9.5px] font-extrabold">
@@ -788,13 +792,13 @@ export function ConfigVolunteers() {
{volunteer.first_name} {volunteer.last_name}
</span>
</span>
<span className="truncate font-mono text-[11px] opacity-80">
<span className="hidden truncate font-mono text-[11px] opacity-80 md:block">
{volunteer.phone ?? '—'}
</span>
<span className="truncate font-mono text-[10.5px] opacity-70">
<span className="hidden truncate font-mono text-[10.5px] opacity-70 md:block">
{volunteer.email ?? '—'}
</span>
<span className="truncate font-mono text-[10px] opacity-70">
<span className="hidden truncate font-mono text-[10px] opacity-70 md:block">
{t('config.vol.wishesCount', {
count:
volunteer.artist_ids.length +
@@ -815,8 +819,17 @@ export function ConfigVolunteers() {
)}
</div>
{/* Fiche : à côté de la liste sur grand écran, par-dessus (plein écran
sur mobile, tiroir à droite sur tablette) en dessous de `lg:`. */}
{selected ? (
<aside className="max-h-[calc(100vh-118px)] w-[360px] flex-none overflow-auto border-l-[3px] border-ink bg-paper">
<div
aria-hidden
onClick={() => setSelectedId(null)}
className="fixed inset-0 z-40 bg-ink/40 lg:hidden"
/>
) : null}
{selected ? (
<aside className="fixed inset-y-0 right-0 z-50 w-full overflow-auto bg-paper sm:w-[400px] sm:border-l-[3px] sm:border-ink lg:static lg:z-auto lg:max-h-[calc(100vh-118px)] lg:w-[360px] lg:flex-none lg:border-l-[3px]">
<div className="bg-ink px-[13px] py-[11px] text-cream">
<div className="flex items-center justify-between">
<div className="flex items-center gap-[6px] font-mono text-[10px] text-yellow">
@@ -826,7 +839,8 @@ export function ConfigVolunteers() {
<button
type="button"
onClick={() => setSelectedId(null)}
className="cursor-pointer font-mono text-[11px] text-cream/70 hover:text-cream"
aria-label={t('action.close')}
className="h-8 w-8 cursor-pointer border-2 border-cream/40 font-mono text-[12px] text-cream/80 hover:text-cream lg:h-auto lg:w-auto lg:border-0"
>
✕
</button>