feat: club set role

This commit is contained in:
2024-07-18 11:46:54 +02:00
parent fe1af4d78f
commit 53d59a5b56
8 changed files with 188 additions and 30 deletions

View File

@@ -2,8 +2,6 @@ import {useEffect, useState} from "react";
import {apiAxios, getSaison} from "../utils/Tools.js";
import {toast} from "react-toastify";
import {useLocation, useNavigate} from "react-router-dom";
import {RoleList} from "../components/MemberCustomFiels.jsx";
import {useAuth} from "../hooks/useAuth.jsx";
const notUpperCase = ["de", "la", "le", "les", "des", "du", "d'", "l'", "sur"];
@@ -96,7 +94,7 @@ export function DemandeAff() {
).then(_ => {
navigate("/club/me")
})
}else if (event.nativeEvent.submitter.value === "edit") {
} else if (event.nativeEvent.submitter.value === "edit") {
formData.append("id", initData.id)
toast.promise(
@@ -109,7 +107,7 @@ export function DemandeAff() {
).then(_ => {
navigate("/club/me")
})
}else {
} else {
formData.append("id", -1)
toast.promise(
@@ -284,15 +282,23 @@ function AssoInfo({initData, needFile}) {
</div>
</div>
<div className="input-group mb-3">
<label className="input-group-text" htmlFor="status">Status*</label>
<input type="file" className="form-control" id="status" name="status" accept=".pdf,.txt" required={needFile}/>
<div className="mb-3">
<div className="input-group">
<label className="input-group-text" htmlFor="logo">Blason{needFile && "*"}</label>
<input type="file" className="form-control" id="logo" name="logo" accept=".jpg,.jpeg,.gif,.png,.svg"
required={needFile}/>
</div>
{!needFile && <div className="form-text" id="status">Laissez vide pour ne rien changer. (Si un blason a déjà été envoyé lors de cette
demande, il sera utilisé, sinon nous utiliserons celui de la précédant affiliation)</div>}
</div>
<div className="input-group mb-3">
<label className="input-group-text" htmlFor="logo">Logo*</label>
<input type="file" className="form-control" id="logo" name="logo" accept=".jpg,.jpeg,.gif,.png,.svg"
required={needFile}/>
<div className="mb-3">
<div className="input-group">
<label className="input-group-text" htmlFor="status">Statue{needFile && "*"}</label>
<input type="file" className="form-control" id="status" name="status" accept=".pdf,.txt" required={needFile}/>
</div>
{!needFile && <div className="form-text" id="status">Laissez vide pour ne rien changer. (Si un statu a déjà été envoyé lors de cette
demande, il sera utilisé, sinon nous utiliserons celui de la précédant affiliation)</div>}
</div>
</>;
}

View File

@@ -24,7 +24,7 @@ export function AffiliationCard({clubData}) {
dispatch({type: 'SORT', payload: (a, b) => b.saison - a.saison})
}, [data]);
return <div className="card mb-4 mb-md-0">
return <div className="card mb-4">
<div className="card-header container-fluid">
<div className="row">
<div className="col">Affiliation</div>

View File

@@ -52,6 +52,7 @@ export function ClubPage() {
</div>
<div className="col-lg-3">
<LoadingProvider><AffiliationCard clubData={data}/></LoadingProvider>
<LoadingProvider><BureauCard clubData={data}/></LoadingProvider>
<div className="col" style={{textAlign: 'right', marginTop: '1em'}}>
<button className="btn btn-danger btn-sm" data-bs-toggle="modal"
data-bs-target="#confirm-delete">Supprimer le club
@@ -60,6 +61,7 @@ export function ClubPage() {
<ConfirmDialog title="Supprimer le club"
message="Êtes-vous sûr de vouloir supprimer ce club ?"
onConfirm={handleRm}/>
</div>
</div>
</div>
@@ -157,3 +159,25 @@ function InformationForm({data}) {
<LocationEditorModal modal={modal} sendData={locationModalCallback}/>
</>
}
export function BureauCard({clubData}) {
const setLoading = useLoadingSwitcher()
const {data, error} = useFetch(`/club/desk/${clubData.id}`, setLoading, 1)
return <>
<div className="card mb-4">
<div className="card-header">Bureau</div>
<div className="card-body">
<ul className="list-group">
{data && data.map((d, index) => {
return <div key={index} className="list-group-item d-flex justify-content-between align-items-start">
<div className="me-auto"><small>{d.role}</small><br/>{d.lname} {d.fname}</div>
</div>
})}
</ul>
</div>
</div>
{error && <AxiosError error={error}/>}
</>
}

View File

@@ -10,25 +10,16 @@ import {SimpleReducer} from "../../../utils/SimpleReducer.jsx";
import {useNavigate} from "react-router-dom";
export function AffiliationCard({clubData}) {
const navigate = useNavigate();
const setLoading = useLoadingSwitcher()
const {data, error} = useFetch(`/affiliation/${clubData.id}`, setLoading, 1)
const [modalAffiliation, setModal] = useState({id: 0, club: clubData.id})
const sendAffiliationRequest = () => {
let createData = {}
apiAxios.get(`/club/renew/${clubData.id}`).then(data => {
navigate('/affiliation#d' + encodeURI(JSON.stringify(data.data)))
})
}
return <div className="card mb-4 mb-md-0">
return <div className="card mb-4">
<div className="card-header container-fluid">
<div className="row">
<div className="col">Affiliation</div>
<div className="col" style={{textAlign: 'right'}}>
<button className="btn btn-primary btn-sm" onClick={e => sendAffiliationRequest()}>Renouveler
</button>
<button className="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#RenewModal">Renouveler</button>
</div>
</div>
</div>
@@ -92,4 +83,87 @@ function ModalContent({affiliation}) {
</div>
}
</>
}
export function BureauCard({clubData}) {
const setLoading = useLoadingSwitcher()
const {data, error} = useFetch(`/club/desk/${clubData.id}`, setLoading, 1)
return <>
<div className="card mb-4">
<div className="card-header">Bureau</div>
<div className="card-body">
<ul className="list-group">
{data && data.map((d, index) => {
return <div key={index} className="list-group-item d-flex justify-content-between align-items-start">
<div className="me-auto"><small>{d.role}</small><br/>{d.lname} {d.fname}</div>
</div>
})}
</ul>
</div>
</div>
<div className="modal fade" id="RenewModal" tabIndex="-1" aria-labelledby="RenewModalLabel"
aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<ModalContent2 clubData={clubData} data={data}/>
</div>
</div>
</div>
{error && <AxiosError error={error}/>}
</>
}
function ModalContent2({clubData, data}) {
const navigate = useNavigate();
const sendAffiliationRequest = (event) => {
event.preventDefault()
let list = []
for (let i = 0; i < event.target.length; i++) {
if (event.target[i].type === "checkbox") {
if (event.target[i].checked) {
list.push(event.target[i].name)
}
}
}
if (list.length !== 3) {
toast.error("Il faut sélectionner 3 membres pour renouveler l'affiliation")
return
}
apiAxios.get(`/club/renew/${clubData.id}?m1=${list[0]}&m2=${list[1]}&m3=${list[2]}`).then(data => {
navigate('/affiliation#d' + encodeURI(JSON.stringify(data.data)))
})
}
return <form onSubmit={sendAffiliationRequest}>
<div className="modal-header">
<h1 className="modal-title fs-5" id="AffiliationModalLabel">Renouvellement de l'affiliation</h1>
<button type="button" className="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div className="modal-body">
<p>Veuillez sélectionner 3 membres du bureau pour remplir la pré-demande. (Si un membre non-bureau va le devenir l'an prochain,
vous pourrez toujours remplacer un des membres sélectionné à la prochaine étape)</p>
{data && data.map((d, index) => {
return <div key={index} className="input-group mb-1">
<div className="input-group-text">
<input className="form-check-input mt-0" type="checkbox" value="" aria-label={d.lname + " " + d.fname}
name={d.id}/>
</div>
<span className="input-group-text">{d.role}</span>
<span className="input-group-text">{d.lname} {d.fname}</span>
</div>
}
)}
</div>
<div className="modal-footer">
<button type="reset" className="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
<button type="submit" className="btn btn-primary" data-bs-dismiss="modal">Suivant</button>
</div>
</form>
}

View File

@@ -5,7 +5,7 @@ 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 {AffiliationCard, BureauCard} from "./AffiliationCard.jsx";
import {CountryList, TextField} from "../../../components/MemberCustomFiels.jsx";
import {useRef, useState} from "react";
@@ -32,7 +32,10 @@ export function MyClubPage() {
</LoadingProvider>
</div>
<div className="col-lg-3">
<LoadingProvider><AffiliationCard clubData={data}/></LoadingProvider>
<LoadingProvider>
<AffiliationCard clubData={data}/>
<BureauCard clubData={data}/>
</LoadingProvider>
</div>
</div>
</div>