feat: AffiliationCard
This commit is contained in:
parent
6a21bd4735
commit
b2438ec3d8
@ -21,7 +21,7 @@ public class AffiliationRequestModel {
|
|||||||
Long id;
|
Long id;
|
||||||
|
|
||||||
String name;
|
String name;
|
||||||
long siren;
|
long siret;
|
||||||
String RNA;
|
String RNA;
|
||||||
String address;
|
String address;
|
||||||
|
|
||||||
|
|||||||
@ -53,6 +53,6 @@ public class ClubModel {
|
|||||||
|
|
||||||
boolean international;
|
boolean international;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "club", fetch = FetchType.EAGER)
|
@OneToMany(mappedBy = "club", fetch = FetchType.LAZY)
|
||||||
List<AffiliationModel> affiliations;
|
List<AffiliationModel> affiliations;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.repository;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.AffiliationModel;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class AffiliationRepository implements PanacheRepositoryBase<AffiliationModel, Long> {
|
||||||
|
}
|
||||||
@ -1,11 +1,12 @@
|
|||||||
package fr.titionfire.ffsaf.domain.service;
|
package fr.titionfire.ffsaf.domain.service;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.AffiliationModel;
|
||||||
import fr.titionfire.ffsaf.data.model.AffiliationRequestModel;
|
import fr.titionfire.ffsaf.data.model.AffiliationRequestModel;
|
||||||
import fr.titionfire.ffsaf.data.model.ClubModel;
|
import fr.titionfire.ffsaf.data.repository.AffiliationRepository;
|
||||||
import fr.titionfire.ffsaf.data.repository.AffiliationRequestRepository;
|
import fr.titionfire.ffsaf.data.repository.AffiliationRequestRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.ClubRepository;
|
||||||
import fr.titionfire.ffsaf.data.repository.CombRepository;
|
import fr.titionfire.ffsaf.data.repository.CombRepository;
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleAffiliation;
|
import fr.titionfire.ffsaf.rest.data.SimpleAffiliation;
|
||||||
import fr.titionfire.ffsaf.rest.from.AffiliationForm;
|
|
||||||
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
||||||
import fr.titionfire.ffsaf.utils.Utils;
|
import fr.titionfire.ffsaf.utils.Utils;
|
||||||
import io.quarkus.hibernate.reactive.panache.Panache;
|
import io.quarkus.hibernate.reactive.panache.Panache;
|
||||||
@ -14,9 +15,10 @@ import io.smallrye.mutiny.Uni;
|
|||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
|
import org.hibernate.reactive.mutiny.Mutiny;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@WithSession
|
@WithSession
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
@ -26,7 +28,13 @@ public class AffiliationService {
|
|||||||
CombRepository combRepository;
|
CombRepository combRepository;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AffiliationRequestRepository repository;
|
ClubRepository clubRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AffiliationRequestRepository repositoryRequest;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AffiliationRepository repository;
|
||||||
|
|
||||||
@ConfigProperty(name = "upload_dir")
|
@ConfigProperty(name = "upload_dir")
|
||||||
String media;
|
String media;
|
||||||
@ -57,27 +65,46 @@ public class AffiliationService {
|
|||||||
throw new IllegalArgumentException("Licence membre n°3 inconnue");
|
throw new IllegalArgumentException("Licence membre n°3 inconnue");
|
||||||
}
|
}
|
||||||
}) : Uni.createFrom().nullItem())
|
}) : Uni.createFrom().nullItem())
|
||||||
).chain(model -> Panache.withTransaction(() -> repository.persist(model)))
|
).chain(model -> Panache.withTransaction(() -> repositoryRequest.persist(model)))
|
||||||
.onItem().invoke(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getLogo(), media,
|
.onItem()
|
||||||
|
.invoke(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getLogo(), media,
|
||||||
"aff_request/logo")))
|
"aff_request/logo")))
|
||||||
.onItem().invoke(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getStatus(), media,
|
.onItem()
|
||||||
|
.invoke(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getStatus(), media,
|
||||||
"aff_request/status")))
|
"aff_request/status")))
|
||||||
.map(__ -> "Ok");
|
.map(__ -> "Ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<List<SimpleAffiliation>> getCurrentSaisonAffiliation() {
|
public Uni<List<SimpleAffiliation>> getCurrentSaisonAffiliation() {
|
||||||
return Uni.createFrom().nullItem(); // TODO
|
return repository.list("saison = ?1", Utils.getSaison())
|
||||||
|
.map(models -> models.stream().map(SimpleAffiliation::fromModel).toList())
|
||||||
|
.chain(aff -> repositoryRequest.list("saison = ?1", Utils.getSaison())
|
||||||
|
.chain(models -> Uni.join().all(models.stream().map(model ->
|
||||||
|
clubRepository.find("siret = ?1", model.getSiret()).firstResult()
|
||||||
|
.map(c -> new SimpleAffiliation(model.getId() * -1, c.getId(),
|
||||||
|
model.getSaison(), false)))
|
||||||
|
.toList()).andFailFast()
|
||||||
|
).map(aff2 -> Stream.concat(aff2.stream(), aff.stream()).toList())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<List<SimpleAffiliation>> getAffiliation(long id, Consumer<ClubModel> checkPerm) {
|
public Uni<List<SimpleAffiliation>> getAffiliation(long id) {
|
||||||
return Uni.createFrom().nullItem(); // TODO
|
return clubRepository.findById(id).call(model -> Mutiny.fetch(model.getAffiliations()))
|
||||||
|
.chain(model -> repositoryRequest.list("siret = ?1", model.getSIRET())
|
||||||
|
.map(reqs -> reqs.stream().map(req ->
|
||||||
|
new SimpleAffiliation(req.getId() * -1, model.getId(), req.getSaison(), false)))
|
||||||
|
.map(aff2 -> Stream.concat(aff2,
|
||||||
|
model.getAffiliations().stream().map(SimpleAffiliation::fromModel)).toList())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<SimpleAffiliation> setAffiliation(long id, AffiliationForm form) {
|
public Uni<SimpleAffiliation> setAffiliation(long id, int saison) {
|
||||||
return Uni.createFrom().nullItem(); // TODO
|
return clubRepository.findById(id).chain(club ->
|
||||||
|
Panache.withTransaction(() -> repository.persist(new AffiliationModel(null, club, saison))))
|
||||||
|
.map(SimpleAffiliation::fromModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<?> deleteAffiliation(long id) {
|
public Uni<?> deleteAffiliation(long id) {
|
||||||
return Uni.createFrom().nullItem(); // TODO
|
return Panache.withTransaction(() -> repository.deleteById(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
package fr.titionfire.ffsaf.rest;
|
package fr.titionfire.ffsaf.rest;
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.ClubModel;
|
|
||||||
import fr.titionfire.ffsaf.domain.service.AffiliationService;
|
import fr.titionfire.ffsaf.domain.service.AffiliationService;
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleAffiliation;
|
import fr.titionfire.ffsaf.rest.data.SimpleAffiliation;
|
||||||
import fr.titionfire.ffsaf.rest.from.AffiliationForm;
|
|
||||||
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
||||||
import fr.titionfire.ffsaf.utils.GroupeUtils;
|
import fr.titionfire.ffsaf.utils.GroupeUtils;
|
||||||
import io.quarkus.oidc.IdToken;
|
import io.quarkus.oidc.IdToken;
|
||||||
@ -32,8 +30,8 @@ public class AffiliationEndpoints {
|
|||||||
@Inject
|
@Inject
|
||||||
SecurityIdentity securityIdentity;
|
SecurityIdentity securityIdentity;
|
||||||
|
|
||||||
Consumer<ClubModel> checkPerm = Unchecked.consumer(clubModel -> {
|
Consumer<Long> checkPerm = Unchecked.consumer(id -> {
|
||||||
if (!securityIdentity.getRoles().contains("federation_admin") && !GroupeUtils.isInClubGroup(clubModel.getId(), idToken))
|
if (!securityIdentity.getRoles().contains("federation_admin") && !GroupeUtils.isInClubGroup(id, idToken))
|
||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -57,16 +55,15 @@ public class AffiliationEndpoints {
|
|||||||
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"})
|
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"})
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Uni<List<SimpleAffiliation>> getLicence(@PathParam("id") long id) {
|
public Uni<List<SimpleAffiliation>> getLicence(@PathParam("id") long id) {
|
||||||
return service.getAffiliation(id, checkPerm);
|
return Uni.createFrom().item(id).invoke(checkPerm).chain(__ -> service.getAffiliation(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@PUT
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@RolesAllowed("federation_admin")
|
@RolesAllowed("federation_admin")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
public Uni<SimpleAffiliation> setLicence(@PathParam("id") long id, @QueryParam("saison") int saison) {
|
||||||
public Uni<SimpleAffiliation> setLicence(@PathParam("id") long id, AffiliationForm form) {
|
return service.setAffiliation(id, saison);
|
||||||
return service.setAffiliation(id, form);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
|
|||||||
@ -16,7 +16,7 @@ public class SimpleAffiliation {
|
|||||||
int saison;
|
int saison;
|
||||||
boolean validate;
|
boolean validate;
|
||||||
|
|
||||||
public static SimpleAffiliation fromModel(AffiliationModel model, boolean validate) {
|
public static SimpleAffiliation fromModel(AffiliationModel model) {
|
||||||
if (model == null)
|
if (model == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ public class SimpleAffiliation {
|
|||||||
.id(model.getId())
|
.id(model.getId())
|
||||||
.club(model.getClub().getId())
|
.club(model.getClub().getId())
|
||||||
.saison(model.getSaison())
|
.saison(model.getSaison())
|
||||||
.validate(validate)
|
.validate(true)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,8 +14,8 @@ public class AffiliationRequestForm {
|
|||||||
@FormParam("name")
|
@FormParam("name")
|
||||||
private String name = null;
|
private String name = null;
|
||||||
|
|
||||||
@FormParam("siren")
|
@FormParam("siret")
|
||||||
private Long siren = null;
|
private Long siret = null;
|
||||||
|
|
||||||
@FormParam("rna")
|
@FormParam("rna")
|
||||||
private String rna = null;
|
private String rna = null;
|
||||||
@ -67,7 +67,7 @@ public class AffiliationRequestForm {
|
|||||||
public AffiliationRequestModel toModel() {
|
public AffiliationRequestModel toModel() {
|
||||||
AffiliationRequestModel model = new AffiliationRequestModel();
|
AffiliationRequestModel model = new AffiliationRequestModel();
|
||||||
model.setName(this.getName());
|
model.setName(this.getName());
|
||||||
model.setSiren(this.getSiren());
|
model.setSiret(this.getSiret());
|
||||||
model.setRNA(this.getRna());
|
model.setRNA(this.getRna());
|
||||||
model.setAddress(this.getAdresse());
|
model.setAddress(this.getAdresse());
|
||||||
|
|
||||||
|
|||||||
@ -100,14 +100,19 @@ export function DemandeAff() {
|
|||||||
|
|
||||||
function AssoInfo() {
|
function AssoInfo() {
|
||||||
const [denomination, setDenomination] = useState("")
|
const [denomination, setDenomination] = useState("")
|
||||||
const [siren, setSiren] = useState("")
|
const [siret, setSiret] = useState("")
|
||||||
const [rna, setRna] = useState("")
|
const [rna, setRna] = useState("")
|
||||||
const [rnaEnable, setRnaEnable] = useState(false)
|
const [rnaEnable, setRnaEnable] = useState(false)
|
||||||
const [adresse, setAdresse] = useState("")
|
const [adresse, setAdresse] = useState("")
|
||||||
|
|
||||||
const fetchSiren = () => {
|
const fetchSiret = () => {
|
||||||
|
if (siret.length < 14) {
|
||||||
|
toast.error("Le SIRET doit contenir 14 chiffres")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
toast.promise(
|
toast.promise(
|
||||||
apiAxios.get(`asso/siren/${siren}`),
|
apiAxios.get(`asso/siren/${siret.substring(0, siret.length - 5)}`),
|
||||||
{
|
{
|
||||||
pending: "Recherche de l'association en cours",
|
pending: "Recherche de l'association en cours",
|
||||||
success: "Association trouvée avec succès 🎉",
|
success: "Association trouvée avec succès 🎉",
|
||||||
@ -131,11 +136,11 @@ function AssoInfo() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="input-group mb-3">
|
<div className="input-group mb-3">
|
||||||
<span className="input-group-text">N° SIREN*</span>
|
<span className="input-group-text">N° SIRET*</span>
|
||||||
<input type="number" className="form-control" placeholder="siren" name="siren" required value={siren}
|
<input type="number" className="form-control" placeholder="siren" name="siren" required value={siret}
|
||||||
onChange={e => setSiren(e.target.value)} defaultValue={500213731}/>
|
onChange={e => setSiret(e.target.value)} defaultValue={500213731}/>
|
||||||
<button className="btn btn-outline-secondary" type="button" id="button-addon2"
|
<button className="btn btn-outline-secondary" type="button" id="button-addon2"
|
||||||
onClick={fetchSiren}>Rechercher
|
onClick={fetchSiret}>Rechercher
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -2,51 +2,25 @@ import {useLoadingSwitcher} from "../../../hooks/useLoading.jsx";
|
|||||||
import {useFetch} from "../../../hooks/useFetch.js";
|
import {useFetch} from "../../../hooks/useFetch.js";
|
||||||
import {useEffect, useReducer, useState} from "react";
|
import {useEffect, useReducer, useState} from "react";
|
||||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||||
import {faPen} from "@fortawesome/free-solid-svg-icons";
|
import {faEye, faPen} from "@fortawesome/free-solid-svg-icons";
|
||||||
import {AxiosError} from "../../../components/AxiosError.jsx";
|
import {AxiosError} from "../../../components/AxiosError.jsx";
|
||||||
import {apiAxios, getSaison} from "../../../utils/Tools.js";
|
import {apiAxios, getSaison} from "../../../utils/Tools.js";
|
||||||
import {toast} from "react-toastify";
|
import {toast} from "react-toastify";
|
||||||
|
import {SimpleReducer} from "../../../utils/SimpleReducer.jsx";
|
||||||
function affiliationReducer(affiliation, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case 'ADD':
|
|
||||||
return [
|
|
||||||
...affiliation,
|
|
||||||
action.payload
|
|
||||||
]
|
|
||||||
case 'REMOVE':
|
|
||||||
return affiliation.filter(affiliation => affiliation.id !== action.payload)
|
|
||||||
case 'UPDATE_OR_ADD':
|
|
||||||
const index = affiliation.findIndex(affiliation => affiliation.id === action.payload.id)
|
|
||||||
if (index === -1) {
|
|
||||||
return [
|
|
||||||
...affiliation,
|
|
||||||
action.payload
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
affiliation[index] = action.payload
|
|
||||||
return [...affiliation]
|
|
||||||
}
|
|
||||||
case 'SORT':
|
|
||||||
return affiliation.sort((a, b) => b.saison - a.saison)
|
|
||||||
default:
|
|
||||||
throw new Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function AffiliationCard({clubData}) {
|
export function AffiliationCard({clubData}) {
|
||||||
const setLoading = useLoadingSwitcher()
|
const setLoading = useLoadingSwitcher()
|
||||||
const {data, error} = useFetch(`/affiliation/${clubData.id}`, setLoading, 1)
|
const {data, error} = useFetch(`/affiliation/${clubData.id}`, setLoading, 1)
|
||||||
|
|
||||||
const [modalAffiliation, setModal] = useState({id: -1, club: clubData.id})
|
const [modalAffiliation, setModal] = useState({id: -1, club: clubData.id})
|
||||||
const [affiliations, dispatch] = useReducer(affiliationReducer, [])
|
const [affiliations, dispatch] = useReducer(SimpleReducer, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data) return
|
if (!data) return
|
||||||
for (const dataKey of data) {
|
for (const dataKey of data) {
|
||||||
dispatch({type: 'UPDATE_OR_ADD', payload: dataKey})
|
dispatch({type: 'UPDATE_OR_ADD', payload: dataKey})
|
||||||
}
|
}
|
||||||
dispatch({type: 'SORT'})
|
dispatch({type: 'SORT', payload: (a, b) => b.saison - a.saison})
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
return <div className="card mb-4 mb-md-0">
|
return <div className="card mb-4 mb-md-0">
|
||||||
@ -55,7 +29,7 @@ export function AffiliationCard({clubData}) {
|
|||||||
<div className="col">Affiliation</div>
|
<div className="col">Affiliation</div>
|
||||||
<div className="col" style={{textAlign: 'right'}}>
|
<div className="col" style={{textAlign: 'right'}}>
|
||||||
<button className="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#AffiliationModal"
|
<button className="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#AffiliationModal"
|
||||||
onClick={_ => setModal({id: -1, club: clubData.id})}>Ajouter
|
onClick={_ => setModal({id: 0, club: clubData.id, validate: 1})}>Ajouter
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -92,7 +66,7 @@ function sendAffiliation(event, dispatch) {
|
|||||||
|
|
||||||
const formData = new FormData(event.target);
|
const formData = new FormData(event.target);
|
||||||
toast.promise(
|
toast.promise(
|
||||||
apiAxios.post(`/affiliation/${formData.get('membre')}`, formData), // TODO
|
apiAxios.put(`/affiliation/${formData.get('club')}?saison=${formData.get('saison')}`),
|
||||||
{
|
{
|
||||||
pending: "Enregistrement de l'affiliation en cours",
|
pending: "Enregistrement de l'affiliation en cours",
|
||||||
success: "Affiliation enregistrée avec succès 🎉",
|
success: "Affiliation enregistrée avec succès 🎉",
|
||||||
@ -100,12 +74,13 @@ function sendAffiliation(event, dispatch) {
|
|||||||
}
|
}
|
||||||
).then(data => {
|
).then(data => {
|
||||||
dispatch({type: 'UPDATE_OR_ADD', payload: data.data})
|
dispatch({type: 'UPDATE_OR_ADD', payload: data.data})
|
||||||
dispatch({type: 'SORT'})
|
dispatch({type: 'SORT', payload: (a, b) => b.saison - a.saison})
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeAffiliation(id, dispatch) {
|
function removeAffiliation(id, dispatch) {
|
||||||
|
if (id <= 0) return
|
||||||
toast.promise(
|
toast.promise(
|
||||||
apiAxios.delete(`/affiliation/${id}`),
|
apiAxios.delete(`/affiliation/${id}`),
|
||||||
{
|
{
|
||||||
@ -120,30 +95,21 @@ function removeAffiliation(id, dispatch) {
|
|||||||
|
|
||||||
function ModalContent({affiliation, dispatch}) {
|
function ModalContent({affiliation, dispatch}) {
|
||||||
const [saison, setSaison] = useState(0)
|
const [saison, setSaison] = useState(0)
|
||||||
const [validate, setValidate] = useState(false)
|
|
||||||
const [isNew, setNew] = useState(true)
|
|
||||||
const setSeason = (event) => {
|
const setSeason = (event) => {
|
||||||
setSaison(Number(event.target.value))
|
setSaison(Number(event.target.value))
|
||||||
}
|
}
|
||||||
const handleValidateChange = (event) => {
|
|
||||||
setValidate(event.target.value === 'true');
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (affiliation.id !== -1) {
|
if (affiliation.id !== 0) {
|
||||||
setNew(false)
|
|
||||||
setSaison(affiliation.saison)
|
setSaison(affiliation.saison)
|
||||||
setValidate(affiliation.validate)
|
|
||||||
} else {
|
} else {
|
||||||
setNew(true)
|
|
||||||
setSaison(getSaison())
|
setSaison(getSaison())
|
||||||
setValidate(false)
|
|
||||||
}
|
}
|
||||||
}, [affiliation]);
|
}, [affiliation]);
|
||||||
|
|
||||||
return <form onSubmit={e => sendAffiliation(e, dispatch)}>
|
return <form onSubmit={e => sendAffiliation(e, dispatch)}>
|
||||||
<input name="id" value={affiliation.id} readOnly hidden/>
|
<input name="id" value={affiliation.id} readOnly hidden/>
|
||||||
<input name="membre" value={affiliation.membre} readOnly hidden/>
|
<input name="club" value={affiliation.club} readOnly hidden/>
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h1 className="modal-title fs-5" id="AffiliationModalLabel">Edition de l'affiliation</h1>
|
<h1 className="modal-title fs-5" id="AffiliationModalLabel">Edition de l'affiliation</h1>
|
||||||
<button type="button" className="btn-close" data-bs-dismiss="modal"
|
<button type="button" className="btn-close" data-bs-dismiss="modal"
|
||||||
@ -151,7 +117,7 @@ function ModalContent({affiliation, dispatch}) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
<div className="input-group mb-3 justify-content-md-center">
|
<div className="input-group mb-3 justify-content-md-center">
|
||||||
{isNew
|
{affiliation.id === 0
|
||||||
? <input type="number" className="form-control" placeholder="Saison" name="saison"
|
? <input type="number" className="form-control" placeholder="Saison" name="saison"
|
||||||
aria-label="Saison" aria-describedby="basic-addon2" value={saison} onChange={setSeason}/>
|
aria-label="Saison" aria-describedby="basic-addon2" value={saison} onChange={setSeason}/>
|
||||||
: <><span className="input-group-text" id="basic-addon2">{saison}</span>
|
: <><span className="input-group-text" id="basic-addon2">{saison}</span>
|
||||||
@ -159,27 +125,20 @@ function ModalContent({affiliation, dispatch}) {
|
|||||||
<span className="input-group-text" id="basic-addon2">-</span>
|
<span className="input-group-text" id="basic-addon2">-</span>
|
||||||
<span className="input-group-text" id="basic-addon2">{saison + 1}</span>
|
<span className="input-group-text" id="basic-addon2">{saison + 1}</span>
|
||||||
</div>
|
</div>
|
||||||
<RadioGroupeOnOff name="validate" text="Validation de l'affiliation" value={validate}
|
<div className="input-group mb-3 justify-content-md-center">
|
||||||
onChange={handleValidateChange}/>
|
<span className="input-group-text" id="basic-addon2">État de la demande</span>
|
||||||
|
{affiliation.validate ? <span className="input-group-text" id="basic-addon2">Validée</span> :
|
||||||
|
<>
|
||||||
|
<span className="input-group-text" id="basic-addon2">En attente</span>
|
||||||
|
<button type="button" className="btn btn-primary"><FontAwesomeIcon icon={faEye}/></button> // TODO
|
||||||
|
</>}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-footer">
|
<div className="modal-footer">
|
||||||
<button type="submit" className="btn btn-primary" data-bs-dismiss="modal">Enregistrer</button>
|
{affiliation.id === 0 && <button type="submit" className="btn btn-primary" data-bs-dismiss="modal">Enregistrer</button>}
|
||||||
<button type="reset" className="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
<button type="reset" className="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
|
||||||
{isNew || <button type="button" className="btn btn-danger" data-bs-dismiss="modal"
|
{affiliation.id <= 0 || <button type="button" className="btn btn-danger" data-bs-dismiss="modal"
|
||||||
onClick={() => removeAffiliation(affiliation.id, dispatch)}>Supprimer</button>}
|
onClick={() => removeAffiliation(affiliation.id, dispatch)}>Supprimer</button>}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
|
|
||||||
function RadioGroupeOnOff({value, onChange, name, text}) {
|
|
||||||
return <div className="btn-group input-group mb-3 justify-content-md-center" role="group"
|
|
||||||
aria-label="Basic radio toggle button group">
|
|
||||||
<span className="input-group-text">{text}</span>
|
|
||||||
<input type="radio" className="btn-check" id={"btnradio1" + name} autoComplete="off"
|
|
||||||
value="false" checked={value === false} onChange={onChange}/>
|
|
||||||
<label className="btn btn-outline-primary" htmlFor={"btnradio1" + name}>Non</label>
|
|
||||||
<input type="radio" className="btn-check" name={name} id={"btnradio2" + name} autoComplete="off"
|
|
||||||
value="true" checked={value === true} onChange={onChange}/>
|
|
||||||
<label className="btn btn-outline-primary" htmlFor={"btnradio2" + name}>Oui</label>
|
|
||||||
</div>;
|
|
||||||
}
|
|
||||||
@ -52,11 +52,11 @@ export function ClubPage() {
|
|||||||
<LoadingProvider><AffiliationCard clubData={data}/></LoadingProvider>
|
<LoadingProvider><AffiliationCard clubData={data}/></LoadingProvider>
|
||||||
<div className="col" style={{textAlign: 'right', marginTop: '1em'}}>
|
<div className="col" style={{textAlign: 'right', marginTop: '1em'}}>
|
||||||
<button className="btn btn-danger btn-sm" data-bs-toggle="modal"
|
<button className="btn btn-danger btn-sm" data-bs-toggle="modal"
|
||||||
data-bs-target="#confirm-delete">Supprimer le compte
|
data-bs-target="#confirm-delete">Supprimer le club
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ConfirmDialog title="Supprimer le compte"
|
<ConfirmDialog title="Supprimer le club"
|
||||||
message="Êtes-vous sûr de vouloir supprimer ce compte ?"
|
message="Êtes-vous sûr de vouloir supprimer ce club ?"
|
||||||
onConfirm={handleRm}/>
|
onConfirm={handleRm}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user