Refonte du créateur de badges et nombre de badges par bénévole
ci-cd / build-backend (push) Successful in 30s
ci-cd / deploy (push) Successful in 13s
ci-cd / build-frontend (push) Successful in 22s

Créateur de badges refait d'après la maquette : champs sur le recto et le
verso (BadgeField.face, verso placé en miroir dans le PDF pour le
recto-verso), fond de zone, réduction automatique du texte, photo ovale,
initiales sans photo, nom sur deux lignes (migration 0026) ; éditeur en
trois colonnes (champs, aperçu recto/verso avec de vrais bénévoles,
inspecteur), formats prédéfinis, annuler, flèches, zoom, repères de
découpe, dépôt d'image sur l'aperçu, contrôle de tous les badges avant
génération.

Nombre de badges par bénévole (Volunteer.badge_count, 1 par défaut,
migration 0027) : champ sur la fiche, autant d'exemplaires sur les
planches, total affiché à la génération, colonne dans l'export Excel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AdamThomas
2026-10-27 19:20:42 +01:00
co-authored by Claude Opus 5.5
parent 1a23881e81
commit ced0855d47
28 changed files with 3738 additions and 803 deletions
+111 -1
View File
@@ -231,6 +231,8 @@
"config.vol.field.phone": "Téléphone",
"config.vol.field.comment": "Commentaire",
"config.vol.field.badgeText": "Texte du badge",
"config.vol.field.badgeCount": "Nombre de badges",
"config.vol.field.badgeCount.help": "Nombre d'exemplaires de son badge imprimés sur les planches (1 à 100). 1 par défaut.",
"config.vol.field.badgeText.help": "Remplace, pour ce bénévole seulement, le texte libre commun saisi dans l'écran Badges. Vide = texte commun.",
"config.vol.photo.title": "Photo",
"config.vol.photo.hint": "Imprimée sur le badge (champ « Photo du bénévole ») et affichée sur les écrans bénévole et référent. Celle envoyée au formulaire d'inscription, ou ajoutée ici. PNG ou JPEG.",
@@ -384,13 +386,121 @@
"badges.saved": "Enregistré ✓",
"badges.generate.title": "Génération de la planche PDF",
"badges.generate.all": "Tous les bénévoles ({count})",
"badges.generate.total": "{count} badge(s) à imprimer",
"badges.generate.pick": "Choisir ({count} sélectionné(s))",
"badges.generate.action": "Générer le PDF",
"badges.generating": "Génération…",
"badges.face.front": "Recto",
"badges.face.back": "Verso",
"badges.face.front.short": "recto",
"badges.face.back.short": "verso",
"badges.dims": "{width} × {height} mm",
"badges.drop.front": "Déposez ici le visuel du recto (PNG ou JPEG)",
"badges.drop.back": "Déposez ici le visuel du verso (PNG ou JPEG)",
"badges.format.title": "Format du badge",
"badges.format.current": "Format actuel",
"badges.preset.cr80Portrait": "Carte CR80 portrait",
"badges.preset.cr80Landscape": "Carte CR80 paysage",
"badges.preset.a7": "A7 tour de cou",
"badges.fieldsOf": "Champs du {face}",
"badges.fieldsShown": "{count} affiché(s)",
"badges.layer.toggle": "Afficher / masquer",
"badges.layer.hidden": "masqué",
"badges.layer.meta": "{size} pt · {weight}",
"badges.layer.bold": "gras",
"badges.layer.regular": "normal",
"badges.layer.rect": "rectangle",
"badges.layer.oval": "ovale",
"badges.layer.issueCount": "▲ {count}",
"badges.layer.issueTruncated.one": "{count} badge avec texte coupé",
"badges.layer.issueTruncated.other": "{count} badges avec texte coupé",
"badges.layer.issueReduced.one": "{count} badge réduit automatiquement",
"badges.layer.issueReduced.other": "{count} badges réduits automatiquement",
"badges.keys.hint": "Clic sur un champ pour le régler. Flèches : déplacer de 0,5 mm. Maj + flèches : 2 mm. Échap : désélectionner. Ctrl/Cmd + Z : annuler.",
"badges.undo": "↶ Annuler",
"badges.undo.title": "Ctrl/Cmd + Z",
"badges.dirty": "Modifications non enregistrées",
"badges.clean": "✓ Enregistré",
"badges.savedAt": "✓ Enregistré à {time}",
"badges.sample.firstName": "Prénom",
"badges.sample.lastName": "Nom",
"badges.preview.with": "Aperçu avec",
"badges.preview.prev": "Bénévole précédent",
"badges.preview.next": "Bénévole suivant",
"badges.preview.counter": "Badge {index} / {total} · {role}",
"badges.preview.noVolunteer": "Aucun bénévole : exemple fictif",
"badges.preview.longest": "Tester le nom le plus long",
"badges.preview.guides": "Repères",
"badges.preview.guides.help": "Affiche la marge de découpe (1,5 mm) et le cadre de chaque champ",
"badges.preview.zoomIn": "Agrandir l'aperçu",
"badges.preview.zoomOut": "Réduire l'aperçu",
"badges.preview.zoom": "{percent} %",
"badges.preview.truncated": "▲ TEXTE COUPÉ",
"badges.preview.dims": "{width} × {height} mm",
"badges.preview.reducedTo": " · réduit à {size} pt",
"badges.pt": "{size} pt",
"badges.color.white": "Blanc",
"badges.color.black": "Noir",
"badges.color.yellow": "Jaune",
"badges.color.coral": "Corail",
"badges.color.none": "Aucun",
"badges.color.custom": "Autre",
"badges.align.left": "Gauche",
"badges.align.center": "Centre",
"badges.align.right": "Droite",
"badges.inspector.kicker": "{face} · champ sélectionné",
"badges.inspector.content": "Contenu",
"badges.inspector.contentHelp": "Identique sur tous les badges — sauf pour un bénévole dont la fiche porte un « Texte du badge », qui le remplace.",
"badges.inspector.fontSize": "Taille du texte",
"badges.inspector.reducedHere": "Ici réduit à {size} pt",
"badges.inspector.capHeight": "Hauteur ≈ {mm} mm",
"badges.inspector.smaller": "Diminuer la taille",
"badges.inspector.larger": "Augmenter la taille",
"badges.inspector.autoFit": "Réduire automatiquement si le texte est trop long",
"badges.inspector.align": "Alignement",
"badges.inspector.weight": "Graisse",
"badges.inspector.regular": "Normal",
"badges.inspector.bold": "Gras",
"badges.inspector.textColor": "Couleur du texte",
"badges.inspector.background": "Fond de la zone",
"badges.inspector.lowContrast": "⚠ Contraste faible : le texte risque d'être illisible à l'impression.",
"badges.inspector.photoShape": "Forme de la photo",
"badges.inspector.photoRect": "▢ Rectangle",
"badges.inspector.photoOval": "◯ Ovale",
"badges.inspector.photoStat": "{count} photo(s) reçue(s) sur {total}. Sans photo : initiales sur fond beige.",
"badges.inspector.geometry": "Position et taille (mm)",
"badges.inspector.x": "X",
"badges.inspector.y": "Y",
"badges.inspector.w": "L",
"badges.inspector.h": "H",
"badges.inspector.center": "↔ Centrer",
"badges.inspector.fullWidth": "⇤⇥ Pleine largeur",
"badges.inspector.hide": "Masquer ce champ",
"badges.inspector.empty.title": "Sélectionnez un champ sur le badge ou dans la liste de gauche.",
"badges.inspector.empty.hint": "Faites-le glisser pour le déplacer, tirez le carré jaune pour le redimensionner. Ses réglages apparaissent ici.",
"badges.inspector.empty.drop": "Pour changer le visuel de fond, déposez une image directement sur le recto ou le verso.",
"badges.check.title": "Contrôle des {count} badges",
"badges.check.subtitle": "Avant génération des planches",
"badges.check.critical": "⛔ À corriger",
"badges.check.warning": "⚠ À vérifier",
"badges.check.fixAutoFit": "Activer la réduction auto",
"badges.check.showExample": "Voir un exemple",
"badges.check.ok": "Les {count} badges s'affichent sans texte coupé ni champ hors zone de découpe.",
"badges.check.estimate": "Estimation faite dans le navigateur : le PDF généré reste la référence.",
"badges.issue.where": "{field} ({face})",
"badges.issue.truncated.one": "{where} : texte coupé sur {count} badge.",
"badges.issue.truncated.other": "{where} : texte coupé sur {count} badges.",
"badges.issue.reduced.one": "{where} : réduit automatiquement sur {count} badge, jusqu'à {size} pt.",
"badges.issue.reduced.other": "{where} : réduit automatiquement sur {count} badges, jusqu'à {size} pt.",
"badges.issue.margin": "{where} : touche la marge de découpe (1,5 mm), risque d'être rogné.",
"badges.issue.contrast": "{where} : texte et fond de zone trop proches, illisible.",
"badges.issue.noPhoto.one": "{count} bénévole n'a pas de photo : ses initiales seront imprimées à la place.",
"badges.issue.noPhoto.other": "{count} bénévoles n'ont pas de photo : leurs initiales seront imprimées à la place.",
"badge.image_type_not_supported": "L'image doit être au format PNG ou JPEG.",
"badge.empty_image": "L'image est vide.",
"badge.image_too_large": "L'image est trop volumineuse.",
"badge.duplicate_field_type": "Ce champ ne peut apparaître qu'une fois.",
"badge.duplicate_field_type": "Ce champ ne peut apparaître qu'une fois par face.",
"badge.invalid_color": "Couleur invalide (format attendu : #rrggbb).",
"badge.invalid_size": "La taille du badge doit être strictement positive.",
"badge.no_fields": "Activez au moins un champ sur le recto avant de générer.",
"badge.no_volunteers": "Aucun bénévole ne correspond à cette sélection.",