diff --git a/src/main/java/fr/titionfire/ffsaf/domain/service/MembreService.java b/src/main/java/fr/titionfire/ffsaf/domain/service/MembreService.java index 66ffda8..fa9870b 100644 --- a/src/main/java/fr/titionfire/ffsaf/domain/service/MembreService.java +++ b/src/main/java/fr/titionfire/ffsaf/domain/service/MembreService.java @@ -15,6 +15,7 @@ import fr.titionfire.ffsaf.rest.exception.DBadRequestException; import fr.titionfire.ffsaf.rest.exception.DForbiddenException; import fr.titionfire.ffsaf.rest.exception.DInternalError; import fr.titionfire.ffsaf.rest.from.FullMemberForm; +import fr.titionfire.ffsaf.rest.from.UserSettingForm; import fr.titionfire.ffsaf.utils.*; import io.quarkus.hibernate.reactive.panache.Panache; import io.quarkus.hibernate.reactive.panache.PanacheQuery; @@ -467,7 +468,8 @@ public class MembreService { .call(membreModel -> licenceRepository.update("club_id = ?1 where membre = ?2 AND saison = ?3", (membreModel.getClub() == null) ? null : membreModel.getClub().getId(), membreModel, Utils.getSaison())) - .call(membreModel -> (membre.getPhoto_data() != null && membre.getPhoto_data().size() > 0) ? ls.logAUpdate("Photo", + .call(membreModel -> (membre.getPhoto_data() != null && membre.getPhoto_data() + .size() > 0) ? ls.logAUpdate("Photo", membreModel) : Uni.createFrom().nullItem()) .map(__ -> "OK"); } @@ -593,6 +595,20 @@ public class MembreService { .map(__ -> meData); } + public Uni updateSettings(String subject, UserSettingForm settingForm) { + return repository.find("userId = ?1", subject).firstResult() + .invoke(Unchecked.consumer(membreModel -> { + if (settingForm.getResultPrivacy() != null) { + ls.logChange("Confidentialité des résultats", membreModel.getResultPrivacy(), + settingForm.getResultPrivacy(), membreModel); + membreModel.setResultPrivacy(settingForm.getResultPrivacy()); + } + })) + .call(membreModel -> Panache.withTransaction(() -> repository.persist(membreModel))) + .call(membreModel -> ls.append()) + .replaceWithVoid(); + } + @Scheduled(cron = "0 0 1 1 9 ?") Uni everySeason() { return repository.list("birth_date IS NOT NULL") @@ -602,5 +618,4 @@ public class MembreService { }).toList()).andCollectFailures()) .map(__ -> null); } - } diff --git a/src/main/java/fr/titionfire/ffsaf/rest/MembreEndpoints.java b/src/main/java/fr/titionfire/ffsaf/rest/MembreEndpoints.java index c60cb9b..8cac523 100644 --- a/src/main/java/fr/titionfire/ffsaf/rest/MembreEndpoints.java +++ b/src/main/java/fr/titionfire/ffsaf/rest/MembreEndpoints.java @@ -6,6 +6,7 @@ import fr.titionfire.ffsaf.domain.service.PDFService; import fr.titionfire.ffsaf.rest.data.MeData; import fr.titionfire.ffsaf.rest.data.SimpleMembre; import fr.titionfire.ffsaf.rest.exception.DForbiddenException; +import fr.titionfire.ffsaf.rest.from.UserSettingForm; import fr.titionfire.ffsaf.utils.SecurityCtx; import fr.titionfire.ffsaf.utils.Utils; import io.quarkus.security.Authenticated; @@ -113,6 +114,21 @@ public class MembreEndpoints { return pdfService.getLicencePdf(securityCtx.getSubject()); } + @PUT + @Path("me/setting") + @Authenticated + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.TEXT_PLAIN) + @Operation(summary = "Met à jour les paramètres du membre connecté", description = "Met à jour les paramètres du membre connecté") + @APIResponses(value = { + @APIResponse(responseCode = "200", description = "Les paramètres ont été mis à jour"), + @APIResponse(responseCode = "403", description = "Accès refusé"), + @APIResponse(responseCode = "500", description = "Erreur interne du serveur") + }) + public Uni updateMeSettings(UserSettingForm settingForm) { + return membreService.updateSettings(securityCtx.getSubject(), settingForm); + } + @GET @Path("me/photo") @Authenticated diff --git a/src/main/java/fr/titionfire/ffsaf/rest/data/MeData.java b/src/main/java/fr/titionfire/ffsaf/rest/data/MeData.java index 3cf071f..ece32cc 100644 --- a/src/main/java/fr/titionfire/ffsaf/rest/data/MeData.java +++ b/src/main/java/fr/titionfire/ffsaf/rest/data/MeData.java @@ -1,6 +1,7 @@ package fr.titionfire.ffsaf.rest.data; import fr.titionfire.ffsaf.data.model.MembreModel; +import fr.titionfire.ffsaf.utils.ResultPrivacy; import io.quarkus.runtime.annotations.RegisterForReflection; import lombok.Data; import lombok.NoArgsConstructor; @@ -15,30 +16,32 @@ import java.util.List; @NoArgsConstructor @RegisterForReflection public class MeData { - @Schema(description = "L'identifiant du membre.", example = "1") + @Schema(description = "L'identifiant du membre.", examples = "1") private long id; - @Schema(description = "Le nom du membre.", example = "Dupont") + @Schema(description = "Le nom du membre.", examples = "Dupont") private String lname = ""; - @Schema(description = "Le prénom du membre.", example = "Jean") + @Schema(description = "Le prénom du membre.", examples = "Jean") private String fname = ""; - @Schema(description = "La catégorie du membre.", example = "SENIOR") + @Schema(description = "La catégorie du membre.", examples = "SENIOR") private String categorie; - @Schema(description = "Le nom du club du membre.", example = "Association sportive") + @Schema(description = "Le nom du club du membre.", examples = "Association sportive") private String club; - @Schema(description = "Le genre du membre.", example = "Homme") + @Schema(description = "Le genre du membre.", examples = "Homme") private String genre; - @Schema(description = "Le numéro de licence du membre.", example = "12345") + @Schema(description = "Le numéro de licence du membre.", examples = "12345") private int licence; - @Schema(description = "Le pays du membre.", example = "FR") + @Schema(description = "Le pays du membre.", examples = "FR") private String country; @Schema(description = "La date de naissance du membre.") private Date birth_date; - @Schema(description = "L'adresse e-mail du membre.", example = "jean.dupont@example.com") + @Schema(description = "L'adresse e-mail du membre.", examples = "jean.dupont@examples.com") private String email; - @Schema(description = "Le rôle du membre dans l'association.", example = "MEMBRE") + @Schema(description = "Le rôle du membre dans l'association.", examples = "MEMBRE") private String role; - @Schema(description = "Le grade d'arbitrage du membre.", example = "N/A") + @Schema(description = "Le grade d'arbitrage du membre.", examples = "N/A") private String grade_arbitrage; + @Schema(description = "La confidentialité des résultats", examples = "PUBLIC") + private ResultPrivacy resultPrivacy; @Schema(description = "La liste des licences du membre.") private List licences; @@ -55,5 +58,6 @@ public class MeData { this.email = membreModel.getEmail(); this.role = membreModel.getRole().str; this.grade_arbitrage = membreModel.getGrade_arbitrage().str; + this.resultPrivacy = membreModel.getResultPrivacy(); } } diff --git a/src/main/java/fr/titionfire/ffsaf/rest/from/UserSettingForm.java b/src/main/java/fr/titionfire/ffsaf/rest/from/UserSettingForm.java new file mode 100644 index 0000000..566587a --- /dev/null +++ b/src/main/java/fr/titionfire/ffsaf/rest/from/UserSettingForm.java @@ -0,0 +1,15 @@ +package fr.titionfire.ffsaf.rest.from; + +import fr.titionfire.ffsaf.utils.ResultPrivacy; +import jakarta.ws.rs.FormParam; +import lombok.Getter; +import lombok.ToString; +import org.eclipse.microprofile.openapi.annotations.media.Schema; + +@ToString +@Getter +public class UserSettingForm { + @FormParam("resultPrivacy") + @Schema(description = "La confidentialité des résultats", examples = "PUBLIC", defaultValue = "PUBLIC", required = true) + private ResultPrivacy resultPrivacy; +} diff --git a/src/main/webapp/src/pages/MePage.jsx b/src/main/webapp/src/pages/MePage.jsx index 27e74b3..aac61d3 100644 --- a/src/main/webapp/src/pages/MePage.jsx +++ b/src/main/webapp/src/pages/MePage.jsx @@ -12,6 +12,10 @@ import { faUserGroup, faVenus } from "@fortawesome/free-solid-svg-icons"; +import {CheckField} from "../components/MemberCustomFiels.jsx"; +import {toast} from "react-toastify"; +import {apiAxios} from "../utils/Tools.js"; +import {useEffect, useState} from "react"; const vite_url = import.meta.env.VITE_URL; @@ -30,6 +34,7 @@ export function MePage() {
+
@@ -96,8 +101,47 @@ function SelectCard() {
; } +function SettingsCard({data}) { + const [privacy, setPrivacy] = useState("PUBLIC"); -export function InformationForm({data}) { + useEffect(() => { + if (data?.resultPrivacy) { + setPrivacy(data.resultPrivacy); + } + }, [data]); + + const handleChange = (e) => { + const formData = new FormData(); + formData.append("resultPrivacy", e.target.value); + toast.promise(apiAxios.put(`/member/me/setting`, formData), + { + pending: 'Mise à jours des paramètres en cours...', + success: 'Paramètres mis à jours avec succès 🎉', + error: 'Échec de la mise à jours des paramètres 😕' + }) + .then(() => { + setPrivacy(String(formData.get("resultPrivacy"))); + }); + } + + return
+
Paramètres du compte
+
+
+ + +
+
+
; +} + +function InformationForm({data}) { const style = {marginRight: '0.7em'} return
@@ -127,4 +171,4 @@ export function InformationForm({data}) {
; -} \ No newline at end of file +}