Badges : retour à la ligne et créneaux en tableau par jour
ci-cd / build-backend (push) Successful in 37s
ci-cd / build-frontend (push) Successful in 22s
ci-cd / deploy (push) Successful in 13s

Le texte des champs passe à la ligne pour tenir dans la largeur de son
cadre (wrap_text) au lieu de déborder. Les créneaux affectés s'affichent
en tableau : le jour de festival en en-tête, puis une colonne horaire et
une colonne poste (plus de référent sur le badge) ; même tableau dans
l'aperçu de l'éditeur.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AdamThomas
2026-10-27 18:44:55 +01:00
co-authored by Claude Opus 5.5
parent cfed76c239
commit 1a23881e81
8 changed files with 391 additions and 86 deletions
+5 -1
View File
@@ -355,8 +355,12 @@
"badges.fields": "Champs du recto",
"badges.field.fullName": "Prénom + nom",
"badges.field.fullName.placeholder": "Prénom Nom",
"badges.field.positions": "Poste(s) affecté(s)",
"badges.field.positions": "Créneaux affectés (tableau)",
"badges.field.positions.placeholder": "Bar central 19:00–22:00\nAccueil 09:00–13:00 (Référent : Sam Nuit)",
"badges.field.positions.sample1.day": "Vendredi 10",
"badges.field.positions.sample1.rows": "18:00–22:00|Bar central",
"badges.field.positions.sample2.day": "Samedi 11",
"badges.field.positions.sample2.rows": "09:00–13:00|Accueil\n23:00–01:00|Bar central",
"badges.field.category": "Catégorie",
"badges.field.category.placeholder": "Bar",
"badges.field.role": "Rôle (référent / bénévole)",
+44 -1
View File
@@ -506,7 +506,9 @@ function FieldBox({
zIndex: selected ? 10 : undefined,
}}
>
{field.field_type === 'PHOTO' ? (
{field.field_type === 'POSITIONS' ? (
<PositionsTablePreview field={field} scale={scale} />
) : field.field_type === 'PHOTO' ? (
<span className="pointer-events-none flex h-full w-full items-center justify-center bg-sand-dark/70 font-mono text-[10px] font-bold uppercase text-ink/60">
{t(FIELD_PLACEHOLDER_KEY.PHOTO)}
</span>
@@ -536,6 +538,47 @@ function FieldBox({
);
}
/** Aperçu du champ « postes » : le jour en en-tête, puis une ligne
* horaire / poste par créneau, comme dans le PDF
* (`backend/app/badges/pdf.py:_draw_table`), avec des lignes d'exemple. */
function PositionsTablePreview({ field, scale }: { field: FieldState; scale: number }) {
const fontSize = field.font_size * (scale / 2.83); // pt -> px approx. à l'échelle du badge
const sections = [1, 2].map((n) => ({
title: t(`badges.field.positions.sample${n}.day`),
rows: t(`badges.field.positions.sample${n}.rows`)
.split('\n')
.map((row) => row.split('|')),
}));
const cell = 'border px-[0.8mm] py-[0.5mm] text-left align-top';
const border = { borderColor: field.color };
return (
<table
className="pointer-events-none w-full border-collapse font-sans leading-tight"
style={{ fontSize, color: field.color }}
>
{sections.map((section) => (
<tbody key={section.title}>
<tr>
<th colSpan={2} className={cell} style={border}>
{section.title}
</th>
</tr>
{section.rows.map(([time, position]) => (
<tr key={time}>
<td className={cx(cell, 'w-px whitespace-nowrap')} style={border}>
{time}
</td>
<td className={cell} style={border}>
{position}
</td>
</tr>
))}
</tbody>
))}
</table>
);
}
function FieldEditorRow({
type,
field,