Files
ffsaf-site/src/main/webapp/src/App.jsx

191 lines
5.6 KiB
JavaScript

import {lazy, Suspense, 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 {getResultChildren, ResultRoot} from "./pages/result/ResultRoot.jsx";
import {useTranslation} from "react-i18next";
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: 'result',
element: <ResultRoot/>,
children: getResultChildren()
},
{
path: 'competition-manager/*',
element: <GetCompetitionMangerLazy/>,
//children: getCompetitionManagerChildren()
},
{
path: 'me',
element: <MePage/>
}
]
},
{
path: '/complete/auth',
element: <AuthCallback/>
}
])
function GetCompetitionMangerLazy() {
const CMLazy = lazy(() => import('./pages/competition/editor/CompetitionManagerRoot.jsx'))
const {t} = useTranslation();
return <Suspense
fallback={<div>
<h1>{t("comp_manage")}</h1>
<p>{t("loading")}</p>
</div>}>
<CMLazy/>
</Suspense>
}
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 {t} = useTranslation();
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>{t("outdated_session.title")}</h5>
</div>
<div className="card-body">
<p className="card-text">{t("outdated_session.message")}</p>
</div>
<div className="card-footer">
<button className="btn btn-primary" onClick={() => login()} style={{marginRight: "0.5em"}}>{t("outdated_session.login_button")}</button>
<a className="btn btn-secondary" href="/">{t("nav.home")}</a>
</div>
</div>
</div>
</div>
</>
}
function App() {
console.log('render')
return <KeycloakContextProvider>
<RouterProvider router={router}/>
</KeycloakContextProvider>;
}
export default App