Spaces:
Configuration error
Configuration error
File size: 4,065 Bytes
66dca15 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>BOU 2026 – Results (organizer)</title>
<style>
:root{
--bg:#f4f5f7; --card:#ffffff; --text:#1b1e24; --muted:#636a76;
--accent:#2f5ed1; --border:#dfe2e8; --track:#eef0f3;
}
@media (prefers-color-scheme: dark){
:root{
--bg:#14161b; --card:#1d2027; --text:#eef0f3; --muted:#9aa1ad;
--accent:#6e94f2; --border:#2b2f38; --track:#262a32;
}
}
*{box-sizing:border-box;}
body{margin:0; background:var(--bg); color:var(--text); font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;}
.wrap{max-width:560px; margin:0 auto; padding:32px 18px 70px;}
h1{font-size:1.3rem; margin:0 0 18px;}
input{width:100%; padding:10px 12px; border-radius:10px; border:1px solid var(--border); background:var(--card); color:var(--text); margin-bottom:10px;}
button, a.btn{display:inline-block; padding:10px 16px; border:none; border-radius:10px; background:var(--accent); color:#fff; font-weight:600; cursor:pointer; text-decoration:none; font-size:.9rem;}
.card{background:var(--card); border:1px solid var(--border); border-radius:14px; padding:14px 16px; margin-bottom:10px;}
.row{display:flex; justify-content:space-between; align-items:baseline;}
.proj{font-weight:600;}
.presenter{color:var(--muted); font-size:.85rem;}
.pct{font-weight:600; color:var(--accent);}
.track{height:8px; background:var(--track); border-radius:5px; margin-top:8px; overflow:hidden;}
.fill{height:100%; background:var(--accent); width:0%;}
.count{font-size:.75rem; color:var(--muted); margin-top:4px;}
.toolbar{display:flex; gap:10px; margin:16px 0 22px; align-items:center;}
.msg{font-size:.85rem; color:var(--muted);}
</style>
</head>
<body>
<div class="wrap">
<h1>BOU 2026 — Results (organizer only)</h1>
<div id="gate">
<input id="key" type="password" placeholder="Admin key">
<button id="loadBtn">View results</button>
</div>
<div id="dash" style="display:none">
<div class="toolbar">
<a class="btn" id="exportLink" href="#">Download Excel log</a>
<span class="msg" id="total"></span>
</div>
<div id="results"></div>
</div>
<div class="msg" id="err"></div>
</div>
<script>
const keyEl = document.getElementById("key");
const err = document.getElementById("err");
async function load(){
const key = keyEl.value.trim();
if (!key) return;
sessionStorage.setItem("adminKey", key);
err.textContent = "";
try{
const res = await fetch("/api/results?key=" + encodeURIComponent(key));
const data = await res.json();
if (!data.ok){ err.textContent = data.error || "Could not load results."; return; }
document.getElementById("gate").style.display = "none";
document.getElementById("dash").style.display = "block";
document.getElementById("exportLink").href = "/api/export?key=" + encodeURIComponent(key);
render(data);
} catch(e){
err.textContent = "Network error.";
}
}
function render(data){
const resultsEl = document.getElementById("results");
const total = data.total || 0;
document.getElementById("total").textContent = total ? total + " vote" + (total===1?"":"s") + " recorded" : "No votes yet";
resultsEl.innerHTML = "";
data.projects.forEach(p => {
const c = data.counts[p.id] || 0;
const pct = total ? Math.round((c/total)*100) : 0;
const div = document.createElement("div");
div.className = "card";
div.innerHTML = `
<div class="row">
<div><div class="proj">${p.name}</div><div class="presenter">${p.who}</div></div>
<div class="pct">${pct}%</div>
</div>
<div class="track"><div class="fill" style="width:${pct}%"></div></div>
<div class="count">${c} vote${c===1?"":"s"}</div>
`;
resultsEl.appendChild(div);
});
}
document.getElementById("loadBtn").addEventListener("click", load);
const saved = sessionStorage.getItem("adminKey");
if (saved){ keyEl.value = saved; load(); }
</script>
</body>
</html>
|