Athletes.jsx (4039B)
1 import { lazy, useEffect, useState } from 'react' 2 import { supabase } from './supabaseClient' 3 import { exportAthletesToCSV } from './utils' 4 5 const Auth = lazy(() => import('./Auth')) 6 7 async function addAthlete(e) { 8 e.preventDefault() 9 10 // Read the form data 11 const formData = new FormData(e.target); 12 const formJson = Object.fromEntries(formData.entries()); 13 14 // create new athlete 15 const { error } = await supabase 16 .from('athletes') 17 .insert({ 18 nr: formJson.nr, 19 firstname: formJson.firstname, 20 lastname: formJson.lastname, 21 birthday: formJson.birthday ? formJson.birthday : null, 22 school: formJson.school 23 }) 24 25 if (error === null) { 26 window.location.reload() 27 } else { 28 alert('Failed to create new athlete: ' + error.message) 29 } 30 } 31 32 async function deleteAthlete(e, athleteId, athleteFirstName, athleteLastName) { 33 e.preventDefault() 34 35 const athleteName = athleteFirstName + (athleteLastName ? ' ' + athleteLastName : '') 36 if (window.confirm('Do you really want to delete athlete "' + athleteName + '"?')) { 37 await supabase 38 .from('athletes') 39 .delete() 40 .eq('id', athleteId) 41 window.location.reload() 42 } 43 } 44 45 // export athletes 46 function ExportForm() { 47 return ( 48 <div className='exportForm'> 49 <form method='post' onSubmit={e => exportAthletesToCSV(e)}> 50 <button type='submit'>▿ export</button> 51 </form> 52 </div> 53 ) 54 } 55 56 function AthleteForm({session}) { 57 const [loading, setLoading] = useState(false) 58 const [athletes, setAthletes] = useState([]) 59 60 useEffect(() => { 61 (async () => { 62 setLoading(true) 63 const athleteList = await supabase.from('athletes').select() 64 if (athleteList.error === null) 65 setAthletes(athleteList.data) 66 setLoading(false) 67 })(); 68 }, []) 69 70 return ( 71 <div> 72 <button disabled={!loading}>{loading ? '↺ loading' : ''}</button> 73 <form method='post' onSubmit={addAthlete}> 74 <table> 75 <thead> 76 <tr> 77 <th>Created at</th> 78 <th>Start Nr. *</th> 79 <th>Firstname *</th> 80 <th>Lastname</th> 81 <th>Birthday</th> 82 <th>School</th> 83 <th>New/delete</th> 84 </tr> 85 </thead> 86 <tbody> 87 {athletes.map(a => ( 88 <tr key={a.id}> 89 <td data-title='Created at' className='right'>{new Date(a.created_at).toLocaleDateString()}</td> 90 <td data-title='Start Nr.' className='right'>{a.nr}</td> 91 <td data-title='Firstname'>{a.firstname}</td> 92 <td data-title='Lastname'>{a.lastname}</td> 93 <td data-title='Birthday'>{a.birthday}</td> 94 <td data-title='School'>{a.school}</td> 95 <td><button onClick={e => deleteAthlete(e, a.id, a.firstname, a.lastname)}>– del</button></td> 96 </tr> 97 ))} 98 <tr className='input'> 99 <td className='right'><i>* required</i></td> 100 <td data-title='Start Nr. *' className='right'> 101 <input type='number' name='nr' /> 102 </td> 103 <td data-title='Firstname *'> 104 <input type='text' name='firstname' /> 105 </td> 106 <td data-title='Lastname'> 107 <input type='text' name='lastname' /> 108 </td> 109 <td data-title='Birthday' className='right'> 110 <input 111 type='date' 112 name='birthday' /> 113 </td> 114 <td data-title='School'> 115 <input type='text' name='school' /> 116 </td> 117 <td> 118 <button type='submit'>+ new</button> 119 </td> 120 </tr> 121 </tbody> 122 </table> 123 </form> 124 <ExportForm /> 125 </div> 126 ) 127 } 128 129 function Athletes({session}) { 130 return ( 131 <div> 132 {!session ? <Auth /> : <AthleteForm session={session} />} 133 </div> 134 ) 135 } 136 137 export default Athletes