utils.js (3938B)
1 import { supabase } from './supabaseClient' 2 3 export const exportHeatsToCSV = async function(e) { 4 e.preventDefault() 5 6 const { data, error } = await supabase 7 .from('heats') 8 .select('created_at,name,location,planned_start') 9 .csv() 10 11 if (error !== null) { 12 alert(error.message) 13 return 14 } else if (data.length === 0) { 15 alert('No heats yet, nothing to export') 16 return 17 } 18 19 exportCSV(data, "heats") 20 } 21 22 export const exportAthletesToCSV = async function(e) { 23 e.preventDefault() 24 25 const { data, error } = await supabase 26 .from('athletes') 27 .select('created_at,nr,firstname,lastname,birthday,school') 28 .csv() 29 30 if (error !== null) { 31 alert(error.message) 32 return 33 } else if (data.length === 0) { 34 alert('No athletes yet, nothing to export') 35 return 36 } 37 38 exportCSV(data, "athletes") 39 } 40 41 export const exportLeaderboardToCSV = async function(e, leaderboard, heatSelection, rankingComp) { 42 e.preventDefault() 43 44 if (leaderboard.length === 0) { 45 alert('Leaderboard is empty, nothing to export') 46 return 47 } 48 49 // concatenante heat labels 50 const heatNames = heatSelection.map(h => h.label) 51 52 // rank leaderboard by selected comparator 53 const heatSummaries = leaderboard.sort(rankByHeat(rankingComp)).map(i => 54 // for each entry i in the board, for every heat h 55 heatSelection.map(h => 56 // get individual scores of the heat 57 getScores(i, h) + " = " 58 // get heat score sum 59 + i.heats.find(heat => heat.heatId === h.value)?.summary 60 ) 61 ) 62 63 // csv header 64 let csv = "rank,start_nr,firstname,lastname,birthday,school," 65 + heatNames + "," + "best,worst,total\n" 66 67 // append leaderboard score results 68 for (let i = 0; i < leaderboard.length; i++) { 69 csv += i+1 + "," + leaderboard[i].nr + "," + leaderboard[i].firstname + "," + leaderboard[i].lastname + "," 70 + leaderboard[i].birthday + "," + leaderboard[i].school + "," 71 + heatSummaries[i] + "," 72 + leaderboard[i].bestHeat + "," + leaderboard[i].worstHeat + "," + leaderboard[i].sum + "\n" 73 } 74 75 exportCSV(csv, "scores") 76 } 77 78 // define the ranking logic 79 export const rankByHeat = function(rankingComp) { 80 return function(a, b) { 81 // rank by chosen heat or ranking comparator 82 for (const r of rankingComp) { 83 switch(r.value) { 84 case 'start': 85 // rank by start number 86 return b.nr < a.nr 87 case 'best': 88 if (b.bestHeat - a.bestHeat !== 0) { 89 // rank by best heat first 90 return b.bestHeat - a.bestHeat 91 } 92 // rank by least worst heat for identical best heats 93 return b.worstHeat - a.worstHeat 94 case 'worst': 95 // rank by worst heat 96 return b.worstHeat - a.worstHeat 97 case 'total': 98 // rank by total sum across heats 99 return b.sum - a.sum 100 default: 101 // rank by heat totals 102 if (b.heats.find(h => h.heatId === r.value)?.summary - a.heats.find(h => h.heatId === r.value)?.summary !== 0) { 103 return b.heats.find(h => h.heatId === r.value)?.summary - a.heats.find(h => h.heatId === r.value)?.summary 104 } 105 } 106 } 107 } 108 } 109 110 // Scores concat with "+" for leaderboard entry i and heat h 111 export const getScores = function(i, h) { 112 const scores = i.heats.find(heat => heat.heatId === h.value)?.scores?.map(s => s.score).join(" + ") 113 return scores === "" ? 0 : scores 114 } 115 116 // export CSV as blob 117 const exportCSV = function(csv, fileSlug) { 118 // create blob from csv 119 const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }) 120 121 // download blob 122 const url = URL.createObjectURL(blob) 123 const link = document.createElement('a') 124 link.href = url 125 link.download = fileSlug + "-" + new Date().toISOString() + ".csv" 126 document.body.appendChild(link) 127 link.click() 128 document.body.removeChild(link) 129 // let browser know not to keep the reference to the file 130 URL.revokeObjectURL(url) 131 }