commit 3810931c36b65fdf390e374950523441060beeff
parent a5c4c577c6e59aab4e9812964a27b9fc67c28c1e
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date: Thu, 6 Apr 2023 01:06:45 +0200
feat: add athletes
Diffstat:
3 files changed, 87 insertions(+), 5 deletions(-)
diff --git a/schema/athletes.sql b/schema/athletes.sql
@@ -59,11 +59,11 @@ ALTER TABLE public.athletes ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY
--
--- Name: athletes slopestyle_snowboard_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
+-- Name: athletes athletes_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.athletes
- ADD CONSTRAINT slopestyle_snowboard_pkey PRIMARY KEY (id);
+ ADD CONSTRAINT athletes_pkey PRIMARY KEY (id);
--
@@ -74,6 +74,13 @@ CREATE POLICY "Enable delete for authenticated users only" ON public.athletes FO
--
+-- Name: athletes Enable insert for authenticated users only; Type: POLICY; Schema: public; Owner: postgres
+--
+
+CREATE POLICY "Enable insert for authenticated users only" ON public.athletes FOR INSERT TO authenticated WITH CHECK (true);
+
+
+--
-- Name: athletes Enable read access for all users; Type: POLICY; Schema: public; Owner: postgres
--
diff --git a/src/Athletes.js b/src/Athletes.js
@@ -3,6 +3,53 @@ import { supabase } from './supabaseClient';
const Auth = lazy(() => import('./Auth'));
+async function addAthlete(e) {
+ e.preventDefault()
+
+ // Read the form data
+ const formData = new FormData(e.target);
+ const formJson = Object.fromEntries(formData.entries());
+
+ if (defaultsSet(formJson)) {
+ alert('Check data of the new athlete, seems like the defaults')
+ return
+ }
+
+ // create new athlete
+ const { data, error } = await supabase
+ .from('athletes')
+ .insert({
+ nr: formJson.nr,
+ firstname: formJson.firstname,
+ lastname: formJson.lastname,
+ birthday: formJson.birthday ? formJson.birthday : null,
+ school: formJson.school
+ })
+ .select()
+
+ if (error === null) {
+ window.location.reload()
+ } else {
+ alert('Failed to create new athlete: ' + error.message)
+ }
+}
+
+function defaultsSet({nr, firstname, lastname, birthday, school}) {
+ return (
+ nr === '00'
+ || firstname === 'Firstname'
+ || lastname === 'Lastname'
+ || birthday === '0000-00-00'
+ || school === 'School/team'
+ )
+}
+
+function validateBirthday(e) {
+ if (e.target.validity.patternMismatch) {
+ e.target.value = e.target.defaultValue
+ }
+}
+
async function deleteAthlete(e, athleteId, athleteFirstName, athleteLastName) {
e.preventDefault()
@@ -33,6 +80,7 @@ function AthleteForm({session}) {
return (
<div>
<h1>Manage Athletes <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1>
+ <form method="post" onSubmit={addAthlete}>
<table>
<thead>
<tr>
@@ -57,8 +105,35 @@ function AthleteForm({session}) {
<td className='right'><button onClick={e => deleteAthlete(e, a.id, a.firstname, a.lastname)}>🗑️</button></td>
</tr>
))}
+ <tr>
+ <td className='right'><i>* required</i></td>
+ <td className='right'>
+ <input type='number' name='nr' defaultValue='00' /> *
+ </td>
+ <td>
+ <input type='text' name='firstname' defaultValue='Firstname' /> *
+ </td>
+ <td>
+ <input type='text' name='lastname' defaultValue='Lastname' />
+ </td>
+ <td className='right'>
+ <input
+ type='text'
+ name='birthday'
+ defaultValue='0000-00-00'
+ pattern='(\d{4}-\d{2}-\d{2})*'
+ onBlur={(e) => validateBirthday(e)} />
+ </td>
+ <td>
+ <input type='text' name='school' defaultValue='School/team' />
+ </td>
+ <td className='right'>
+ <button type='submit'>➕ add</button>
+ </td>
+ </tr>
</tbody>
</table>
+ </form>
</div>
)
}
diff --git a/src/Leaderboard.js b/src/Leaderboard.js
@@ -260,12 +260,12 @@ function Leaderboard() {
/>
<form>
New heat from top <input
- type="number"
- size="5"
+ type='number'
+ size='5'
value={newHeatSize}
onChange={(e) => setNewHeatSize(e.target.value)}
/>:
- <input type="text" value={newHeatName} onChange={(e) => setNewHeatName(e.target.value)} />
+ <input type='text' value={newHeatName} onChange={(e) => setNewHeatName(e.target.value)} />
<button onClick={e => newHeatFromLeaderboard(
e,
leaderboard,