Compare commits

..

2 Commits

Author SHA1 Message Date
ucef bf4c7b36bd fix(ui): Rendre les tableaux principaux responsives (overflow-x-auto)
AS Talange CI/CD Pipeline / Build & Run Unit Tests (push) Successful in 8m8s
AS Talange CI/CD Pipeline / Build & Run in Docker Container (push) Successful in 6m31s
2026-06-14 01:08:12 +02:00
ucef 3ed9d0454b feat: Refonte du schéma Adhérent (Lieu de naissance, Nationalité, Type Licence), suppression du téléphone, email obligatoire 2026-06-14 01:07:45 +02:00
19 changed files with 230 additions and 104 deletions
@@ -23,15 +23,18 @@ public class Adherent {
@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE) @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)
private LocalDate dateNaissance; private LocalDate dateNaissance;
@Column(length = 20) @Column(name = "lieu_naissance_ville", nullable = false, length = 100)
private String telephone; private String lieuNaissanceVille;
@Column(length = 100) @Column(name = "lieu_naissance_pays", nullable = false, length = 100)
private String lieuNaissancePays;
@Column(nullable = false, length = 100)
private String nationalite;
@Column(nullable = false, length = 100)
private String email; private String email;
@Column(columnDefinition = "TEXT")
private String adresse;
@Column(name = "representant_legal", length = 150) @Column(name = "representant_legal", length = 150)
private String representantLegal; private String representantLegal;
@@ -63,15 +66,18 @@ public class Adherent {
public LocalDate getDateNaissance() { return dateNaissance; } public LocalDate getDateNaissance() { return dateNaissance; }
public void setDateNaissance(LocalDate dateNaissance) { this.dateNaissance = dateNaissance; } public void setDateNaissance(LocalDate dateNaissance) { this.dateNaissance = dateNaissance; }
public String getTelephone() { return telephone; } public String getLieuNaissanceVille() { return lieuNaissanceVille; }
public void setTelephone(String telephone) { this.telephone = telephone; } public void setLieuNaissanceVille(String lieuNaissanceVille) { this.lieuNaissanceVille = lieuNaissanceVille; }
public String getLieuNaissancePays() { return lieuNaissancePays; }
public void setLieuNaissancePays(String lieuNaissancePays) { this.lieuNaissancePays = lieuNaissancePays; }
public String getNationalite() { return nationalite; }
public void setNationalite(String nationalite) { this.nationalite = nationalite; }
public String getEmail() { return email; } public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; } public void setEmail(String email) { this.email = email; }
public String getAdresse() { return adresse; }
public void setAdresse(String adresse) { this.adresse = adresse; }
public String getRepresentantLegal() { return representantLegal; } public String getRepresentantLegal() { return representantLegal; }
public void setRepresentantLegal(String representantLegal) { this.representantLegal = representantLegal; } public void setRepresentantLegal(String representantLegal) { this.representantLegal = representantLegal; }
@@ -6,14 +6,16 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
@Entity @Entity
@Table(name = "categorie") @Table(name = "categorie", uniqueConstraints = {
@UniqueConstraint(columnNames = {"nom", "saison_id"})
})
public class Categorie { public class Categorie {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
@Column(nullable = false, unique = true, length = 20) @Column(nullable = false, length = 20)
private String nom; private String nom;
@Column(name = "annee_min") @Column(name = "annee_min")
@@ -35,6 +35,12 @@ public class Licence {
@Column(name = "numero_licence", length = 50) @Column(name = "numero_licence", length = 50)
private String numeroLicence; private String numeroLicence;
@Column(name = "type_demande", length = 50)
private String typeDemande;
@Column(name = "type_licence", length = 50)
private String typeLicence;
@OneToMany(mappedBy = "licence", cascade = CascadeType.ALL, orphanRemoval = true) @OneToMany(mappedBy = "licence", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Paiement> paiements = new ArrayList<>(); private List<Paiement> paiements = new ArrayList<>();
@@ -113,14 +119,20 @@ public class Licence {
public String getEtat() { return etat; } public String getEtat() { return etat; }
public void setEtat(String etat) { this.etat = etat; } public void setEtat(String etat) { this.etat = etat; }
public String getNumeroLicence() { return numeroLicence; }
public void setNumeroLicence(String numeroLicence) { this.numeroLicence = numeroLicence; }
public String getTypeDemande() { return typeDemande; }
public void setTypeDemande(String typeDemande) { this.typeDemande = typeDemande; }
public String getTypeLicence() { return typeLicence; }
public void setTypeLicence(String typeLicence) { this.typeLicence = typeLicence; }
public List<Paiement> getPaiements() { return paiements; } public List<Paiement> getPaiements() { return paiements; }
public void setPaiements(List<Paiement> paiements) { this.paiements = paiements; } public void setPaiements(List<Paiement> paiements) { this.paiements = paiements; }
public List<Dotation> getDotations() { return dotations; } public List<Dotation> getDotations() { return dotations; }
public void setDotations(List<Dotation> dotations) { this.dotations = dotations; } public void setDotations(List<Dotation> dotations) { this.dotations = dotations; }
public String getNumeroLicence() { return numeroLicence; }
public void setNumeroLicence(String numeroLicence) { this.numeroLicence = numeroLicence; }
public void addPaiement(Paiement paiement) { public void addPaiement(Paiement paiement) {
paiements.add(paiement); paiements.add(paiement);
@@ -21,15 +21,18 @@ public class PreInscription {
@Column(name = "date_naissance", nullable = false) @Column(name = "date_naissance", nullable = false)
private LocalDate dateNaissance; private LocalDate dateNaissance;
@Column(length = 20) @Column(name = "lieu_naissance_ville", nullable = false, length = 100)
private String telephone; private String lieuNaissanceVille;
@Column(length = 150) @Column(name = "lieu_naissance_pays", nullable = false, length = 100)
private String lieuNaissancePays;
@Column(nullable = false, length = 100)
private String nationalite;
@Column(nullable = false, length = 150)
private String email; private String email;
@Column(columnDefinition = "TEXT")
private String adresse;
@Column(name = "representant_legal", length = 150) @Column(name = "representant_legal", length = 150)
private String representantLegal; private String representantLegal;
@@ -56,15 +59,18 @@ public class PreInscription {
public LocalDate getDateNaissance() { return dateNaissance; } public LocalDate getDateNaissance() { return dateNaissance; }
public void setDateNaissance(LocalDate dateNaissance) { this.dateNaissance = dateNaissance; } public void setDateNaissance(LocalDate dateNaissance) { this.dateNaissance = dateNaissance; }
public String getTelephone() { return telephone; } public String getLieuNaissanceVille() { return lieuNaissanceVille; }
public void setTelephone(String telephone) { this.telephone = telephone; } public void setLieuNaissanceVille(String lieuNaissanceVille) { this.lieuNaissanceVille = lieuNaissanceVille; }
public String getLieuNaissancePays() { return lieuNaissancePays; }
public void setLieuNaissancePays(String lieuNaissancePays) { this.lieuNaissancePays = lieuNaissancePays; }
public String getNationalite() { return nationalite; }
public void setNationalite(String nationalite) { this.nationalite = nationalite; }
public String getEmail() { return email; } public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; } public void setEmail(String email) { this.email = email; }
public String getAdresse() { return adresse; }
public void setAdresse(String adresse) { this.adresse = adresse; }
public String getRepresentantLegal() { return representantLegal; } public String getRepresentantLegal() { return representantLegal; }
public void setRepresentantLegal(String representantLegal) { this.representantLegal = representantLegal; } public void setRepresentantLegal(String representantLegal) { this.representantLegal = representantLegal; }
@@ -38,9 +38,10 @@ public class PreInscriptionService {
adherent.setNom(pre.getNom().toUpperCase()); adherent.setNom(pre.getNom().toUpperCase());
adherent.setPrenom(pre.getPrenom()); adherent.setPrenom(pre.getPrenom());
adherent.setDateNaissance(pre.getDateNaissance()); adherent.setDateNaissance(pre.getDateNaissance());
adherent.setTelephone(pre.getTelephone()); adherent.setLieuNaissanceVille(pre.getLieuNaissanceVille());
adherent.setLieuNaissancePays(pre.getLieuNaissancePays());
adherent.setNationalite(pre.getNationalite());
adherent.setEmail(pre.getEmail()); adherent.setEmail(pre.getEmail());
adherent.setAdresse(pre.getAdresse());
adherent.setRepresentantLegal(pre.getRepresentantLegal()); adherent.setRepresentantLegal(pre.getRepresentantLegal());
// Par défaut // Par défaut
adherent.setSexe("MASCULIN"); adherent.setSexe("MASCULIN");
@@ -0,0 +1,5 @@
-- Drop the global unique constraint on 'nom'
ALTER TABLE categorie DROP CONSTRAINT IF EXISTS categorie_nom_key;
-- Add a composite unique constraint for 'nom' and 'saison_id'
ALTER TABLE categorie ADD CONSTRAINT categorie_nom_saison_id_key UNIQUE (nom, saison_id);
@@ -0,0 +1,11 @@
-- adherent modifications
ALTER TABLE adherent DROP COLUMN IF EXISTS adresse;
ALTER TABLE adherent ADD COLUMN lieu_naissance_ville VARCHAR(100);
ALTER TABLE adherent ADD COLUMN lieu_naissance_pays VARCHAR(100);
ALTER TABLE adherent ADD COLUMN nationalite VARCHAR(100);
-- pre_inscription modifications
ALTER TABLE pre_inscription DROP COLUMN IF EXISTS adresse;
ALTER TABLE pre_inscription ADD COLUMN lieu_naissance_ville VARCHAR(100);
ALTER TABLE pre_inscription ADD COLUMN lieu_naissance_pays VARCHAR(100);
ALTER TABLE pre_inscription ADD COLUMN nationalite VARCHAR(100);
@@ -0,0 +1,2 @@
ALTER TABLE licence ADD COLUMN type_demande VARCHAR(50);
ALTER TABLE licence ADD COLUMN type_licence VARCHAR(50);
@@ -0,0 +1,18 @@
-- Default values for existing records in adherent
UPDATE adherent SET lieu_naissance_ville = 'Non renseigné' WHERE lieu_naissance_ville IS NULL;
UPDATE adherent SET lieu_naissance_pays = 'France' WHERE lieu_naissance_pays IS NULL;
UPDATE adherent SET nationalite = 'Française' WHERE nationalite IS NULL;
-- Default values for existing records in pre_inscription
UPDATE pre_inscription SET lieu_naissance_ville = 'Non renseigné' WHERE lieu_naissance_ville IS NULL;
UPDATE pre_inscription SET lieu_naissance_pays = 'France' WHERE lieu_naissance_pays IS NULL;
UPDATE pre_inscription SET nationalite = 'Française' WHERE nationalite IS NULL;
-- Now make them NOT NULL
ALTER TABLE adherent ALTER COLUMN lieu_naissance_ville SET NOT NULL;
ALTER TABLE adherent ALTER COLUMN lieu_naissance_pays SET NOT NULL;
ALTER TABLE adherent ALTER COLUMN nationalite SET NOT NULL;
ALTER TABLE pre_inscription ALTER COLUMN lieu_naissance_ville SET NOT NULL;
ALTER TABLE pre_inscription ALTER COLUMN lieu_naissance_pays SET NOT NULL;
ALTER TABLE pre_inscription ALTER COLUMN nationalite SET NOT NULL;
@@ -0,0 +1,11 @@
-- Provide fallback email if null
UPDATE adherent SET email = 'nonrenseigne@example.com' WHERE email IS NULL OR email = '';
UPDATE pre_inscription SET email = 'nonrenseigne@example.com' WHERE email IS NULL OR email = '';
-- Make email NOT NULL
ALTER TABLE adherent ALTER COLUMN email SET NOT NULL;
ALTER TABLE pre_inscription ALTER COLUMN email SET NOT NULL;
-- Remove telephone
ALTER TABLE adherent DROP COLUMN IF EXISTS telephone;
ALTER TABLE pre_inscription DROP COLUMN IF EXISTS telephone;
@@ -45,7 +45,6 @@ public class AdherentController {
@org.springframework.web.bind.annotation.RequestParam(required = false) String categorie, @org.springframework.web.bind.annotation.RequestParam(required = false) String categorie,
@org.springframework.web.bind.annotation.RequestParam(required = false) String licence, @org.springframework.web.bind.annotation.RequestParam(required = false) String licence,
@org.springframework.web.bind.annotation.RequestParam(required = false) String email, @org.springframework.web.bind.annotation.RequestParam(required = false) String email,
@org.springframework.web.bind.annotation.RequestParam(required = false) String telephone,
@org.springframework.web.bind.annotation.RequestParam(required = false) String paiement, @org.springframework.web.bind.annotation.RequestParam(required = false) String paiement,
@org.springframework.web.bind.annotation.RequestParam(defaultValue = "0") int page, @org.springframework.web.bind.annotation.RequestParam(defaultValue = "0") int page,
@org.springframework.web.bind.annotation.RequestParam(defaultValue = "20") int size, @org.springframework.web.bind.annotation.RequestParam(defaultValue = "20") int size,
@@ -97,11 +96,6 @@ public class AdherentController {
adherents = adherents.stream().filter(a -> a.getEmail() != null && a.getEmail().toLowerCase().contains(e)).collect(java.util.stream.Collectors.toList()); adherents = adherents.stream().filter(a -> a.getEmail() != null && a.getEmail().toLowerCase().contains(e)).collect(java.util.stream.Collectors.toList());
model.addAttribute("emailFilter", email.trim()); model.addAttribute("emailFilter", email.trim());
} }
if (telephone != null && !telephone.trim().isEmpty()) {
String t = telephone.trim().toLowerCase();
adherents = adherents.stream().filter(a -> a.getTelephone() != null && a.getTelephone().toLowerCase().contains(t)).collect(java.util.stream.Collectors.toList());
model.addAttribute("telephoneFilter", telephone.trim());
}
if (paiement != null && !paiement.trim().isEmpty()) { if (paiement != null && !paiement.trim().isEmpty()) {
adherents = adherents.stream().filter(a -> { adherents = adherents.stream().filter(a -> {
String statut = a.getStatutPaiement(); String statut = a.getStatutPaiement();
@@ -201,9 +195,10 @@ public class AdherentController {
existing.setNom(adherent.getNom()); existing.setNom(adherent.getNom());
existing.setPrenom(adherent.getPrenom()); existing.setPrenom(adherent.getPrenom());
existing.setDateNaissance(adherent.getDateNaissance()); existing.setDateNaissance(adherent.getDateNaissance());
existing.setTelephone(adherent.getTelephone()); existing.setLieuNaissanceVille(adherent.getLieuNaissanceVille());
existing.setLieuNaissancePays(adherent.getLieuNaissancePays());
existing.setNationalite(adherent.getNationalite());
existing.setEmail(adherent.getEmail()); existing.setEmail(adherent.getEmail());
existing.setAdresse(adherent.getAdresse());
existing.setRepresentantLegal(adherent.getRepresentantLegal()); existing.setRepresentantLegal(adherent.getRepresentantLegal());
existing.setResidentTalange(adherent.isResidentTalange()); existing.setResidentTalange(adherent.isResidentTalange());
existing.setSexe(adherent.getSexe()); existing.setSexe(adherent.getSexe());
@@ -44,6 +44,8 @@ public class LicenceController {
@RequestParam Long categorieId, @RequestParam Long categorieId,
@RequestParam String etat, @RequestParam String etat,
@RequestParam(required = false) String numeroLicence, @RequestParam(required = false) String numeroLicence,
@RequestParam(required = false) String typeDemande,
@RequestParam(required = false) String typeLicence,
@RequestParam(required = false) Long equipeId) { @RequestParam(required = false) Long equipeId) {
Adherent adherent = adherentRepository.findById(id) Adherent adherent = adherentRepository.findById(id)
@@ -66,6 +68,8 @@ public class LicenceController {
licence.setSaison(saisonActive); licence.setSaison(saisonActive);
licence.setEtat(etat); licence.setEtat(etat);
licence.setNumeroLicence(numeroLicence); licence.setNumeroLicence(numeroLicence);
licence.setTypeDemande(typeDemande);
licence.setTypeLicence(typeLicence);
if (equipeId != null) { if (equipeId != null) {
Equipe equipe = equipeRepository.findById(equipeId) Equipe equipe = equipeRepository.findById(equipeId)
@@ -101,6 +105,8 @@ public class LicenceController {
@RequestParam Long categorieId, @RequestParam Long categorieId,
@RequestParam String etat, @RequestParam String etat,
@RequestParam(required = false) String numeroLicence, @RequestParam(required = false) String numeroLicence,
@RequestParam(required = false) String typeDemande,
@RequestParam(required = false) String typeLicence,
@RequestParam(required = false) Long equipeId) { @RequestParam(required = false) Long equipeId) {
Licence licence = licenceRepository.findById(licenceId) Licence licence = licenceRepository.findById(licenceId)
@@ -112,6 +118,8 @@ public class LicenceController {
licence.setCategorie(categorie); licence.setCategorie(categorie);
licence.setEtat(etat); licence.setEtat(etat);
licence.setNumeroLicence(numeroLicence); licence.setNumeroLicence(numeroLicence);
licence.setTypeDemande(typeDemande);
licence.setTypeLicence(typeLicence);
if (equipeId != null) { if (equipeId != null) {
Equipe equipe = equipeRepository.findById(equipeId) Equipe equipe = equipeRepository.findById(equipeId)
@@ -64,16 +64,38 @@
<p th:if="${#fields.hasErrors('dateNaissance')}" th:errors="*{dateNaissance}" class="mt-1 text-xs text-red-600"></p> <p th:if="${#fields.hasErrors('dateNaissance')}" th:errors="*{dateNaissance}" class="mt-1 text-xs text-red-600"></p>
</div> </div>
<!-- Téléphone --> <!-- Lieu de naissance (Ville) -->
<div> <div>
<label for="telephone" class="block text-sm font-medium text-gray-700 mb-1">Téléphone</label> <label for="lieuNaissanceVille" class="block text-sm font-medium text-gray-700 mb-1">Ville de naissance <span class="text-red-500">*</span></label>
<input type="tel" id="telephone" th:field="*{telephone}" <input type="text" id="lieuNaissanceVille" th:field="*{lieuNaissanceVille}" required
class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
th:classappend="${#fields.hasErrors('telephone')} ? 'border-red-500' : ''"> th:classappend="${#fields.hasErrors('lieuNaissanceVille')} ? 'border-red-500' : ''">
<p th:if="${#fields.hasErrors('telephone')}" th:errors="*{telephone}" class="mt-1 text-xs text-red-600"></p> <p th:if="${#fields.hasErrors('lieuNaissanceVille')}" th:errors="*{lieuNaissanceVille}" class="mt-1 text-xs text-red-600"></p>
</div> </div>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Lieu de naissance (Pays) -->
<div>
<label for="lieuNaissancePays" class="block text-sm font-medium text-gray-700 mb-1">Pays de naissance <span class="text-red-500">*</span></label>
<input type="text" id="lieuNaissancePays" th:field="*{lieuNaissancePays}" required
class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
th:classappend="${#fields.hasErrors('lieuNaissancePays')} ? 'border-red-500' : ''">
<p th:if="${#fields.hasErrors('lieuNaissancePays')}" th:errors="*{lieuNaissancePays}" class="mt-1 text-xs text-red-600"></p>
</div>
<!-- Nationalité -->
<div>
<label for="nationalite" class="block text-sm font-medium text-gray-700 mb-1">Nationalité <span class="text-red-500">*</span></label>
<input type="text" id="nationalite" th:field="*{nationalite}" required
class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
th:classappend="${#fields.hasErrors('nationalite')} ? 'border-red-500' : ''">
<p th:if="${#fields.hasErrors('nationalite')}" th:errors="*{nationalite}" class="mt-1 text-xs text-red-600"></p>
</div>
</div>
<!-- Removed telephone -->
<!-- Représentant Légal (Dynamique) --> <!-- Représentant Légal (Dynamique) -->
<div id="representantBlock" class="hidden-block bg-blue-50 p-4 rounded-lg border border-blue-100"> <div id="representantBlock" class="hidden-block bg-blue-50 p-4 rounded-lg border border-blue-100">
<label for="representantLegal" class="block text-sm font-medium text-blue-800 mb-1"> <label for="representantLegal" class="block text-sm font-medium text-blue-800 mb-1">
@@ -89,20 +111,12 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Email --> <!-- Email -->
<div> <div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label> <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email <span class="text-red-500">*</span></label>
<input type="email" id="email" th:field="*{email}" <input type="email" id="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 focus:border-blue-500 outline-none transition-colors" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
th:classappend="${#fields.hasErrors('email')} ? 'border-red-500' : ''"> th:classappend="${#fields.hasErrors('email')} ? 'border-red-500' : ''">
<p th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="mt-1 text-xs text-red-600"></p> <p th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="mt-1 text-xs text-red-600"></p>
</div> </div>
<!-- Résident Talange -->
<div class="flex items-center space-x-3 mt-7">
<input type="checkbox" id="residentTalange" th:field="*{residentTalange}" class="w-5 h-5 text-blue-600 border-gray-300 rounded focus:ring-blue-500">
<label for="residentTalange" class="text-sm font-medium text-gray-700">
Résident de la commune de Talange
</label>
</div>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
@@ -125,14 +139,7 @@
</div> </div>
</div> </div>
<!-- Adresse --> <!-- Removed Adresse -->
<div>
<label for="adresse" class="block text-sm font-medium text-gray-700 mb-1">Adresse postale</label>
<textarea id="adresse" th:field="*{adresse}" rows="3"
class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
th:classappend="${#fields.hasErrors('adresse')} ? 'border-red-500' : ''"></textarea>
<p th:if="${#fields.hasErrors('adresse')}" th:errors="*{adresse}" class="mt-1 text-xs text-red-600"></p>
</div>
<div class="pt-4 flex justify-end space-x-3 border-t border-gray-100"> <div class="pt-4 flex justify-end space-x-3 border-t border-gray-100">
<a th:href="@{/adherents}" class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">Annuler</a> <a th:href="@{/adherents}" class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">Annuler</a>
@@ -150,11 +157,13 @@
</button> </button>
</div> </div>
<table class="w-full text-left border-collapse"> <div class="overflow-x-auto">
<table class="w-full text-left border-collapse min-w-[800px]">
<thead> <thead>
<tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200"> <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">Saison</th> <th class="py-3 px-4 font-medium">Saison</th>
<th class="py-3 px-4 font-medium">Catégorie</th> <th class="py-3 px-4 font-medium">Catégorie</th>
<th class="py-3 px-4 font-medium">Demande / Type</th>
<th class="py-3 px-4 font-medium">N° Licence</th> <th class="py-3 px-4 font-medium">N° Licence</th>
<th class="py-3 px-4 font-medium">État</th> <th class="py-3 px-4 font-medium">État</th>
<th class="py-3 px-4 font-medium">Tarif Global</th> <th class="py-3 px-4 font-medium">Tarif Global</th>
@@ -164,7 +173,7 @@
</thead> </thead>
<tbody class="divide-y divide-gray-200 text-sm"> <tbody class="divide-y divide-gray-200 text-sm">
<tr th:if="${#lists.isEmpty(licences)}"> <tr th:if="${#lists.isEmpty(licences)}">
<td colspan="7" class="py-4 px-4 text-center text-gray-500">Aucune licence enregistrée.</td> <td colspan="8" class="py-4 px-4 text-center text-gray-500">Aucune licence enregistrée.</td>
</tr> </tr>
<th:block th:each="lic : ${licences}"> <th:block th:each="lic : ${licences}">
<tr class="hover:bg-gray-50 border-b border-gray-100 licence-row" <tr class="hover:bg-gray-50 border-b border-gray-100 licence-row"
@@ -177,6 +186,10 @@
<span th:text="${lic.categorie.nom + (lic.equipe != null ? ' (' + lic.equipe.nom + ')' : '')}">U15</span> <span th:text="${lic.categorie.nom + (lic.equipe != null ? ' (' + lic.equipe.nom + ')' : '')}">U15</span>
<span class="text-[10px] text-gray-400 block cell-tarif-categorie" th:text="${(lic.adherent != null && lic.adherent.residentTalange ? lic.categorie.tarifBase : lic.categorie.tarifExterieur) + ' € (Catégorie)'}">100.00 € (Catégorie)</span> <span class="text-[10px] text-gray-400 block cell-tarif-categorie" th:text="${(lic.adherent != null && lic.adherent.residentTalange ? lic.categorie.tarifBase : lic.categorie.tarifExterieur) + ' € (Catégorie)'}">100.00 € (Catégorie)</span>
</td> </td>
<td class="py-4 px-4 text-gray-600 text-xs">
<div th:text="${lic.typeDemande != null ? lic.typeDemande : '-'}">Nouvelle</div>
<div class="text-[10px] text-gray-500" th:text="${lic.typeLicence != null ? lic.typeLicence : '-'}">Libre</div>
</td>
<td class="py-4 px-4 text-gray-600 font-mono text-xs" th:text="${lic.numeroLicence != null and !lic.numeroLicence.isEmpty() ? lic.numeroLicence : '-'}">-</td> <td class="py-4 px-4 text-gray-600 font-mono text-xs" th:text="${lic.numeroLicence != null and !lic.numeroLicence.isEmpty() ? lic.numeroLicence : '-'}">-</td>
<td class="py-4 px-4"> <td class="py-4 px-4">
<span class="px-2 py-1 text-xs font-semibold rounded-full" <span class="px-2 py-1 text-xs font-semibold rounded-full"
@@ -193,8 +206,10 @@
th:data-categorie-id="${lic.categorie.id}" th:data-categorie-id="${lic.categorie.id}"
th:data-numero-licence="${lic.numeroLicence}" th:data-numero-licence="${lic.numeroLicence}"
th:data-etat="${lic.etat}" th:data-etat="${lic.etat}"
th:data-type-demande="${lic.typeDemande}"
th:data-type-licence="${lic.typeLicence}"
th:data-equipe-id="${lic.equipe != null ? lic.equipe.id : ''}" th:data-equipe-id="${lic.equipe != null ? lic.equipe.id : ''}"
onclick="openLicenceModal(this.getAttribute('data-licence-id'), this.getAttribute('data-categorie-id'), this.getAttribute('data-numero-licence'), this.getAttribute('data-etat'), this.getAttribute('data-equipe-id'))" onclick="openLicenceModal(this.getAttribute('data-licence-id'), this.getAttribute('data-categorie-id'), this.getAttribute('data-numero-licence'), this.getAttribute('data-etat'), this.getAttribute('data-type-demande'), this.getAttribute('data-type-licence'), this.getAttribute('data-equipe-id'))"
class="text-blue-600 hover:text-blue-800 font-medium bg-blue-50 px-3 py-1 rounded-lg">Modifier</button> class="text-blue-600 hover:text-blue-800 font-medium bg-blue-50 px-3 py-1 rounded-lg">Modifier</button>
<button th:if="${lic.getResteAPayer() > 0}" <button th:if="${lic.getResteAPayer() > 0}"
type="button" type="button"
@@ -205,7 +220,7 @@
</td> </td>
</tr> </tr>
<tr th:if="${!#lists.isEmpty(lic.paiements)}" class="bg-gray-50/50"> <tr th:if="${!#lists.isEmpty(lic.paiements)}" class="bg-gray-50/50">
<td colspan="7" class="py-3 px-6"> <td colspan="8" class="py-3 px-6">
<div class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">Historique des paiements</div> <div class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-2">Historique des paiements</div>
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 bg-white rounded-lg border border-gray-200 shadow-sm text-xs"> <table class="min-w-full divide-y divide-gray-200 bg-white rounded-lg border border-gray-200 shadow-sm text-xs">
@@ -344,8 +359,8 @@
</tr> </tr>
</th:block> </th:block>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</main> </main>
@@ -382,6 +397,27 @@
<label class="block text-sm font-medium text-gray-700 mb-1">Numéro de licence</label> <label class="block text-sm font-medium text-gray-700 mb-1">Numéro de licence</label>
<input id="numeroLicenceInput" type="text" name="numeroLicence" placeholder="Ex: FFF-123456" 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 id="numeroLicenceInput" type="text" name="numeroLicence" placeholder="Ex: FFF-123456" 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>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Type de demande</label>
<select id="typeDemandeSelect" name="typeDemande" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
<option value="">Sélectionnez...</option>
<option value="Renouvellement">Renouvellement</option>
<option value="Nouvelle demande">Nouvelle demande</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Type de licence</label>
<select id="typeLicenceSelect" name="typeLicence" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
<option value="">Sélectionnez...</option>
<option value="Animateur">Animateur</option>
<option value="Arbitre">Arbitre</option>
<option value="Dirigeant">Dirigeant</option>
<option value="Educateur Fédéral">Educateur Fédéral</option>
<option value="Foot loisir">Foot loisir</option>
<option value="Libre">Libre</option>
<option value="Technique">Technique</option>
</select>
</div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-1">Saison</label> <label class="block text-sm font-medium text-gray-700 mb-1">Saison</label>
<input id="saisonInput" type="text" name="saison" value="Saison Actuelle" readonly class="w-full border border-gray-200 bg-gray-50 rounded-lg px-4 py-2 text-sm text-gray-500 outline-none cursor-not-allowed"> <input id="saisonInput" type="text" name="saison" value="Saison Actuelle" readonly class="w-full border border-gray-200 bg-gray-50 rounded-lg px-4 py-2 text-sm text-gray-500 outline-none cursor-not-allowed">
@@ -468,7 +504,7 @@
</div> </div>
<script th:inline="javascript"> <script th:inline="javascript">
function openLicenceModal(licenceId = null, categorieId = '', numeroLicence = '', etat = 'Brouillon', equipeId = '') { function openLicenceModal(licenceId = null, categorieId = '', numeroLicence = '', etat = 'Brouillon', typeDemande = '', typeLicence = '', equipeId = '') {
document.getElementById('licenceModal').classList.remove('hidden'); document.getElementById('licenceModal').classList.remove('hidden');
const form = document.getElementById('licenceForm'); const form = document.getElementById('licenceForm');
const title = document.getElementById('licenceModalTitle'); const title = document.getElementById('licenceModalTitle');
@@ -485,6 +521,8 @@
catSelect.value = categorieId; catSelect.value = categorieId;
document.getElementById('numeroLicenceInput').value = numeroLicence; document.getElementById('numeroLicenceInput').value = numeroLicence;
document.getElementById('etatSelect').value = etat; document.getElementById('etatSelect').value = etat;
document.getElementById('typeDemandeSelect').value = typeDemande;
document.getElementById('typeLicenceSelect').value = typeLicence;
// Fetch and populate teams // Fetch and populate teams
if (categorieId) { if (categorieId) {
@@ -500,6 +538,8 @@
form.action = '/adherents/' + adherentId + '/licences'; form.action = '/adherents/' + adherentId + '/licences';
document.getElementById('numeroLicenceInput').value = ''; document.getElementById('numeroLicenceInput').value = '';
document.getElementById('etatSelect').value = 'Brouillon'; document.getElementById('etatSelect').value = 'Brouillon';
document.getElementById('typeDemandeSelect').value = '';
document.getElementById('typeLicenceSelect').value = '';
// Pré-sélection de la catégorie selon l'année de naissance // Pré-sélection de la catégorie selon l'année de naissance
const dateNaissanceStr = document.getElementById('dateNaissance').value; const dateNaissanceStr = document.getElementById('dateNaissance').value;
@@ -54,7 +54,8 @@
</form> </form>
</div> </div>
<table class="w-full text-left border-collapse"> <div class="overflow-x-auto">
<table class="w-full text-left border-collapse min-w-[1000px]">
<thead> <thead>
<tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200"> <tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200">
<th class="py-3 px-6 font-medium text-left">Nom</th> <th class="py-3 px-6 font-medium text-left">Nom</th>
@@ -62,7 +63,6 @@
<th class="py-3 px-6 font-medium text-left">Catégorie</th> <th class="py-3 px-6 font-medium text-left">Catégorie</th>
<th class="py-3 px-6 font-medium text-center">N° Licence</th> <th class="py-3 px-6 font-medium text-center">N° Licence</th>
<th class="py-3 px-6 font-medium text-left">Email</th> <th class="py-3 px-6 font-medium text-left">Email</th>
<th class="py-3 px-6 font-medium text-left">Téléphone</th>
<th class="py-3 px-6 font-medium text-center">Paiement</th> <th class="py-3 px-6 font-medium text-center">Paiement</th>
<th class="py-3 px-6 font-medium text-right">Actions</th> <th class="py-3 px-6 font-medium text-right">Actions</th>
</tr> </tr>
@@ -86,9 +86,6 @@
<td class="py-2 px-3"> <td class="py-2 px-3">
<input type="text" id="filterEmail" name="email" th:value="${emailFilter}" placeholder="Filtrer Email..." class="w-full border border-gray-300 rounded px-2 py-1 text-xs focus:ring-1 focus:ring-blue-500 focus:outline-none"> <input type="text" id="filterEmail" name="email" th:value="${emailFilter}" placeholder="Filtrer Email..." class="w-full border border-gray-300 rounded px-2 py-1 text-xs focus:ring-1 focus:ring-blue-500 focus:outline-none">
</td> </td>
<td class="py-2 px-3">
<input type="text" id="filterTelephone" name="telephone" th:value="${telephoneFilter}" placeholder="Filtrer Tél..." class="w-full border border-gray-300 rounded px-2 py-1 text-xs focus:ring-1 focus:ring-blue-500 focus:outline-none">
</td>
<td class="py-2 px-3"> <td class="py-2 px-3">
<select id="filterPaiement" name="paiement" class="w-full border border-gray-300 rounded px-2 py-1 text-xs focus:ring-1 focus:ring-blue-500 focus:outline-none"> <select id="filterPaiement" name="paiement" class="w-full border border-gray-300 rounded px-2 py-1 text-xs focus:ring-1 focus:ring-blue-500 focus:outline-none">
<option value="">Tous</option> <option value="">Tous</option>
@@ -102,7 +99,7 @@
</thead> </thead>
<tbody class="divide-y divide-gray-200 text-sm"> <tbody class="divide-y divide-gray-200 text-sm">
<tr th:if="${#lists.isEmpty(adherents)}"> <tr th:if="${#lists.isEmpty(adherents)}">
<td colspan="8" class="py-8 text-center text-gray-500">Aucun adhérent enregistré.</td> <td colspan="7" class="py-8 text-center text-gray-500">Aucun adhérent enregistré.</td>
</tr> </tr>
<tr th:each="adherent : ${adherents}" class="hover:bg-gray-50 transition-colors adherent-row"> <tr th:each="adherent : ${adherents}" class="hover:bg-gray-50 transition-colors adherent-row">
<td class="py-4 px-6 font-medium text-gray-900"> <td class="py-4 px-6 font-medium text-gray-900">
@@ -119,7 +116,6 @@
<td class="py-4 px-6 text-center text-gray-600 font-mono text-xs" <td class="py-4 px-6 text-center text-gray-600 font-mono text-xs"
th:text="${adherent.getLicenceActuelle() != null and adherent.getLicenceActuelle().numeroLicence != null and !adherent.getLicenceActuelle().numeroLicence.isEmpty() ? adherent.getLicenceActuelle().numeroLicence : '-'}">-</td> th:text="${adherent.getLicenceActuelle() != null and adherent.getLicenceActuelle().numeroLicence != null and !adherent.getLicenceActuelle().numeroLicence.isEmpty() ? adherent.getLicenceActuelle().numeroLicence : '-'}">-</td>
<td class="py-4 px-6 text-gray-600" th:text="${adherent.email}">jean@example.com</td> <td class="py-4 px-6 text-gray-600" th:text="${adherent.email}">jean@example.com</td>
<td class="py-4 px-6 text-gray-600" th:text="${adherent.telephone}">0600000000</td>
<td class="py-3 px-4"> <td class="py-3 px-4">
<!-- Aucune licence --> <!-- Aucune licence -->
<div th:if="${adherent.getLicenceActuelle() == null}" class="text-center text-gray-400 text-xs italic"> <div th:if="${adherent.getLicenceActuelle() == null}" class="text-center text-gray-400 text-xs italic">
@@ -158,7 +154,8 @@
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
<!-- Pagination Footer --> <!-- Pagination Footer -->
<div class="px-6 py-4 border-t border-gray-200 flex items-center justify-between bg-gray-50 text-sm text-gray-700"> <div class="px-6 py-4 border-t border-gray-200 flex items-center justify-between bg-gray-50 text-sm text-gray-700">
@@ -79,18 +79,18 @@
<h3 class="text-lg font-semibold text-gray-900">Derniers adhérents inscrits</h3> <h3 class="text-lg font-semibold text-gray-900">Derniers adhérents inscrits</h3>
<a href="/adherents" class="text-sm font-medium text-blue-600 hover:text-blue-800">Voir tout &rarr;</a> <a href="/adherents" class="text-sm font-medium text-blue-600 hover:text-blue-800">Voir tout &rarr;</a>
</div> </div>
<table class="w-full text-left border-collapse"> <div class="overflow-x-auto">
<table class="w-full text-left border-collapse min-w-[600px]">
<thead> <thead>
<tr class="bg-gray-50/50 text-gray-500 text-xs uppercase tracking-wider border-b border-gray-100"> <tr class="bg-gray-50/50 text-gray-500 text-xs uppercase tracking-wider border-b border-gray-100">
<th class="py-3 px-6 font-medium">Nom & Prénom</th> <th class="py-3 px-6 font-medium">Nom & Prénom</th>
<th class="py-3 px-6 font-medium">Date de naissance</th> <th class="py-3 px-6 font-medium">Date de naissance</th>
<th class="py-3 px-6 font-medium">Téléphone</th>
<th class="py-3 px-6 font-medium text-right">Action</th> <th class="py-3 px-6 font-medium text-right">Action</th>
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-100 text-sm"> <tbody class="divide-y divide-gray-100 text-sm">
<tr th:if="${#lists.isEmpty(derniersInscrits)}"> <tr th:if="${#lists.isEmpty(derniersInscrits)}">
<td colspan="4" class="py-4 px-6 text-center text-gray-500">Aucun adhérent récent.</td> <td colspan="3" class="py-4 px-6 text-center text-gray-500">Aucun adhérent récent.</td>
</tr> </tr>
<tr th:each="adh : ${derniersInscrits}" class="hover:bg-gray-50 transition-colors"> <tr th:each="adh : ${derniersInscrits}" class="hover:bg-gray-50 transition-colors">
<td class="py-4 px-6"> <td class="py-4 px-6">
@@ -98,13 +98,13 @@
<div class="text-xs text-gray-500" th:text="${adh.email}">jean@example.com</div> <div class="text-xs text-gray-500" th:text="${adh.email}">jean@example.com</div>
</td> </td>
<td class="py-4 px-6 text-gray-600" th:text="${#temporals.format(adh.dateNaissance, 'dd/MM/yyyy')}">01/01/2000</td> <td class="py-4 px-6 text-gray-600" th:text="${#temporals.format(adh.dateNaissance, 'dd/MM/yyyy')}">01/01/2000</td>
<td class="py-4 px-6 text-gray-600" th:text="${adh.telephone}">0600000000</td>
<td class="py-4 px-6 text-right"> <td class="py-4 px-6 text-right">
<a th:href="@{/adherents/{id}/edit(id=${adh.id})}" class="text-blue-600 hover:text-blue-800 font-medium">Voir profil</a> <a th:href="@{/adherents/{id}/edit(id=${adh.id})}" class="text-blue-600 hover:text-blue-800 font-medium">Voir profil</a>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div> </div>
@@ -34,8 +34,8 @@
<form id="filter-form" hx-get="/paiements" hx-target="#paiements-table-container" hx-select="#paiements-table-container" hx-trigger="change, keyup changed delay:300ms" hx-sync="this:replace" hx-on::config-request="if (event.detail.trigger.tagName !== 'BUTTON') { event.detail.parameters['page'] = 0; }" class="m-0"> <form id="filter-form" hx-get="/paiements" hx-target="#paiements-table-container" hx-select="#paiements-table-container" hx-trigger="change, keyup changed delay:300ms" hx-sync="this:replace" hx-on::config-request="if (event.detail.trigger.tagName !== 'BUTTON') { event.detail.parameters['page'] = 0; }" class="m-0">
<input type="hidden" name="query" th:value="${searchQuery}"> <input type="hidden" name="query" th:value="${searchQuery}">
<div class="overflow-x-auto">
<table class="w-full text-left border-collapse"> <table class="w-full text-left border-collapse min-w-[1000px]">
<thead> <thead>
<tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200"> <tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200">
<th class="py-3 px-6 font-medium text-left">Date</th> <th class="py-3 px-6 font-medium text-left">Date</th>
@@ -120,7 +120,8 @@
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
</form> </form>
<!-- Pagination Footer --> <!-- Pagination Footer -->
@@ -25,7 +25,8 @@
</div> </div>
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden"> <div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
<table class="w-full text-left border-collapse"> <div class="overflow-x-auto">
<table class="w-full text-left border-collapse min-w-[800px]">
<thead> <thead>
<tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200"> <tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200">
<th class="py-3 px-6 font-medium text-left">Nom de la catégorie</th> <th class="py-3 px-6 font-medium text-left">Nom de la catégorie</th>
@@ -54,7 +55,8 @@
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div> </div>
</main> </main>
@@ -21,7 +21,8 @@
<div class="flex-1 overflow-auto p-6"> <div class="flex-1 overflow-auto p-6">
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden"> <div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
<table class="w-full text-left border-collapse"> <div class="overflow-x-auto">
<table class="w-full text-left border-collapse min-w-[800px]">
<thead> <thead>
<tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200"> <tr class="bg-gray-50 text-gray-500 text-sm uppercase tracking-wider border-b border-gray-200">
<th class="py-3 px-6 font-medium">Date</th> <th class="py-3 px-6 font-medium">Date</th>
@@ -42,7 +43,6 @@
<div th:if="${pre.representantLegal != null}" class="text-[10px] text-blue-600 font-semibold mt-1" th:text="'Parent : ' + ${pre.representantLegal}"></div> <div th:if="${pre.representantLegal != null}" class="text-[10px] text-blue-600 font-semibold mt-1" th:text="'Parent : ' + ${pre.representantLegal}"></div>
</td> </td>
<td class="py-4 px-6"> <td class="py-4 px-6">
<div class="text-gray-900" th:text="${pre.telephone}"></div>
<div class="text-xs text-gray-500" th:text="${pre.email}"></div> <div class="text-xs text-gray-500" th:text="${pre.email}"></div>
</td> </td>
<td class="py-4 px-6 text-right space-x-2"> <td class="py-4 px-6 text-right space-x-2">
@@ -59,7 +59,8 @@
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div> </div>
</main> </main>
@@ -27,9 +27,26 @@
</div> </div>
</div> </div>
<div> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<label class="block text-sm font-medium text-gray-700 mb-1">Date de naissance <span class="text-red-500">*</span></label> <div>
<input type="date" id="dateNaissance" th:field="*{dateNaissance}" 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"> <label class="block text-sm font-medium text-gray-700 mb-1">Date de naissance <span class="text-red-500">*</span></label>
<input type="date" id="dateNaissance" th:field="*{dateNaissance}" 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>
<label class="block text-sm font-medium text-gray-700 mb-1">Ville de naissance <span class="text-red-500">*</span></label>
<input type="text" th:field="*{lieuNaissanceVille}" 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>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Pays de naissance <span class="text-red-500">*</span></label>
<input type="text" th:field="*{lieuNaissancePays}" 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>
<label class="block text-sm font-medium text-gray-700 mb-1">Nationalité <span class="text-red-500">*</span></label>
<input type="text" th:field="*{nationalite}" 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> </div>
<div id="representantBlock" class="hidden bg-blue-50 p-4 rounded-lg border border-blue-100"> <div id="representantBlock" class="hidden bg-blue-50 p-4 rounded-lg border border-blue-100">
@@ -38,21 +55,12 @@
<input type="text" id="representantLegal" th:field="*{representantLegal}" placeholder="Nom et Prénom du parent" 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="text" id="representantLegal" th:field="*{representantLegal}" placeholder="Nom et Prénom du parent" 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>
<div class="grid grid-cols-2 gap-4"> <div>
<div> <label class="block text-sm font-medium text-gray-700 mb-1">Email <span class="text-red-500">*</span></label>
<label class="block text-sm font-medium text-gray-700 mb-1">Téléphone</label> <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="tel" th:field="*{telephone}" 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>
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input type="email" th:field="*{email}" 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> </div>
<div> <!-- Removed Adresse -->
<label class="block text-sm font-medium text-gray-700 mb-1">Adresse postale</label>
<textarea th:field="*{adresse}" 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>
<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