Startlist.js (4448B)
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 <h1>Startlist #{heatId} {heatName} <button disabled={!loading}>{loading ? '🔄 loading' : ''}</button></h1> 96 <div className='heatInfo'> 97 <ul> 98 <li><b>Location:</b>   {heatLocation ? heatLocation : 'n/a'}</li> 99 <li><b>Planned start:</b> {heatStart ? heatStart : 'n/a'}</li> 100 </ul> 101 </div> 102 <table> 103 <thead> 104 <tr> 105 <th>Nr</th> 106 <th>Firstname</th> 107 <th>Lastname</th> 108 <th>Birthday</th> 109 <th>School</th> 110 <th>Add/remove</th> 111 </tr> 112 </thead> 113 <tbody> 114 {startlist.map(i => ( 115 <tr key={i.id}> 116 <td className='right'>{i.athlete.nr}</td> 117 <td>{i.athlete.firstname}</td> 118 <td>{i.athlete.lastname}</td> 119 <td className='right'>{i.athlete.birthday}</td> 120 <td>{i.athlete.school}</td> 121 <td className='right'><button onClick={e => removeAthleteFromHeat( 122 e, 123 i.id, 124 i.athlete.firstname, 125 i.athlete.lastname, 126 heatName 127 )}>🗑️ remove</button></td> 128 </tr> 129 ))} 130 <tr> 131 <td></td> 132 <td colSpan={2}> 133 <Select 134 options={athleteOpts} 135 onChange={(e) => setselectedAthlete(e)} 136 /> 137 </td> 138 <td colSpan={2}></td> 139 <td className='right'> 140 <button onClick={(e) => addAthleteToHeat(e, selectedAthlete, heatId)}>➕ add</button> 141 </td> 142 </tr> 143 </tbody> 144 </table> 145 </div> 146 ) 147 } 148 149 function Startlist({session}) { 150 const { heatId } = useParams(); 151 152 return ( 153 <div> 154 {!session ? <Auth /> : <StartlistForm heatId={heatId} />} 155 </div> 156 ) 157 } 158 159 export default Startlist