feat: add pay information to licence
This commit is contained in:
@@ -10,6 +10,8 @@ import {apiAxios, errFormater} from "../utils/Tools.js";
|
||||
import {toast} from "react-toastify";
|
||||
import {SearchBar} from "../components/SearchBar.jsx";
|
||||
import * as XLSX from "xlsx-js-style";
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import {faEuroSign} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
export function MemberList({source}) {
|
||||
const {hash} = useLocation();
|
||||
@@ -23,14 +25,15 @@ export function MemberList({source}) {
|
||||
const [clubFilter, setClubFilter] = useState("");
|
||||
const [stateFilter, setStateFilter] = useState(4)
|
||||
const [lastSearch, setLastSearch] = useState("");
|
||||
const [paymentFilter, setPaymentFilter] = useState(2);
|
||||
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const {data, error, refresh} = useFetch(`/member/find/${source}?page=${page}&licenceRequest=${stateFilter}`, setLoading, 1)
|
||||
const {data, error, refresh} = useFetch(`/member/find/${source}?page=${page}&licenceRequest=${stateFilter}&payment=${paymentFilter}`, setLoading, 1)
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
||||
}, [hash, clubFilter, stateFilter]);
|
||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}&payment=${paymentFilter}`);
|
||||
}, [hash, clubFilter, stateFilter, lastSearch, paymentFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!data)
|
||||
@@ -74,7 +77,6 @@ export function MemberList({source}) {
|
||||
if (search === lastSearch)
|
||||
return;
|
||||
setLastSearch(search);
|
||||
refresh(`/member/find/${source}?page=${page}&search=${search}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
||||
}
|
||||
|
||||
return <>
|
||||
@@ -102,7 +104,8 @@ export function MemberList({source}) {
|
||||
<div className="card-body">
|
||||
<FiltreBar showLicenceState={showLicenceState} setShowLicenceState={setShowLicenceState} data={data}
|
||||
clubFilter={clubFilter} setClubFilter={setClubFilter} source={source}
|
||||
stateFilter={stateFilter} setStateFilter={setStateFilter}/>
|
||||
stateFilter={stateFilter} setStateFilter={setStateFilter} paymentFilter={paymentFilter}
|
||||
setPaymentFilter={setPaymentFilter}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -361,7 +364,8 @@ function MakeCentralPanel({data, visibleMember, navigate, showLicenceState, page
|
||||
function MakeRow({member, showLicenceState, navigate, source}) {
|
||||
const rowContent = <>
|
||||
<div className="row">
|
||||
<span className="col-auto">{member.licence_number ? String(member.licence_number).padStart(5, '0') : "-------"}</span>
|
||||
<span className="col-auto">{(member.licence_number ? String(member.licence_number).padStart(5, '0') : "-------") + " "}
|
||||
{(showLicenceState && member.licence != null && member.licence.pay)? <FontAwesomeIcon icon={faEuroSign}/> : <> </>}</span>
|
||||
<div className="ms-2 col-auto">
|
||||
<div className="fw-bold">{member.fname} {member.lname}</div>
|
||||
</div>
|
||||
@@ -386,7 +390,7 @@ function MakeRow({member, showLicenceState, navigate, source}) {
|
||||
|
||||
let allClub = []
|
||||
|
||||
function FiltreBar({showLicenceState, setShowLicenceState, data, clubFilter, setClubFilter, source, stateFilter, setStateFilter}) {
|
||||
function FiltreBar({showLicenceState, setShowLicenceState, data, clubFilter, setClubFilter, source, stateFilter, setStateFilter, paymentFilter, setPaymentFilter}) {
|
||||
useEffect(() => {
|
||||
if (!data)
|
||||
return;
|
||||
@@ -410,6 +414,14 @@ function FiltreBar({showLicenceState, setShowLicenceState, data, clubFilter, set
|
||||
<option value={3}>Licence validée</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<select className="form-select" value={paymentFilter} onChange={event => setPaymentFilter(Number(event.target.value))}
|
||||
hidden={stateFilter === 0 || stateFilter === 4}>
|
||||
<option value={2}>Tout les états de paiement</option>
|
||||
<option value={0}>Sans paiement</option>
|
||||
<option value={1}>Avec paiement</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import {apiAxios, errFormater} from "../utils/Tools.js";
|
||||
import {toast} from "react-toastify";
|
||||
import {SearchBar} from "../components/SearchBar.jsx";
|
||||
import {ConfirmDialog} from "../components/ConfirmDialog.jsx";
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import {faEuroSign} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
export function ValidateList({source}) {
|
||||
const {hash} = useLocation();
|
||||
@@ -20,16 +22,21 @@ export function ValidateList({source}) {
|
||||
const [clubFilter, setClubFilter] = useState("");
|
||||
const [stateFilter, setStateFilter] = useState(2)
|
||||
const [lastSearch, setLastSearch] = useState("");
|
||||
const [paymentFilter, setPaymentFilter] = useState(2);
|
||||
|
||||
const [selectedMembers, setSelectedMembers] = useState([]);
|
||||
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const {data, error, refresh} = useFetch(`/member/find/${source}?page=${page}&licenceRequest=${stateFilter}`, setLoading, 1)
|
||||
const {
|
||||
data,
|
||||
error,
|
||||
refresh
|
||||
} = useFetch(`/member/find/${source}?page=${page}&licenceRequest=${stateFilter}&payment=${paymentFilter}`, setLoading, 1)
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
||||
}, [hash, clubFilter, stateFilter]);
|
||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}&payment=${paymentFilter}`);
|
||||
}, [hash, clubFilter, stateFilter, lastSearch, paymentFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!data)
|
||||
@@ -70,7 +77,6 @@ export function ValidateList({source}) {
|
||||
if (search === lastSearch)
|
||||
return;
|
||||
setLastSearch(search);
|
||||
refresh(`/member/find/${source}?page=${page}&search=${search}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
||||
}
|
||||
|
||||
const handleValidation = () => {
|
||||
@@ -92,7 +98,7 @@ export function ValidateList({source}) {
|
||||
}
|
||||
).then(() => {
|
||||
setSelectedMembers([]);
|
||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}&payment=${paymentFilter}`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -119,7 +125,8 @@ export function ValidateList({source}) {
|
||||
<div className="card-header">Filtre</div>
|
||||
<div className="card-body">
|
||||
<FiltreBar data={data} clubFilter={clubFilter} setClubFilter={setClubFilter} source={source}
|
||||
stateFilter={stateFilter} setStateFilter={setStateFilter}/>
|
||||
stateFilter={stateFilter} setStateFilter={setStateFilter} paymentFilter={paymentFilter}
|
||||
setPaymentFilter={setPaymentFilter}/>
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
@@ -128,7 +135,8 @@ export function ValidateList({source}) {
|
||||
<button className="btn btn-primary" data-bs-toggle="modal" data-bs-target="#confirm-validation">Valider
|
||||
les {selectedMembers.length} licences sélectionnée
|
||||
</button>
|
||||
<ConfirmDialog title="Validation des licences" message={"Êtes-vous sûr de vouloir valider les "+selectedMembers.length+" licences ?"}
|
||||
<ConfirmDialog title="Validation des licences"
|
||||
message={"Êtes-vous sûr de vouloir valider les " + selectedMembers.length + " licences ?"}
|
||||
onConfirm={handleValidation} id="confirm-validation"/>
|
||||
</>}
|
||||
</div>
|
||||
@@ -223,7 +231,8 @@ function MakeRow({member, source, isChecked, onCheckboxClick, onRowClick}) {
|
||||
<input className="form-check-input me-1" type="checkbox" checked={isChecked || false} onChange={() => {
|
||||
}}
|
||||
onClick={(e) => onCheckboxClick(e, member.id)}/>
|
||||
<span>{member.licence_number ? String(member.licence_number).padStart(5, '0') : "-------"}</span>
|
||||
<span className="col-auto">{(member.licence_number ? String(member.licence_number).padStart(5, '0') : "-------") + " "}
|
||||
{(member.licence != null && member.licence.pay)? <FontAwesomeIcon icon={faEuroSign}/> : <> </>}</span>
|
||||
</div>
|
||||
<div className="ms-2 col-auto">
|
||||
<div className="fw-bold">{member.fname} {member.lname}</div>
|
||||
@@ -251,7 +260,7 @@ function MakeRow({member, source, isChecked, onCheckboxClick, onRowClick}) {
|
||||
|
||||
let allClub = []
|
||||
|
||||
function FiltreBar({data, clubFilter, setClubFilter, source, stateFilter, setStateFilter}) {
|
||||
function FiltreBar({data, clubFilter, setClubFilter, source, stateFilter, setStateFilter, paymentFilter, setPaymentFilter}) {
|
||||
useEffect(() => {
|
||||
if (!data)
|
||||
return;
|
||||
@@ -268,6 +277,13 @@ function FiltreBar({data, clubFilter, setClubFilter, source, stateFilter, setSta
|
||||
<option value={6}>Demande incomplet</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<select className="form-select" value={paymentFilter} onChange={event => setPaymentFilter(Number(event.target.value))}>
|
||||
<option value={2}>Tout les états de paiement</option>
|
||||
<option value={0}>Sans paiement</option>
|
||||
<option value={1}>Avec paiement</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ 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 {faEuroSign, faPen} from "@fortawesome/free-solid-svg-icons";
|
||||
import {AxiosError} from "../../../components/AxiosError.jsx";
|
||||
import {apiAxios, errFormater, getSaison} from "../../../utils/Tools.js";
|
||||
import {toast} from "react-toastify";
|
||||
@@ -66,7 +66,7 @@ export function LicenceCard({userData}) {
|
||||
return <div key={index}
|
||||
className={"list-group-item d-flex justify-content-between align-items-start list-group-item-" +
|
||||
(licence.validate ? "success" : (licence.certificate?.length > 1 ? "warning" : "danger"))}>
|
||||
<div className="me-auto">{licence?.saison}-{licence?.saison + 1}</div>
|
||||
<div className="me-auto">{licence?.saison}-{licence?.saison + 1} {(licence.pay) && <FontAwesomeIcon icon={faEuroSign}/>}</div>
|
||||
<button className="badge btn btn-primary rounded-pill" data-bs-toggle="modal"
|
||||
data-bs-target="#LicenceModal" onClick={_ => setModal(licence)}>
|
||||
<FontAwesomeIcon icon={faPen}/></button>
|
||||
@@ -134,6 +134,7 @@ function ModalContent({licence, dispatch}) {
|
||||
const [certificateBy, setCertificateBy] = useState("")
|
||||
const [certificateDate, setCertificateDate] = useState("")
|
||||
const [validate, setValidate] = useState(false)
|
||||
const [pay, setPay] = useState(false)
|
||||
const [isNew, setNew] = useState(true)
|
||||
const setSeason = (event) => {
|
||||
setSaison(Number(event.target.value))
|
||||
@@ -147,6 +148,9 @@ function ModalContent({licence, dispatch}) {
|
||||
const handleValidateChange = (event) => {
|
||||
setValidate(event.target.value === 'true');
|
||||
}
|
||||
const handlePayChange = (event) => {
|
||||
setPay(event.target.value === 'true');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (licence.id !== -1) {
|
||||
@@ -160,12 +164,14 @@ function ModalContent({licence, dispatch}) {
|
||||
setCertificateDate(licence.certificate.split('¤')[1])
|
||||
}
|
||||
setValidate(licence.validate)
|
||||
setPay(licence.pay);
|
||||
} else {
|
||||
setNew(true)
|
||||
setSaison(getSaison())
|
||||
setCertificateBy("")
|
||||
setCertificateDate("")
|
||||
setValidate(false)
|
||||
setPay(false);
|
||||
}
|
||||
}, [licence]);
|
||||
|
||||
@@ -197,6 +203,8 @@ function ModalContent({licence, dispatch}) {
|
||||
<input type="date" className="form-control" placeholder="jj/mm/aaaa" name="certificateDate"
|
||||
aria-describedby="basic-addon2" value={certificateDate} onChange={handleCertificateDateChange}/>
|
||||
</div>
|
||||
<RadioGroupeOnOff name="pay" text="Paiement de la licence" value={pay}
|
||||
onChange={handlePayChange}/>
|
||||
<RadioGroupeOnOff name="validate" text="Validation de la licence" value={validate}
|
||||
onChange={handleValidateChange}/>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ 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 {faInfo, faPen} from "@fortawesome/free-solid-svg-icons";
|
||||
import {faEuroSign, faInfo, faPen} from "@fortawesome/free-solid-svg-icons";
|
||||
import {AxiosError} from "../../../components/AxiosError.jsx";
|
||||
import {apiAxios, errFormater, getSaison} from "../../../utils/Tools.js";
|
||||
import {toast} from "react-toastify";
|
||||
@@ -172,13 +172,16 @@ function ModalContent({licence, dispatch}) {
|
||||
<span>Certificat médical</span>
|
||||
<div className="input-group mb-3 ">
|
||||
<span className="input-group-text" id="basic-addon2">Fait par</span>
|
||||
<input type="text" className="form-control" placeholder="Fait par" name="certificateBy"
|
||||
<input type="text" className="form-control" placeholder="Fait par" name="certificateBy" disabled={licence.validate}
|
||||
aria-label="Fait par" aria-describedby="basic-addon2" value={certificateBy} onChange={handleCertificateByChange}/>
|
||||
<span className="input-group-text" id="basic-addon2">, le</span>
|
||||
<input type="date" className="form-control" placeholder="jj/mm/aaaa" name="certificateDate"
|
||||
<input type="date" className="form-control" placeholder="jj/mm/aaaa" name="certificateDate" disabled={licence.validate}
|
||||
aria-describedby="basic-addon2" value={certificateDate} onChange={handleCertificateDateChange}/>
|
||||
</div>
|
||||
|
||||
<div className="input-group mb-3 justify-content-md-center">
|
||||
<div>Paiement de la licence: <ColoredText boolean={licence.pay}/></div>
|
||||
</div>
|
||||
<div className="input-group mb-3 justify-content-md-center">
|
||||
<div>Validation de la licence: <ColoredText boolean={licence.validate}/></div>
|
||||
</div>
|
||||
@@ -187,7 +190,7 @@ function ModalContent({licence, dispatch}) {
|
||||
{currentSaison && !licence.validate &&
|
||||
<button type="submit" className="btn btn-primary" data-bs-dismiss="modal">Enregistrer</button>}
|
||||
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
|
||||
{currentSaison && !licence.validate && licence.id !== -1 &&
|
||||
{currentSaison && !licence.validate && licence.id !== -1 && !licence.pay &&
|
||||
<button type="button" className="btn btn-danger" data-bs-dismiss="modal"
|
||||
onClick={() => removeLicence(licence.id, dispatch)}>Annuler</button>}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user