Startlist.jsx (4476B)
1 import { lazy, useEffect, useState } from 'react' 2 import { useParams } from 'react-router-dom' 3 import Select from 'react-select' 4 import { supabase } from './supabaseClient' 5 6 const Auth = lazy(() => import('./Auth')) 7 8 async function addAthleteToHeat(e, selectedAthlete, heatId) { 9 e.preventDefault() 10 11 const { error } = await supabase.from('startlist').upsert({ 12 athlete: selectedAthlete.value, 13 heat: heatId 14 }) 15 16 if (error === null) 17 window.location.reload() 18 } 19 20 async function removeAthleteFromHeat(e, startlistId, athleteFirstName, athleteLastName, heatName) { 21 e.preventDefault() 22 const athleteName = athleteFirstName + (athleteLastName ? ' ' + athleteLastName : '') 23 24 if (window.confirm('Do you really want to remove athlete "' + athleteName + '" from heat "' + heatName + '"?')) { 25 await supabase 26 .from('startlist') 27 .delete() 28 .eq('id', startlistId) 29 window.location.reload() 30 } 31 } 32 33 function StartlistForm({heatId}) { 34 const [heatName, setheatName] = useState("") 35 const [heatLocation, setheatLocation] = useState("") 36 const [heatStart, setheatStart] = useState("") 37 const [startlist, setStartlist] = useState([]) 38 const [athleteOpts, setAthleteOpts] = useState([]) 39 const [selectedAthlete, setselectedAthlete] = useState({}) 40 41 const [loading, setLoading] = useState(false) 42 43 useEffect(() => { 44 (async () => { 45 setLoading(true) 46 47 const startlistData = await supabase 48 .from('startlist') 49 .select(` 50 id, 51 heat, 52 athlete ( 53 id, 54 nr, 55 firstname, 56 lastname, 57 birthday, 58 school 59 ) 60 `) 61 .eq('heat', heatId) 62 63 if (startlistData.error === null) 64 setStartlist(startlistData.data) 65 66 const heatData = await supabase 67 .from('heats') 68 .select('name, location, planned_start') 69 .eq('id', heatId) 70 .single() 71 72 if (heatData.error === null) { 73 setheatName(heatData.data.name) 74 setheatLocation(heatData.data.location) 75 setheatStart(heatData.data.planned_start) 76 } 77 78 const athleteList = await supabase.from('athletes').select() 79 if (athleteList.error === null) { 80 let options = athleteList.data.map(a => { 81 return { 82 value: a.id, 83 label: a.nr + " " + a.firstname + " " + (a.lastname ? a.lastname : "") 84 } 85 }) 86 setAthleteOpts(options) 87 } 88 89 setLoading(false) 90 })(); 91 }, [heatId]) 92 93 return ( 94 <div> 95 <button disabled={!loading}>{loading ? '↺ loading' : ''}</button> 96 <h1>Startlist #{heatId} {heatName}</h1> 97 <div className='heatInfo'> 98 <ul> 99 <li><b>Location:</b> {heatLocation ? heatLocation : 'n/a'}</li> 100 <li><b>Planned start:</b> {heatStart ? heatStart : 'n/a'}</li> 101 </ul> 102 </div> 103 <table> 104 <thead> 105 <tr> 106 <th>Start Nr.</th> 107 <th>Firstname</th> 108 <th>Lastname</th> 109 <th>Birthday</th> 110 <th>School</th> 111 <th>Add/Delete</th> 112 </tr> 113 </thead> 114 <tbody> 115 {startlist.map(i => ( 116 <tr key={i.id}> 117 <td data-title='Start Nr.' className='right'>{i.athlete.nr}</td> 118 <td data-title='Firstname'>{i.athlete.firstname}</td> 119 <td data-title='Lastname'>{i.athlete.lastname}</td> 120 <td data-title='Birthday'>{i.athlete.birthday}</td> 121 <td data-title='School'>{i.athlete.school}</td> 122 <td><button onClick={e => removeAthleteFromHeat( 123 e, 124 i.id, 125 i.athlete.firstname, 126 i.athlete.lastname, 127 heatName 128 )}>– del</button></td> 129 </tr> 130 ))} 131 <tr className='input'> 132 <td data-title='Athlete' colSpan={5}> 133 <Select 134 options={athleteOpts} 135 onChange={(e) => setselectedAthlete(e)} 136 /> 137 </td> 138 <td> 139 <button onClick={(e) => addAthleteToHeat(e, selectedAthlete, heatId)}>+ add</button> 140 </td> 141 </tr> 142 </tbody> 143 </table> 144 </div> 145 ) 146 } 147 148 function Startlist({session}) { 149 const { heatId } = useParams(); 150 151 return ( 152 <div> 153 {!session ? <Auth /> : <StartlistForm heatId={heatId} />} 154 </div> 155 ) 156 } 157 158 export default Startlist