feat: add keycloak role configuration
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import {LoadingContextProvider, useLoadingSwitcher} from "../hooks/useLoading.jsx";
|
||||
import {LoadingProvider, useLoadingSwitcher} from "../hooks/useLoading.jsx";
|
||||
import {useFetch} from "../hooks/useFetch.js";
|
||||
import {AxiosError} from "./AxiosError.jsx";
|
||||
|
||||
export function ClubSelect({defaultValue, name}) {
|
||||
return <LoadingContextProvider>
|
||||
return <LoadingProvider>
|
||||
<div className="input-group mb-3">
|
||||
<ClubSelect_ defaultValue={defaultValue} name={name}/>
|
||||
</div>
|
||||
</LoadingContextProvider>
|
||||
</LoadingProvider>
|
||||
}
|
||||
|
||||
function ClubSelect_({defaultValue, name}) {
|
||||
|
||||
@@ -13,7 +13,7 @@ export function useLoadingSwitcher() {
|
||||
return useContext(LoadingSwitcherContext);
|
||||
}
|
||||
|
||||
export function LoadingContextProvider({children}) {
|
||||
export function LoadingProvider({children}) {
|
||||
const [showOverlay, setOverlay] = useState(0);
|
||||
|
||||
return <LoadingContext.Provider value={showOverlay}>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import {NavLink, Outlet} from "react-router-dom";
|
||||
import './AdminRoot.css'
|
||||
import {LoadingContextProvider} from "../../hooks/useLoading.jsx";
|
||||
import {LoadingProvider} from "../../hooks/useLoading.jsx";
|
||||
import {MemberList} from "./MemberList.jsx";
|
||||
import {MemberPage} from "./MemberPage.jsx";
|
||||
|
||||
export function AdminRoot() {
|
||||
return <>
|
||||
<h1>Espace administration</h1>
|
||||
<LoadingContextProvider>
|
||||
<LoadingProvider>
|
||||
<Outlet/>
|
||||
</LoadingContextProvider>
|
||||
</LoadingProvider>
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {useNavigate, useParams} from "react-router-dom";
|
||||
import {useLoadingSwitcher} from "../../hooks/useLoading.jsx";
|
||||
import {LoadingProvider, useLoadingSwitcher} from "../../hooks/useLoading.jsx";
|
||||
import {useFetch, useFetchPut} from "../../hooks/useFetch.js";
|
||||
import {AxiosError} from "../../components/AxiosError.jsx";
|
||||
import {ClubSelect} from "../../components/ClubSelect.jsx";
|
||||
@@ -18,63 +18,6 @@ export function MemberPage() {
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const {data, error} = useFetch(`/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_) => {
|
||||
apiAxios.post(`/member/${id}`, formData_, {
|
||||
headers: {
|
||||
'Accept': '*/*',
|
||||
'Content-Type': 'multipart/form-data',
|
||||
}
|
||||
}).then(data => {
|
||||
console.log(data.data) // TODO
|
||||
}).catch(e => {
|
||||
console.log(e.response) // TODO
|
||||
}).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)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmitPerm = (event) => {
|
||||
|
||||
}
|
||||
|
||||
return <>
|
||||
<h2>Page membre</h2>
|
||||
<button type="button" className="btn btn-link" onClick={() => navigate("/admin/member")}>
|
||||
@@ -85,11 +28,11 @@ export function MemberPage() {
|
||||
<div className="row">
|
||||
<div className="col-lg-4">
|
||||
<PhotoCard data={data}/>
|
||||
<CompteInfo userData={data}/>
|
||||
<LoadingProvider><CompteInfo userData={data}/></LoadingProvider>
|
||||
</div>
|
||||
<div className="col-lg-8">
|
||||
<InformationForm handleSubmit={handleSubmit} data={data}/>
|
||||
<PremForm handleSubmitPerm={handleSubmitPerm}/>
|
||||
<InformationForm data={data}/>
|
||||
<LoadingProvider><PremForm userData={data}/></LoadingProvider>
|
||||
<div className="row">
|
||||
<LicenceCard/>
|
||||
<SelectCard/>
|
||||
@@ -116,7 +59,62 @@ function PhotoCard({data}) {
|
||||
</div>;
|
||||
}
|
||||
|
||||
function InformationForm({handleSubmit, data}) {
|
||||
function InformationForm({data}) {
|
||||
const setLoading = useLoadingSwitcher()
|
||||
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_) => {
|
||||
apiAxios.post(`/member/${data.id}`, formData_, {
|
||||
headers: {
|
||||
'Accept': '*/*',
|
||||
'Content-Type': 'multipart/form-data',
|
||||
}
|
||||
}).then(data => {
|
||||
toast.success('Profile mis à jours avec succès 🎉');
|
||||
}).catch(e => {
|
||||
console.log(e.response)
|
||||
toast.error('Échec de la mise à jours du profile 😕 (code: ' + e.response.status + ')');
|
||||
}).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 <form onSubmit={handleSubmit}>
|
||||
<div className="card mb-4">
|
||||
<div className="card-header">Information</div>
|
||||
@@ -161,31 +159,85 @@ function InformationForm({handleSubmit, data}) {
|
||||
</form>;
|
||||
}
|
||||
|
||||
function PremForm({handleSubmitPerm}) {
|
||||
function PremForm({userData}) {
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const handleSubmitPerm = (event) => {
|
||||
event.preventDefault();
|
||||
setLoading(1)
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("federation_admin", event.target.federation_admin?.checked);
|
||||
formData.append("safca_user", event.target.safca_user?.checked);
|
||||
formData.append("safca_create_compet", event.target.safca_create_compet?.checked);
|
||||
formData.append("safca_super_admin", event.target.safca_super_admin?.checked);
|
||||
|
||||
apiAxios.put(`/compte/${userData.userId}/roles`, formData, {
|
||||
headers: {
|
||||
'Accept': '*/*',
|
||||
'Content-Type': 'form-data',
|
||||
}
|
||||
}).then(data => {
|
||||
toast.success('Permission mise à jours avec succès 🎉');
|
||||
}).catch(e => {
|
||||
console.log(e.response)
|
||||
toast.error('Échec de la mise à jours des permissions 😕 (code: ' + e.response.status + ')');
|
||||
}).finally(() => {
|
||||
if (setLoading)
|
||||
setLoading(0)
|
||||
})
|
||||
}
|
||||
|
||||
return <form onSubmit={handleSubmitPerm}>
|
||||
<div className="card mb-4">
|
||||
<div className="card-header">Permission</div>
|
||||
<div className="card-body">
|
||||
<div className="row g-3">
|
||||
<div className="col">
|
||||
<h5>FFSAF intra</h5>
|
||||
<CheckField name="federation_admin" text="Accès à l'intra" value={false}/>
|
||||
</div>
|
||||
<div className="col">
|
||||
<h5>SAFCA</h5>
|
||||
<CheckField name="safca_user" text="Accès à l'application" value={false}/>
|
||||
<CheckField name="safca_create_compet" text="Créer des compétion" value={false}/>
|
||||
<CheckField name="safca_super_admin" text="Super administrateur" value={false}/>
|
||||
</div>
|
||||
{userData.userId
|
||||
? <PremFormContent userData={userData}/>
|
||||
: <div className="col">
|
||||
<div className="input-group mb-3">
|
||||
<div>Ce membre ne dispose pas de compte...</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-md-12 text-right">
|
||||
<button type="submit" className="btn btn-primary">Enregistrer</button>
|
||||
{userData.userId && <button type="submit" className="btn btn-primary">Enregistrer</button>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>;
|
||||
</form>
|
||||
}
|
||||
|
||||
function PremFormContent({userData}) {
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const {data, error} = useFetch(`/compte/${userData.userId}/roles`, setLoading, 1)
|
||||
|
||||
return <>
|
||||
<div className="col">
|
||||
<h5>FFSAF intra</h5>
|
||||
{data
|
||||
? <>
|
||||
<CheckField name="federation_admin" text="Accès à l'intra"
|
||||
value={data.includes("federation_admin")}/>
|
||||
</>
|
||||
: error && <AxiosError error={error}/>}
|
||||
</div>
|
||||
<div className="col">
|
||||
<h5>SAFCA</h5>
|
||||
{data
|
||||
? <>
|
||||
<CheckField name="safca_user" text="Accès à l'application" value={data.includes("safca_user")}/>
|
||||
<CheckField name="safca_create_compet" text="Créer des compétion"
|
||||
value={data.includes("safca_create_compet")}/>
|
||||
<CheckField name="safca_super_admin" text="Super administrateur"
|
||||
value={data.includes("safca_super_admin")}/>
|
||||
</>
|
||||
: error && <AxiosError error={error}/>}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
function LicenceCard() {
|
||||
@@ -214,12 +266,15 @@ function SelectCard() {
|
||||
function CompteInfo({userData}) {
|
||||
|
||||
const creatAccount = () => {
|
||||
let err = {};
|
||||
toast.promise(
|
||||
apiAxios.put(`/compte/${userData.id}/init`),
|
||||
apiAxios.put(`/compte/${userData.id}/init`).catch(e => {
|
||||
err = e
|
||||
}),
|
||||
{
|
||||
pending: 'Création du compte en cours',
|
||||
success: 'Compte créé avec succès 🎉',
|
||||
error: 'Échec de la création du compte 😕'
|
||||
error: 'Échec de la création du compte 😕 (code: ' + err.response.status + ')'
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -229,7 +284,8 @@ function CompteInfo({userData}) {
|
||||
<div className="card-body text-center">
|
||||
{userData.userId
|
||||
? <CompteInfoContent userData={userData}/>
|
||||
: <>
|
||||
:
|
||||
<>
|
||||
<div className="row">
|
||||
<div className="input-group mb-3">
|
||||
<div>Ce membre ne dispose pas de compte...</div>
|
||||
@@ -240,13 +296,16 @@ function CompteInfo({userData}) {
|
||||
<button className="btn btn-primary" onClick={creatAccount}>Initialiser le compte</button>
|
||||
</div>
|
||||
</div>
|
||||
</>}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
function CompteInfoContent({userData}) {
|
||||
function CompteInfoContent({
|
||||
userData
|
||||
}) {
|
||||
const setLoading = useLoadingSwitcher()
|
||||
const {data, error} = useFetch(`/compte/${userData.userId}`, setLoading, 1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user