feat: affiliation request list
This commit is contained in:
parent
dae32e3607
commit
2737e53de5
@ -48,6 +48,10 @@ public class AffiliationService {
|
|||||||
@ConfigProperty(name = "upload_dir")
|
@ConfigProperty(name = "upload_dir")
|
||||||
String media;
|
String media;
|
||||||
|
|
||||||
|
public Uni<List<AffiliationRequestModel>> getAllReq() {
|
||||||
|
return repositoryRequest.listAll();
|
||||||
|
}
|
||||||
|
|
||||||
public Uni<String> save(AffiliationRequestForm form) {
|
public Uni<String> save(AffiliationRequestForm form) {
|
||||||
AffiliationRequestModel affModel = form.toModel();
|
AffiliationRequestModel affModel = form.toModel();
|
||||||
affModel.setSaison(Utils.getSaison());
|
affModel.setSaison(Utils.getSaison());
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package fr.titionfire.ffsaf.rest;
|
|||||||
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.data.SimpleReqAffiliation;
|
import fr.titionfire.ffsaf.rest.data.SimpleReqAffiliation;
|
||||||
|
import fr.titionfire.ffsaf.rest.data.SimpleReqAffiliationResume;
|
||||||
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
||||||
import fr.titionfire.ffsaf.rest.from.AffiliationRequestSaveForm;
|
import fr.titionfire.ffsaf.rest.from.AffiliationRequestSaveForm;
|
||||||
import fr.titionfire.ffsaf.utils.GroupeUtils;
|
import fr.titionfire.ffsaf.utils.GroupeUtils;
|
||||||
@ -44,6 +45,22 @@ public class AffiliationEndpoints {
|
|||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/request")
|
||||||
|
@RolesAllowed({"federation_admin"})
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Uni<List<SimpleReqAffiliationResume>> getAllAffRequest() {
|
||||||
|
return service.getAllReq().map(o -> o.stream().map(SimpleReqAffiliationResume::fromModel).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/request")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
public Uni<String> saveAffRequest(AffiliationRequestForm form) {
|
||||||
|
return service.save(form);
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/request/{id}")
|
@Path("/request/{id}")
|
||||||
@RolesAllowed({"federation_admin"})
|
@RolesAllowed({"federation_admin"})
|
||||||
@ -78,20 +95,12 @@ public class AffiliationEndpoints {
|
|||||||
return service.accept(form);
|
return service.accept(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("/request")
|
|
||||||
@Produces(MediaType.TEXT_PLAIN)
|
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
|
||||||
public Uni<String> saveAffRequest(AffiliationRequestForm form) {
|
|
||||||
return service.save(form);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/current")
|
@Path("/current")
|
||||||
@RolesAllowed({"federation_admin"})
|
@RolesAllowed({"federation_admin"})
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Uni<List<SimpleAffiliation>> getCurrentSaisonLicenceAdmin() {
|
public Uni<List<SimpleAffiliation>> getCurrentSaisonAffiliationAdmin() {
|
||||||
return service.getCurrentSaisonAffiliation();
|
return service.getCurrentSaisonAffiliation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +108,7 @@ public class AffiliationEndpoints {
|
|||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@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>> getAffiliation(@PathParam("id") long id) {
|
||||||
return Uni.createFrom().item(id).invoke(checkPerm).chain(__ -> service.getAffiliation(id));
|
return Uni.createFrom().item(id).invoke(checkPerm).chain(__ -> service.getAffiliation(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +116,7 @@ public class AffiliationEndpoints {
|
|||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@RolesAllowed("federation_admin")
|
@RolesAllowed("federation_admin")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Uni<SimpleAffiliation> setLicence(@PathParam("id") long id, @QueryParam("saison") int saison) {
|
public Uni<SimpleAffiliation> setAffiliation(@PathParam("id") long id, @QueryParam("saison") int saison) {
|
||||||
return service.setAffiliation(id, saison);
|
return service.setAffiliation(id, saison);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +124,7 @@ public class AffiliationEndpoints {
|
|||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@RolesAllowed("federation_admin")
|
@RolesAllowed("federation_admin")
|
||||||
@Produces(MediaType.TEXT_PLAIN)
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
public Uni<?> deleteLicence(@PathParam("id") long id) {
|
public Uni<?> deleteAffiliation(@PathParam("id") long id) {
|
||||||
return service.deleteAffiliation(id);
|
return service.deleteAffiliation(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
package fr.titionfire.ffsaf.rest.data;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.AffiliationRequestModel;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
public class SimpleReqAffiliationResume {
|
||||||
|
Long id;
|
||||||
|
String name;
|
||||||
|
long siret;
|
||||||
|
int saison;
|
||||||
|
|
||||||
|
public static SimpleReqAffiliationResume fromModel(AffiliationRequestModel model) {
|
||||||
|
if (model == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new SimpleReqAffiliationResume.SimpleReqAffiliationResumeBuilder()
|
||||||
|
.id(model.getId())
|
||||||
|
.name(model.getName())
|
||||||
|
.siret(model.getSiret())
|
||||||
|
.saison(model.getSaison())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,6 +8,7 @@ import {ClubList} from "./club/ClubList.jsx";
|
|||||||
import {AffiliationReqPage} from "./affiliation/AffiliationReqPage.jsx";
|
import {AffiliationReqPage} from "./affiliation/AffiliationReqPage.jsx";
|
||||||
import {NewClubPage} from "./club/NewClubPage.jsx";
|
import {NewClubPage} from "./club/NewClubPage.jsx";
|
||||||
import {ClubPage} from "./club/ClubPage.jsx";
|
import {ClubPage} from "./club/ClubPage.jsx";
|
||||||
|
import {AffiliationReqList} from "./affiliation/AffiliationReqList.jsx";
|
||||||
|
|
||||||
export function AdminRoot() {
|
export function AdminRoot() {
|
||||||
return <>
|
return <>
|
||||||
@ -44,6 +45,10 @@ export function getAdminChildren() {
|
|||||||
path: 'affiliation/request/:id',
|
path: 'affiliation/request/:id',
|
||||||
element: <AffiliationReqPage/>
|
element: <AffiliationReqPage/>
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'affiliation/request',
|
||||||
|
element: <AffiliationReqList/>
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'club/new',
|
path: 'club/new',
|
||||||
element: <NewClubPage/>
|
element: <NewClubPage/>
|
||||||
|
|||||||
@ -0,0 +1,107 @@
|
|||||||
|
import {AxiosError} from "../../../components/AxiosError.jsx";
|
||||||
|
import {useNavigate} from "react-router-dom";
|
||||||
|
import {useLoadingSwitcher} from "../../../hooks/useLoading.jsx";
|
||||||
|
import {useFetch} from "../../../hooks/useFetch.js";
|
||||||
|
import {ThreeDots} from "react-loader-spinner";
|
||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {Checkbox} from "../../../components/MemberCustomFiels.jsx";
|
||||||
|
|
||||||
|
export function AffiliationReqList() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const setLoading = useLoadingSwitcher()
|
||||||
|
const {data, refresh, error} = useFetch(`/affiliation/request`, setLoading, 1)
|
||||||
|
|
||||||
|
const [saisonFilter, setSaisonFilter] = useState(null)
|
||||||
|
const visibleRequest = (data == null) ? [] : data.filter(e => !(saisonFilter && e.saison !== saisonFilter)).sort((a, b) => {
|
||||||
|
if (a.saison > b.saison) return 1
|
||||||
|
if (a.saison < b.saison) return -1
|
||||||
|
if (a.name.toLowerCase() > b.name.toLowerCase()) return 1
|
||||||
|
if (a.name.toLowerCase() < b.name.toLowerCase()) return -1
|
||||||
|
return 0
|
||||||
|
});
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<h2>Demande d'affiliation</h2>
|
||||||
|
<button type="button" className="btn btn-link" onClick={() => navigate("/admin/club")}>
|
||||||
|
« retour
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-lg-9">
|
||||||
|
{data
|
||||||
|
? <MakeCentralPanel data={data} visibleRequest={visibleRequest} navigate={navigate}/>
|
||||||
|
: error
|
||||||
|
? <AxiosError error={error}/>
|
||||||
|
: <Def/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-3">
|
||||||
|
<div className="card mb-4">
|
||||||
|
<div className="card-header">Filtre</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<FiltreBar data={data} saisonFilter={saisonFilter} setSaisonFilter={setSaisonFilter}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
function MakeCentralPanel({data, visibleRequest, navigate}) {
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<div className="mb-4">
|
||||||
|
<small>{visibleRequest.length} ligne(s) affichée(s) sur {data.length}</small>
|
||||||
|
<div className="list-group">
|
||||||
|
{visibleRequest.map(req => (<MakeRow key={req.id} request={req} navigate={navigate}/>))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
function MakeRow({request, navigate}) {
|
||||||
|
return <div className="list-group-item d-flex justify-content-between align-items-start list-group-item-action"
|
||||||
|
onClick={() => navigate("" + request.id)}>
|
||||||
|
<div className="ms-2 col-auto">
|
||||||
|
<div className="fw-bold">{request.name}</div>
|
||||||
|
</div>
|
||||||
|
<small style={{textAlign: 'right'}}>{request.saison}-{request.saison + 1}<br/>{request.siret}</small>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
let allSaison = []
|
||||||
|
|
||||||
|
function FiltreBar({data, saisonFilter, setSaisonFilter}) {
|
||||||
|
useEffect(() => {
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
allSaison.push(...data.map((e) => e.saison))
|
||||||
|
allSaison = allSaison.filter((value, index, self) => self.indexOf(value) === index).filter(value => value != null).sort()
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
return <div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<select className="form-select" value={String(saisonFilter)} onChange={event => setSaisonFilter(Number(event.target.value))}>
|
||||||
|
<option value="">--- tout les saisons ---</option>
|
||||||
|
{allSaison && allSaison.map((value, index) => {
|
||||||
|
return <option key={index} value={value}>{value}-{value+1}</option>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Def() {
|
||||||
|
return <div className="list-group">
|
||||||
|
<li className="list-group-item"><ThreeDots/></li>
|
||||||
|
<li className="list-group-item"><ThreeDots/></li>
|
||||||
|
<li className="list-group-item"><ThreeDots/></li>
|
||||||
|
<li className="list-group-item"><ThreeDots/></li>
|
||||||
|
<li className="list-group-item"><ThreeDots/></li>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@ -21,7 +21,7 @@ export function AffiliationReqPage() {
|
|||||||
|
|
||||||
return <>
|
return <>
|
||||||
<h2>Demande d'affiliation</h2>
|
<h2>Demande d'affiliation</h2>
|
||||||
<button type="button" className="btn btn-link" onClick={() => navigate("/admin/affiliation")}>
|
<button type="button" className="btn btn-link" onClick={() => navigate("/admin/affiliation/request")}>
|
||||||
« retour
|
« retour
|
||||||
</button>
|
</button>
|
||||||
<div>
|
<div>
|
||||||
@ -47,7 +47,7 @@ function Content({data, refresh}) {
|
|||||||
error: "Échec de la suppression de la demande d'affiliation 😕"
|
error: "Échec de la suppression de la demande d'affiliation 😕"
|
||||||
}
|
}
|
||||||
).then(_ => {
|
).then(_ => {
|
||||||
navigate("/admin/affiliation")
|
navigate("/admin/affiliation/request")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ function Content({data, refresh}) {
|
|||||||
error: "Échec de l'acceptation de l'affiliation 😕"
|
error: "Échec de l'acceptation de l'affiliation 😕"
|
||||||
}
|
}
|
||||||
).then(_ => {
|
).then(_ => {
|
||||||
navigate("/admin/affiliation")
|
navigate("/admin/affiliation/request")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user