myheats

Live heats, scoring and leaderboard for sport events
git clone https://git.in0rdr.ch/myheats.git
Log | Files | Refs | README | LICENSE

App.js (2632B)


      1 import './App.css'
      2 import { Suspense, lazy, useState, useEffect } from 'react'
      3 import { BrowserRouter as Router, Routes, Route, Outlet, Link } from 'react-router-dom'
      4 import { supabase } from './supabaseClient'
      5 
      6 
      7 const Score = lazy(() => import('./Score'))
      8 const Heats = lazy(() => import('./Heats'))
      9 const Athletes = lazy(() => import('./Athletes'))
     10 const Startlist = lazy(() => import('./Startlist'))
     11 const Auth = lazy(() => import('./Auth'))
     12 const Leaderboard = lazy(() => import('./Leaderboard'))
     13 
     14 document.title = process.env.REACT_APP_DOC_TITLE ? process.env.REACT_APP_DOC_TITLE : 'My Heats'
     15 
     16 function Layout({session}) {
     17   return (
     18     <div>
     19       <nav>
     20         <ul>
     21           <li><Link to="/">Leaderboard</Link></li>
     22           {session ? <li><Link to="/score">Scoring</Link></li> : ''}
     23           {session ? <li><Link to="/heats">Heats and Startlists</Link></li> : ''}
     24           {session ? <li> <Link to="/athletes">Athletes</Link></li> : ''}
     25           <li>
     26             {session ? <button onClick={() => supabase.auth.signOut()}> Sign out {session.user.email} </button> :
     27             <Link to="/auth">Login</Link>}
     28           </li>
     29         </ul>
     30       </nav>
     31       <Outlet />
     32       <div>
     33         <br />
     34         MyHeats <a href="https://code.in0rdr.ch/myheats/refs.html">v0.4-nightly</a>
     35       </div>
     36     </div>
     37   )
     38 }
     39 
     40 function NoMatch() {
     41   return (
     42     <div className="NoMatch">
     43       Nothing to see here, <Link to="/">go to leaderboard</Link>
     44     </div>
     45   )
     46 }
     47 
     48 function App() {
     49   const [session, setSession] = useState(null)
     50 
     51   useEffect(() => {
     52     // Returns the session, refreshing it if necessary
     53     supabase.auth.getSession().then(({ data: { session } }) => {
     54       setSession(session)
     55     })
     56 
     57     supabase.auth.onAuthStateChange((_event, session) => {
     58       setSession(session)
     59     })
     60   }, [])
     61 
     62   return (
     63     <div className="App">
     64       <Router>
     65         <Suspense fallback={<div>Loading...</div>}>
     66           <Routes>
     67             <Route path="/" element={<Layout session={session} />}>
     68               <Route path="/" element={<Leaderboard session={session} />} />
     69               <Route path="/score" element={<Score session={session} />} />
     70               <Route path="/heats" element={<Heats session={session} />} />
     71               <Route path="/athletes" element={<Athletes session={session} />} />
     72               <Route path="/startlist/:heatId"  element={<Startlist session={session} />} />
     73               <Route path="/auth" element={<Auth />} />
     74               <Route path="*" element={<NoMatch />} />
     75             </Route>
     76           </Routes>
     77         </Suspense>
     78       </Router>
     79     </div>
     80   );
     81 }
     82 
     83 export default App;