Files
ffsaf-site/src/main/webapp/src/App.jsx
Thibaut Valentin d95c173fa8
All checks were successful
Deploy Production Server / if_merged (pull_request) Successful in 10m51s
fix: aff renew select length
2025-11-07 16:19:49 +01:00

167 lines
4.9 KiB
JavaScript

import {useEffect, useRef} from 'react'
import {Nav} from "./components/Nav.jsx";
import {createBrowserRouter, Outlet, RouterProvider, useLocation, useRouteError} from "react-router-dom";
import {Home} from "./pages/Homepage.jsx";
import {AdminRoot, getAdminChildren} from "./pages/admin/AdminRoot.jsx";
import {AuthCallback} from "./components/auhCallback.jsx";
import {KeycloakContextProvider, useAuth, useAuthDispatch} from "./hooks/useAuth.jsx";
import {check_validity, login} from "./utils/auth.js";
import {ToastContainer} from "react-toastify";
import './App.css'
import 'react-toastify/dist/ReactToastify.css';
import {ClubRoot, getClubChildren} from "./pages/club/ClubRoot.jsx";
import {DemandeAff, DemandeAffOk} from "./pages/DemandeAff.jsx";
import {MePage} from "./pages/MePage.jsx";
import {CompetitionRoot, getCompetitionChildren} from "./pages/competition/CompetitionRoot.jsx";
import {FallingLines} from "react-loader-spinner";
const router = createBrowserRouter([
{
path: '/',
element: <Root/>,
errorElement: <PageError/>,
children: [
{
path: '',
element: <Home/>
},
{
path: 'admin',
element: <AdminRoot/>,
children: getAdminChildren()
},
{
path: 'club',
element: <ClubRoot/>,
children: getClubChildren()
},
{
path: 'affiliation',
children: [
{
path: '',
element: <DemandeAff/>
},
{
path: 'ok',
element: <DemandeAffOk/>
}
]
},
{
path: 'competition',
element: <CompetitionRoot/>,
children: getCompetitionChildren()
},
{
path: 'me',
element: <MePage/>
}
]
},
{
path: '/complete/auth',
element: <AuthCallback/>
}
])
function PageError() {
const error = useRouteError()
return <div style={{textAlign: 'center'}}>
<h1>Une erreur est survenue</h1>
<p>
{error?.error?.toString() ?? error?.toString()}
</p>
</div>
}
function Root() {
const dispatch = useAuthDispatch()
const isInit = useRef(false)
useEffect(() => {
if (isInit.current)
return;
isInit.current = true
check_validity(data => dispatch({type: 'init', val: data}))
}, []);
useEffect(() => {
const interval = setInterval(() => {
check_validity(data => dispatch({type: 'update', val: data}))
}, 1000 * 60 * 9)
return () => clearInterval(interval)
}, []);
return <>
<header>
<Nav/>
</header>
<div className="container my-4">
<Outlet/>
<ToastContainer
position="bottom-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="light"
transition: Flip
/>
<ReAuthMsg/>
</div>
</>
}
function ReAuthMsg() {
const {is_authenticated} = useAuth()
const location = useLocation()
const notAuthPaths = [
/^\/$/s,
/^\/affiliation(\/)?$/s,
/^\/affiliation\/ok(\/)?$/s,
/^\/complete\/auth.*$/s
]
if (is_authenticated || notAuthPaths.some(r => r.test(location.pathname)))
return <></>
return <>
<div className="overlayBG" style={{position: 'fixed'}}>
<div className="overlayContent" onClick={(e) => {
e.stopPropagation()
}}>
<div className="card">
<div className="card-header">
<h5>Session expirée</h5>
</div>
<div className="card-body">
<p className="card-text">Votre session a expirée, veuillez vous reconnecter pour continuer à
utiliser l'application.</p>
</div>
<div className="card-footer">
<button className="btn btn-primary" onClick={() => login()} style={{marginRight: "0.5em"}}>Se reconnecter</button>
<a className="btn btn-secondary" href="/">Accueil</a>
</div>
</div>
</div>
</div>
</>
}
function App() {
console.log('render')
return <KeycloakContextProvider>
<RouterProvider router={router}/>
</KeycloakContextProvider>;
}
export default App