commit 85d73ae80442cd29d6a89c4502eb4ea3b37bdcc4
parent 99a58339accd294dd0dfff3b9e87b78534ddfe41
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date: Fri, 31 Mar 2023 23:11:44 +0200
fix: TypeErrors leaderboard & heats
Diffstat:
M | src/Leaderboard.js | | | 140 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
1 file changed, 79 insertions(+), 61 deletions(-)
diff --git a/src/Leaderboard.js b/src/Leaderboard.js
@@ -18,32 +18,34 @@ async function getRatingForHeatAndAthlete(heatId, athleteId) {
}
async function getRatingSummary(heatIds) {
- let startlist = {data: []}
- startlist = await getStartlistForHeats(heatIds)
+ const startListWithRatings = []
+
+ const startlist = await getStartlistForHeats(heatIds)
if (startlist.error !== null) {
- return {data: []}
+ // fail silently & return empty startlist in case of errors
+ return []
}
- let startListWithRatings = []
-
for (const i of startlist.data) {
i.heats = []
for (const h of heatIds) {
- let ratings = await getRatingForHeatAndAthlete(h, i.athlete)
+ const ratings = await getRatingForHeatAndAthlete(h, i.athlete)
- let summary = {data: []}
- summary = await supabase.from('rating_summary').select('rating_summary')
+ const summary = await supabase.from('rating_summary').select('rating_summary')
.eq('heat_id', h)
.eq('athlete_id', i.athlete)
- // add heat results of athlete to startlist entry
- i.heats.push({
- heatId: h,
- ratings: ratings.data,
- summary: summary.data.length > 0 ? summary.data[0].rating_summary : 0
- })
+ if (summary.error === null) {
+ // add heat results of athlete to startlist entry
+ i.heats.push({
+ heatId: h,
+ ratings: ratings.data,
+ summary: summary.data.length > 0 ? summary.data[0].rating_summary : 0
+ })
+ }
+ // else don't push any heats (fail silently)
// find best/worst heat
i.bestHeat = Math.max(...i.heats.map(h => h.summary))
@@ -90,7 +92,7 @@ function rankByHeat(rankingComp) {
}
}
-async function newHeatFromLeaderboard(e, leaderboard, rankingComp, selectHeatRef, newHeatSize, newHeatName) {
+async function newHeatFromLeaderboard(e, leaderboard, rankingComp, selectHeatRef, selectRankRef, newHeatSize, newHeatName) {
e.preventDefault()
if (leaderboard.length === 0) {
@@ -103,8 +105,6 @@ async function newHeatFromLeaderboard(e, leaderboard, rankingComp, selectHeatRef
return
}
- selectHeatRef.current.clearValue()
-
// create new heat
const { data, error } = await supabase
.from('heats')
@@ -116,7 +116,7 @@ async function newHeatFromLeaderboard(e, leaderboard, rankingComp, selectHeatRef
return
}
- let sortedBoard = leaderboard.sort(rankByHeat(rankingComp))
+ const sortedBoard = leaderboard.sort(rankByHeat(rankingComp))
for (let i = 0; i < newHeatSize && i < sortedBoard.length; i++ ) {
// add top N athletes from current leaderboard to new heat
await supabase
@@ -124,54 +124,26 @@ async function newHeatFromLeaderboard(e, leaderboard, rankingComp, selectHeatRef
.insert({ heat: data[0].id, athlete: sortedBoard[i].athlete })
}
- // clear values in heat Select box to refresh list of heats
+ // clear values in selects to refresh list of heats
selectHeatRef.current.clearValue()
+ selectRankRef.current.clearValue()
alert('Created new heat "' + newHeatName + '" with top ' + newHeatSize + ' athletes')
}
function Leaderboard() {
const [leaderboard, setLeaderboard] = useState([])
- const [heatSelection, setHeatSelection] = useState([{value: 0, label: ''}])
+ const [heatSelection, setHeatSelection] = useState([])
const [heats, setHeats] = useState([])
- const [rankingComp, setRankingComp] = useState([{value: 0, label: ''}])
+ const [heatOpts, setHeatOpts] = useState([])
+ const [rankOpts, setRankOpts] = useState([])
+ const [rankingComp, setRankingComp] = useState([])
// state for new heat from top N leaderboard
const [newHeatSize, setNewHeatSize] = useState(6)
const [newHeatName, setNewHeatName] = useState("Heat name")
const selectHeatRef = useRef();
-
- // add options to select or rank by heat
- const heatOpts = heats.map(h => {
- return {
- value: h.id,
- label: h.name
- }
- })
-
- // add options to rank by best/worst heat
- const rankOpts = heatOpts.map(h => {
- return {
- value: h.value,
- label: "Sum " + h.label
- }
- })
-
- rankOpts.push(...[
- {
- value: 'start',
- label: 'Start Nr.'
- }, {
- value: 'best',
- label: 'Best Heat'
- }, {
- value: 'worst',
- label: 'Worst Heat'
- }, {
- value: 'total',
- label: 'Total Sum (all heats)'
- }
- ])
+ const selectRankRef = useRef();
// subscribe to ratings from judges and
// reload all ratings to refresh leaderboard
@@ -183,21 +155,66 @@ function Leaderboard() {
table: 'ratings',
},
async (payload) => {
- let ratingSummary = await getRatingSummary(heatSelection.map(h => h.value))
+ const ratingSummary = await getRatingSummary(heatSelection.map(h => h.value))
setLeaderboard(ratingSummary)
}
).subscribe()
useEffect(() => {
(async () => {
- let heatList = {data: []}
- heatList = await supabase.from('heats').select()
+ const heatList = await supabase.from('heats').select()
setHeats(heatList.data)
- let ratingSummary = await getRatingSummary(heatSelection.map(h => h.value))
+ // add options to select or rank by heat
+ setHeatOpts(heats.map(h => {
+ return {
+ value: h.id,
+ label: h.name
+ }
+ }))
+
+ // add static ranking options
+ const rankOptions = [
+ {
+ value: 'start',
+ label: 'Start Nr.'
+ }, {
+ value: 'best',
+ label: 'Best Heat'
+ }, {
+ value: 'worst',
+ label: 'Worst Heat'
+ }, {
+ value: 'total',
+ label: 'Total Sum (all heats)'
+ }
+ ]
+
+ // add dynamic options to rank by best/worst heat
+ const myHeatOpts = heatOpts.map(h => {
+ return {
+ value: h.value,
+ label: "Sum " + h.label
+ }
+ })
+
+ const groupedOptions = [
+ {
+ label: "Overall",
+ options: rankOptions
+ },
+ {
+ label: "Heat Sum",
+ options: myHeatOpts
+ }
+ ];
+
+ setRankOpts(groupedOptions)
+
+ const ratingSummary = await getRatingSummary(heatSelection.map(h => h.value))
setLeaderboard(ratingSummary)
})();
- }, [heatSelection, leaderboard]);
+ }, [heatSelection, heatOpts, heats]);
return (
<div className="Leaderboard">
@@ -217,6 +234,7 @@ function Leaderboard() {
isMulti
options={rankOpts}
onChange={h => setRankingComp(h)}
+ ref={selectRankRef}
/>
<form>
New heat from top <input
@@ -226,11 +244,12 @@ function Leaderboard() {
onChange={(e) => setNewHeatSize(e.target.value)}
/>:
<input type="text" value={newHeatName} onChange={(e) => setNewHeatName(e.target.value)} />
- <button onClick={(e) => newHeatFromLeaderboard(
+ <button onClick={e => newHeatFromLeaderboard(
e,
leaderboard,
rankingComp,
selectHeatRef,
+ selectRankRef,
newHeatSize,
newHeatName
)}>Create</button>
@@ -291,4 +310,4 @@ function Leaderboard() {
);
}
-export default Leaderboard;
-\ No newline at end of file
+export default Leaderboard;