myheats

Live heats, scoring and leaderboard for sport events
git clone https://git.in0rdr.ch/myheats.git
Log | Files | Refs | README | LICENSE

Rate.js (2744B)


      1 import { lazy, useEffect, useState } from 'react'
      2 import { getStartlistForHeats } from './Leaderboard'
      3 import Select from 'react-select'
      4 import { supabase } from './supabaseClient'
      5 
      6 const Auth = lazy(() => import('./Auth'))
      7 
      8 async function updateRating(rating, heatId, athleteId, userId) {
      9   await supabase.from('ratings').upsert({
     10     rating: rating,
     11     heat: heatId,
     12     athlete: athleteId,
     13     judge: userId
     14   })
     15 }
     16 
     17 function RatingForm({session}) {
     18   const [heats, setHeats] = useState([])
     19   const [heatSelection, setHeatSelection] = useState(0)
     20   const [athleteOpts, setAthleteOpts] = useState([])
     21   const [athleteSelection, setAthleteSelection] = useState(0)
     22   const [rating, setRating] = useState(0)
     23 
     24   // add options to select or rank by heat
     25   const heatOpts = heats.map(h => {
     26     return {
     27       value: h.id,
     28       label: h.name
     29     }
     30   })
     31 
     32   useEffect(() => {
     33     (async () => {
     34       const heatList = await supabase.from('heats').select()
     35       setHeats(heatList.data)
     36 
     37       const startlist = await getStartlistForHeats([heatSelection.value])
     38 
     39       if (startlist.error)
     40         return
     41 
     42       setAthleteOpts(startlist.data.map(s => {
     43         return {
     44           value: s.athlete,
     45           label: s.nr + " " + s.firstname + " " + (s.lastname ? s.lastname : "")
     46         }
     47       }))
     48 
     49       if (heatSelection.value === undefined || athleteSelection.value === undefined)
     50         return
     51 
     52       // check if existing rating for heat and athlete exists
     53       const currentRating = await supabase.from('ratings').select()
     54         .eq('heat', heatSelection.value)
     55         .eq('athlete', athleteSelection.value)
     56         .eq('judge', session.user.id)
     57 
     58       if (rating === 0 && currentRating.data?.length > 0) {
     59         // fallback to current rating when no rating was given
     60         setRating(currentRating.data[0].rating)
     61       } else {
     62         // store new rating
     63         updateRating(rating,
     64           heatSelection.value,
     65           athleteSelection.value,
     66           session.user.id)
     67       }
     68     })();
     69   }, [heatSelection, athleteSelection, session.user.id, rating]);
     70 
     71   return (
     72     <div>
     73       <h1>Rate Athletes</h1>
     74       Heat:
     75           <Select
     76             options={heatOpts}
     77             onChange={h => { setHeatSelection(h); setRating(0) }}
     78           />
     79       Athlete:
     80       <Select
     81             options={athleteOpts}
     82             onChange={a => { setAthleteSelection(a); setRating(0) }}
     83           />
     84       Rating:
     85       <input
     86             type="number"
     87             size="5"
     88             value={rating}
     89             onChange={(e) => setRating(e.target.value)}
     90           />
     91     </div>
     92   )
     93 }
     94 
     95 function Rate({session}) {
     96   return (
     97     <div>
     98       {!session ? <Auth /> : <RatingForm session={session} />}
     99     </div>
    100   )
    101 }
    102 
    103 export default Rate