Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e867acbb70 | |||
| c4bb9803ed | |||
| e1cd5930fd | |||
| d913579c77 | |||
| 2adbdde121 |
@@ -26,6 +26,9 @@ public class Paiement {
|
|||||||
@JoinColumn(name = "mode_paiement_id", nullable = false)
|
@JoinColumn(name = "mode_paiement_id", nullable = false)
|
||||||
private ModePaiement modePaiement;
|
private ModePaiement modePaiement;
|
||||||
|
|
||||||
|
@Column(name = "gestionnaire")
|
||||||
|
private String gestionnaire;
|
||||||
|
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
|
|
||||||
public Long getId() { return id; }
|
public Long getId() { return id; }
|
||||||
@@ -42,4 +45,7 @@ public class Paiement {
|
|||||||
|
|
||||||
public ModePaiement getModePaiement() { return modePaiement; }
|
public ModePaiement getModePaiement() { return modePaiement; }
|
||||||
public void setModePaiement(ModePaiement modePaiement) { this.modePaiement = modePaiement; }
|
public void setModePaiement(ModePaiement modePaiement) { this.modePaiement = modePaiement; }
|
||||||
|
|
||||||
|
public String getGestionnaire() { return gestionnaire; }
|
||||||
|
public void setGestionnaire(String gestionnaire) { this.gestionnaire = gestionnaire; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ public class PreInscription {
|
|||||||
@JoinColumn(name = "saison_id", nullable = false)
|
@JoinColumn(name = "saison_id", nullable = false)
|
||||||
private Saison saison;
|
private Saison saison;
|
||||||
|
|
||||||
|
@Column(name = "consentement_rgpd", nullable = false)
|
||||||
|
private Boolean consentementRgpd = false;
|
||||||
|
|
||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
public Long getId() { return id; }
|
public Long getId() { return id; }
|
||||||
public void setId(Long id) { this.id = id; }
|
public void setId(Long id) { this.id = id; }
|
||||||
@@ -82,4 +85,7 @@ public class PreInscription {
|
|||||||
|
|
||||||
public Saison getSaison() { return saison; }
|
public Saison getSaison() { return saison; }
|
||||||
public void setSaison(Saison saison) { this.saison = saison; }
|
public void setSaison(Saison saison) { this.saison = saison; }
|
||||||
|
|
||||||
|
public Boolean getConsentementRgpd() { return consentementRgpd; }
|
||||||
|
public void setConsentementRgpd(Boolean consentementRgpd) { this.consentementRgpd = consentementRgpd; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.astalange.core.repository;
|
package com.astalange.core.repository;
|
||||||
|
|
||||||
import com.astalange.core.entity.Dotation;
|
import com.astalange.core.entity.Dotation;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@@ -8,6 +9,6 @@ import java.util.List;
|
|||||||
import com.astalange.core.entity.Saison;
|
import com.astalange.core.entity.Saison;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface DotationRepository extends JpaRepository<Dotation, Long> {
|
public interface DotationRepository extends JpaRepository<Dotation, Long>, JpaSpecificationExecutor<Dotation> {
|
||||||
List<Dotation> findByLicence_SaisonAndChoisiTrueAndFourniFalse(Saison saison);
|
List<Dotation> findByLicence_SaisonAndChoisiTrueAndFourniFalse(Saison saison);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import org.springframework.stereotype.Repository;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface LicenceRepository extends JpaRepository<Licence, Long> {
|
public interface LicenceRepository extends JpaRepository<Licence, Long>, JpaSpecificationExecutor<Licence> {
|
||||||
List<Licence> findByAdherentId(Long adherentId);
|
List<Licence> findByAdherentId(Long adherentId);
|
||||||
|
|
||||||
List<Licence> findBySaisonAndCategorie(com.astalange.core.entity.Saison saison, com.astalange.core.entity.Categorie categorie);
|
List<Licence> findBySaisonAndCategorie(com.astalange.core.entity.Saison saison, com.astalange.core.entity.Categorie categorie);
|
||||||
|
|||||||
@@ -76,7 +76,13 @@ public class CategorieService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDotationsForLicence(Licence licence, List<CategorieEquipement> categorieEquipements) {
|
public void syncDotationsForLicence(Licence licence) {
|
||||||
|
if (licence.getCategorie() != null) {
|
||||||
|
updateDotationsForLicence(licence, licence.getCategorie().getCategorieEquipements());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateDotationsForLicence(Licence licence, List<CategorieEquipement> categorieEquipements) {
|
||||||
List<Dotation> currentDotations = licence.getDotations();
|
List<Dotation> currentDotations = licence.getDotations();
|
||||||
List<Dotation> toRemove = new ArrayList<>();
|
List<Dotation> toRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
|||||||
@@ -24,12 +24,14 @@ public class DotationService {
|
|||||||
sb.append('\ufeff');
|
sb.append('\ufeff');
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
sb.append("Catégorie;Nom;Prénom;Équipement;Taille;Flocage;Numéro\n");
|
sb.append("Catégorie;Nom;Prénom;Poste;Sexe;Équipement;Taille;Flocage;Numéro\n");
|
||||||
|
|
||||||
for (Dotation d : dotations) {
|
for (Dotation d : dotations) {
|
||||||
String categorie = d.getLicence().getCategorie() != null ? d.getLicence().getCategorie().getNom() : "";
|
String categorie = d.getLicence().getCategorie() != null ? d.getLicence().getCategorie().getNom() : "";
|
||||||
String nom = d.getLicence().getAdherent().getNom();
|
String nom = d.getLicence().getAdherent().getNom();
|
||||||
String prenom = d.getLicence().getAdherent().getPrenom();
|
String prenom = d.getLicence().getAdherent().getPrenom();
|
||||||
|
String poste = d.getLicence().getAdherent().getTypeMaillot() != null ? d.getLicence().getAdherent().getTypeMaillot() : "";
|
||||||
|
String sexe = d.getLicence().getAdherent().getSexe() != null ? d.getLicence().getAdherent().getSexe() : "";
|
||||||
String equipement = d.getEquipement() != null ? d.getEquipement().getNom() : "";
|
String equipement = d.getEquipement() != null ? d.getEquipement().getNom() : "";
|
||||||
String taille = d.getTaille() != null ? d.getTaille() : "";
|
String taille = d.getTaille() != null ? d.getTaille() : "";
|
||||||
String flocage = d.getFlocage() != null ? d.getFlocage() : "";
|
String flocage = d.getFlocage() != null ? d.getFlocage() : "";
|
||||||
@@ -38,6 +40,8 @@ public class DotationService {
|
|||||||
sb.append(escapeCsv(categorie)).append(";")
|
sb.append(escapeCsv(categorie)).append(";")
|
||||||
.append(escapeCsv(nom)).append(";")
|
.append(escapeCsv(nom)).append(";")
|
||||||
.append(escapeCsv(prenom)).append(";")
|
.append(escapeCsv(prenom)).append(";")
|
||||||
|
.append(escapeCsv(poste)).append(";")
|
||||||
|
.append(escapeCsv(sexe)).append(";")
|
||||||
.append(escapeCsv(equipement)).append(";")
|
.append(escapeCsv(equipement)).append(";")
|
||||||
.append(escapeCsv(taille)).append(";")
|
.append(escapeCsv(taille)).append(";")
|
||||||
.append(escapeCsv(flocage)).append(";")
|
.append(escapeCsv(flocage)).append(";")
|
||||||
@@ -47,6 +51,43 @@ public class DotationService {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String genererCsvSearchEquipement(List<Dotation> dotations) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
// BOM for Excel to open UTF-8 correctly
|
||||||
|
sb.append('\ufeff');
|
||||||
|
|
||||||
|
// Header
|
||||||
|
sb.append("Saison;Catégorie;Nom;Prénom;Poste;Sexe;Équipement;Taille;Flocage;Numéro;Fourni\n");
|
||||||
|
|
||||||
|
for (Dotation d : dotations) {
|
||||||
|
String saison = d.getLicence().getSaison() != null ? d.getLicence().getSaison().getNom() : "";
|
||||||
|
String categorie = d.getLicence().getCategorie() != null ? d.getLicence().getCategorie().getNom() : "";
|
||||||
|
String nom = d.getLicence().getAdherent().getNom();
|
||||||
|
String prenom = d.getLicence().getAdherent().getPrenom();
|
||||||
|
String poste = d.getLicence().getAdherent().getTypeMaillot() != null ? d.getLicence().getAdherent().getTypeMaillot() : "";
|
||||||
|
String sexe = d.getLicence().getAdherent().getSexe() != null ? d.getLicence().getAdherent().getSexe() : "";
|
||||||
|
String equipement = d.getEquipement() != null ? d.getEquipement().getNom() : "";
|
||||||
|
String taille = d.getTaille() != null ? d.getTaille() : "";
|
||||||
|
String flocage = d.getFlocage() != null ? d.getFlocage() : "";
|
||||||
|
String numero = d.getNumero() != null ? d.getNumero() : "";
|
||||||
|
String fourni = Boolean.TRUE.equals(d.getFourni()) ? "Oui" : "Non";
|
||||||
|
|
||||||
|
sb.append(escapeCsv(saison)).append(";")
|
||||||
|
.append(escapeCsv(categorie)).append(";")
|
||||||
|
.append(escapeCsv(nom)).append(";")
|
||||||
|
.append(escapeCsv(prenom)).append(";")
|
||||||
|
.append(escapeCsv(poste)).append(";")
|
||||||
|
.append(escapeCsv(sexe)).append(";")
|
||||||
|
.append(escapeCsv(equipement)).append(";")
|
||||||
|
.append(escapeCsv(taille)).append(";")
|
||||||
|
.append(escapeCsv(flocage)).append(";")
|
||||||
|
.append(escapeCsv(numero)).append(";")
|
||||||
|
.append(escapeCsv(fourni)).append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private String escapeCsv(String value) {
|
private String escapeCsv(String value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE paiement ADD COLUMN gestionnaire VARCHAR(255);
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE pre_inscription ADD COLUMN consentement_rgpd BOOLEAN NOT NULL DEFAULT FALSE;
|
||||||
@@ -23,13 +23,15 @@ public class AdherentController {
|
|||||||
private final com.astalange.core.repository.LicenceRepository licenceRepository;
|
private final com.astalange.core.repository.LicenceRepository licenceRepository;
|
||||||
private final com.astalange.core.repository.ModePaiementRepository modePaiementRepository;
|
private final com.astalange.core.repository.ModePaiementRepository modePaiementRepository;
|
||||||
private final SaisonRepository saisonRepository;
|
private final SaisonRepository saisonRepository;
|
||||||
|
private final com.astalange.core.service.CategorieService categorieService;
|
||||||
|
|
||||||
public AdherentController(AdherentRepository adherentRepository, CategorieRepository categorieRepository, com.astalange.core.repository.LicenceRepository licenceRepository, com.astalange.core.repository.ModePaiementRepository modePaiementRepository, SaisonRepository saisonRepository) {
|
public AdherentController(AdherentRepository adherentRepository, CategorieRepository categorieRepository, com.astalange.core.repository.LicenceRepository licenceRepository, com.astalange.core.repository.ModePaiementRepository modePaiementRepository, SaisonRepository saisonRepository, com.astalange.core.service.CategorieService categorieService) {
|
||||||
this.adherentRepository = adherentRepository;
|
this.adherentRepository = adherentRepository;
|
||||||
this.categorieRepository = categorieRepository;
|
this.categorieRepository = categorieRepository;
|
||||||
this.licenceRepository = licenceRepository;
|
this.licenceRepository = licenceRepository;
|
||||||
this.modePaiementRepository = modePaiementRepository;
|
this.modePaiementRepository = modePaiementRepository;
|
||||||
this.saisonRepository = saisonRepository;
|
this.saisonRepository = saisonRepository;
|
||||||
|
this.categorieService = categorieService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@org.springframework.web.bind.annotation.ModelAttribute("equipes")
|
@org.springframework.web.bind.annotation.ModelAttribute("equipes")
|
||||||
@@ -187,7 +189,8 @@ public class AdherentController {
|
|||||||
.orElse(null);
|
.orElse(null);
|
||||||
if (newCat != null) {
|
if (newCat != null) {
|
||||||
licence.setCategorie(newCat);
|
licence.setCategorie(newCat);
|
||||||
licenceRepository.save(licence);
|
licence = licenceRepository.save(licence);
|
||||||
|
categorieService.syncDotationsForLicence(licence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,8 +47,13 @@ public class CategorieController {
|
|||||||
Categorie categorie = categorieRepository.findById(id)
|
Categorie categorie = categorieRepository.findById(id)
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Invalid category ID: " + id));
|
.orElseThrow(() -> new IllegalArgumentException("Invalid category ID: " + id));
|
||||||
model.addAttribute("categorie", categorie);
|
model.addAttribute("categorie", categorie);
|
||||||
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
|
|
||||||
model.addAttribute("allEquipements", activeSaison != null ? equipementRepository.findBySaison(activeSaison) : List.of());
|
Saison saison = categorie.getSaison();
|
||||||
|
if (saison == null) {
|
||||||
|
saison = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addAttribute("allEquipements", saison != null ? equipementRepository.findBySaison(saison) : List.of());
|
||||||
return "parametrage/categories_form";
|
return "parametrage/categories_form";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,17 +21,95 @@ import com.astalange.core.service.DotationService;
|
|||||||
import com.astalange.core.repository.SaisonRepository;
|
import com.astalange.core.repository.SaisonRepository;
|
||||||
import com.astalange.core.entity.Saison;
|
import com.astalange.core.entity.Saison;
|
||||||
|
|
||||||
|
import com.astalange.core.repository.EquipementRepository;
|
||||||
|
import com.astalange.core.repository.CategorieRepository;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class DotationController {
|
public class DotationController {
|
||||||
|
|
||||||
private final DotationRepository dotationRepository;
|
private final DotationRepository dotationRepository;
|
||||||
private final DotationService dotationService;
|
private final DotationService dotationService;
|
||||||
private final SaisonRepository saisonRepository;
|
private final SaisonRepository saisonRepository;
|
||||||
|
private final EquipementRepository equipementRepository;
|
||||||
|
private final CategorieRepository categorieRepository;
|
||||||
|
|
||||||
public DotationController(DotationRepository dotationRepository, DotationService dotationService, SaisonRepository saisonRepository) {
|
public DotationController(DotationRepository dotationRepository, DotationService dotationService, SaisonRepository saisonRepository, EquipementRepository equipementRepository, CategorieRepository categorieRepository) {
|
||||||
this.dotationRepository = dotationRepository;
|
this.dotationRepository = dotationRepository;
|
||||||
this.dotationService = dotationService;
|
this.dotationService = dotationService;
|
||||||
this.saisonRepository = saisonRepository;
|
this.saisonRepository = saisonRepository;
|
||||||
|
this.equipementRepository = equipementRepository;
|
||||||
|
this.categorieRepository = categorieRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Specification<Dotation> buildSpecification(Long equipementId, Long categorieId, Boolean fourni, Saison saisonActive) {
|
||||||
|
return (root, query, cb) -> {
|
||||||
|
if (Long.class != query.getResultType() && long.class != query.getResultType()) {
|
||||||
|
root.fetch("equipement", jakarta.persistence.criteria.JoinType.LEFT);
|
||||||
|
jakarta.persistence.criteria.Fetch<Object, Object> licenceFetch = root.fetch("licence", jakarta.persistence.criteria.JoinType.LEFT);
|
||||||
|
licenceFetch.fetch("adherent", jakarta.persistence.criteria.JoinType.LEFT);
|
||||||
|
licenceFetch.fetch("categorie", jakarta.persistence.criteria.JoinType.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Predicate> predicates = new ArrayList<>();
|
||||||
|
if (saisonActive != null) {
|
||||||
|
predicates.add(cb.equal(root.get("licence").get("saison"), saisonActive));
|
||||||
|
}
|
||||||
|
if (equipementId != null) {
|
||||||
|
predicates.add(cb.equal(root.get("equipement").get("id"), equipementId));
|
||||||
|
}
|
||||||
|
if (categorieId != null) {
|
||||||
|
predicates.add(cb.equal(root.get("licence").get("categorie").get("id"), categorieId));
|
||||||
|
}
|
||||||
|
if (fourni != null) {
|
||||||
|
predicates.add(cb.equal(root.get("fourni"), fourni));
|
||||||
|
}
|
||||||
|
return cb.and(predicates.toArray(new Predicate[0]));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/admin/equipements/recherche")
|
||||||
|
public String rechercheEquipements(
|
||||||
|
@RequestParam(required = false) Long equipementId,
|
||||||
|
@RequestParam(required = false) Long categorieId,
|
||||||
|
@RequestParam(required = false) Boolean fourni,
|
||||||
|
Model model) {
|
||||||
|
|
||||||
|
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||||
|
Specification<Dotation> spec = buildSpecification(equipementId, categorieId, fourni, saisonActive);
|
||||||
|
List<Dotation> dotations = dotationRepository.findAll(spec);
|
||||||
|
|
||||||
|
model.addAttribute("dotations", dotations);
|
||||||
|
model.addAttribute("equipements", equipementRepository.findAll());
|
||||||
|
model.addAttribute("categories", categorieRepository.findAll());
|
||||||
|
model.addAttribute("equipementId", equipementId);
|
||||||
|
model.addAttribute("categorieId", categorieId);
|
||||||
|
model.addAttribute("fourni", fourni);
|
||||||
|
|
||||||
|
return "parametrage/equipements_recherche";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/admin/equipements/recherche/export")
|
||||||
|
public ResponseEntity<byte[]> exportRechercheEquipements(
|
||||||
|
@RequestParam(required = false) Long equipementId,
|
||||||
|
@RequestParam(required = false) Long categorieId,
|
||||||
|
@RequestParam(required = false) Boolean fourni) {
|
||||||
|
|
||||||
|
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||||
|
Specification<Dotation> spec = buildSpecification(equipementId, categorieId, fourni, saisonActive);
|
||||||
|
List<Dotation> dotations = dotationRepository.findAll(spec);
|
||||||
|
|
||||||
|
String csvContent = dotationService.genererCsvSearchEquipement(dotations);
|
||||||
|
byte[] csvBytes = csvContent.getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentDispositionFormData("attachment", "recherche_equipements_" + LocalDate.now() + ".csv");
|
||||||
|
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||||
|
|
||||||
|
return new ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/admin/equipements/export-commande")
|
@GetMapping("/admin/equipements/export-commande")
|
||||||
|
|||||||
@@ -22,7 +22,12 @@ public class EquipementController {
|
|||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public String listEquipements(Model model) {
|
public String listEquipements(Model model) {
|
||||||
model.addAttribute("equipements", equipementRepository.findAll());
|
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||||
|
if (activeSaison != null) {
|
||||||
|
model.addAttribute("equipements", equipementRepository.findBySaison(activeSaison));
|
||||||
|
} else {
|
||||||
|
model.addAttribute("equipements", java.util.List.of());
|
||||||
|
}
|
||||||
return "parametrage/equipements_list";
|
return "parametrage/equipements_list";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public class LicenceController {
|
|||||||
private final DotationRepository dotationRepository;
|
private final DotationRepository dotationRepository;
|
||||||
private final SaisonRepository saisonRepository;
|
private final SaisonRepository saisonRepository;
|
||||||
private final EquipeRepository equipeRepository;
|
private final EquipeRepository equipeRepository;
|
||||||
|
private final com.astalange.core.service.CategorieService categorieService;
|
||||||
|
|
||||||
public LicenceController(AdherentRepository adherentRepository,
|
public LicenceController(AdherentRepository adherentRepository,
|
||||||
CategorieRepository categorieRepository,
|
CategorieRepository categorieRepository,
|
||||||
@@ -28,7 +29,8 @@ public class LicenceController {
|
|||||||
EquipementRepository equipementRepository,
|
EquipementRepository equipementRepository,
|
||||||
DotationRepository dotationRepository,
|
DotationRepository dotationRepository,
|
||||||
SaisonRepository saisonRepository,
|
SaisonRepository saisonRepository,
|
||||||
EquipeRepository equipeRepository) {
|
EquipeRepository equipeRepository,
|
||||||
|
com.astalange.core.service.CategorieService categorieService) {
|
||||||
this.adherentRepository = adherentRepository;
|
this.adherentRepository = adherentRepository;
|
||||||
this.categorieRepository = categorieRepository;
|
this.categorieRepository = categorieRepository;
|
||||||
this.licenceRepository = licenceRepository;
|
this.licenceRepository = licenceRepository;
|
||||||
@@ -36,6 +38,7 @@ public class LicenceController {
|
|||||||
this.dotationRepository = dotationRepository;
|
this.dotationRepository = dotationRepository;
|
||||||
this.saisonRepository = saisonRepository;
|
this.saisonRepository = saisonRepository;
|
||||||
this.equipeRepository = equipeRepository;
|
this.equipeRepository = equipeRepository;
|
||||||
|
this.categorieService = categorieService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/adherents/{id}/licences")
|
@PostMapping("/adherents/{id}/licences")
|
||||||
@@ -129,8 +132,125 @@ public class LicenceController {
|
|||||||
licence.setEquipe(null);
|
licence.setEquipe(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
licenceRepository.save(licence);
|
licence = licenceRepository.save(licence);
|
||||||
|
|
||||||
|
// Sync dotations when category changes
|
||||||
|
categorieService.syncDotationsForLicence(licence);
|
||||||
|
|
||||||
return "redirect:/adherents/" + adherentId + "/edit";
|
return "redirect:/adherents/" + adherentId + "/edit";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@org.springframework.web.bind.annotation.GetMapping("/admin/licences/recherche")
|
||||||
|
public String rechercheLicences(
|
||||||
|
@RequestParam(required = false) String nom,
|
||||||
|
@RequestParam(required = false) String prenom,
|
||||||
|
@RequestParam(required = false) Long categorieId,
|
||||||
|
@RequestParam(required = false) String numeroLicence,
|
||||||
|
@RequestParam(required = false) String email,
|
||||||
|
@RequestParam(required = false) String typeDemande,
|
||||||
|
org.springframework.ui.Model model) {
|
||||||
|
|
||||||
|
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||||
|
org.springframework.data.jpa.domain.Specification<Licence> spec = buildLicenceSpecification(nom, prenom, categorieId, numeroLicence, email, typeDemande, saisonActive);
|
||||||
|
|
||||||
|
List<Licence> licences = licenceRepository.findAll(spec);
|
||||||
|
|
||||||
|
model.addAttribute("licences", licences);
|
||||||
|
model.addAttribute("categories", categorieRepository.findAll());
|
||||||
|
model.addAttribute("nomFilter", nom);
|
||||||
|
model.addAttribute("prenomFilter", prenom);
|
||||||
|
model.addAttribute("categorieId", categorieId);
|
||||||
|
model.addAttribute("numeroLicenceFilter", numeroLicence);
|
||||||
|
model.addAttribute("emailFilter", email);
|
||||||
|
model.addAttribute("typeDemandeFilter", typeDemande);
|
||||||
|
|
||||||
|
return "parametrage/licences_recherche";
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.springframework.web.bind.annotation.GetMapping("/admin/licences/recherche/export")
|
||||||
|
public org.springframework.http.ResponseEntity<byte[]> exportRechercheLicences(
|
||||||
|
@RequestParam(required = false) String nom,
|
||||||
|
@RequestParam(required = false) String prenom,
|
||||||
|
@RequestParam(required = false) Long categorieId,
|
||||||
|
@RequestParam(required = false) String numeroLicence,
|
||||||
|
@RequestParam(required = false) String email,
|
||||||
|
@RequestParam(required = false) String typeDemande) {
|
||||||
|
|
||||||
|
Saison saisonActive = saisonRepository.findByEstActiveTrue().orElse(null);
|
||||||
|
org.springframework.data.jpa.domain.Specification<Licence> spec = buildLicenceSpecification(nom, prenom, categorieId, numeroLicence, email, typeDemande, saisonActive);
|
||||||
|
List<Licence> licences = licenceRepository.findAll(spec);
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append('\ufeff');
|
||||||
|
sb.append("Nom;Prénom;Catégorie;N° Licence;Email;Type de Demande;Saison;Etat\n");
|
||||||
|
|
||||||
|
for (Licence l : licences) {
|
||||||
|
String n = l.getAdherent() != null && l.getAdherent().getNom() != null ? l.getAdherent().getNom() : "";
|
||||||
|
String p = l.getAdherent() != null && l.getAdherent().getPrenom() != null ? l.getAdherent().getPrenom() : "";
|
||||||
|
String c = l.getCategorie() != null ? l.getCategorie().getNom() : "";
|
||||||
|
String num = l.getNumeroLicence() != null ? l.getNumeroLicence() : "";
|
||||||
|
String e = l.getAdherent() != null && l.getAdherent().getEmail() != null ? l.getAdherent().getEmail() : "";
|
||||||
|
String td = l.getTypeDemande() != null ? l.getTypeDemande() : "";
|
||||||
|
String s = l.getSaison() != null ? l.getSaison().getNom() : "";
|
||||||
|
String etat = l.getEtat() != null ? l.getEtat() : "";
|
||||||
|
|
||||||
|
sb.append(escapeCsv(n)).append(";")
|
||||||
|
.append(escapeCsv(p)).append(";")
|
||||||
|
.append(escapeCsv(c)).append(";")
|
||||||
|
.append(escapeCsv(num)).append(";")
|
||||||
|
.append(escapeCsv(e)).append(";")
|
||||||
|
.append(escapeCsv(td)).append(";")
|
||||||
|
.append(escapeCsv(s)).append(";")
|
||||||
|
.append(escapeCsv(etat)).append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] csvBytes = sb.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||||
|
org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
|
||||||
|
headers.setContentDispositionFormData("attachment", "recherche_licences_" + java.time.LocalDate.now() + ".csv");
|
||||||
|
headers.setContentType(org.springframework.http.MediaType.parseMediaType("text/csv; charset=UTF-8"));
|
||||||
|
|
||||||
|
return new org.springframework.http.ResponseEntity<>(csvBytes, headers, org.springframework.http.HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String escapeCsv(String value) {
|
||||||
|
if (value == null) return "";
|
||||||
|
if (value.contains("\"")) value = value.replace("\"", "\"\"");
|
||||||
|
if (value.contains(";") || value.contains("\n") || value.contains("\"")) return "\"" + value + "\"";
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private org.springframework.data.jpa.domain.Specification<Licence> buildLicenceSpecification(
|
||||||
|
String nom, String prenom, Long categorieId, String numeroLicence, String email, String typeDemande, Saison saisonActive) {
|
||||||
|
return (root, query, cb) -> {
|
||||||
|
List<jakarta.persistence.criteria.Predicate> predicates = new java.util.ArrayList<>();
|
||||||
|
|
||||||
|
if (Long.class != query.getResultType() && long.class != query.getResultType()) {
|
||||||
|
root.fetch("adherent", jakarta.persistence.criteria.JoinType.LEFT);
|
||||||
|
root.fetch("categorie", jakarta.persistence.criteria.JoinType.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saisonActive != null) {
|
||||||
|
predicates.add(cb.equal(root.get("saison"), saisonActive));
|
||||||
|
}
|
||||||
|
if (nom != null && !nom.trim().isEmpty()) {
|
||||||
|
predicates.add(cb.like(cb.lower(root.get("adherent").get("nom")), "%" + nom.trim().toLowerCase() + "%"));
|
||||||
|
}
|
||||||
|
if (prenom != null && !prenom.trim().isEmpty()) {
|
||||||
|
predicates.add(cb.like(cb.lower(root.get("adherent").get("prenom")), "%" + prenom.trim().toLowerCase() + "%"));
|
||||||
|
}
|
||||||
|
if (categorieId != null) {
|
||||||
|
predicates.add(cb.equal(root.get("categorie").get("id"), categorieId));
|
||||||
|
}
|
||||||
|
if (numeroLicence != null && !numeroLicence.trim().isEmpty()) {
|
||||||
|
predicates.add(cb.like(cb.lower(root.get("numeroLicence")), "%" + numeroLicence.trim().toLowerCase() + "%"));
|
||||||
|
}
|
||||||
|
if (email != null && !email.trim().isEmpty()) {
|
||||||
|
predicates.add(cb.like(cb.lower(root.get("adherent").get("email")), "%" + email.trim().toLowerCase() + "%"));
|
||||||
|
}
|
||||||
|
if (typeDemande != null && !typeDemande.trim().isEmpty()) {
|
||||||
|
predicates.add(cb.equal(root.get("typeDemande"), typeDemande.trim()));
|
||||||
|
}
|
||||||
|
return cb.and(predicates.toArray(new jakarta.persistence.criteria.Predicate[0]));
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.springframework.stereotype.Controller;
|
|||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import java.security.Principal;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@@ -34,7 +35,8 @@ public class PaiementController {
|
|||||||
@RequestParam Long adherentId,
|
@RequestParam Long adherentId,
|
||||||
@RequestParam BigDecimal montant,
|
@RequestParam BigDecimal montant,
|
||||||
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate datePaiement,
|
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate datePaiement,
|
||||||
@RequestParam Long modePaiementId) {
|
@RequestParam Long modePaiementId,
|
||||||
|
Principal principal) {
|
||||||
|
|
||||||
Licence licence = licenceRepository.findById(id)
|
Licence licence = licenceRepository.findById(id)
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Invalid Licence ID"));
|
.orElseThrow(() -> new IllegalArgumentException("Invalid Licence ID"));
|
||||||
@@ -52,6 +54,9 @@ public class PaiementController {
|
|||||||
paiement.setModePaiement(mode);
|
paiement.setModePaiement(mode);
|
||||||
paiement.setMontant(montant);
|
paiement.setMontant(montant);
|
||||||
paiement.setDatePaiement(datePaiement);
|
paiement.setDatePaiement(datePaiement);
|
||||||
|
if (principal != null) {
|
||||||
|
paiement.setGestionnaire(principal.getName());
|
||||||
|
}
|
||||||
paiementRepository.save(paiement);
|
paiementRepository.save(paiement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +69,8 @@ public class PaiementController {
|
|||||||
@RequestParam BigDecimal montant,
|
@RequestParam BigDecimal montant,
|
||||||
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate datePaiement,
|
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate datePaiement,
|
||||||
@RequestParam Long modePaiementId,
|
@RequestParam Long modePaiementId,
|
||||||
@RequestParam(required = false) String redirect) {
|
@RequestParam(required = false) String redirect,
|
||||||
|
Principal principal) {
|
||||||
|
|
||||||
Paiement paiement = paiementRepository.findById(id)
|
Paiement paiement = paiementRepository.findById(id)
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Invalid Paiement ID"));
|
.orElseThrow(() -> new IllegalArgumentException("Invalid Paiement ID"));
|
||||||
@@ -84,6 +90,9 @@ public class PaiementController {
|
|||||||
paiement.setModePaiement(mode);
|
paiement.setModePaiement(mode);
|
||||||
paiement.setMontant(montant);
|
paiement.setMontant(montant);
|
||||||
paiement.setDatePaiement(datePaiement);
|
paiement.setDatePaiement(datePaiement);
|
||||||
|
if (principal != null) {
|
||||||
|
paiement.setGestionnaire(principal.getName());
|
||||||
|
}
|
||||||
paiementRepository.save(paiement);
|
paiementRepository.save(paiement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -228,6 +228,7 @@
|
|||||||
<tr class="bg-gray-50 text-gray-500 uppercase font-medium">
|
<tr class="bg-gray-50 text-gray-500 uppercase font-medium">
|
||||||
<th class="py-2 px-3 text-left">Date</th>
|
<th class="py-2 px-3 text-left">Date</th>
|
||||||
<th class="py-2 px-3 text-left">Mode</th>
|
<th class="py-2 px-3 text-left">Mode</th>
|
||||||
|
<th class="py-2 px-3 text-left">Géré par</th>
|
||||||
<th class="py-2 px-3 text-right font-medium">Montant</th>
|
<th class="py-2 px-3 text-right font-medium">Montant</th>
|
||||||
<th class="py-2 px-3 text-right font-medium pr-4">Actions</th>
|
<th class="py-2 px-3 text-right font-medium pr-4">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -238,6 +239,7 @@
|
|||||||
<td class="py-2 px-3 text-gray-600">
|
<td class="py-2 px-3 text-gray-600">
|
||||||
<span class="px-2 py-0.5 rounded bg-gray-100 text-gray-700 font-mono text-[10px]" th:text="${paiement.modePaiement.nom}">Chèque</span>
|
<span class="px-2 py-0.5 rounded bg-gray-100 text-gray-700 font-mono text-[10px]" th:text="${paiement.modePaiement.nom}">Chèque</span>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="py-2 px-3 text-gray-500 text-xs italic" th:text="${paiement.gestionnaire != null ? paiement.gestionnaire : '-'}">-</td>
|
||||||
<td class="py-2 px-3 text-right font-semibold text-green-600" th:text="${paiement.montant + ' €'}">50.00 €</td>
|
<td class="py-2 px-3 text-right font-semibold text-green-600" th:text="${paiement.montant + ' €'}">50.00 €</td>
|
||||||
<td class="py-2 px-3 text-right pr-4">
|
<td class="py-2 px-3 text-right pr-4">
|
||||||
<div class="flex justify-end items-center space-x-2">
|
<div class="flex justify-end items-center space-x-2">
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Changement de mot de passe - AS Talange</title>
|
<title>Changement de mot de passe - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,37 +1,46 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<aside th:fragment="sidebar" class="w-64 bg-white border-r border-gray-200 flex flex-col hidden md:flex">
|
<aside th:fragment="sidebar" class="w-64 bg-white border-r border-gray-200 flex flex-col hidden md:flex">
|
||||||
<div class="h-16 flex items-center px-6 border-b border-gray-200">
|
<div class="h-16 flex items-center px-6 border-b border-gray-200">
|
||||||
|
<img src="/images/logo.png" alt="Logo AS Talange" class="h-8 w-8 mr-3 object-contain">
|
||||||
<h1 class="text-xl font-bold text-blue-600">AS Talange</h1>
|
<h1 class="text-xl font-bold text-blue-600">AS Talange</h1>
|
||||||
</div>
|
</div>
|
||||||
<nav class="flex-1 overflow-y-auto py-4 px-3 space-y-1">
|
<nav class="flex-1 overflow-y-auto py-4 px-3 space-y-1">
|
||||||
|
<!-- Menu Principal -->
|
||||||
|
<div class="pb-2 px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Gestion</div>
|
||||||
<a href="/" th:classappend="${requestURI == '/' ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Tableau de bord</a>
|
<a href="/" th:classappend="${requestURI == '/' ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Tableau de bord</a>
|
||||||
<a href="/adherents" th:classappend="${requestURI != null and requestURI.startsWith('/adherents') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Adhérents</a>
|
<a href="/adherents" th:classappend="${requestURI != null and requestURI.startsWith('/adherents') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Adhérents</a>
|
||||||
|
<a sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_AGENT_SAISIE')" href="/admin/pre-inscriptions" th:classappend="${requestURI != null and requestURI.startsWith('/admin/pre-inscriptions') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="flex items-center justify-between px-3 py-2 rounded-lg transition-colors">
|
||||||
<a sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_AGENT_SAISIE')" href="/admin/pre-inscriptions" th:classappend="${requestURI != null and requestURI.startsWith('/admin/pre-inscriptions') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="flex items-center px-3 py-2 rounded-lg transition-colors">
|
|
||||||
<span>Pré-inscriptions</span>
|
<span>Pré-inscriptions</span>
|
||||||
<span hx-get="/admin/pre-inscriptions/count" hx-trigger="load, every 30s, refreshBadge from:body" hx-swap="outerHTML"></span>
|
<span hx-get="/admin/pre-inscriptions/count" hx-trigger="load, every 30s, refreshBadge from:body" hx-swap="outerHTML"></span>
|
||||||
</a>
|
</a>
|
||||||
<a sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_TRESORERIE')" href="/paiements" th:classappend="${requestURI != null and requestURI.startsWith('/paiements') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Paiements</a>
|
<a sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_TRESORERIE')" href="/paiements" th:classappend="${requestURI != null and requestURI.startsWith('/paiements') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Paiements</a>
|
||||||
|
|
||||||
<th:block sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_AGENT_SAISIE')">
|
<th:block sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_AGENT_SAISIE')">
|
||||||
<div class="pt-4 pb-2 px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Planning</div>
|
<a href="/planning" th:classappend="${requestURI != null and requestURI.startsWith('/planning') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Planning</a>
|
||||||
<a href="/planning" th:classappend="${requestURI != null and requestURI.startsWith('/planning') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Entraînements</a>
|
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
<th:block sec:authorize="hasRole('ROLE_ADMIN')">
|
<th:block sec:authorize="hasRole('ROLE_ADMIN')">
|
||||||
|
<!-- Recherches & Exports -->
|
||||||
|
<div class="pt-4 pb-2 px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Recherches & Exports</div>
|
||||||
|
<a href="/admin/licences/recherche" th:classappend="${requestURI != null and requestURI.startsWith('/admin/licences/recherche') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Recherche Licences</a>
|
||||||
|
<a href="/admin/equipements/recherche" th:classappend="${requestURI != null and requestURI.startsWith('/admin/equipements/recherche') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Recherche Équipements</a>
|
||||||
|
|
||||||
|
<!-- Paramétrage -->
|
||||||
<div class="pt-4 pb-2 px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Paramétrage</div>
|
<div class="pt-4 pb-2 px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Paramétrage</div>
|
||||||
<a href="/saisons" th:classappend="${requestURI != null and requestURI.startsWith('/saisons') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Saisons</a>
|
<a href="/saisons" th:classappend="${requestURI != null and requestURI.startsWith('/saisons') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Saisons</a>
|
||||||
<a href="/categories" th:classappend="${requestURI != null and requestURI.startsWith('/categories') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Catégories</a>
|
<a href="/categories" th:classappend="${requestURI != null and requestURI.startsWith('/categories') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Catégories</a>
|
||||||
<a href="/equipes" th:classappend="${requestURI != null and requestURI.startsWith('/equipes') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Équipes</a>
|
<a href="/equipes" th:classappend="${requestURI != null and requestURI.startsWith('/equipes') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Équipes</a>
|
||||||
<a href="/educateurs" th:classappend="${requestURI != null and requestURI.startsWith('/educateurs') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Éducateurs</a>
|
<a href="/educateurs" th:classappend="${requestURI != null and requestURI.startsWith('/educateurs') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Éducateurs</a>
|
||||||
|
<a href="/equipements" th:classappend="${requestURI != null and requestURI.equals('/equipements') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Équipements</a>
|
||||||
<a href="/modespaiement" th:classappend="${requestURI != null and requestURI.startsWith('/modespaiement') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Modes de Paiement</a>
|
<a href="/modespaiement" th:classappend="${requestURI != null and requestURI.startsWith('/modespaiement') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Modes de Paiement</a>
|
||||||
<a href="/equipements" th:classappend="${requestURI != null and requestURI.startsWith('/equipements') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Équipements</a>
|
|
||||||
|
|
||||||
|
<!-- Administration -->
|
||||||
<div class="pt-4 pb-2 px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Administration</div>
|
<div class="pt-4 pb-2 px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Administration</div>
|
||||||
<a href="/utilisateurs" th:classappend="${requestURI != null and requestURI.startsWith('/utilisateurs') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Utilisateurs</a>
|
<a href="/utilisateurs" th:classappend="${requestURI != null and requestURI.startsWith('/utilisateurs') ? 'bg-blue-50 text-blue-700 font-medium' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'}" class="block px-3 py-2 rounded-lg transition-colors">Utilisateurs</a>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Connexion - AS Talange</title>
|
<title>Connexion - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Catégorie - AS Talange</title>
|
<title>Catégorie - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Paramétrage - Catégories</title>
|
<title>Paramétrage - Catégories</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Éducateur - AS Talange</title>
|
<title>Éducateur - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Paramétrage - Éducateurs</title>
|
<title>Paramétrage - Éducateurs</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Équipement - AS Talange</title>
|
<title>Équipement - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Paramétrage - Équipements</title>
|
<title>Paramétrage - Équipements</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Paramétrage - Recherche Équipements</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
|
<style> body { font-family: 'Inter', sans-serif; } </style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-gray-50 text-gray-900 flex h-screen overflow-hidden">
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<div th:replace="~{fragments/sidebar :: sidebar}"></div>
|
||||||
|
|
||||||
|
<main class="flex-1 flex flex-col h-screen overflow-hidden">
|
||||||
|
<header class="h-16 bg-white border-b border-gray-200 flex items-center px-6">
|
||||||
|
<h2 class="text-lg font-semibold text-gray-800">Recherche Équipements</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="flex-1 overflow-auto p-6">
|
||||||
|
|
||||||
|
<div class="bg-white p-6 rounded-lg border border-gray-200 shadow-sm mb-6">
|
||||||
|
<form th:action="@{/admin/equipements/recherche}" method="get" class="space-y-4">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">Équipement</label>
|
||||||
|
<select name="equipementId" class="w-full border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm px-3 py-2 border">
|
||||||
|
<option value="">Tous les équipements</option>
|
||||||
|
<option th:each="equip : ${equipements}" th:value="${equip.id}" th:text="${equip.nom}" th:selected="${equip.id == equipementId}"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">Catégorie</label>
|
||||||
|
<select name="categorieId" class="w-full border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm px-3 py-2 border">
|
||||||
|
<option value="">Toutes les catégories</option>
|
||||||
|
<option th:each="cat : ${categories}" th:value="${cat.id}" th:text="${cat.nom}" th:selected="${cat.id == categorieId}"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">Fourni</label>
|
||||||
|
<select name="fourni" class="w-full border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 sm:text-sm px-3 py-2 border">
|
||||||
|
<option value="">Tous</option>
|
||||||
|
<option value="true" th:selected="${fourni != null && fourni}">Oui</option>
|
||||||
|
<option value="false" th:selected="${fourni != null && !fourni}">Non</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end space-x-3">
|
||||||
|
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded-lg text-sm font-medium hover:bg-blue-700">Rechercher</button>
|
||||||
|
<a th:href="@{/admin/equipements/recherche/export(equipementId=${equipementId},categorieId=${categorieId},fourni=${fourni})}" class="bg-green-600 text-white px-4 py-2 rounded-lg text-sm font-medium hover:bg-green-700">Exporter</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
||||||
|
<table class="w-full text-left border-collapse">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-gray-50 text-gray-500 text-xs uppercase tracking-wider border-b border-gray-200">
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Licencié</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Poste / Sexe</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Catégorie</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Équipement</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Taille / Floc.</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-center">Fourni</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 text-sm">
|
||||||
|
<tr th:if="${#lists.isEmpty(dotations)}">
|
||||||
|
<td colspan="6" class="py-8 text-center text-gray-500">Aucun résultat trouvé pour cette recherche.</td>
|
||||||
|
</tr>
|
||||||
|
<tr th:each="dotation : ${dotations}" class="hover:bg-gray-50">
|
||||||
|
<td class="py-3 px-4 font-medium text-gray-900">
|
||||||
|
<span th:text="${dotation.licence.adherent.nom + ' ' + dotation.licence.adherent.prenom}">Nom Prénom</span>
|
||||||
|
</td>
|
||||||
|
<td class="py-3 px-4 text-gray-600 text-xs">
|
||||||
|
<div th:text="${dotation.licence.adherent.typeMaillot}">Joueur</div>
|
||||||
|
<div th:text="${dotation.licence.adherent.sexe}">Masculin</div>
|
||||||
|
</td>
|
||||||
|
<td class="py-3 px-4 text-gray-600" th:text="${dotation.licence.categorie != null ? dotation.licence.categorie.nom : '-'}">Catégorie</td>
|
||||||
|
<td class="py-3 px-4 text-gray-900 font-medium" th:text="${dotation.equipement != null ? dotation.equipement.nom : '-'}">Maillot</td>
|
||||||
|
<td class="py-3 px-4 text-gray-600">
|
||||||
|
<div th:text="'T: ' + (${dotation.taille != null && !dotation.taille.isEmpty() ? dotation.taille : '-'})">Taille</div>
|
||||||
|
<div th:if="${dotation.flocage != null && !dotation.flocage.isEmpty()}" th:text="'F: ' + ${dotation.flocage}">Flocage</div>
|
||||||
|
<div th:if="${dotation.numero != null && !dotation.numero.isEmpty()}" th:text="'N: ' + ${dotation.numero}">N°</div>
|
||||||
|
</td>
|
||||||
|
<td class="py-3 px-4 text-center">
|
||||||
|
<span th:if="${dotation.fourni}" class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800">Oui</span>
|
||||||
|
<span th:unless="${dotation.fourni}" class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800">Non</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Paramétrage - Équipes</title>
|
<title>Paramétrage - Équipes</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Recherche Licences - AS Talange</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
|
<style> body { font-family: 'Inter', sans-serif; } </style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-gray-50 text-gray-900 flex h-screen overflow-hidden">
|
||||||
|
<div th:replace="~{fragments/sidebar :: sidebar}"></div>
|
||||||
|
|
||||||
|
<main class="flex-1 flex flex-col h-screen overflow-hidden">
|
||||||
|
<header class="h-16 bg-white border-b border-gray-200 flex items-center px-6">
|
||||||
|
<h2 class="text-lg font-semibold text-gray-800">Recherche de Licences</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="flex-1 overflow-auto p-6">
|
||||||
|
<div class="bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-6">
|
||||||
|
<form th:action="@{/admin/licences/recherche}" method="get" class="flex flex-wrap items-end gap-4">
|
||||||
|
<div class="w-48">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">Nom</label>
|
||||||
|
<input type="text" name="nom" th:value="${nomFilter}" class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-blue-500 focus:border-blue-500">
|
||||||
|
</div>
|
||||||
|
<div class="w-48">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">Prénom</label>
|
||||||
|
<input type="text" name="prenom" th:value="${prenomFilter}" class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-blue-500 focus:border-blue-500">
|
||||||
|
</div>
|
||||||
|
<div class="w-48">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">N° Licence</label>
|
||||||
|
<input type="text" name="numeroLicence" th:value="${numeroLicenceFilter}" class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-blue-500 focus:border-blue-500">
|
||||||
|
</div>
|
||||||
|
<div class="w-64">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
|
||||||
|
<input type="text" name="email" th:value="${emailFilter}" class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-blue-500 focus:border-blue-500">
|
||||||
|
</div>
|
||||||
|
<div class="w-48">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">Catégorie</label>
|
||||||
|
<select name="categorieId" class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-blue-500 focus:border-blue-500">
|
||||||
|
<option value="">Toutes les catégories</option>
|
||||||
|
<option th:each="cat : ${categories}" th:value="${cat.id}" th:text="${cat.nom}" th:selected="${cat.id == categorieId}"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="w-48">
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-1">Type de Demande</label>
|
||||||
|
<select name="typeDemande" class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:ring-blue-500 focus:border-blue-500">
|
||||||
|
<option value="">Tous les types</option>
|
||||||
|
<option value="Nouvelle demande" th:selected="${typeDemandeFilter == 'Nouvelle demande'}">Nouvelle Demande</option>
|
||||||
|
<option value="Renouvellement" th:selected="${typeDemandeFilter == 'Renouvellement'}">Renouvellement</option>
|
||||||
|
<option value="Mutation" th:selected="${typeDemandeFilter == 'Mutation'}">Mutation</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex space-x-2">
|
||||||
|
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded-lg text-sm font-medium hover:bg-blue-700">Rechercher</button>
|
||||||
|
<a th:href="@{/admin/licences/recherche}" class="bg-gray-100 text-gray-700 px-4 py-2 rounded-lg text-sm font-medium hover:bg-gray-200">Réinitialiser</a>
|
||||||
|
<a th:href="@{/admin/licences/recherche/export(nom=${nomFilter},prenom=${prenomFilter},categorieId=${categorieId},numeroLicence=${numeroLicenceFilter},email=${emailFilter},typeDemande=${typeDemandeFilter})}"
|
||||||
|
class="bg-indigo-50 text-indigo-700 px-4 py-2 rounded-lg text-sm font-medium hover:bg-indigo-100 flex items-center">
|
||||||
|
Exporter CSV
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full text-left border-collapse min-w-[900px]">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200">
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Nom Prénom</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Catégorie</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">N° Licence</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Type de Demande</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">Email</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-left">État</th>
|
||||||
|
<th class="py-3 px-4 font-medium text-right">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200 text-sm">
|
||||||
|
<tr th:if="${#lists.isEmpty(licences)}">
|
||||||
|
<td colspan="7" class="py-8 text-center text-gray-500">Aucun résultat trouvé pour cette recherche.</td>
|
||||||
|
</tr>
|
||||||
|
<tr th:each="licence : ${licences}" class="hover:bg-gray-50">
|
||||||
|
<td class="py-3 px-4 font-medium text-gray-900">
|
||||||
|
<span th:text="${licence.adherent.nom + ' ' + licence.adherent.prenom}">Nom Prénom</span>
|
||||||
|
</td>
|
||||||
|
<td class="py-3 px-4 text-gray-600" th:text="${licence.categorie != null ? licence.categorie.nom : '-'}">Catégorie</td>
|
||||||
|
<td class="py-3 px-4 text-gray-600 font-mono" th:text="${licence.numeroLicence != null ? licence.numeroLicence : '-'}">N°</td>
|
||||||
|
<td class="py-3 px-4 text-gray-600" th:text="${licence.typeDemande != null ? licence.typeDemande : '-'}">Type</td>
|
||||||
|
<td class="py-3 px-4 text-gray-600" th:text="${licence.adherent.email != null ? licence.adherent.email : '-'}">Email</td>
|
||||||
|
<td class="py-3 px-4 text-gray-600" th:text="${licence.etat != null ? licence.etat : '-'}">Etat</td>
|
||||||
|
<td class="py-3 px-4 text-right">
|
||||||
|
<a th:href="@{/adherents/{id}/edit(id=${licence.adherent.id})}" class="text-indigo-600 hover:text-indigo-900 font-medium">Voir Profil</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Mode de Paiement - AS Talange</title>
|
<title>Mode de Paiement - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Paramétrage - Modes de Paiement</title>
|
<title>Paramétrage - Modes de Paiement</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Nouvelle Saison - AS Talange</title>
|
<title>Nouvelle Saison - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Paramétrage - Saisons</title>
|
<title>Paramétrage - Saisons</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Créneau d'Entraînement - AS Talange</title>
|
<title>Créneau d'Entraînement - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Planning des Entraînements - AS Talange</title>
|
<title>Planning des Entraînements - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>AS Talange - Pré-inscription</title>
|
<title>AS Talange - Pré-inscription</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>AS Talange - Formulaire d'inscription</title>
|
<title>AS Talange - Formulaire d'inscription</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
@@ -60,11 +61,23 @@
|
|||||||
<input type="email" th:field="*{email}" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
<input type="email" th:field="*{email}" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Removed Adresse -->
|
<div class="flex items-start pt-2">
|
||||||
|
<div class="flex items-center h-5">
|
||||||
|
<input id="consentementRgpd" name="consentementRgpd" type="checkbox" required class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500">
|
||||||
|
</div>
|
||||||
|
<div class="ml-3 text-sm">
|
||||||
|
<label for="consentementRgpd" class="font-medium text-gray-700">Consentement RGPD <span class="text-red-500">*</span></label>
|
||||||
|
<p class="text-gray-500 text-xs mt-1">J'accepte que l'AS Talange recueille et traite ces données pour la gestion de mon inscription et la logistique de la saison.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-3 px-4 rounded-lg transition-colors mt-4">
|
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-3 px-4 rounded-lg transition-colors mt-4">
|
||||||
Soumettre le dossier
|
Soumettre le dossier
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<p class="text-[10px] text-gray-400 text-center mt-4 leading-tight">
|
||||||
|
Les données sont stockées de manière sécurisée, accessibles uniquement au bureau du club. Vous pouvez demander leur suppression à tout moment.
|
||||||
|
</p>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Lien expiré</title>
|
<title>Lien expiré</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Inscription réussie</title>
|
<title>Inscription réussie</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Ajouter un Utilisateur - AS Talange</title>
|
<title>Ajouter un Utilisateur - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
<head>
|
<head>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Gestion des Utilisateurs - AS Talange</title>
|
<title>Gestion des Utilisateurs - AS Talange</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
import os
|
||||||
|
import glob
|
||||||
|
|
||||||
|
template_dir = "/home/ucef/.gemini/antigravity/scratch/as-talange/as-talange-web/src/main/resources/templates"
|
||||||
|
html_files = glob.glob(template_dir + "/**/*.html", recursive=True)
|
||||||
|
|
||||||
|
for file in html_files:
|
||||||
|
with open(file, "r") as f:
|
||||||
|
content = f.read()
|
||||||
|
if "htmx.org" not in content and "<head>" in content:
|
||||||
|
content = content.replace("<head>", "<head>\n <script src=\"https://unpkg.com/htmx.org@1.9.11\"></script>")
|
||||||
|
with open(file, "w") as f:
|
||||||
|
f.write(content)
|
||||||
|
print(f"Fixed {file}")
|
||||||
Reference in New Issue
Block a user