228 lines
10 KiB
JavaScript
228 lines
10 KiB
JavaScript
import {useNavigate, useParams} from "react-router-dom";
|
|
import {useLoadingSwitcher} from "../../hooks/useLoading.jsx";
|
|
import {useFetch, useFetchPut} from "../../hooks/useFetch.js";
|
|
import {AxiosError} from "../../components/AxiosError.jsx";
|
|
import {ClubSelect} from "../../components/ClubSelect.jsx";
|
|
import {useEffect, useState} from "react";
|
|
import {getCategoryFormBirthDate, getSaison} from "../../utils/Tools.js";
|
|
import axios from "axios";
|
|
import imageCompression from "browser-image-compression";
|
|
|
|
const api_url = import.meta.env.VITE_API_URL;
|
|
|
|
export function MemberPage() {
|
|
const {id} = useParams()
|
|
const navigate = useNavigate();
|
|
|
|
const setLoading = useLoadingSwitcher()
|
|
const {data, error} = useFetch(`${api_url}/member/${id}`, setLoading, 1)
|
|
|
|
const handleSubmit = (event) => {
|
|
event.preventDefault();
|
|
|
|
setLoading(1)
|
|
|
|
const formData = new FormData();
|
|
formData.append("id", data.id);
|
|
formData.append("lname", event.target.lname?.value);
|
|
formData.append("fname", event.target.fname?.value);
|
|
formData.append("categorie", event.target.category?.value);
|
|
formData.append("club", event.target.club?.value);
|
|
formData.append("genre", event.target.genre?.value);
|
|
formData.append("country", event.target.country?.value);
|
|
formData.append("birth_date", new Date(event.target.birth_date?.value).toUTCString());
|
|
formData.append("email", event.target.email?.value);
|
|
formData.append("role", event.target.role?.value);
|
|
formData.append("grade_arbitrage", event.target.grade_arbitrage?.value);
|
|
|
|
const send = (formData_) => {
|
|
axios.post(`${api_url}/member/${id}`, formData_, {
|
|
headers: {
|
|
'Authorization': `Bearer ${localStorage.getItem("access_token")}`,
|
|
'Accept': '*/*',
|
|
'Content-Type': 'multipart/form-data',
|
|
}
|
|
}).then(data => {
|
|
console.log(data.data)
|
|
}).catch(e => {
|
|
console.log(e.response)
|
|
}).finally(() => {
|
|
if (setLoading)
|
|
setLoading(0)
|
|
})
|
|
}
|
|
|
|
const imageFile = event.target.url_photo.files[0];
|
|
if (imageFile) {
|
|
console.log(`originalFile size ${imageFile.size / 1024 / 1024} MB`);
|
|
|
|
const options = {
|
|
maxSizeMB: 1,
|
|
maxWidthOrHeight: 1920,
|
|
useWebWorker: true,
|
|
}
|
|
|
|
imageCompression(imageFile, options).then(compressedFile => {
|
|
console.log(`compressedFile size ${compressedFile.size / 1024 / 1024} MB`); // smaller than maxSizeMB
|
|
formData.append("photo_data", compressedFile)
|
|
send(formData)
|
|
});
|
|
} else {
|
|
send(formData)
|
|
}
|
|
}
|
|
|
|
return <>
|
|
<h2>Page membre</h2>
|
|
<button type="button" className="btn btn-link" onClick={() => navigate("/admin/member")}>
|
|
<< retour
|
|
</button>
|
|
{data
|
|
? <MemberForm data={data} handleSubmit={handleSubmit}/>
|
|
: error && <AxiosError error={error}/>
|
|
}
|
|
</>
|
|
}
|
|
|
|
|
|
function MemberForm({data, handleSubmit}) {
|
|
return <div>
|
|
<div className="row">
|
|
<div className="col-lg-4">
|
|
<div className="card mb-4">
|
|
<div className="card-header">Licence n°{data.licence}</div>
|
|
<div className="card-body text-center">
|
|
<div className="input-group mb-3">
|
|
<img
|
|
src={"http://localhost:8080/member/"+data.id+"/photo"}
|
|
alt="avatar"
|
|
className="rounded-circle img-fluid" style={{object_fit: 'contain'}}/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="col-lg-8">
|
|
<form onSubmit={handleSubmit}>
|
|
<div className="card mb-4">
|
|
<div className="card-header">Information</div>
|
|
<div className="card-body">
|
|
<TextField name="lname" text="Nom" value={data.lname}/>
|
|
<TextField name="fname" text="Prénom" value={data.fname}/>
|
|
<TextField name="email" text="Email" value={data.email} placeholder="name@example.com"
|
|
type="email"/>
|
|
<OptionField name="genre" text="Genre" value={data.genre}
|
|
values={{NA: 'N/A', H: 'H', F: 'F'}}/>
|
|
<OptionField name="country" text="Pays" value={data.country}
|
|
values={{NA: 'Sélectionner...', fr: 'FR', es: 'ES', be: 'BE'}}/>
|
|
<BirthDayField inti_date={data.birth_date ? data.birth_date.split('T')[0] : ''}
|
|
inti_category={data.categorie}/>
|
|
<div className="row">
|
|
<ClubSelect defaultValue={data?.club?.id} name="club"/>
|
|
</div>
|
|
<OptionField name="grade_arbitrage" text="Rôle" value={data.role}
|
|
values={{NA: 'N/A', ASSESSEUR: 'Assesseur', ARBITRE: 'Arbitre'}}/>
|
|
<OptionField name="role" text="Grade d'arbitrage" value={data.grade_arbitrage}
|
|
values={{
|
|
MEMBRE: 'Membre',
|
|
PRESIDENT: 'Président',
|
|
TRESORIER: 'Trésorier',
|
|
SECRETAIRE: 'Secrétaire'
|
|
}}/>
|
|
<div className="row">
|
|
<div className="input-group mb-3">
|
|
<label className="input-group-text" htmlFor="url_photo">Photos
|
|
(optionnelle)</label>
|
|
<input type="file" className="form-control" id="url_photo" name="url_photo"
|
|
accept=".jpg,.jpeg,.gif,.png,.svg"/>
|
|
</div>
|
|
</div>
|
|
<div className="row">
|
|
<div className="col-md-12 text-right">
|
|
<button type="submit" className="btn btn-primary">Enregistrer</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<div className="row">
|
|
<div className="col-md-6">
|
|
<div className="card mb-4 mb-md-0">
|
|
<div className="card-header">Licence</div>
|
|
<div className="card-body">
|
|
<p className="mb-1">Web Design</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="col-md-6">
|
|
<div className="card mb-4 mb-md-0">
|
|
<div className="card-header">Sélection en équipe de France</div>
|
|
<div className="card-body">
|
|
<p className="mb-1">Web Design</p>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
function BirthDayField({inti_date, inti_category}) {
|
|
const [date, setDate] = useState(inti_date)
|
|
const [category, setCategory] = useState(inti_category)
|
|
const [canUpdate, setCanUpdate] = useState(false)
|
|
useEffect(() => {
|
|
const b = category !== getCategoryFormBirthDate(new Date(date), new Date('2023-09-01'))
|
|
if (b !== canUpdate)
|
|
setCanUpdate(b)
|
|
}, [date, category])
|
|
|
|
const updateCat = (e) => {
|
|
console.log(date)
|
|
setCategory(getCategoryFormBirthDate(new Date(date), new Date('2023-09-01')))
|
|
}
|
|
|
|
|
|
return <>
|
|
<div className="input-group mb-3">
|
|
<span className="input-group-text" id="birth_date">Date de naissance</span>
|
|
<input type="date" className="form-control" placeholder="jj/mm/aaaa" aria-label="birth_date"
|
|
name="birth_date" aria-describedby="birth_date" defaultValue={date} required
|
|
onChange={(e) => setDate(e.target.value)}/>
|
|
</div>
|
|
<div className="row">
|
|
<div className="input-group mb-3">
|
|
<span className="input-group-text" id="category">Catégorie</span>
|
|
<input type="text" className="form-control" placeholder="" name="category"
|
|
aria-label="category" value={category} aria-describedby="category"
|
|
disabled/>
|
|
{canUpdate && <button className="btn btn-outline-secondary" type="button" id="button-addon1"
|
|
onClick={updateCat}>Mettre à jours</button>}
|
|
</div>
|
|
</div>
|
|
</>
|
|
}
|
|
|
|
function OptionField({name, text, values, value}) {
|
|
return <div className="row">
|
|
<div className="input-group mb-3">
|
|
<label className="input-group-text" id={name}>{text}</label>
|
|
<select className="form-select" id={name} name={name} defaultValue={value} required>
|
|
{Object.keys(values).map((key, _) => {
|
|
return (<option key={key} value={key}>{values[key]}</option>)
|
|
})}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
function TextField({name, text, value, placeholder, type = "text"}) {
|
|
return <div className="row">
|
|
<div className="input-group mb-3">
|
|
<span className="input-group-text" id={name}>{text}</span>
|
|
<input type={type} className="form-control" placeholder={placeholder ? placeholder : text} aria-label={name}
|
|
name={name} aria-describedby={name} defaultValue={value} required/>
|
|
</div>
|
|
</div>
|
|
} |