dev #105

Merged
Thibaut merged 8 commits from dev into master 2026-01-23 15:49:25 +00:00
12 changed files with 142 additions and 35 deletions
Showing only changes of commit 4a07eb4ed9 - Show all commits

View File

@ -44,6 +44,7 @@ public class CompetitionGuestModel implements CombModel {
String country = "fr"; String country = "fr";
Integer weight = null; Integer weight = null;
Integer weightReal = null;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinTable( @JoinTable(
@ -107,4 +108,8 @@ public class CompetitionGuestModel implements CombModel {
} }
return Stream.concat(comb.stream(), guest.stream()).anyMatch(c -> Objects.equals(c, comb_)); return Stream.concat(comb.stream(), guest.stream()).anyMatch(c -> Objects.equals(c, comb_));
} }
public Integer getWeight2() {
return (this.weightReal != null) ? this.weightReal : this.weight;
}
} }

View File

@ -1,5 +1,6 @@
package fr.titionfire.ffsaf.data.model; package fr.titionfire.ffsaf.data.model;
import fr.titionfire.ffsaf.utils.Categorie;
import fr.titionfire.ffsaf.utils.CompetitionSystem; import fr.titionfire.ffsaf.utils.CompetitionSystem;
import fr.titionfire.ffsaf.utils.RegisterMode; import fr.titionfire.ffsaf.utils.RegisterMode;
import io.quarkus.runtime.annotations.RegisterForReflection; import io.quarkus.runtime.annotations.RegisterForReflection;
@ -61,6 +62,8 @@ public class CompetitionModel {
@OneToMany(mappedBy = "competition", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @OneToMany(mappedBy = "competition", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
List<CatPresetModel> catPreset = new ArrayList<>(); List<CatPresetModel> catPreset = new ArrayList<>();
List<Categorie> requiredWeight = new ArrayList<>();
List<Long> banMembre = new ArrayList<>(); List<Long> banMembre = new ArrayList<>();
String owner; String owner;

View File

@ -38,6 +38,7 @@ public class RegisterModel {
MembreModel membre; MembreModel membre;
Integer weight; Integer weight;
Integer weightReal;
int overCategory = 0; int overCategory = 0;
Categorie categorie; Categorie categorie;
@ -89,4 +90,10 @@ public class RegisterModel {
return null; return null;
return Categorie.values()[Math.min(tmp.ordinal() + this.overCategory, Categorie.values().length - 1)]; return Categorie.values()[Math.min(tmp.ordinal() + this.overCategory, Categorie.values().length - 1)];
} }
public Integer getWeight2() {
if (weightReal != null)
return weightReal;
return weight;
}
} }

View File

@ -301,6 +301,7 @@ public class CompetitionService {
model.setStartRegister(data.getStartRegister()); model.setStartRegister(data.getStartRegister());
model.setEndRegister(data.getEndRegister()); model.setEndRegister(data.getEndRegister());
model.setRegisterMode(data.getRegisterMode()); model.setRegisterMode(data.getRegisterMode());
model.setRequiredWeight(data.getRequiredWeight());
model.setData1(data.getData1()); model.setData1(data.getData1());
model.setData2(data.getData2()); model.setData2(data.getData2());
model.setData3(data.getData3()); model.setData3(data.getData3());
@ -388,7 +389,9 @@ public class CompetitionService {
model.setGenre(data.getGenre()); model.setGenre(data.getGenre());
model.setClub(data.getClub()); model.setClub(data.getClub());
model.setCountry(data.getCountry()); model.setCountry(data.getCountry());
model.setWeight(data.getWeight()); model.setWeightReal(data.getWeightReal());
if (model.getCompetition().getRequiredWeight().contains(model.getCategorie()))
model.setWeight(data.getWeight());
model.setCategorie(data.getCategorie()); model.setCategorie(data.getCategorie());
}) })
.call(g -> Mutiny.fetch(g.getCategoriesInscrites())) .call(g -> Mutiny.fetch(g.getCategoriesInscrites()))
@ -452,7 +455,6 @@ public class CompetitionService {
if (r != null) { if (r != null) {
if (!admin && r.isLockEdit()) if (!admin && r.isLockEdit())
throw new DForbiddenException(trad.t("insc.err3")); throw new DForbiddenException(trad.t("insc.err3"));
r.setWeight(data.getWeight());
r.setOverCategory(data.getOverCategory()); r.setOverCategory(data.getOverCategory());
r.setCategorie( r.setCategorie(
(combModel.getBirth_date() == null) ? combModel.getCategorie() : (combModel.getBirth_date() == null) ? combModel.getCategorie() :
@ -461,24 +463,29 @@ public class CompetitionService {
int days = Utils.getDaysBeforeCompetition(c.getDate()); int days = Utils.getDaysBeforeCompetition(c.getDate());
if (days > -7) if (days > -7)
r.setClub(combModel.getClub()); r.setClub(combModel.getClub());
if (admin) if (c.getRequiredWeight().contains(r.getCategorie2()))
r.setWeight(data.getWeight());
if (admin) {
r.setWeightReal(data.getWeightReal());
r.setLockEdit(data.isLockEdit()); r.setLockEdit(data.isLockEdit());
}
} else { } else {
r = new RegisterModel(c, combModel, data.getWeight(), data.getOverCategory(), r = new RegisterModel(c, combModel, data.getWeight(), data.getOverCategory(),
(combModel.getBirth_date() == null) ? combModel.getCategorie() : (combModel.getBirth_date() == null) ? combModel.getCategorie() :
Utils.getCategoryFormBirthDate(combModel.getBirth_date(), Utils.getCategoryFormBirthDate(combModel.getBirth_date(),
c.getDate()), c.getDate()),
(combModel.getClub() == null) ? null : combModel.getClub()); (combModel.getClub() == null) ? null : combModel.getClub());
if (admin) if (admin) {
r.setWeightReal(data.getWeightReal());
r.setLockEdit(data.isLockEdit()); r.setLockEdit(data.isLockEdit());
else } else
r.setLockEdit(false); r.setLockEdit(false);
} }
if (c.getSystem() == CompetitionSystem.SAFCA) { if (c.getSystem() == CompetitionSystem.SAFCA) {
SReqRegister.sendIfNeed(serverCustom.clients, SReqRegister.sendIfNeed(serverCustom.clients,
new CompetitionData.SimpleRegister(r.getMembre().getId(), new CompetitionData.SimpleRegister(r.getMembre().getId(),
r.getOverCategory(), r.getWeight(), r.getCategorie(), r.getOverCategory(), r.getWeight2(), r.getCategorie(),
(r.getClub() == null) ? null : r.getClub().getId(), (r.getClub() == null) ? null : r.getClub().getId(),
(r.getClub() == null) ? null : r.getClub().getName()), c.getId()); (r.getClub() == null) ? null : r.getClub().getName()), c.getId());
} }
@ -779,7 +786,7 @@ public class CompetitionService {
public Uni<Response> registerHelloAsso(NotificationData data) { public Uni<Response> registerHelloAsso(NotificationData data) {
String organizationSlug = data.getOrganizationSlug(); String organizationSlug = data.getOrganizationSlug();
String formSlug = data.getFormSlug(); String formSlug = data.getFormSlug();
RegisterRequestData req = new RegisterRequestData(null, "", "", null, 0, false, new ArrayList<>(), null, RegisterRequestData req = new RegisterRequestData(null, "", "", null, null, 0, false, new ArrayList<>(), null,
Categorie.CADET, Genre.NA, null, "fr", false); Categorie.CADET, Genre.NA, null, "fr", false);
return repository.find("data1 = ?1 AND data2 = ?2", organizationSlug, formSlug).firstResult() return repository.find("data1 = ?1 AND data2 = ?2", organizationSlug, formSlug).firstResult()

View File

@ -35,7 +35,7 @@ public class CompetitionData {
private Long club; private Long club;
private String clubName; private String clubName;
private String owner; private String owner;
private List<SimpleRegister> registers; private List<SimpleRegister> registers; // for SAFCA
private boolean canEdit; private boolean canEdit;
private boolean canEditRegisters; private boolean canEditRegisters;
private String data1; private String data1;
@ -44,12 +44,13 @@ public class CompetitionData {
private String data4; private String data4;
private String config; private String config;
private List<PresetData> presets; private List<PresetData> presets;
private List<Categorie> requiredWeight;
public CompetitionData () { public CompetitionData() {
this(null, "", "", "", "", new Date(), new Date(), this(null, "", "", "", "", new Date(), new Date(),
CompetitionSystem.INTERNAL, RegisterMode.FREE, new Date(), new Date(), true, CompetitionSystem.INTERNAL, RegisterMode.FREE, new Date(), new Date(), true,
null, "", "", null, true, true, null, "", "", null, true, true,
"", "", "", "", "{}", new ArrayList<>()); "", "", "", "", "{}", new ArrayList<>(), new ArrayList<>());
} }
public static CompetitionData fromModel(CompetitionModel model) { public static CompetitionData fromModel(CompetitionModel model) {
@ -60,7 +61,8 @@ public class CompetitionData {
model.getUuid(), model.getDate(), model.getTodate(), model.getSystem(), model.getUuid(), model.getDate(), model.getTodate(), model.getSystem(),
model.getRegisterMode(), model.getStartRegister(), model.getEndRegister(), model.isPublicVisible(), model.getRegisterMode(), model.getStartRegister(), model.getEndRegister(), model.isPublicVisible(),
model.getClub().getId(), model.getClub().getName(), model.getOwner(), null, false, false, model.getClub().getId(), model.getClub().getName(), model.getOwner(), null, false, false,
model.getData1(), model.getData2(), model.getData3(), model.getData4(), model.getConfig(), new ArrayList<>()); model.getData1(), model.getData2(), model.getData3(), model.getData4(), model.getConfig(),
new ArrayList<>(), model.getRequiredWeight());
} }
public static CompetitionData fromModelLight(CompetitionModel model) { public static CompetitionData fromModelLight(CompetitionModel model) {
@ -71,7 +73,7 @@ public class CompetitionData {
model.getAdresse(), "", model.getDate(), model.getTodate(), null, model.getAdresse(), "", model.getDate(), model.getTodate(), null,
model.getRegisterMode(), model.getStartRegister(), model.getEndRegister(), model.isPublicVisible(), model.getRegisterMode(), model.getStartRegister(), model.getEndRegister(), model.isPublicVisible(),
null, model.getClub().getName(), "", null, false, false, null, model.getClub().getName(), "", null, false, false,
"", "", "", "", "{}", new ArrayList<>()); "", "", "", "", "{}", new ArrayList<>(), model.getRequiredWeight());
if (model.getRegisterMode() == RegisterMode.HELLOASSO) { if (model.getRegisterMode() == RegisterMode.HELLOASSO) {
out.setData1(model.getData1()); out.setData1(model.getData1());
@ -85,11 +87,11 @@ public class CompetitionData {
public CompetitionData addInsc(List<RegisterModel> insc, List<CompetitionGuestModel> guests) { public CompetitionData addInsc(List<RegisterModel> insc, List<CompetitionGuestModel> guests) {
this.registers = Stream.concat( this.registers = Stream.concat(
insc.stream() insc.stream()
.map(i -> new SimpleRegister(i.getMembre().getId(), i.getOverCategory(), i.getWeight(), .map(i -> new SimpleRegister(i.getMembre().getId(), i.getOverCategory(), i.getWeight2(),
i.getCategorie(), (i.getClub() == null) ? null : i.getClub().getId(), i.getCategorie(), (i.getClub() == null) ? null : i.getClub().getId(),
(i.getClub() == null) ? null : i.getClub().getName())), (i.getClub() == null) ? null : i.getClub().getName())),
guests.stream() guests.stream()
.map(i -> new SimpleRegister(i.getId() * -1, 0, i.getWeight(), .map(i -> new SimpleRegister(i.getId() * -1, 0, i.getWeight2(),
i.getCategorie(), null, i.getClub()))).toList(); i.getCategorie(), null, i.getClub()))).toList();
return this; return this;
} }

View File

@ -19,6 +19,7 @@ public class RegisterRequestData {
private String lname; private String lname;
private Integer weight; private Integer weight;
private Integer weightReal;
private int overCategory; private int overCategory;
private boolean lockEdit = false; private boolean lockEdit = false;
private List<Long> categoriesInscrites; private List<Long> categoriesInscrites;

View File

@ -25,6 +25,7 @@ public class SimpleRegisterComb {
private SimpleClubModel club; private SimpleClubModel club;
private Integer licence; private Integer licence;
private Integer weight; private Integer weight;
private Integer weightReal;
private int overCategory; private int overCategory;
private boolean hasLicenceActive; private boolean hasLicenceActive;
private boolean lockEdit; private boolean lockEdit;
@ -36,7 +37,7 @@ public class SimpleRegisterComb {
membreModel.getGenre(), membreModel.getCountry(), membreModel.getGenre(), membreModel.getCountry(),
(register.getCategorie() == null) ? null : register.getCategorie(), (register.getCategorie() == null) ? null : register.getCategorie(),
SimpleClubModel.fromModel(register.getClub()), membreModel.getLicence(), register.getWeight(), SimpleClubModel.fromModel(register.getClub()), membreModel.getLicence(), register.getWeight(),
register.getOverCategory(), register.getWeightReal(), register.getOverCategory(),
licences.stream().anyMatch(l -> l.isValidate() && l.getSaison() == Utils.getSaison()), licences.stream().anyMatch(l -> l.isValidate() && l.getSaison() == Utils.getSaison()),
register.isLockEdit(), new ArrayList<>()); register.isLockEdit(), new ArrayList<>());
} }
@ -45,7 +46,7 @@ public class SimpleRegisterComb {
return new SimpleRegisterComb(guest.getId() * -1, guest.getFname(), guest.getLname(), return new SimpleRegisterComb(guest.getId() * -1, guest.getFname(), guest.getLname(),
guest.getGenre(), guest.getCountry(), guest.getCategorie(), guest.getGenre(), guest.getCountry(), guest.getCategorie(),
new SimpleClubModel(null, guest.getClub(), "fr", null), new SimpleClubModel(null, guest.getClub(), "fr", null),
null, guest.getWeight(), 0, false, false, null, guest.getWeight(), guest.getWeightReal(), 0, false, false,
new ArrayList<>()); new ArrayList<>());
} }

View File

@ -76,6 +76,7 @@
"aff_req.toast.undo.error": "Failed to cancel affiliation request", "aff_req.toast.undo.error": "Failed to cancel affiliation request",
"aff_req.toast.undo.pending": "Cancelling affiliation request in progress", "aff_req.toast.undo.pending": "Cancelling affiliation request in progress",
"aff_req.toast.undo.success": "Affiliation request cancelled successfully 🎉", "aff_req.toast.undo.success": "Affiliation request cancelled successfully 🎉",
"afficherLesCombattantsNonPesés": "Show unweighed fighters",
"afficherLétatDesAffiliation": "Display affiliation status", "afficherLétatDesAffiliation": "Display affiliation status",
"affiliation": "Affiliation", "affiliation": "Affiliation",
"affiliationNo": "Affiliation no. {{no}}", "affiliationNo": "Affiliation no. {{no}}",
@ -193,7 +194,9 @@
"comp.inscriptionsParLesAdministrateursDeLaCompétition": "Registrations by competition administrators", "comp.inscriptionsParLesAdministrateursDeLaCompétition": "Registrations by competition administrators",
"comp.inscriptionsParLesResponsablesDeClub": "Registrations by club managers", "comp.inscriptionsParLesResponsablesDeClub": "Registrations by club managers",
"comp.inscriptionsSurLaBilletterieHelloasso": "Registrations on the HelloAsso ticketing", "comp.inscriptionsSurLaBilletterieHelloasso": "Registrations on the HelloAsso ticketing",
"comp.modal.annoncé": "Announced",
"comp.modal.information": "Information", "comp.modal.information": "Information",
"comp.modal.pesé": "Weighed",
"comp.modal.poids": "Weight (in kg)", "comp.modal.poids": "Weight (in kg)",
"comp.modal.recherche": "Search*", "comp.modal.recherche": "Search*",
"comp.modal.surclassement": "Overclassification", "comp.modal.surclassement": "Overclassification",
@ -490,6 +493,7 @@
"peutSinscrire": "Can register?", "peutSinscrire": "Can register?",
"photos": "Photos", "photos": "Photos",
"plastron": "Breastplate", "plastron": "Breastplate",
"poidsDemandéPour": "Weight required for",
"prenom": "First name", "prenom": "First name",
"protectionDeBras": "Arm protection", "protectionDeBras": "Arm protection",
"protectionDeBrasArmé": "Protection of armed arm(s)", "protectionDeBrasArmé": "Protection of armed arm(s)",

View File

@ -76,6 +76,7 @@
"aff_req.toast.undo.error": "Échec de l'annulation de la demande d'affiliation", "aff_req.toast.undo.error": "Échec de l'annulation de la demande d'affiliation",
"aff_req.toast.undo.pending": "Annulation de la demande d'affiliation en cours", "aff_req.toast.undo.pending": "Annulation de la demande d'affiliation en cours",
"aff_req.toast.undo.success": "Demande d'affiliation annulée avec succès 🎉", "aff_req.toast.undo.success": "Demande d'affiliation annulée avec succès 🎉",
"afficherLesCombattantsNonPesés": "Afficher les combattants non pesés",
"afficherLétatDesAffiliation": "Afficher l'état des affiliation", "afficherLétatDesAffiliation": "Afficher l'état des affiliation",
"affiliation": "Affiliation", "affiliation": "Affiliation",
"affiliationNo": "Affiliation n°{{no}}", "affiliationNo": "Affiliation n°{{no}}",
@ -193,7 +194,9 @@
"comp.inscriptionsParLesAdministrateursDeLaCompétition": "Inscriptions par les administrateurs de la compétition", "comp.inscriptionsParLesAdministrateursDeLaCompétition": "Inscriptions par les administrateurs de la compétition",
"comp.inscriptionsParLesResponsablesDeClub": "Inscriptions par les responsables de club", "comp.inscriptionsParLesResponsablesDeClub": "Inscriptions par les responsables de club",
"comp.inscriptionsSurLaBilletterieHelloasso": "Inscriptions sur la billetterie HelloAsso", "comp.inscriptionsSurLaBilletterieHelloasso": "Inscriptions sur la billetterie HelloAsso",
"comp.modal.annoncé": "Annoncé",
"comp.modal.information": "Information", "comp.modal.information": "Information",
"comp.modal.pesé": "Pesé",
"comp.modal.poids": "Poids (en kg)", "comp.modal.poids": "Poids (en kg)",
"comp.modal.recherche": "Recherche*", "comp.modal.recherche": "Recherche*",
"comp.modal.surclassement": "Surclassement", "comp.modal.surclassement": "Surclassement",
@ -490,6 +493,7 @@
"peutSinscrire": "Peut s'inscrire?", "peutSinscrire": "Peut s'inscrire?",
"photos": "Photos", "photos": "Photos",
"plastron": "Plastron", "plastron": "Plastron",
"poidsDemandéPour": "Poids demandé pour",
"prenom": "Prénom", "prenom": "Prénom",
"protectionDeBras": "Protection de bras", "protectionDeBras": "Protection de bras",
"protectionDeBrasArmé": "Protection de bras armé(s)", "protectionDeBrasArmé": "Protection de bras armé(s)",

View File

@ -56,7 +56,7 @@ export function CompetitionEdit() {
<Content data={data} refresh={refresh}/> <Content data={data} refresh={refresh}/>
{data.id !== null && <button style={{marginBottom: "1.5em", width: "100%"}} className="btn btn-primary" {data.id !== null && <button style={{marginBottom: "1.5em", width: "100%"}} className="btn btn-primary"
onClick={_ => navigate(`/competition/${data.id}/register?type=${data.registerMode}`)}> onClick={_ => navigate(`/competition/${data.id}/register`)}>
{t('comp.modifierLesParticipants')}</button>} {t('comp.modifierLesParticipants')}</button>}
{data.id !== null && (data.system === "SAFCA" || data.system === "INTERNAL") && {data.id !== null && (data.system === "SAFCA" || data.system === "INTERNAL") &&
@ -219,9 +219,21 @@ function Content({data}) {
const [registerMode, setRegisterMode] = useState(data.registerMode || "FREE"); const [registerMode, setRegisterMode] = useState(data.registerMode || "FREE");
const [modaleState, setModaleState] = useState({}) const [modaleState, setModaleState] = useState({})
const [presets, setPresets] = useState(data.presets || []); const [presets, setPresets] = useState(data.presets || []);
const [cats, setCats] = useState(data.requiredWeight || [])
const [presetChange, setPresetChange] = useState(false) const [presetChange, setPresetChange] = useState(false)
const {t} = useTranslation(); const {t} = useTranslation();
const setCat = (e, cat) => {
if (e.target.checked) {
if (!cats.includes(cat)) {
setCats([...cats, cat])
}
} else {
setCats(cats.filter(c => c !== cat))
}
}
const isCatSelected = (cat) => cats.includes(cat)
const handleSubmit = (event) => { const handleSubmit = (event) => {
event.preventDefault(); event.preventDefault();
@ -243,6 +255,7 @@ function Content({data}) {
out['endRegister'] = event.target.endRegister?.value out['endRegister'] = event.target.endRegister?.value
out['registerMode'] = registerMode out['registerMode'] = registerMode
out['presets'] = presets out['presets'] = presets
out['requiredWeight'] = cats
if (out['registerMode'] === "HELLOASSO") { if (out['registerMode'] === "HELLOASSO") {
out['data3'] = event.target.data3?.value out['data3'] = event.target.data3?.value
@ -444,6 +457,16 @@ function Content({data}) {
defaultValue={data.endRegister ? data.endRegister.substring(0, 16) : ''}/> defaultValue={data.endRegister ? data.endRegister.substring(0, 16) : ''}/>
</div> </div>
<div className="input-group mb-3"
style={{display: registerMode === "FREE" || registerMode === "CLUB_ADMIN" ? "flex" : "none"}}>
<span className="input-group-text" id="startRegister">{t('poidsDemandéPour')}</span>
{CatList.map((cat, index) => <div key={index} className="input-group-text">
<input className="form-check-input mt-0" type="checkbox" id={"catInput" + index} checked={isCatSelected(cat)}
aria-label={getCatName(cat)} onChange={e => setCat(e, cat)}/>
<label style={{marginLeft: "0.5em"}} htmlFor={"catInput" + index}>{getCatName(cat)}</label>
</div>)}
</div>
<div style={{display: registerMode === "HELLOASSO" ? "initial" : "none"}}> <div style={{display: registerMode === "HELLOASSO" ? "initial" : "none"}}>
<span style={{textAlign: "left"}}> <span style={{textAlign: "left"}}>
<div>{t('comp.ha.text1')}</div> <div>{t('comp.ha.text1')}</div>

View File

@ -1,4 +1,4 @@
import {useNavigate, useParams, useSearchParams} from "react-router-dom"; import {useNavigate, useParams} from "react-router-dom";
import {LoadingProvider, useLoadingSwitcher} from "../../hooks/useLoading.jsx"; import {LoadingProvider, useLoadingSwitcher} from "../../hooks/useLoading.jsx";
import {useFetch} from "../../hooks/useFetch.js"; import {useFetch} from "../../hooks/useFetch.js";
import {AxiosError} from "../../components/AxiosError.jsx"; import {AxiosError} from "../../components/AxiosError.jsx";
@ -13,6 +13,7 @@ import "./CompetitionRegisterAdmin.css"
import * as XLSX from "xlsx-js-style"; import * as XLSX from "xlsx-js-style";
import {useCountries} from "../../hooks/useCountries.jsx"; import {useCountries} from "../../hooks/useCountries.jsx";
import {Trans, useTranslation} from "react-i18next"; import {Trans, useTranslation} from "react-i18next";
import {Checkbox} from "../../components/MemberCustomFiels.jsx";
export function CompetitionRegisterAdmin({source}) { export function CompetitionRegisterAdmin({source}) {
const {id} = useParams() const {id} = useParams()
@ -21,12 +22,14 @@ export function CompetitionRegisterAdmin({source}) {
const [clubFilter, setClubFilter] = useState("") const [clubFilter, setClubFilter] = useState("")
const [catAgeFilter, setCatAgeFilter] = useState("") const [catAgeFilter, setCatAgeFilter] = useState("")
const [catFilter, setCatFilter] = useState(-1) const [catFilter, setCatFilter] = useState(-1)
const [filterNotWeight, setFilterNotWeight] = useState(false)
const [modalState, setModalState] = useState({}) const [modalState, setModalState] = useState({})
const {t} = useTranslation(); const {t} = useTranslation();
const setLoading = useLoadingSwitcher() const setLoading = useLoadingSwitcher()
const {data, error} = useFetch(`/competition/${id}/register/${source}`, setLoading, 1) const {data, error} = useFetch(`/competition/${id}/register/${source}`, setLoading, 1)
const {data: data2, error: error2} = useFetch(`/competition/${id}/categories`, setLoading, 1) const {data: data2, error: error2} = useFetch(`/competition/${id}/categories`, setLoading, 1)
const {data: data3} = useFetch(`/competition/${id}?light=true`, setLoading, 1)
const sortName = (a, b) => { const sortName = (a, b) => {
if (a.data.fname === b.data.fname) return a.data.lname.localeCompare(b.data.lname); if (a.data.fname === b.data.fname) return a.data.lname.localeCompare(b.data.lname);
@ -66,8 +69,13 @@ export function CompetitionRegisterAdmin({source}) {
<MakeCentralPanel <MakeCentralPanel
data={state.filter(s => (clubFilter.length === 0 || s.data.club.name === clubFilter) data={state.filter(s => (clubFilter.length === 0 || s.data.club.name === clubFilter)
&& (catAgeFilter.length === 0 || s.data.categorie === catAgeFilter) && (catAgeFilter.length === 0 || s.data.categorie === catAgeFilter)
&& (catFilter === -1 || s.data.categoriesInscrites.includes(catFilter)))} && (catFilter === -1 || s.data.categoriesInscrites.includes(catFilter))
data2={data2} dispatch={dispatch} id={id} setModalState={setModalState} source={source}/> && (!filterNotWeight || (data3?.requiredWeight.includes(s.data.categorie) && (
(source === "admin" && (s.data.weightReal === "" || s.data.weightReal === null)) ||
(source !== "admin" && (s.data.weight === "" || s.data.weight === null))
)))
)}
data2={data2} data3={data3} dispatch={dispatch} id={id} setModalState={setModalState} source={source}/>
</div> : error ? <AxiosError error={error}/> : <Def/>} </div> : error ? <AxiosError error={error}/> : <Def/>}
</div> </div>
<div className="col-lg-3"> <div className="col-lg-3">
@ -86,14 +94,16 @@ export function CompetitionRegisterAdmin({source}) {
<div className="card-header">{t('filtre')}</div> <div className="card-header">{t('filtre')}</div>
<div className="card-body"> <div className="card-body">
<FiltreBar data={data} data2={data2} clubFilter={clubFilter} setClubFilter={setClubFilter} catFilter={catFilter} <FiltreBar data={data} data2={data2} clubFilter={clubFilter} setClubFilter={setClubFilter} catFilter={catFilter}
setCatFilter={setCatFilter} catAgeFilter={catAgeFilter} setCatAgeFilter={setCatAgeFilter} source={source}/> setCatFilter={setCatFilter} catAgeFilter={catAgeFilter} setCatAgeFilter={setCatAgeFilter}
filterNotWeight={filterNotWeight} setFilterNotWeight={setFilterNotWeight} source={source}/>
</div> </div>
</div> </div>
{source === "admin" && <FileOutput data={data}/>} {source === "admin" && <FileOutput data={data}/>}
</div> </div>
</div> </div>
<Modal data2={data2} error2={error2} sendRegister={sendRegister} modalState={modalState} setModalState={setModalState} source={source}/> <Modal data2={data2} error2={error2} data3={data3} sendRegister={sendRegister} modalState={modalState} setModalState={setModalState}
source={source}/>
</div> </div>
} }
@ -336,7 +346,7 @@ function CategoriesList({error2, availableCats, fistCatInput, categories, setCat
</> </>
} }
function Modal({data2, error2, sendRegister, modalState, setModalState, source}) { function Modal({data2, data3, error2, sendRegister, modalState, setModalState, source}) {
const country = useCountries('fr') const country = useCountries('fr')
const {t} = useTranslation(); const {t} = useTranslation();
const closeBtn = useRef(null); const closeBtn = useRef(null);
@ -349,6 +359,7 @@ function Modal({data2, error2, sendRegister, modalState, setModalState, source})
const [fname, setFname] = useState("") const [fname, setFname] = useState("")
const [lname, setLname] = useState("") const [lname, setLname] = useState("")
const [weight, setWeight] = useState("") const [weight, setWeight] = useState("")
const [weightReal, setWeightReal] = useState("")
const [cat, setCat] = useState(0) const [cat, setCat] = useState(0)
const [gcat, setGCat] = useState("") const [gcat, setGCat] = useState("")
const [club, setClub] = useState("") const [club, setClub] = useState("")
@ -363,6 +374,7 @@ function Modal({data2, error2, sendRegister, modalState, setModalState, source})
setFname(modalState?.fname ? modalState.fname : "") setFname(modalState?.fname ? modalState.fname : "")
setLname(modalState?.lname ? modalState.lname : "") setLname(modalState?.lname ? modalState.lname : "")
setWeight(modalState?.weight ? modalState.weight : "") setWeight(modalState?.weight ? modalState.weight : "")
setWeightReal(modalState?.weightReal ? modalState.weightReal : "")
setCat(modalState?.overCategory ? modalState.overCategory : 0) setCat(modalState?.overCategory ? modalState.overCategory : 0)
setEditMode(modalState?.licence || (modalState.fname && modalState.lname)) setEditMode(modalState?.licence || (modalState.fname && modalState.lname))
setLockEdit(modalState?.lockEdit === undefined ? false : modalState.lockEdit) setLockEdit(modalState?.lockEdit === undefined ? false : modalState.lockEdit)
@ -398,6 +410,7 @@ function Modal({data2, error2, sendRegister, modalState, setModalState, source})
fname: fname.trim(), fname: fname.trim(),
lname: lname.trim(), lname: lname.trim(),
weight: weight, weight: weight,
weightReal: weightReal,
overCategory: cat, overCategory: cat,
lockEdit: lockEdit, lockEdit: lockEdit,
categoriesInscrites: categories, categoriesInscrites: categories,
@ -517,8 +530,14 @@ function Modal({data2, error2, sendRegister, modalState, setModalState, source})
<div className="input-group mb-3"> <div className="input-group mb-3">
<span className="input-group-text" id="weight">{t('comp.modal.poids')}</span> <span className="input-group-text" id="weight">{t('comp.modal.poids')}</span>
<input type="number" min={1} step={1} className="form-control" placeholder="42" aria-label="weight" {source === "admin" && <span className="input-group-text" id="weightReal">{t('comp.modal.annoncé')}</span>}
name="weight" aria-describedby="weight" value={weight} onChange={e => setWeight(e.target.value)}/> <input type="number" min={1} step={1} className="form-control" placeholder="--" aria-label="weight"
name="weight" aria-describedby="weight" disabled={!(data3.requiredWeight.includes(currenCat))} value={weight}
onChange={e => setWeight(e.target.value)}/>
{source === "admin" && <><span className="input-group-text" id="weightReal">{t('comp.modal.pesé')}</span>
<input type="number" min={1} step={1} className="form-control" placeholder="--" aria-label="weightReal"
name="weightReal" aria-describedby="weightReal" value={weightReal}
onChange={e => setWeightReal(e.target.value)}/></>}
</div> </div>
<div className="input-group mb-3" hidden={modalState.id < 0}> <div className="input-group mb-3" hidden={modalState.id < 0}>
@ -558,7 +577,19 @@ function Modal({data2, error2, sendRegister, modalState, setModalState, source})
let allClub = [] let allClub = []
function FiltreBar({data, data2, clubFilter, setClubFilter, catFilter, setCatFilter, catAgeFilter, setCatAgeFilter, source}) { function FiltreBar({
data,
data2,
clubFilter,
setClubFilter,
catFilter,
setCatFilter,
catAgeFilter,
setCatAgeFilter,
filterNotWeight,
setFilterNotWeight,
source
}) {
const {t} = useTranslation(); const {t} = useTranslation();
useEffect(() => { useEffect(() => {
if (!data) return; if (!data) return;
@ -567,6 +598,10 @@ function FiltreBar({data, data2, clubFilter, setClubFilter, catFilter, setCatFil
}, [data]); }, [data]);
return <div> return <div>
<div className="mb-3">
<Checkbox value={filterNotWeight} onChange={setFilterNotWeight} name="checkbox2" label={t('afficherLesCombattantsNonPesés')}/>
</div>
{source === "admin" && <div className="mb-3"> {source === "admin" && <div className="mb-3">
<select className="form-select" value={clubFilter} onChange={event => setClubFilter(event.target.value)}> <select className="form-select" value={clubFilter} onChange={event => setClubFilter(event.target.value)}>
<option value="">{t('---ToutLesClubs---')}</option> <option value="">{t('---ToutLesClubs---')}</option>
@ -592,9 +627,8 @@ function FiltreBar({data, data2, clubFilter, setClubFilter, catFilter, setCatFil
</div> </div>
} }
function MakeCentralPanel({data, data2, dispatch, id, setModalState, source}) { function MakeCentralPanel({data, data2, data3, dispatch, id, setModalState, source}) {
const [searchParams] = useSearchParams(); const registerType = data3?.registerMode || "FREE";
const registerType = searchParams.get("type") || "FREE";
const {t} = useTranslation(); const {t} = useTranslation();
return <> return <>
@ -622,7 +656,13 @@ function MakeCentralPanel({data, data2, dispatch, id, setModalState, source}) {
<small>{t("comp.surclassement", { <small>{t("comp.surclassement", {
count: req.data.overCategory, count: req.data.overCategory,
cat: getCatName(req.data.categorie) cat: getCatName(req.data.categorie)
})} | {req.data.weight ? req.data.weight : "---"} kg</small> })} {source !== "admin" && data3?.requiredWeight.includes(applyOverCategory(req.data.categorie, req.data.weight)) && <>
| {req.data.weight ? req.data.weight : "---"} kg
</>}
{source === "admin" && (data3?.requiredWeight.includes(applyOverCategory(req.data.categorie, req.data.overCategory)) || req.data.weightReal) && <>
| {req.data.weightReal ? <span style={{color: "#3cbc02"}}>{req.data.weightReal} kg</span> :
(req.data.weight ? <span style={{color: "#e40101"}}>{req.data.weight} kg</span> : "--- kg")}
</>}</small>
<br/> <br/>
<small> <small>
{req.data.categoriesInscrites.map(catId => data2?.find(c => c.id === catId)).filter(o => o !== undefined) {req.data.categoriesInscrites.map(catId => data2?.find(c => c.id === catId)).filter(o => o !== undefined)

View File

@ -75,7 +75,7 @@ function MakeContent({data}) {
onClick={_ => navigate("/competition/" + data.id + "/club/register")}>{t('comp.inscription')}</button> onClick={_ => navigate("/competition/" + data.id + "/club/register")}>{t('comp.inscription')}</button>
} }
{data.registerMode === "FREE" && !isClubAdmin(userinfo) && <SelfRegister data2={data}/> {data.registerMode === "FREE" && !isClubAdmin(userinfo) && <SelfRegister data2={data}/>
|| <ShowRegister/> || <ShowRegister data2={data}/>
} }
{data.registerMode === "HELLOASSO" && {data.registerMode === "HELLOASSO" &&
<p><strong>{t('comp.billetterie')} :</strong> <a <p><strong>{t('comp.billetterie')} :</strong> <a
@ -154,10 +154,16 @@ function SelfRegister({data2}) {
? data.length > 0 ? data.length > 0
? <div style={{textAlign: "right", maxWidth: "30em"}}> ? <div style={{textAlign: "right", maxWidth: "30em"}}>
<h4 style={{textAlign: "left"}}>{t('comp.monInscription')}</h4> <h4 style={{textAlign: "left"}}>{t('comp.monInscription')}</h4>
<div className="input-group mb-3"> <div className="input-group mb-3" hidden={!(data2?.requiredWeight.includes(currenCat))}>
<span className="input-group-text" id="weight">{t("comp.modal.poids")}</span> <span className="input-group-text" id="weight">{t("comp.modal.poids")}</span>
<input type="number" min={1} step={1} className="form-control" placeholder="42" aria-label="weight" disabled={disabled} <input type="number" min={1} step={1} className="form-control" placeholder="--" aria-label="weight" disabled={disabled}
name="weight" aria-describedby="weight" value={weight} onChange={e => setWeight(e.target.value)}/> name="weight" aria-describedby="weight" value={weight} onChange={e => setWeight(e.target.value)}/>
{data[0]?.weightReal && <>
<span className="input-group-text" id="weight">{t("comp.modal.pesé")}</span>
<input type="number" min={1} step={1} className="form-control" placeholder="--" aria-label="weight" disabled={true}
name="weight" aria-describedby="weight" value={data[0]?.weightReal} onChange={() => {
}}/>
</>}
</div> </div>
<div style={{textAlign: "left"}}>{t('comp.catégorieNormalisée')}: {getCatName(data[0].categorie)}</div> <div style={{textAlign: "left"}}>{t('comp.catégorieNormalisée')}: {getCatName(data[0].categorie)}</div>
@ -207,13 +213,14 @@ function SelfRegister({data2}) {
</> </>
} }
function ShowRegister() { function ShowRegister({data2}) {
const {id} = useParams() const {id} = useParams()
const setLoading = useLoadingSwitcher() const setLoading = useLoadingSwitcher()
const {data, error} = useFetch(`/competition/${id}/register/user`, setLoading, 1) const {data, error} = useFetch(`/competition/${id}/register/user`, setLoading, 1)
const {data: data3, error: error2} = useFetch(`/competition/${id}/categories`, setLoading, 1) const {data: data3, error: error2} = useFetch(`/competition/${id}/categories`, setLoading, 1)
const {t} = useTranslation(); const {t} = useTranslation();
const currenCat = data?.length > 0 && data[0]?.categorie !== "" ? applyOverCategory(data[0]?.categorie, data[0].overCategory) : "";
return <> return <>
{data ? data.length > 0 {data ? data.length > 0
@ -225,7 +232,10 @@ function ShowRegister() {
{data[0].overCategory === 1 && ` ${t('1Catégorie')}`} {data[0].overCategory === 1 && ` ${t('1Catégorie')}`}
{data[0].overCategory === 2 && ` ${t('2Catégorie')}`} {data[0].overCategory === 2 && ` ${t('2Catégorie')}`}
</div> </div>
<div style={{textAlign: "left"}}>{t("comp.modal.poids")} : {data[0].weight}</div> {data2?.requiredWeight.includes(currenCat) &&
<div style={{textAlign: "left"}}>{t("comp.modal.poids")} : {data[0].weight} {data[0]?.weightReal && <>
({t("comp.modal.pesé")} : {data[0]?.weightReal})</>}</div>}
<div style={{textAlign: "left"}}>{t('catégorie')} : <div style={{textAlign: "left"}}>{t('catégorie')} :
{error2 ? <AxiosError error={error2}/> : <> {error2 ? <AxiosError error={error2}/> : <>
{data3 && data3.length === 0 && <div>{t('aucuneCatégorieDisponible')}</div>} {data3 && data3.length === 0 && <div>{t('aucuneCatégorieDisponible')}</div>}