Compare commits
5 Commits
870891a77c
...
ee730be570
| Author | SHA1 | Date | |
|---|---|---|---|
| ee730be570 | |||
| 4856326b29 | |||
| b94f4b43ce | |||
| 795d044c0b | |||
| dc5ab9c3c4 |
@ -355,19 +355,25 @@ public class AffiliationService {
|
||||
.map(c -> club));
|
||||
})
|
||||
.call(club -> reactiveMailer.send(
|
||||
Mail.withText(form.getM1_email(),
|
||||
"FFSAF - Acceptation de votre demande d'affiliation",
|
||||
String.format(
|
||||
"""
|
||||
Bonjour,
|
||||
Mail.withHtml(form.getM1_email(), "FFSAF - Creation de votre compte sur l'intranet",
|
||||
String.format(Utils.HTML_HEADER, "FFSAF - Creation de votre compte sur l'intranet") +
|
||||
String.format("""
|
||||
<p>Votre demande d'affiliation pour le club <span class="highlight">%s</span> a été acceptée.</p>
|
||||
<p>LLe numéro d'affiliation de votre club est le <span class="highlight">%d</span>.</p>
|
||||
""",
|
||||
club.getName(), club.getNo_affiliation()) +
|
||||
Utils.HTML_FOOTER
|
||||
)
|
||||
.setText(String.format("""
|
||||
Bonjour,
|
||||
|
||||
Votre demande d'affiliation pour le club %s a été acceptée.
|
||||
Le numéro d'affiliation de votre club est le %d.
|
||||
Votre demande d'affiliation pour le club %s a été acceptée.
|
||||
Le numéro d'affiliation de votre club est le %d.
|
||||
|
||||
Cordialement,
|
||||
L'équipe de la FFSAF
|
||||
""", club.getName(), club.getNo_affiliation())
|
||||
).setFrom("FFSAF <no-reply@ffsaf.fr>").setReplyTo("contact@ffsaf.fr")
|
||||
Cordialement,
|
||||
L'équipe de la FFSAF
|
||||
""", club.getName(), club.getNo_affiliation()))
|
||||
.setFrom("FFSAF <no-reply@ffsaf.fr>").setReplyTo("contact@ffsaf.fr")
|
||||
.addTo(form.getM2_email(), form.getM3_email())
|
||||
));
|
||||
}
|
||||
@ -458,21 +464,27 @@ public class AffiliationService {
|
||||
public Uni<?> deleteReqAffiliation(long id, String reason, boolean federationAdmin) {
|
||||
return repositoryRequest.findById(id)
|
||||
.call(aff -> federationAdmin ? reactiveMailer.send(
|
||||
Mail.withText(aff.getM1_email(),
|
||||
"FFSAF - Votre demande d'affiliation a été rejetée.",
|
||||
String.format(
|
||||
"""
|
||||
Bonjour,
|
||||
Mail.withHtml(aff.getM1_email(), "FFSAF - Votre demande d'affiliation a été rejetée.",
|
||||
String.format(Utils.HTML_HEADER, "FFSAF - Votre demande d'affiliation a été rejetée.") +
|
||||
String.format("""
|
||||
<p>Votre demande d'affiliation pour le club %s a été rejetée pour la/les raison(s) suivante(s):<br/>%s</p>
|
||||
<p>Si vous rencontrez un problème ou si vous avez des questions, n'hésitez pas à nous contacter à l'adresse <a href="mailto:contact@ffsaf.fr">contact@ffsaf.fr</a>.</p>
|
||||
""",
|
||||
aff.getName(), reason) +
|
||||
Utils.HTML_FOOTER
|
||||
)
|
||||
.setText(String.format("""
|
||||
Bonjour,
|
||||
|
||||
Votre demande d'affiliation pour le club %s a été rejetée pour la/les raison(s) suivante(s):
|
||||
%s
|
||||
Votre demande d'affiliation pour le club %s a été rejetée pour la/les raison(s) suivante(s):
|
||||
%s
|
||||
|
||||
Si vous rencontrez un problème ou si vous avez des questions, n'hésitez pas à nous contacter à l'adresse contact@ffsaf.fr.
|
||||
Si vous rencontrez un problème ou si vous avez des questions, n'hésitez pas à nous contacter à l'adresse contact@ffsaf.fr.
|
||||
|
||||
Cordialement,
|
||||
L'équipe de la FFSAF
|
||||
""", aff.getName(), reason)
|
||||
).setFrom("FFSAF <no-reply@ffsaf.fr>").setReplyTo("contact@ffsaf.fr")
|
||||
Cordialement,
|
||||
L'équipe de la FFSAF
|
||||
""", aff.getName(), reason))
|
||||
.setFrom("FFSAF <no-reply@ffsaf.fr>").setReplyTo("contact@ffsaf.fr")
|
||||
.addTo(aff.getM2_email(), aff.getM3_email())
|
||||
) : Uni.createFrom().nullItem())
|
||||
.chain(aff -> Panache.withTransaction(() -> repositoryRequest.delete(aff)))
|
||||
|
||||
@ -156,24 +156,32 @@ public class KeycloakService {
|
||||
return oldEmail;
|
||||
}).call(oldEmail -> oldEmail == null || !enabled_email ? Uni.createFrom().item("") :
|
||||
reactiveMailer.send(
|
||||
Mail.withText(oldEmail,
|
||||
"FFSAF - Changement de votre adresse email",
|
||||
String.format(
|
||||
"""
|
||||
Bonjour,
|
||||
Mail.withHtml(oldEmail, "FFSAF - Changement de votre adresse email",
|
||||
String.format(Utils.HTML_HEADER, "FFSAF - Changement de votre adresse email") +
|
||||
String.format("""
|
||||
<p>Suite à la modification de votre adresse email fournie lors de votre (ré)inscription à la FFSAF,<br/>
|
||||
vous allez recevoir dans les prochaines minutes un email de vérification de votre nouvelle adresse sur celle-ci.</p>
|
||||
<p>Ancienne adresse email : <span class="highlight">%s</span><br/>Nouvelle adresse email : <span class="highlight">%s</span></p>
|
||||
<p>Si vous n'avez pas demandé cette modification, veuillez contacter le support à l'adresse <a href="mailto:support@ffsaf.fr">support@ffsaf.fr</a>.</p>
|
||||
""",
|
||||
oldEmail, email) +
|
||||
Utils.HTML_FOOTER
|
||||
)
|
||||
.setText(String.format("""
|
||||
Bonjour,
|
||||
|
||||
Suite à la modification de votre adresse email fournie lors de votre (ré)inscription à la FFSAF,
|
||||
vous allez recevoir dans les prochaines minutes un email de vérification de votre nouvelle adresse sur celle-ci.
|
||||
Suite à la modification de votre adresse email fournie lors de votre (ré)inscription à la FFSAF,
|
||||
vous allez recevoir dans les prochaines minutes un email de vérification de votre nouvelle adresse sur celle-ci.
|
||||
|
||||
Ancienne adresse email : %s
|
||||
Nouvelle adresse email : %s
|
||||
Ancienne adresse email : %s
|
||||
Nouvelle adresse email : %s
|
||||
|
||||
Si vous n'avez pas demandé cette modification, veuillez contacter le support à l'adresse support@ffsaf.fr.
|
||||
Si vous n'avez pas demandé cette modification, veuillez contacter le support à l'adresse support@ffsaf.fr.
|
||||
|
||||
Cordialement,
|
||||
L'équipe de la FFSAF
|
||||
""", oldEmail, email)
|
||||
).setFrom("FFSAF <no-reply@ffsaf.fr>").setReplyTo("support@ffsaf.fr")
|
||||
Cordialement,
|
||||
L'équipe de la FFSAF
|
||||
""", oldEmail, email))
|
||||
.setFrom("FFSAF <no-reply@ffsaf.fr>").setReplyTo("support@ffsaf.fr")
|
||||
).onFailure().invoke(e -> LOGGER.error("Fail to send email", e)));
|
||||
}
|
||||
|
||||
@ -270,93 +278,27 @@ public class KeycloakService {
|
||||
.invoke(user -> membreModel.setUserId(user.getId()))
|
||||
.call(user -> updateRole(user.getId(), List.of("safca_user"), List.of()))
|
||||
.call(user -> enabled_email ? reactiveMailer.send(
|
||||
Mail.withHtml(user.getEmail(), "FFSAF - Creation de votre compte sur l'intranet", String.format(
|
||||
"""
|
||||
<!DOCTYPE html>
|
||||
<html data-lt-installed="true">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Création de votre compte intranet FFSAF</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: #003366;
|
||||
color: white;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 0 0 5px 5px;
|
||||
border: 1px solid #ddd;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
background-color: #003366;
|
||||
color: white !important;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 20px;
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
font-weight: bold;
|
||||
color: #003366;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body data-gramm="false" data-lt-tmp-id="lt-957854">
|
||||
<div class="header">
|
||||
<div><img src="https://intra.ffsaf.fr/Logo-FFSAF-2023.png" alt="ffsaf" height="128">
|
||||
<h1>Fédération France Soft Armored Fighting</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>Bonjour,</p>
|
||||
<p>Suite à votre première inscription <span class="highlight">%s</span> à la <strong>Fédération France Soft Armored Fighting (FFSAF)</strong>, votre compte intranet a été créé.</p>
|
||||
<p>Ce compte vous permettra de :</p>
|
||||
<ul>
|
||||
<li>Consulter vos informations personnelles,</li>
|
||||
<li>Vous inscrire aux compétitions (bientôt disponible),</li>
|
||||
<li>Consulter les résultats des compétitions.</li>
|
||||
</ul>
|
||||
<p>L’intranet est accessible à l’adresse suivante :</p>
|
||||
<p style="text-align: center;"><a href="https://intra.ffsaf.fr" class="button">Accéder à l'intranet</a></p>
|
||||
<p>Votre nom d’utilisateur est : <span class="highlight">%s</span></p>
|
||||
<p>Pour définir votre mot de passe, rendez-vous sur l’intranet : <strong>Connexion > Mot de passe oublié ?</strong></p>
|
||||
<p>Si vous n’avez pas demandé cette inscription, veuillez contacter le support à l’adresse : <a href="mailto:support@ffsaf.fr">support@ffsaf.fr</a>.</p>
|
||||
<p class="footer">(Pas de panique, nous ne vous enverrons pas de message autre que ceux concernant votre compte.)</p>
|
||||
<p>Cordialement,<br>L’équipe de la FFSAF</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
""",
|
||||
membreModel.getRole() == RoleAsso.MEMBRE ? "par votre club (" + membreModel.getClub()
|
||||
.getName() + ") " : "", user.getUsername())
|
||||
Mail.withHtml(user.getEmail(), "FFSAF - Creation de votre compte sur l'intranet",
|
||||
String.format(Utils.HTML_HEADER, "Création de votre compte intranet FFSAF") +
|
||||
String.format(
|
||||
"""
|
||||
<p>Suite à votre première inscription <span class="highlight">%s</span> à la <strong>Fédération France Soft Armored Fighting (FFSAF)</strong>, votre compte intranet a été créé.</p>
|
||||
<p>Ce compte vous permettra de :</p>
|
||||
<ul>
|
||||
<li>Consulter vos informations personnelles,</li>
|
||||
<li>Vous inscrire aux compétitions (bientôt disponible),</li>
|
||||
<li>Consulter les résultats des compétitions.</li>
|
||||
</ul>
|
||||
<p>L’intranet est accessible à l’adresse suivante :</p>
|
||||
<p style="text-align: center;"><a href="https://intra.ffsaf.fr" class="button">Accéder à l'intranet</a></p>
|
||||
<p>Votre nom d’utilisateur est : <span class="highlight">%s</span></p>
|
||||
<p>Pour définir votre mot de passe, rendez-vous sur l’intranet : <strong>Connexion > Mot de passe oublié ?</strong></p>
|
||||
<p>Si vous n’avez pas demandé cette inscription, veuillez contacter le support à l’adresse : <a href="mailto:support@ffsaf.fr">support@ffsaf.fr</a>.</p>
|
||||
<p class="footer">(Pas de panique, nous ne vous enverrons pas de message autre que ceux concernant votre compte.)</p>
|
||||
""",
|
||||
membreModel.getRole() == RoleAsso.MEMBRE ? "par votre club (" + membreModel.getClub()
|
||||
.getName() + ") " : "", user.getUsername()) +
|
||||
Utils.HTML_FOOTER
|
||||
)
|
||||
.setText(String.format(
|
||||
"""
|
||||
|
||||
@ -125,8 +125,21 @@ public class MembreService {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public Uni<PageResult<SimpleMembre>> searchAdmin(int limit, int page, String search, String club,
|
||||
int licenceRequest, int payState, String order, String categorie) {
|
||||
public Uni<PageResult<SimpleMembre>> search(int limit, int page, String search, int licenceRequest, int payState,
|
||||
String order, String categorie, Boolean archive, String subject) {
|
||||
return repository.find("userId = ?1", subject).firstResult()
|
||||
.invoke(Unchecked.consumer(membreModel -> {
|
||||
if (membreModel == null || membreModel.getClub() == null)
|
||||
throw new DForbiddenException();
|
||||
}))
|
||||
.chain(membreModel ->
|
||||
searchAdmin(limit, page, search, membreModel.getClub(), licenceRequest, payState, order,
|
||||
categorie, archive));
|
||||
}
|
||||
|
||||
public Uni<PageResult<SimpleMembre>> searchAdmin(int limit, int page, String search, Object club,
|
||||
int licenceRequest, int payState, String order, String categorie,
|
||||
Boolean archive) {
|
||||
if (search == null)
|
||||
search = "";
|
||||
search = "%" + search.replaceAll(" ", "% %") + "%";
|
||||
@ -137,77 +150,47 @@ public class MembreService {
|
||||
else
|
||||
categorieFilter = "categorie = " + Categorie.valueOf(categorie).ordinal();
|
||||
|
||||
String finalSearch = search;
|
||||
Uni<List<LicenceModel>> baseUni = getLicenceListe(licenceRequest, payState);
|
||||
String archiveFilter;
|
||||
if (archive == null || archive)
|
||||
archiveFilter = "True";
|
||||
else
|
||||
archiveFilter = String.format(
|
||||
"EXISTS (SELECT 1 FROM LicenceModel l WHERE l.membre.id = m.id AND l.saison >= %s)",
|
||||
Utils.getSaison() - 1);
|
||||
|
||||
String clubFilter = "?3 = ?3";
|
||||
if (club != null) {
|
||||
if (club instanceof String club_) {
|
||||
if (!club_.isBlank()) {
|
||||
if (club_.equals("null"))
|
||||
clubFilter = "club IS NULL AND ?3 = ?3";
|
||||
else
|
||||
clubFilter = "LOWER(club.name) LIKE LOWER(?3)";
|
||||
}
|
||||
} else if (club instanceof ClubModel)
|
||||
clubFilter = "club = ?3";
|
||||
}
|
||||
|
||||
String queryStr = String.format(
|
||||
"SELECT m FROM MembreModel m WHERE id %s ?2 AND %s AND (%s) AND %s AND %s",
|
||||
(licenceRequest == 0 || licenceRequest == 4) ? "NOT IN" : "IN", clubFilter, FIND_NAME_REQUEST,
|
||||
categorieFilter,
|
||||
archiveFilter);
|
||||
|
||||
Sort sort = getSort(order);
|
||||
if (sort == null)
|
||||
return Uni.createFrom().failure(new DInternalError("Erreur lors calcul du trie"));
|
||||
|
||||
return baseUni
|
||||
String finalSearch = search;
|
||||
return getLicenceListe(licenceRequest, payState)
|
||||
.map(l -> l.stream().map(l2 -> l2.getMembre().getId()).toList())
|
||||
.chain(ids -> {
|
||||
PanacheQuery<MembreModel> query;
|
||||
|
||||
String idf = ((licenceRequest == 0 || licenceRequest == 4) ? "NOT IN" : "IN");
|
||||
|
||||
if (club == null || club.isBlank()) {
|
||||
query = repository.find(
|
||||
"id " + idf + " ?2 AND (" + FIND_NAME_REQUEST + ") AND " + categorieFilter,
|
||||
sort, finalSearch, ids)
|
||||
.page(Page.ofSize(limit));
|
||||
} else {
|
||||
if (club.equals("null")) {
|
||||
query = repository.find(
|
||||
"id " + idf + " ?2 AND club IS NULL AND (" + FIND_NAME_REQUEST + ") AND " + categorieFilter,
|
||||
sort, finalSearch, ids).page(Page.ofSize(limit));
|
||||
} else {
|
||||
query = repository.find(
|
||||
"id " + idf + " ?3 AND LOWER(club.name) LIKE LOWER(?2) AND (" + FIND_NAME_REQUEST + ") AND " + categorieFilter,
|
||||
sort, finalSearch, club, ids)
|
||||
.page(Page.ofSize(limit));
|
||||
}
|
||||
}
|
||||
query = repository.find(queryStr, sort, finalSearch, ids, club).page(Page.ofSize(limit));
|
||||
return getPageResult(query, limit, page);
|
||||
});
|
||||
}
|
||||
|
||||
public Uni<PageResult<SimpleMembre>> search(int limit, int page, String search, int licenceRequest, int payState,
|
||||
String order, String categorie, String subject) {
|
||||
if (search == null)
|
||||
search = "";
|
||||
search = "%" + search.replaceAll(" ", "% %") + "%";
|
||||
|
||||
String finalSearch = search;
|
||||
|
||||
Uni<List<LicenceModel>> baseUni = getLicenceListe(licenceRequest, payState);
|
||||
|
||||
String categorieFilter;
|
||||
if (categorie == null || categorie.isBlank())
|
||||
categorieFilter = " True";
|
||||
else
|
||||
categorieFilter = "categorie = " + Categorie.valueOf(categorie).ordinal();
|
||||
|
||||
Sort sort = getSort(order);
|
||||
if (sort == null)
|
||||
return Uni.createFrom().failure(new DInternalError("Erreur lors calcul du trie"));
|
||||
|
||||
return baseUni
|
||||
.map(l -> l.stream().map(l2 -> l2.getMembre().getId()).toList())
|
||||
.chain(ids -> {
|
||||
String idf = ((licenceRequest == 0 || licenceRequest == 4) ? "NOT IN" : "IN");
|
||||
|
||||
return repository.find("userId = ?1", subject).firstResult()
|
||||
.chain(membreModel -> {
|
||||
PanacheQuery<MembreModel> query = repository.find(
|
||||
"id " + idf + " ?3 AND club = ?2 AND (" + FIND_NAME_REQUEST + ") AND " + categorieFilter,
|
||||
sort, finalSearch, membreModel.getClub(), ids)
|
||||
.page(Page.ofSize(limit));
|
||||
return getPageResult(query, limit, page);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private Uni<PageResult<SimpleMembre>> getPageResult(PanacheQuery<MembreModel> query, int limit, int page) {
|
||||
return Uni.createFrom().item(new PageResult<SimpleMembre>())
|
||||
.invoke(result -> result.setPage(page))
|
||||
|
||||
@ -59,6 +59,7 @@ public class MembreAdminEndpoints {
|
||||
@Parameter(description = "Text à rechercher") @QueryParam("search") String search,
|
||||
@Parameter(description = "Club à filter") @QueryParam("club") String club,
|
||||
@Parameter(description = "Catégorie à filter") @QueryParam("categorie") String categorie,
|
||||
@Parameter(description = "Inclure les archive") @QueryParam("archive") Boolean archive,
|
||||
@Parameter(description = "État de la demande de licence: 0 -> sans demande, 1 -> avec demande ou validée, 2 -> toute les demande non validée, 3 -> validée, 4 -> tout, 5 -> demande complete, 6 -> demande incomplete") @QueryParam("licenceRequest") int licenceRequest,
|
||||
@Parameter(description = "État du payment: 0 -> non payer, 1 -> payer, 2 -> tout") @QueryParam("payment") int payment,
|
||||
@Parameter(description = "Ordre") @QueryParam("order") String order) {
|
||||
@ -66,7 +67,8 @@ public class MembreAdminEndpoints {
|
||||
limit = 50;
|
||||
if (page == null || page < 1)
|
||||
page = 1;
|
||||
return membreService.searchAdmin(limit, page - 1, search, club, licenceRequest, payment, order, categorie);
|
||||
return membreService.searchAdmin(limit, page - 1, search, club, licenceRequest, payment, order,
|
||||
categorie, archive);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
||||
@ -51,6 +51,7 @@ public class MembreClubEndpoints {
|
||||
@Parameter(description = "Page à consulter") @QueryParam("page") Integer page,
|
||||
@Parameter(description = "Text à rechercher") @QueryParam("search") String search,
|
||||
@Parameter(description = "Catégorie à filter") @QueryParam("categorie") String categorie,
|
||||
@Parameter(description = "Inclure les archive") @QueryParam("archive") Boolean archive,
|
||||
@Parameter(description = "Etat de la demande de licence: 0 -> sans demande, 1 -> avec demande ou validée, 2 -> toute les demande non validée, 3 -> validée, 4 -> tout, 5 -> demande complete, 6 -> demande incomplete") @QueryParam("licenceRequest") int licenceRequest,
|
||||
@Parameter(description = "Etat du payment: 0 -> non payer, 1 -> payer, 2 -> tout") @QueryParam("payment") int payment,
|
||||
@Parameter(description = "Ordre") @QueryParam("order") String order) {
|
||||
@ -58,7 +59,7 @@ public class MembreClubEndpoints {
|
||||
limit = 50;
|
||||
if (page == null || page < 1)
|
||||
page = 1;
|
||||
return membreService.search(limit, page - 1, search, licenceRequest, payment, order, categorie, securityCtx.getSubject());
|
||||
return membreService.search(limit, page - 1, search, licenceRequest, payment, order, categorie, archive, securityCtx.getSubject());
|
||||
}
|
||||
|
||||
@GET
|
||||
|
||||
@ -21,6 +21,79 @@ import java.util.concurrent.Future;
|
||||
public class Utils {
|
||||
private static final Logger LOGGER = Logger.getLogger(Utils.class);
|
||||
|
||||
public static String HTML_HEADER = """
|
||||
<!DOCTYPE html>
|
||||
<html data-lt-installed="true">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>%s</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: #003366;
|
||||
color: white;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 0 0 5px 5px;
|
||||
border: 1px solid #ddd;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
background-color: #003366;
|
||||
color: white !important;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 20px;
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
font-weight: bold;
|
||||
color: #003366;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body data-gramm="false" data-lt-tmp-id="lt-957854">
|
||||
<div class="header">
|
||||
<div><img src="https://intra.ffsaf.fr/Logo-FFSAF-2023.png" alt="ffsaf" height="128">
|
||||
<h1>Fédération France Soft Armored Fighting</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>Bonjour,</p>
|
||||
""";
|
||||
public static String HTML_FOOTER = """
|
||||
<p>Cordialement,<br>L’équipe de la FFSAF</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
""";
|
||||
|
||||
public static int getSaison() {
|
||||
return getSaison(new Date());
|
||||
}
|
||||
|
||||
@ -292,9 +292,10 @@ public class RMatch {
|
||||
if (!o.getCompet().getUuid().equals(connection.pathParam("uuid")))
|
||||
throw new DForbiddenException("Permission denied");
|
||||
}))
|
||||
.call(cm -> matchRepository.delete("id IN ?1 AND category = ?2", data.matchesToRemove, cm)
|
||||
.call(cm -> Panache.withTransaction(
|
||||
() -> matchRepository.delete("id IN ?1 AND category = ?2", data.matchesToRemove, cm))
|
||||
.call(__ -> SSMatch.sendDeleteMatch(connection, data.matchesToRemove)))
|
||||
.call(cm -> matchRepository.list("id IN ?1 AND category = ?2",
|
||||
.call(cm -> Panache.withSession(() -> matchRepository.list("id IN ?1 AND category = ?2",
|
||||
Stream.concat(data.matchOrderToUpdate.keySet().stream(),
|
||||
data.matchPouleToUpdate.keySet().stream())
|
||||
.distinct().toList(), cm)
|
||||
@ -305,13 +306,14 @@ public class RMatch {
|
||||
model.setCategory_ord(data.matchOrderToUpdate.get(model.getId()));
|
||||
}))
|
||||
.call(mm -> Panache.withTransaction(() -> matchRepository.persist(mm)))
|
||||
.invoke(mm -> matches.addAll(mm.stream().map(MatchEntity::fromModel).toList()))
|
||||
.invoke(mm -> matches.addAll(mm.stream().map(MatchEntity::fromModel).toList())))
|
||||
)
|
||||
.chain(categoryModel -> {
|
||||
Uni<List<MatchModel>> uni = Uni.createFrom().item(new ArrayList<>());
|
||||
for (AddMatch match : data.newMatch)
|
||||
uni = uni.call(l -> creatMatch(categoryModel, match).invoke(l::add));
|
||||
return uni;
|
||||
Uni<List<MatchModel>> finalUni = uni;
|
||||
return Panache.withSession(() -> finalUni);
|
||||
}
|
||||
)
|
||||
.chain(mm -> Panache.withTransaction(() -> matchRepository.create(mm))
|
||||
|
||||
@ -119,13 +119,13 @@ export function CheckField({name, text, value, row = false}) {
|
||||
</>
|
||||
}
|
||||
|
||||
export const Checkbox = ({label, value, onChange}) => {
|
||||
export const Checkbox = ({label, value, onChange, name = "checkbox1"}) => {
|
||||
const handleChange = () => {
|
||||
onChange(!value);
|
||||
};
|
||||
|
||||
return <div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" id="checkbox1" checked={value} onChange={handleChange}/>
|
||||
<label className="form-check-label" htmlFor="checkbox1">{label}</label>
|
||||
<input className="form-check-input" type="checkbox" id={name} checked={value} onChange={handleChange}/>
|
||||
<label className="form-check-label" htmlFor={name}>{label}</label>
|
||||
</div>
|
||||
};
|
||||
|
||||
@ -299,7 +299,7 @@ function AssoInfo({initData, needFile}) {
|
||||
|
||||
<div className="mb-3">
|
||||
<div className="input-group">
|
||||
<label className="input-group-text" htmlFor="status">Statue{needFile && "*"}</label>
|
||||
<label className="input-group-text" htmlFor="status">Statuts{needFile && "*"}</label>
|
||||
<input type="file" className="form-control" id="status" name="status" accept=".pdf,.txt" required={needFile}/>
|
||||
</div>
|
||||
{!needFile && <div className="form-text" id="status">Laissez vide pour ne rien changer. (Si un statu a déjà été envoyé lors de cette
|
||||
@ -313,7 +313,7 @@ function MembreInfo({role, initData}) {
|
||||
|
||||
return <>
|
||||
<div className="input-group mb-3">
|
||||
<label className="input-group-text" htmlFor="inputGroupSelect01">Rôles</label>
|
||||
<label className="input-group-text" htmlFor="inputGroupSelect01">Rôle</label>
|
||||
<select className="form-select" id="inputGroupSelect01" defaultValue={initData.role ? initData.role : (role === "m1" ? "PRESIDENT" : 0)}
|
||||
disabled={initData.role ? initData.role === "PRESIDENT" : role === "m1"} name={role + "_role"} required>
|
||||
<option value="0">Sélectionner...</option>
|
||||
|
||||
@ -35,6 +35,7 @@ export function MemberList({source}) {
|
||||
payment: 2,
|
||||
order: "",
|
||||
categorie: "",
|
||||
archived: false,
|
||||
...JSON.parse(decodeURI(hash.substring(1)) || "{}"),
|
||||
}
|
||||
|
||||
@ -43,10 +44,10 @@ export function MemberList({source}) {
|
||||
data,
|
||||
error,
|
||||
refresh
|
||||
} = useFetch(`/member/find/${source}?page=${filter.page}&search=${filter.search}&club=${filter.club}&licenceRequest=${filter.licenceRequest}&payment=${filter.payment}&order=${filter.order}&categorie=${filter.categorie}`, setLoading, 1)
|
||||
} = useFetch(`/member/find/${source}?page=${filter.page}&search=${filter.search}&club=${filter.club}&licenceRequest=${filter.licenceRequest}&payment=${filter.payment}&order=${filter.order}&categorie=${filter.categorie}&archive=${filter.archived}`, setLoading, 1)
|
||||
|
||||
useEffect(() => {
|
||||
const tmp = `/member/find/${source}?page=${filter.page}&search=${filter.search}&club=${filter.club}&licenceRequest=${filter.licenceRequest}&payment=${filter.payment}&order=${filter.order}&categorie=${filter.categorie}`;
|
||||
const tmp = `/member/find/${source}?page=${filter.page}&search=${filter.search}&club=${filter.club}&licenceRequest=${filter.licenceRequest}&payment=${filter.payment}&order=${filter.order}&categorie=${filter.categorie}&archive=${filter.archived}`;
|
||||
if (tmp === lastRefresh)
|
||||
return;
|
||||
lastRefresh = tmp
|
||||
@ -137,6 +138,8 @@ export function MemberList({source}) {
|
||||
<div className="card-body">
|
||||
<FiltreBar showLicenceState={showLicenceState}
|
||||
setShowLicenceState={setShowLicenceState}
|
||||
showArchived={filter.archived}
|
||||
setShowArchived={e => setFilter({...filter, archived: e})}
|
||||
clubFilter={filter.club}
|
||||
setClubFilter={e => setFilter({...filter, club: e})}
|
||||
source={source}
|
||||
@ -523,6 +526,8 @@ function OrderBar({onOrderChange, defaultValues = "", source}) {
|
||||
function FiltreBar({
|
||||
showLicenceState,
|
||||
setShowLicenceState,
|
||||
showArchived,
|
||||
setShowArchived,
|
||||
clubFilter,
|
||||
setClubFilter,
|
||||
source,
|
||||
@ -538,6 +543,9 @@ function FiltreBar({
|
||||
<div className="mb-3">
|
||||
<Checkbox value={showLicenceState} onChange={setShowLicenceState} label="Afficher l'état des licences"/>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<Checkbox value={showArchived} onChange={setShowArchived} name="checkbox2" label="Afficher les combattants inactifs"/>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<select className="form-select" value={catFilter} onChange={event => setCatFilter(event.target.value)}>
|
||||
<option value="">--- toute les catégories ---</option>
|
||||
|
||||
@ -155,8 +155,8 @@ function ModalContent2({clubData, data}) {
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<p>Veuillez sélectionner 3 membres du bureau pour remplir la pré-demande. (Si un membre non-bureau va le devenir l'an prochain,
|
||||
vous pourrez toujours remplacer un des membres sélectionné à la prochaine étape)</p>
|
||||
<p>Veuillez sélectionner 0 à 3 membres du bureau pour remplir la pré-demande. (Si un membre non-bureau va le devenir l'an prochain,
|
||||
vous pourrez les renseigner à la prochaine étape)</p>
|
||||
{data && data.map((d, index) => {
|
||||
return <div key={index} className="input-group mb-1">
|
||||
<div className="input-group-text">
|
||||
|
||||
@ -147,15 +147,13 @@ function SearchMember({sendRegister}) {
|
||||
|
||||
const handleAdd = (name) => {
|
||||
const member = data.find(m => `${m.fname} ${m.lname}`.trim() === name);
|
||||
console.log("Quick add licence:", member)
|
||||
|
||||
if (!member) {
|
||||
toast.error("Combattant non trouvé");
|
||||
return;
|
||||
}
|
||||
|
||||
sendRegister({
|
||||
licence: member.licence, fname: member.fname, lname: member.lname, weight: "", overCategory: 0, lockEdit: false, id: null
|
||||
licence: member.licence.trim(), fname: member.fname.trim(), lname: member.lname.trim(), weight: "", overCategory: 0, lockEdit: false, id: null
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -116,7 +116,7 @@ export function CategoryContent({cat, catId, setCat}) {
|
||||
|
||||
const activeMatches = matches2.filter(m => m.poule !== '-')
|
||||
|
||||
const combsIDs = activeMatches.flatMap(d => [d.c1, d.c2]).filter((v, i, a) => v != null && a.indexOf(v) === i)
|
||||
const combsIDs = matches2.flatMap(d => [d.c1, d.c2]).filter((v, i, a) => v != null && a.indexOf(v) === i)
|
||||
.map(d => {
|
||||
let poule = activeMatches.find(m => (m.c1 === d || m.c2 === d) && m.categorie_ord !== -42)?.poule
|
||||
if (!poule)
|
||||
|
||||
@ -111,11 +111,11 @@ function Home2({perm}) {
|
||||
<h4 className="col-auto" style={{margin: "auto 0"}}>Sélectionne les modes d'affichage</h4>
|
||||
<div className="col">
|
||||
{perm === "ADMIN" && <>
|
||||
<button className="btn btn-primary" onClick={() => nav("table")}>Table de marque</button>
|
||||
<button className="btn btn-primary" onClick={() => nav("table")}>Secrétariats de lice</button>
|
||||
<button className="btn btn-primary ms-3" onClick={() => nav("admin")}>Administration</button>
|
||||
</>}
|
||||
{perm === "TABLE" && <>
|
||||
<button className="btn btn-primary" onClick={() => nav("table")}>Table de marque</button>
|
||||
<button className="btn btn-primary" onClick={() => nav("table")}>Secrétariats de lice</button>
|
||||
</>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user