feat: paramétrage dynamique des dotations (sexe, tailles, couleurs)

This commit is contained in:
2026-06-29 11:11:53 +02:00
parent 194986f880
commit 7e036c1966
6 changed files with 83 additions and 15 deletions
@@ -168,12 +168,14 @@ public class DotationController {
.orElseThrow(() -> new IllegalArgumentException("Invalid Dotation ID: " + id));
String taille = request.getParameter("taille_" + id);
String couleur = request.getParameter("couleur_" + id);
String numero = request.getParameter("numero_" + id);
String flocage = request.getParameter("flocage_" + id);
String choisiParam = request.getParameter("choisi_" + id);
String fourniParam = request.getParameter("fourni_" + id);
if (taille != null) dotation.setTaille(taille);
if (couleur != null) dotation.setCouleur(couleur);
if (numero != null) dotation.setNumero(numero);
if (flocage != null) dotation.setFlocage(flocage);
@@ -354,17 +354,10 @@
</div>
<div class="text-[10px] text-gray-400 mb-2 truncate" th:title="${dot.equipement.description}" th:text="${dot.equipement.description != null and !dot.equipement.description.isEmpty() ? dot.equipement.description : 'Pas de description'}">Description</div>
<!-- Special dynamic label for equipment style -->
<div class="mb-2" th:if="${dot.equipement.nom == 'Maillot' or dot.equipement.nom == 'Short' or dot.equipement.nom == 'Chaussettes'}">
<div class="mb-2" th:if="${dot.equipement.gestionSexe}">
<span class="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-semibold bg-blue-50 text-blue-700 border border-blue-100 dotation-style-label"
th:data-equipement="${dot.equipement.nom}"
th:text="${adherent.sexe == 'FEMININ' ? 'Modèle Femme' : 'Modèle Homme'} + ' - ' + ${adherent.typeMaillot == 'GARDIEN' ? 'Gardien' : 'Joueur'}">
Modèle Homme - Joueur
</span>
</div>
<div class="mb-2" th:if="${dot.equipement.nom == 'Survêtement'}">
<span class="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-semibold bg-indigo-50 text-indigo-700 border border-indigo-100 dotation-style-label"
th:data-equipement="${dot.equipement.nom}"
th:text="${adherent.sexe == 'FEMININ' ? 'Modèle Femme' : 'Modèle Homme'}">
th:text="${adherent.sexe == 'FEMININ' ? 'Modèle Femme' : 'Modèle Homme'} + (${dot.equipement.nom == 'Maillot' or dot.equipement.nom == 'Short' or dot.equipement.nom == 'Chaussettes'} ? ' - ' + (${adherent.typeMaillot == 'GARDIEN' ? 'Gardien' : 'Joueur'}) : '')">
Modèle Homme
</span>
</div>
@@ -381,17 +374,43 @@
</div>
<div class="grid grid-cols-2 gap-1.5 mb-1.5">
<div>
<div th:if="${dot.equipement.taillesDisponibles != null and !dot.equipement.taillesDisponibles.trim().isEmpty()}">
<label class="block text-[9px] uppercase font-bold text-gray-400">Taille</label>
<input type="text" th:name="'taille_' + ${dot.id}" th:value="${dot.taille}" placeholder="S, M, L..."
class="w-full text-xs border border-gray-300 rounded px-1 py-0.5 focus:ring-1 focus:ring-blue-500 outline-none">
<select th:name="'taille_' + ${dot.id}" class="w-full text-xs border border-gray-300 rounded px-1 py-0.5 focus:ring-1 focus:ring-blue-500 outline-none">
<option value="">Choisir...</option>
<option th:each="t : ${#strings.arraySplit(dot.equipement.taillesDisponibles, ',')}"
th:value="${#strings.trim(t)}"
th:text="${#strings.trim(t)}"
th:selected="${dot.taille == #strings.trim(t)}"></option>
</select>
</div>
<div th:if="${(dot.equipement.taillesDisponibles == null or dot.equipement.taillesDisponibles.trim().isEmpty()) and (dot.taille != null and !dot.taille.isEmpty())}">
<label class="block text-[9px] uppercase font-bold text-gray-400">Taille</label>
<input type="text" th:name="'taille_' + ${dot.id}" th:value="${dot.taille}" class="w-full text-xs border border-gray-300 rounded px-1 py-0.5 outline-none bg-gray-50 text-gray-500" readonly>
</div>
<div th:if="${dot.equipement.couleursDisponibles != null and !dot.equipement.couleursDisponibles.trim().isEmpty()}">
<label class="block text-[9px] uppercase font-bold text-gray-400">Couleur</label>
<select th:name="'couleur_' + ${dot.id}" class="w-full text-xs border border-gray-300 rounded px-1 py-0.5 focus:ring-1 focus:ring-blue-500 outline-none">
<option value="">Choisir...</option>
<option th:each="c : ${#strings.arraySplit(dot.equipement.couleursDisponibles, ',')}"
th:value="${#strings.trim(c)}"
th:text="${#strings.trim(c)}"
th:selected="${dot.couleur == #strings.trim(c)}"></option>
</select>
</div>
<div th:if="${(dot.equipement.couleursDisponibles == null or dot.equipement.couleursDisponibles.trim().isEmpty()) and (dot.couleur != null and !dot.couleur.isEmpty())}">
<label class="block text-[9px] uppercase font-bold text-gray-400">Couleur</label>
<input type="text" th:name="'couleur_' + ${dot.id}" th:value="${dot.couleur}" class="w-full text-xs border border-gray-300 rounded px-1 py-0.5 outline-none bg-gray-50 text-gray-500" readonly>
</div>
</div>
<div class="grid grid-cols-2 gap-1.5 mb-1.5">
<div>
<label class="block text-[9px] uppercase font-bold text-gray-400">Numéro</label>
<input type="text" th:name="'numero_' + ${dot.id}" th:value="${dot.numero}" placeholder="Ex: 10"
class="w-full text-xs border border-gray-300 rounded px-1 py-0.5 focus:ring-1 focus:ring-blue-500 outline-none">
</div>
</div>
<div>
<label class="block text-[9px] uppercase font-bold text-gray-400">Flocage</label>
<input type="text" th:name="'flocage_' + ${dot.id}" th:value="${dot.flocage}" placeholder="Nom du joueur"
@@ -36,10 +36,28 @@
<label class="block text-sm font-medium text-gray-700 mb-1">Description (ex: Maillot domicile officiel)</label>
<textarea th:field="*{description}" rows="3" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none"></textarea>
</div>
<div class="pt-4 border-t border-gray-100">
<h3 class="text-sm font-medium text-gray-900 mb-4">Options de déclinaison (facultatif)</h3>
<div class="space-y-4">
<div class="flex items-center">
<input type="checkbox" th:field="*{gestionSexe}" class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500">
<label class="ml-2 block text-sm text-gray-700">Gérer les coupes Homme/Femme</label>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Tailles disponibles</label>
<input type="text" th:field="*{taillesDisponibles}" placeholder="ex: XS, S, M, L, XL ou 5/6 ANS, 7/8 ANS..." class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
<p class="text-xs text-gray-500 mt-1">Séparez les tailles par des virgules. Laissez vide si taille unique ou standard.</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Couleurs disponibles</label>
<input type="text" th:field="*{couleursDisponibles}" placeholder="ex: Bleu, Rouge, Blanc..." class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
<p class="text-xs text-gray-500 mt-1">Séparez les couleurs par des virgules. Laissez vide si couleur unique.</p>
</div>
</div>
</div>
<div class="pt-4 flex justify-end space-x-3 border-t border-gray-100">
<a th:href="@{/equipements}" class="px-4 py-2 text-sm font-medium text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-50">Annuler</a>
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700">Enregistrer</button>