myheats

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

commit 749e2272bdead6c36da0f9bb154406bef5cbe656
parent 3810931c36b65fdf390e374950523441060beeff
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date:   Fri,  7 Apr 2023 17:10:23 +0200

feat: add startlist routing

Diffstat:
Msrc/App.js | 16+++++++++-------
Msrc/Athletes.js | 8++++----
Msrc/Heats.js | 15+++++++++++----
Msrc/Rate.js | 6+++---
Asrc/Startlist.js | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 94 insertions(+), 18 deletions(-)

diff --git a/src/App.js b/src/App.js @@ -4,11 +4,12 @@ import { BrowserRouter as Router, Routes, Route, Outlet, Link } from 'react-rout import { supabase } from './supabaseClient' -const Rate = lazy(() => import('./Rate')); -const Heats = lazy(() => import('./Heats')); -const Athletes = lazy(() => import('./Athletes')); -const Auth = lazy(() => import('./Auth')); -const Leaderboard = lazy(() => import('./Leaderboard')); +const Rate = lazy(() => import('./Rate')) +const Heats = lazy(() => import('./Heats')) +const Athletes = lazy(() => import('./Athletes')) +const Startlist = lazy(() => import('./Startlist')) +const Auth = lazy(() => import('./Auth')) +const Leaderboard = lazy(() => import('./Leaderboard')) document.title = process.env.REACT_APP_DOC_TITLE ? process.env.REACT_APP_DOC_TITLE : 'My Heats' @@ -19,8 +20,8 @@ function Layout({session}) { <ul> <li><Link to="/leaderboard">Leaderboard</Link></li> <li><Link to="/rate">Rate</Link></li> - <li><Link to="/heats">Manage Heats</Link></li> - <li><Link to="/athletes">Manage Athletes</Link></li> + <li><Link to="/heats">Heats and Startlists</Link></li> + <li><Link to="/athletes">Athletes</Link></li> {session ? <li><button onClick={() => supabase.auth.signOut()}>Sign out {session.user.email}</button></li> : ""} </ul> </nav> @@ -65,6 +66,7 @@ function App() { <Route path="/rate" element={<Rate session={session} />} /> <Route path="/heats" element={<Heats session={session} />} /> <Route path="/athletes" element={<Athletes session={session} />} /> + <Route path="/startlist/:heatId" element={<Startlist session={session} />} /> <Route path="/auth" element={<Auth />} /> <Route path="*" element={<NoMatch />} /> </Route> diff --git a/src/Athletes.js b/src/Athletes.js @@ -1,7 +1,7 @@ import { lazy, useEffect, useState } from 'react' -import { supabase } from './supabaseClient'; +import { supabase } from './supabaseClient' -const Auth = lazy(() => import('./Auth')); +const Auth = lazy(() => import('./Auth')) async function addAthlete(e) { e.preventDefault() @@ -79,7 +79,7 @@ function AthleteForm({session}) { return ( <div> - <h1>Manage Athletes <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1> + <h1>Athletes <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1> <form method="post" onSubmit={addAthlete}> <table> <thead> @@ -141,7 +141,7 @@ function AthleteForm({session}) { function Athletes({session}) { return ( <div> - {!session ? <Auth /> : <AthleteForm key={session.user.id} session={session} />} + {!session ? <Auth /> : <AthleteForm session={session} />} </div> ) } diff --git a/src/Heats.js b/src/Heats.js @@ -1,7 +1,8 @@ import { lazy, useEffect, useState } from 'react' -import { supabase } from './supabaseClient'; +import { useNavigate, generatePath } from 'react-router-dom' +import { supabase } from './supabaseClient' -const Auth = lazy(() => import('./Auth')); +const Auth = lazy(() => import('./Auth')) async function deleteHeat(e, heatId, heatName) { e.preventDefault() @@ -19,6 +20,8 @@ function HeatForm({session}) { const [loading, setLoading] = useState(false) const [heats, setHeats] = useState([]) + const navigate = useNavigate() + useEffect(() => { (async () => { setLoading(true) @@ -31,7 +34,7 @@ function HeatForm({session}) { return ( <div> - <h1>Manage Heats <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1> + <h1>Heats <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1> <table> <thead> <tr> @@ -39,6 +42,7 @@ function HeatForm({session}) { <th>Name</th> <th>Location</th> <th>Planned start</th> + <th>Startlist</th> <th>Delete</th> </tr> </thead> @@ -49,6 +53,9 @@ function HeatForm({session}) { <td>{h.name}</td> <td>{h.location}</td> <td className='right'>{h.planned_start}</td> + <td className='right'> + <button onClick={e => navigate(generatePath('/startlist/:heatId', {heatId:h.id}))}>🏁</button> + </td> <td className='right'><button onClick={e => deleteHeat(e, h.id, h.name)}>🗑️</button></td> </tr> ))} @@ -61,7 +68,7 @@ function HeatForm({session}) { function Heats({session}) { return ( <div> - {!session ? <Auth /> : <HeatForm key={session.user.id} session={session} />} + {!session ? <Auth /> : <HeatForm session={session} />} </div> ) } diff --git a/src/Rate.js b/src/Rate.js @@ -1,9 +1,9 @@ import { lazy, useEffect, useState } from 'react' import { getStartlistForHeats } from './Leaderboard' import Select from 'react-select' -import { supabase } from './supabaseClient'; +import { supabase } from './supabaseClient' -const Auth = lazy(() => import('./Auth')); +const Auth = lazy(() => import('./Auth')) async function updateRating(rating, heatId, athleteId, userId) { await supabase.from('ratings').upsert({ @@ -95,7 +95,7 @@ function RatingForm({session}) { function Rate({session}) { return ( <div> - {!session ? <Auth /> : <RatingForm key={session.user.id} session={session} />} + {!session ? <Auth /> : <RatingForm session={session} />} </div> ) } diff --git a/src/Startlist.js b/src/Startlist.js @@ -0,0 +1,67 @@ +import { lazy, useEffect, useState } from 'react' +import { useParams } from 'react-router-dom' +import { supabase } from './supabaseClient' + +const Auth = lazy(() => import('./Auth')) + +function StartlistForm({session, heatId}) { + const [heatName, setheatName] = useState("") + + const [loading, setLoading] = useState(false) + const [startlist, setStartlist] = useState([]) + + useEffect(() => { + (async () => { + setLoading(true) + const startlistData = await supabase + .from('startlist') + .select() + if (startlistData.error === null) + setStartlist(startlistData.data) + const heatNameData = await supabase + .from('heats') + .select('name') + .eq('id', heatId) + .single() + if (heatNameData.error === null) + setheatName(heatNameData.data.name) + setLoading(false) + })(); + }, [heatId]) + + return ( + <div> + <h1>Startlist #{heatId} {heatName} <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1> + <form method="post"> + <table> + <thead> + <tr> + <th>Created at</th> + <th>Nr</th> + <th>Firstname</th> + <th>Lastname</th> + <th>Birthday</th> + <th>School</th> + <th>Delete</th> + </tr> + </thead> + <tbody> + + </tbody> + </table> + </form> + </div> + ) +} + +function Startlist({session}) { + const { heatId } = useParams(); + + return ( + <div> + {!session ? <Auth /> : <StartlistForm session={session} heatId={heatId} />} + </div> + ) + } + + export default Startlist;