commit e2f243718ec2cdb04267fba22b2167d02dba0bcc
parent ceeaa524f0dd0e9cc5859092c2c371003f390da2
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date: Wed, 5 Apr 2023 00:21:10 +0200
feat(athletes): UI to delete athletes
Diffstat:
2 files changed, 77 insertions(+), 0 deletions(-)
diff --git a/src/App.js b/src/App.js
@@ -6,6 +6,7 @@ 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'));
@@ -19,6 +20,7 @@ function Layout({session}) {
<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>
{session ? <li><button onClick={() => supabase.auth.signOut()}>Sign out {session.user.email}</button></li> : ""}
</ul>
</nav>
@@ -62,6 +64,7 @@ function App() {
<Route path="/leaderboard" element={<Leaderboard />} />
<Route path="/rate" element={<Rate session={session} />} />
<Route path="/heats" element={<Heats session={session} />} />
+ <Route path="/athletes" element={<Athletes session={session} />} />
<Route path="/auth" element={<Auth />} />
<Route path="*" element={<NoMatch />} />
</Route>
diff --git a/src/Athletes.js b/src/Athletes.js
@@ -0,0 +1,74 @@
+import { lazy, useEffect, useState } from 'react'
+import { supabase } from './supabaseClient';
+
+const Auth = lazy(() => import('./Auth'));
+
+async function deleteAthlete(e, athleteId, athleteFirstName, athleteLastName) {
+ e.preventDefault()
+
+ const athleteName = athleteFirstName + (athleteLastName ? ' ' + athleteLastName : '')
+ if (window.confirm('Do you really want to delete athlete "' + athleteName + '"?')) {
+ await supabase
+ .from('athletes')
+ .delete()
+ .eq('id', athleteId)
+ window.location.reload()
+ }
+}
+
+function AthleteForm({session}) {
+ const [loading, setLoading] = useState(false)
+ const [athletes, setAthletes] = useState([])
+
+ useEffect(() => {
+ (async () => {
+ setLoading(true)
+ const athleteList = await supabase.from('athletes').select()
+ if (athleteList.error === null)
+ setAthletes(athleteList.data)
+ setLoading(false)
+ })();
+ }, [])
+
+ return (
+ <div>
+ <h1>Manage Athletes <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1>
+ <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>
+ {athletes.map(a => (
+ <tr key={a.id}>
+ <td className='right'>{new Date(a.created_at).toLocaleString()}</td>
+ <td className='right'>{a.nr}</td>
+ <td>{a.firstname}</td>
+ <td>{a.lastname}</td>
+ <td className='right'>{a.birthday}</td>
+ <td>{a.school}</td>
+ <td className='right'><button onClick={e => deleteAthlete(e, a.id, a.firstname, a.lastname)}>🗑️</button></td>
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ )
+}
+
+function Athletes({session}) {
+ return (
+ <div>
+ {!session ? <Auth /> : <AthleteForm key={session.user.id} session={session} />}
+ </div>
+ )
+ }
+
+ export default Athletes;