diff --git a/src/main/java/fr/titionfire/ffsaf/domain/service/AffiliationService.java b/src/main/java/fr/titionfire/ffsaf/domain/service/AffiliationService.java index 3ad1ea1..61c72b9 100644 --- a/src/main/java/fr/titionfire/ffsaf/domain/service/AffiliationService.java +++ b/src/main/java/fr/titionfire/ffsaf/domain/service/AffiliationService.java @@ -308,7 +308,13 @@ public class AffiliationService { } })) .chain(club -> - Panache.withTransaction(() -> repository.persist(new AffiliationModel(null, club, saison)))) + Panache.withTransaction(() -> repository.persist(new AffiliationModel(null, club, saison)) + .chain(c -> (club.getNo_affiliation() != null) ? Uni.createFrom().item(c) : + sequenceRepository.getNextValueInTransaction(SequenceType.Affiliation) + .invoke(club::setNo_affiliation) + .chain(() -> clubRepository.persist(club)) + .map(o -> c) + ))) .map(SimpleAffiliation::fromModel); } diff --git a/src/main/java/fr/titionfire/ffsaf/domain/service/ClubService.java b/src/main/java/fr/titionfire/ffsaf/domain/service/ClubService.java index 17669fc..ef72137 100644 --- a/src/main/java/fr/titionfire/ffsaf/domain/service/ClubService.java +++ b/src/main/java/fr/titionfire/ffsaf/domain/service/ClubService.java @@ -122,13 +122,15 @@ public class ClubService { m.setName(input.getName()); m.setCountry(input.getCountry()); + m.setInternational(input.isInternational()); if (!input.isInternational()) { m.setTraining_location(input.getTraining_location()); m.setTraining_day_time(input.getTraining_day_time()); m.setContact_intern(input.getContact_intern()); m.setRNA(input.getRna()); - m.setSIRET(input.getSiret()); + if (input.getSiret() != null && !input.getSiret().isBlank()) + m.setSIRET(Long.parseLong(input.getSiret())); m.setAddress(input.getAddress()); try { @@ -145,7 +147,37 @@ public class ClubService { } public Uni add(FullClubForm input) { - return Uni.createFrom().nullItem(); + TypeReference> typeRef = new TypeReference<>() { + }; + + return Uni.createFrom().nullItem() + .chain(() -> { + ClubModel clubModel = new ClubModel(); + + clubModel.setName(input.getName()); + clubModel.setCountry(input.getCountry()); + clubModel.setInternational(input.isInternational()); + clubModel.setNo_affiliation(null); + if (!input.isInternational()) { + clubModel.setTraining_location(input.getTraining_location()); + clubModel.setTraining_day_time(input.getTraining_day_time()); + clubModel.setContact_intern(input.getContact_intern()); + clubModel.setRNA(input.getRna()); + if (input.getSiret() != null && !input.getSiret().isBlank()) + clubModel.setSIRET(Long.parseLong(input.getSiret())); + clubModel.setAddress(input.getAddress()); + + try { + clubModel.setContact(MAPPER.readValue(input.getContact(), typeRef)); + } catch (JsonProcessingException ignored) { + } + } + + return Panache.withTransaction(() -> repository.persist(clubModel)); + }) + .call(clubModel -> keycloakService.getGroupFromClub(clubModel)) // create group in keycloak + .invoke(clubModel -> SReqClub.sendAddIfNeed(serverCustom.clients, SimpleClubModel.fromModel(clubModel))) + .map(ClubModel::getId); } public Uni delete(long id) { @@ -155,8 +187,10 @@ public class ClubService { combModel.setClub(null); combModel.setRole(RoleAsso.MEMBRE); }).toList()) - .call(list -> Uni.join().all(list.stream().filter(m -> m.getUserId() != null) - .map(m -> keycloakService.clearUser(m.getUserId())).toList()).andCollectFailures()) + .call(list -> (list.isEmpty()) ? Uni.createFrom().voidItem() : + Uni.join().all(list.stream().filter(m -> m.getUserId() != null) + .map(m -> keycloakService.clearUser(m.getUserId())).toList()) + .andCollectFailures()) .chain(list -> Panache.withTransaction(() -> combRepository.persist(list))) .map(o -> club) ) diff --git a/src/main/java/fr/titionfire/ffsaf/rest/ClubEndpoints.java b/src/main/java/fr/titionfire/ffsaf/rest/ClubEndpoints.java index 7361198..abb255f 100644 --- a/src/main/java/fr/titionfire/ffsaf/rest/ClubEndpoints.java +++ b/src/main/java/fr/titionfire/ffsaf/rest/ClubEndpoints.java @@ -24,6 +24,7 @@ import org.eclipse.microprofile.config.inject.ConfigProperty; import org.eclipse.microprofile.jwt.JsonWebToken; import java.net.URISyntaxException; +import java.util.HashMap; import java.util.List; import java.util.function.Consumer; @@ -57,6 +58,14 @@ public class ClubEndpoints { return clubService.getAll().map(clubModels -> clubModels.stream().map(SimpleClubModel::fromModel).toList()); } + @GET + @Path("/contact_type") + @Authenticated + @Produces(MediaType.APPLICATION_JSON) + public Uni> getConcatType() { + return Uni.createFrom().item(Contact.toSite()); + } + @GET @Path("/find") @RolesAllowed({"federation_admin"}) @@ -111,11 +120,12 @@ public class ClubEndpoints { }); } - @POST + @PUT @RolesAllowed({"federation_admin"}) @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.MULTIPART_FORM_DATA) public Uni addAdminClub(FullClubForm input) { + System.out.println(input); return clubService.add(input) .invoke(Unchecked.consumer(id -> { if (id == null) throw new InternalError("Fail to create club data"); diff --git a/src/main/java/fr/titionfire/ffsaf/rest/from/FullClubForm.java b/src/main/java/fr/titionfire/ffsaf/rest/from/FullClubForm.java index a8a407a..a9b27d0 100644 --- a/src/main/java/fr/titionfire/ffsaf/rest/from/FullClubForm.java +++ b/src/main/java/fr/titionfire/ffsaf/rest/from/FullClubForm.java @@ -37,7 +37,7 @@ public class FullClubForm { private String rna = null; @FormParam("siret") - private Long siret = null; + private String siret = null; @FormParam("international") private boolean international = false; diff --git a/src/main/webapp/src/pages/admin/club/ClubList.jsx b/src/main/webapp/src/pages/admin/club/ClubList.jsx index 7f1dc8d..4f537a6 100644 --- a/src/main/webapp/src/pages/admin/club/ClubList.jsx +++ b/src/main/webapp/src/pages/admin/club/ClubList.jsx @@ -70,7 +70,7 @@ export function ClubList() { } return <> -

Club

+

Club

@@ -85,8 +85,11 @@ export function ClubList() {
- - +
+ +
+
Filtre
diff --git a/src/main/webapp/src/pages/admin/club/ClubPage.jsx b/src/main/webapp/src/pages/admin/club/ClubPage.jsx index f317ddf..2f751d3 100644 --- a/src/main/webapp/src/pages/admin/club/ClubPage.jsx +++ b/src/main/webapp/src/pages/admin/club/ClubPage.jsx @@ -22,7 +22,7 @@ export function ClubPage() { const navigate = useNavigate(); const setLoading = useLoadingSwitcher() - const {data, error} = useFetch(`/club/${id}`, setLoading, 1) + const {data, refresh, error} = useFetch(`/club/${id}`, setLoading, 1) const handleRm = () => { toast.promise( @@ -38,7 +38,7 @@ export function ClubPage() { } return <> -

Page membre

+

Page club

@@ -92,7 +92,7 @@ function InformationForm({data}) {
-
Licence n°{data.no_affiliation}
+
Affiliation n°{data.no_affiliation}
@@ -120,11 +120,12 @@ function InformationForm({data}) {
{!switchOn && <> - + - +
diff --git a/src/main/webapp/src/pages/admin/club/NewClubPage.jsx b/src/main/webapp/src/pages/admin/club/NewClubPage.jsx index 20fe771..74903a6 100644 --- a/src/main/webapp/src/pages/admin/club/NewClubPage.jsx +++ b/src/main/webapp/src/pages/admin/club/NewClubPage.jsx @@ -1,16 +1,111 @@ import {useNavigate} from "react-router-dom"; +import {LoadingProvider} from "../../../hooks/useLoading.jsx"; +import {useFetch} from "../../../hooks/useFetch.js"; +import {toast} from "react-toastify"; +import {apiAxios} from "../../../utils/Tools.js"; +import {CountryList, TextField} from "../../../components/MemberCustomFiels.jsx"; + +import {useRef, useState} from "react"; +import {LocationEditor, LocationEditorModal} from "../../../components/Club/LocationEditor.jsx"; +import {ContactEditor} from "../../../components/Club/ContactEditor.jsx"; +import {HoraireEditor} from "../../../components/Club/HoraireEditor.jsx"; export function NewClubPage() { - const navigate = useNavigate(); + const navigate = useNavigate() return <> -

Page affiliation

-
+
+ + + +
-} \ No newline at end of file +} + +function InformationForm() { + const [switchOn, setSwitchOn] = useState(false); + const [modal, setModal] = useState({id: -1}) + const locationModalCallback = useRef(null) + const navigate = useNavigate() + + const {data} = useFetch(`/club/contact_type`) + + const handleSubmit = (event) => { + event.preventDefault(); + + const formData = new FormData(event.target); + + toast.promise( + apiAxios.put(`/club`, formData), + { + pending: "Création du club en cours", + success: "Club créé avec succès 🎉", + error: "Échec de la création du club 😕" + } + ).then(data => { + navigate(`/admin/club/${data.data}`); + }) + } + + return <> + +
+
Nouveau club
+
+ + + + +
+
+ + +
+
+ +
+
+ setSwitchOn(!switchOn)}/> + +
+
+ {!switchOn && <> + + + + + +
+
+ + +
+
+ + + + + + } +
+
+
+ +
+
+
+ + + + +} diff --git a/src/main/webapp/src/pages/club/club/ClubPage.jsx b/src/main/webapp/src/pages/club/club/ClubPage.jsx new file mode 100644 index 0000000..d7196b4 --- /dev/null +++ b/src/main/webapp/src/pages/club/club/ClubPage.jsx @@ -0,0 +1,158 @@ +import {useNavigate, useParams} from "react-router-dom"; +import {LoadingProvider, useLoadingSwitcher} from "../../../hooks/useLoading.jsx"; +import {useFetch} from "../../../hooks/useFetch.js"; +import {toast} from "react-toastify"; +import {apiAxios} from "../../../utils/Tools.js"; +import {ConfirmDialog} from "../../../components/ConfirmDialog.jsx"; +import {AxiosError} from "../../../components/AxiosError.jsx"; +import {AffiliationCard} from "./AffiliationCard.jsx"; +import {CountryList, TextField} from "../../../components/MemberCustomFiels.jsx"; + +import {useRef, useState} from "react"; +import {LocationEditor, LocationEditorModal} from "../../../components/Club/LocationEditor.jsx"; +import {ContactEditor} from "../../../components/Club/ContactEditor.jsx"; +import {HoraireEditor} from "../../../components/Club/HoraireEditor.jsx"; +import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; +import {faFilePdf} from "@fortawesome/free-solid-svg-icons"; + +const vite_url = import.meta.env.VITE_URL; + +export function ClubPage() { + const {id} = useParams() + const navigate = useNavigate(); + + const setLoading = useLoadingSwitcher() + const {data, error} = useFetch(`/club/${id}`, setLoading, 1) + + const handleRm = () => { + toast.promise( + apiAxios.delete(`/club/${id}`), + { + pending: "Suppression du club en cours...", + success: "Club supprimé avec succès 🎉", + error: "Échec de la suppression du club 😕" + } + ).then(_ => { + navigate("/admin/club") + }) + } + + return <> +

Page club

+ + {data + ?
+
+
+ + + +
+
+ +
+ +
+ +
+
+
+ : error && + } + +} + +function InformationForm({data}) { + const [switchOn, setSwitchOn] = useState(data.international); + const [modal, setModal] = useState({id: -1}) + const locationModalCallback = useRef(null) + + const handleSubmit = (event) => { + event.preventDefault(); + + const formData = new FormData(event.target); + + toast.promise( + apiAxios.put(`/club/${data.id}`, formData), + { + pending: "Enregistrement du club en cours", + success: "Club enregistrée avec succès 🎉", + error: "Échec de l'enregistrement du club 😕" + } + ) + } + + return <> +
+
+ +
Affiliation n°{data.no_affiliation}
+
+ + + + + + avatar +
+
+ + +
+ +
+ +
+
+ setSwitchOn(!switchOn)}/> + +
+
+ {!switchOn && <> + + + + + +
+
+ + + + + +
+
Laissez vide pour ne rien changer.
+
+ + + + + + } +
+
+
+ +
+
+
+
+ + + +}