commit c87d07ab995bf37c9d9ae7da37fe9477a965d491
parent b0853f4821f4a8f8dce63f78c40f20d5c284cc87
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date: Thu, 9 Mar 2023 00:16:07 +0100
feat: add sorting for best/worst/sum
Diffstat:
M | src/App.css | | | 21 | +++++++++++++++++++++ |
M | src/App.js | | | 71 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- |
2 files changed, 77 insertions(+), 15 deletions(-)
diff --git a/src/App.css b/src/App.css
@@ -9,4 +9,25 @@ tr, th,td {
.right {
text-align: right;
+}
+
+/* set medal icon for first three rows */
+table tr:first-child td:first-child::after {
+ content: "🥇";
+}
+table tr:nth-child(2) td:first-child::after {
+ content: "🥈";
+}
+table tr:nth-child(3) td:first-child::after {
+ content: "🥉";
+}
+
+/* increment rank row number */
+table tr {
+ counter-increment: rowNumber;
+}
+table tr td:first-child::before {
+ content: counter(rowNumber);
+ min-width: 1em;
+ margin-right: 0.5em;
}
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
@@ -49,6 +49,13 @@ async function getRatingSummary(heatIds) {
ratings: ratings.data,
summary: summary.data.length > 0 ? summary.data[0].rating_summary : 0
})
+
+ // find best/worst heat
+ i.bestHeat = Math.max(...i.heats.map(h => h.summary))
+ i.worstHeat = Math.min(...i.heats.map(h => h.summary))
+
+ // sum up all totals across heats
+ i.sum = i.heats.map(h => h.summary).reduce((a, b) => a + b, 0)
}
startListWithRatings.push(i)
@@ -61,8 +68,22 @@ function rankByHeat(rankingComp) {
return function(a, b) {
// rank by chosen heat or ranking comparator
for (const r of rankingComp) {
- if (b.heats.find(h => h.heatId === r.value)?.summary - a.heats.find(h => h.heatId === r.value)?.summary !== 0) {
- return b.heats.find(h => h.heatId === r.value)?.summary - a.heats.find(h => h.heatId === r.value)?.summary
+ switch(r.value) {
+ case 'best':
+ if (b.bestHeat - a.bestHeat !== 0) {
+ // rank by best heat first
+ return b.bestHeat - a.bestHeat
+ }
+ // rank by least worst heat for identical best heats
+ return b.worstHeat - a.worstHeat
+ case 'worst':
+ // rank by worst heat
+ return b.worstHeat - a.worstHeat
+ default:
+ // rank by heat totals
+ if (b.heats.find(h => h.heatId === r.value)?.summary - a.heats.find(h => h.heatId === r.value)?.summary !== 0) {
+ return b.heats.find(h => h.heatId === r.value)?.summary - a.heats.find(h => h.heatId === r.value)?.summary
+ }
}
}
}
@@ -74,11 +95,31 @@ function App() {
const [heats, setHeats] = useState([]);
const [rankingComp, setRankingComp] = useState([{value: 0, label: ''}]);
+ // add options to select or rank by heat
+ let heatOpts = heats.map(h => {
+ return {
+ value: h.id,
+ label: h.name
+ }
+ })
+
+ // add options to rank by best/worst heat
+ let rankOpts = heatOpts.concat([
+ {
+ value: 'best',
+ label: 'Best Heat'
+ }, {
+ value: 'worst',
+ label: 'Worst Heat'
+ }
+ ])
+
useEffect(() => {
(async () => {
let heatList = {data: []}
heatList = await supabase.from('heats').select()
setHeats(heatList.data)
+
let ratingSummary = await getRatingSummary(heatSelection.map(h => h.value))
setLeaderboard(ratingSummary)
})();
@@ -107,34 +148,30 @@ function App() {
<Select
closeMenuOnSelect={false}
isMulti
- options={heats.map(h => {return {
- value: h.id,
- label: h.name
- }})}
+ options={heatOpts}
onChange={h => setHeatSelection(h)}
/>
Rank by (in this order):
<Select
closeMenuOnSelect={false}
isMulti
- options={heats.map(h => {return {
- value: h.id,
- label: h.name
- }})}
+ options={rankOpts}
onChange={h => setRankingComp(h)}
/>
</div>
- <h1>🏅 Leaderboard</h1>
+ <h1>Leaderboard</h1>
</header>
<table>
<thead>
<tr>
- <th>#</th>
+ <th>Rank</th>
+ <th>Start Nr.</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Birthday</th>
<th>School</th>
- <th colSpan={heatSelection.length * 2 + 2}>Ratings & Total</th>
+ <th colSpan={heatSelection.length * 2}>Heat Ratings & Sum</th>
+ <th colSpan={3}>Summary (all heats)</th>
</tr>
<tr>
<th></th>
@@ -142,16 +179,19 @@ function App() {
<th></th>
<th></th>
<th></th>
+ <th></th>
{heatSelection.map(h => (
<th key={h.value} colSpan={2}>{h.label}</th>
))}
<th>👍 Best</th>
<th>👎 Worst</th>
+ <th>Total</th>
</tr>
</thead>
<tbody>
{leaderboard.sort(rankByHeat(rankingComp)).map(i => (
<tr key={i.id}>
+ <td></td>
<td>{i.nr}</td>
<td>{i.firstname}</td>
<td>{i.lastname}</td>
@@ -163,8 +203,9 @@ function App() {
<td className='right'>{i.heats.find(heat => heat.heatId === h.value)?.summary}</td>
</Fragment>
))}
- <th>{Math.max(...i.heats.map(h => h.summary))}</th>
- <th>{Math.min(...i.heats.map(h => h.summary))}</th>
+ <td>{i.bestHeat}</td>
+ <td>{i.worstHeat}</td>
+ <td>{i.sum}</td>
</tr>
))}
</tbody>