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 cd3c28307d376295499eb4e30a2d1a348a553ca9
parent 749e2272bdead6c36da0f9bb154406bef5cbe656
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date:   Fri,  7 Apr 2023 18:14:35 +0200

feat: remove athlete from heat

Diffstat:
Mschema/startlist.sql | 7+++++++
Msrc/App.css | 10++++++++++
Msrc/Startlist.js | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 81 insertions(+), 12 deletions(-)

diff --git a/schema/startlist.sql b/schema/startlist.sql @@ -80,6 +80,13 @@ ALTER TABLE ONLY public.startlist -- +-- Name: startlist Enable delete for authenticated users only; Type: POLICY; Schema: public; Owner: postgres +-- + +CREATE POLICY "Enable delete for authenticated users only" ON public.startlist FOR DELETE TO authenticated USING (true); + + +-- -- Name: startlist Enable insert for authenticated users only; Type: POLICY; Schema: public; Owner: postgres -- diff --git a/src/App.css b/src/App.css @@ -35,3 +35,13 @@ table.leaderboard tr td:first-child::before { button:disabled { visibility: hidden; } + +.heatInfo { + border-left: 10px solid rgb(255, 242, 166); +} +.heatInfo ul { + padding: 5px; +} +.heatInfo li { + list-style: none; +} diff --git a/src/Startlist.js b/src/Startlist.js @@ -1,11 +1,29 @@ import { lazy, useEffect, useState } from 'react' import { useParams } from 'react-router-dom' import { supabase } from './supabaseClient' +import { hasSelectionSupport } from '@testing-library/user-event/dist/utils' const Auth = lazy(() => import('./Auth')) -function StartlistForm({session, heatId}) { +async function removeAthleteFromHeat(e, startlistId, athleteFirstName, athleteLastName, heatName) { + e.preventDefault() + const athleteName = athleteFirstName + (athleteLastName ? ' ' + athleteLastName : '') + + if (window.confirm( + 'Do you really want to remove athlete "' + athleteName + '" from heat "' + heatName + '"?' + )) { + await supabase + .from('startlist') + .delete() + .eq('id', startlistId) + window.location.reload() + } +} + +function StartlistForm({heatId}) { const [heatName, setheatName] = useState("") + const [heatLocation, setheatLocation] = useState("") + const [heatStart, setheatStart] = useState("") const [loading, setLoading] = useState(false) const [startlist, setStartlist] = useState([]) @@ -15,16 +33,30 @@ function StartlistForm({session, heatId}) { setLoading(true) const startlistData = await supabase .from('startlist') - .select() + .select(` + id, + heat, + athlete ( + nr, + firstname, + lastname, + birthday, + school + ) + `) + .eq('heat', heatId) if (startlistData.error === null) setStartlist(startlistData.data) - const heatNameData = await supabase + const heatData = await supabase .from('heats') - .select('name') + .select('name, location, planned_start') .eq('id', heatId) .single() - if (heatNameData.error === null) - setheatName(heatNameData.data.name) + if (heatData.error === null) { + setheatName(heatData.data.name) + setheatLocation(heatData.data.location) + setheatStart(heatData.data.planned_start) + } setLoading(false) })(); }, [heatId]) @@ -32,24 +64,44 @@ function StartlistForm({session, heatId}) { return ( <div> <h1>Startlist #{heatId} {heatName} <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1> - <form method="post"> + <div className='heatInfo'> + <ul> + <li><b>Location:</b>&emsp;&emsp;&emsp;{heatLocation ? heatLocation : 'n/a'}</li> + <li><b>Planned start:</b>&emsp;{heatStart ? heatStart : 'n/a'}</li> + </ul> + </div> + {/* <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> + <th>Remove from heat</th> </tr> </thead> <tbody> - + {startlist.map(i => ( + <tr key={i.id}> + <td className='right'>{i.athlete.nr}</td> + <td>{i.athlete.firstname}</td> + <td>{i.athlete.lastname}</td> + <td className='right'>{i.athlete.birthday}</td> + <td>{i.athlete.school}</td> + <td className='right'><button onClick={e => removeAthleteFromHeat( + e, + i.id, + i.athlete.firstname, + i.athlete.lastname, + heatName + )}>🗑️</button></td> + </tr> + ))} </tbody> </table> - </form> + {/* </form> */} </div> ) } @@ -59,7 +111,7 @@ function Startlist({session}) { return ( <div> - {!session ? <Auth /> : <StartlistForm session={session} heatId={heatId} />} + {!session ? <Auth /> : <StartlistForm heatId={heatId} />} </div> ) }