feat: AffiliationCard
This commit is contained in:
@@ -100,14 +100,19 @@ export function DemandeAff() {
|
||||
|
||||
function AssoInfo() {
|
||||
const [denomination, setDenomination] = useState("")
|
||||
const [siren, setSiren] = useState("")
|
||||
const [siret, setSiret] = useState("")
|
||||
const [rna, setRna] = useState("")
|
||||
const [rnaEnable, setRnaEnable] = useState(false)
|
||||
const [adresse, setAdresse] = useState("")
|
||||
|
||||
const fetchSiren = () => {
|
||||
const fetchSiret = () => {
|
||||
if (siret.length < 14) {
|
||||
toast.error("Le SIRET doit contenir 14 chiffres")
|
||||
return;
|
||||
}
|
||||
|
||||
toast.promise(
|
||||
apiAxios.get(`asso/siren/${siren}`),
|
||||
apiAxios.get(`asso/siren/${siret.substring(0, siret.length - 5)}`),
|
||||
{
|
||||
pending: "Recherche de l'association en cours",
|
||||
success: "Association trouvée avec succès 🎉",
|
||||
@@ -131,11 +136,11 @@ function AssoInfo() {
|
||||
</div>
|
||||
|
||||
<div className="input-group mb-3">
|
||||
<span className="input-group-text">N° SIREN*</span>
|
||||
<input type="number" className="form-control" placeholder="siren" name="siren" required value={siren}
|
||||
onChange={e => setSiren(e.target.value)} defaultValue={500213731}/>
|
||||
<span className="input-group-text">N° SIRET*</span>
|
||||
<input type="number" className="form-control" placeholder="siren" name="siren" required value={siret}
|
||||
onChange={e => setSiret(e.target.value)} defaultValue={500213731}/>
|
||||
<button className="btn btn-outline-secondary" type="button" id="button-addon2"
|
||||
onClick={fetchSiren}>Rechercher
|
||||
onClick={fetchSiret}>Rechercher
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,51 +2,25 @@ import {useLoadingSwitcher} from "../../../hooks/useLoading.jsx";
|
||||
import {useFetch} from "../../../hooks/useFetch.js";
|
||||
import {useEffect, useReducer, useState} from "react";
|
||||
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 {apiAxios, getSaison} from "../../../utils/Tools.js";
|
||||
import {toast} from "react-toastify";
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
import {SimpleReducer} from "../../../utils/SimpleReducer.jsx";
|
||||
|
||||
export function AffiliationCard({clubData}) {
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const {data, error} = useFetch(`/affiliation/${clubData.id}`, setLoading, 1)
|
||||
|
||||
const [modalAffiliation, setModal] = useState({id: -1, club: clubData.id})
|
||||
const [affiliations, dispatch] = useReducer(affiliationReducer, [])
|
||||
const [affiliations, dispatch] = useReducer(SimpleReducer, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!data) return
|
||||
for (const dataKey of data) {
|
||||
dispatch({type: 'UPDATE_OR_ADD', payload: dataKey})
|
||||
}
|
||||
dispatch({type: 'SORT'})
|
||||
dispatch({type: 'SORT', payload: (a, b) => b.saison - a.saison})
|
||||
}, [data]);
|
||||
|
||||
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" style={{textAlign: 'right'}}>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,7 +66,7 @@ function sendAffiliation(event, dispatch) {
|
||||
|
||||
const formData = new FormData(event.target);
|
||||
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",
|
||||
success: "Affiliation enregistrée avec succès 🎉",
|
||||
@@ -100,12 +74,13 @@ function sendAffiliation(event, dispatch) {
|
||||
}
|
||||
).then(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) {
|
||||
if (id <= 0) return
|
||||
toast.promise(
|
||||
apiAxios.delete(`/affiliation/${id}`),
|
||||
{
|
||||
@@ -120,30 +95,21 @@ function removeAffiliation(id, dispatch) {
|
||||
|
||||
function ModalContent({affiliation, dispatch}) {
|
||||
const [saison, setSaison] = useState(0)
|
||||
const [validate, setValidate] = useState(false)
|
||||
const [isNew, setNew] = useState(true)
|
||||
const setSeason = (event) => {
|
||||
setSaison(Number(event.target.value))
|
||||
}
|
||||
const handleValidateChange = (event) => {
|
||||
setValidate(event.target.value === 'true');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (affiliation.id !== -1) {
|
||||
setNew(false)
|
||||
if (affiliation.id !== 0) {
|
||||
setSaison(affiliation.saison)
|
||||
setValidate(affiliation.validate)
|
||||
} else {
|
||||
setNew(true)
|
||||
setSaison(getSaison())
|
||||
setValidate(false)
|
||||
}
|
||||
}, [affiliation]);
|
||||
|
||||
return <form onSubmit={e => sendAffiliation(e, dispatch)}>
|
||||
<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">
|
||||
<h1 className="modal-title fs-5" id="AffiliationModalLabel">Edition de l'affiliation</h1>
|
||||
<button type="button" className="btn-close" data-bs-dismiss="modal"
|
||||
@@ -151,7 +117,7 @@ function ModalContent({affiliation, dispatch}) {
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="input-group mb-3 justify-content-md-center">
|
||||
{isNew
|
||||
{affiliation.id === 0
|
||||
? <input type="number" className="form-control" placeholder="Saison" name="saison"
|
||||
aria-label="Saison" aria-describedby="basic-addon2" value={saison} onChange={setSeason}/>
|
||||
: <><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">{saison + 1}</span>
|
||||
</div>
|
||||
<RadioGroupeOnOff name="validate" text="Validation de l'affiliation" value={validate}
|
||||
onChange={handleValidateChange}/>
|
||||
<div className="input-group mb-3 justify-content-md-center">
|
||||
<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 className="modal-footer">
|
||||
<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>
|
||||
{isNew || <button type="button" className="btn btn-danger" data-bs-dismiss="modal"
|
||||
{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">Fermer</button>
|
||||
{affiliation.id <= 0 || <button type="button" className="btn btn-danger" data-bs-dismiss="modal"
|
||||
onClick={() => removeAffiliation(affiliation.id, dispatch)}>Supprimer</button>}
|
||||
</div>
|
||||
</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>
|
||||
<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 compte
|
||||
data-bs-target="#confirm-delete">Supprimer le club
|
||||
</button>
|
||||
</div>
|
||||
<ConfirmDialog title="Supprimer le compte"
|
||||
message="Êtes-vous sûr de vouloir supprimer ce compte ?"
|
||||
<ConfirmDialog title="Supprimer le club"
|
||||
message="Êtes-vous sûr de vouloir supprimer ce club ?"
|
||||
onConfirm={handleRm}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user