feat: show org names for teams_distance slide

This commit is contained in:
Philipp Dormann 2025-04-04 22:16:59 +02:00
parent c286969a9d
commit c6f7210196
Signed by: philipp
GPG Key ID: 3BB9ADD52DCA4314

View File

@ -1,416 +1,420 @@
<script> <script>
import axios from "axios"; import axios from "axios";
import bg from "/beamershow_background.png?import"; import bg from "/beamershow_background.png?inline";
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { slide } from "svelte/transition"; import { slide } from "svelte/transition";
import { apikey, api_endpoint, laptime_track } from "./store.js"; import { apikey, api_endpoint, laptime_track } from "./store.js";
function init(el) { $: pages = [
el.focus(); "general",
} "runners_distance",
$: pages = [ // "runners_laptime",
"general", "orgs_distance",
"runners_distance", // "teams_distance",
// "runners_laptime", ];
"orgs_distance", $: current_page = "general";
// "teams_distance", $: general = {};
]; $: runners = [];
$: current_page = "general"; $: runners_by_laptime = [];
$: general = {}; $: orgs = [];
$: runners = []; $: teams = [];
$: runners_by_laptime = [];
$: orgs = [];
$: teams = [];
let time = new Date(); let time = new Date();
$: hours = (time.getHours() + "").padStart(2, "0"); $: hours = (time.getHours() + "").padStart(2, "0");
$: minutes = (time.getMinutes() + "").padStart(2, "0"); $: minutes = (time.getMinutes() + "").padStart(2, "0");
$: seconds = (time.getSeconds() + "").padStart(2, "0"); $: seconds = (time.getSeconds() + "").padStart(2, "0");
function format_laptime(laptime) { function format_laptime(laptime) {
if (laptime < 60) { if (laptime < 60) {
return `${laptime}s`; return `${laptime}s`;
} }
if (laptime < 3600) { if (laptime < 3600) {
return `${Math.floor(laptime / 60)}min ${ return `${Math.floor(laptime / 60)}min ${
laptime - Math.floor(laptime / 60) * 60 laptime - Math.floor(laptime / 60) * 60
}s`; }s`;
} }
return `${Math.floor(laptime / 3600)}h ${ return `${Math.floor(laptime / 3600)}h ${
laptime - Math.floor(laptime / 3600) * 3600 laptime - Math.floor(laptime / 3600) * 3600
}min ${ }min ${
laptime - laptime -
Math.floor(laptime / 3600) * 3600 - Math.floor(laptime / 3600) * 3600 -
Math.floor(laptime / 60) * 60 Math.floor(laptime / 60) * 60
}`; }`;
} }
function stats_general() { function stats_general() {
axios axios
.request({ .request({
method: "GET", method: "GET",
url: $api_endpoint + "api/stats/", url: $api_endpoint + "api/stats/",
headers: { Authorization: "Bearer " + $apikey }, headers: { Authorization: "Bearer " + $apikey },
}) })
.then(function ({ data }) { .then(function ({ data }) {
general = data; general = data;
}) })
.catch(function (e) { .catch(function (e) {
console.log(e); console.log(e);
}); });
} }
function stats_runners() { function stats_runners() {
axios axios
.request({ .request({
method: "GET", method: "GET",
url: $api_endpoint + "api/stats/runners/distance", url: $api_endpoint + "api/stats/runners/distance",
headers: { Authorization: "Bearer " + $apikey }, headers: { Authorization: "Bearer " + $apikey },
}) })
.then(function ({ data }) { .then(function ({ data }) {
runners = data; runners = data;
}) })
.catch(function (e) { .catch(function (e) {
console.log(e); console.log(e);
}); });
} }
function stats_runners_by_laptime() { function stats_runners_by_laptime() {
axios axios
.request({ .request({
method: "GET", method: "GET",
url: url:
$api_endpoint + "api/stats/runners/laptime?track=" + $laptime_track, $api_endpoint + "api/stats/runners/laptime?track=" + $laptime_track,
headers: { Authorization: "Bearer " + $apikey }, headers: { Authorization: "Bearer " + $apikey },
}) })
.then(function ({ data }) { .then(function ({ data }) {
runners_by_laptime = data; runners_by_laptime = data;
}) })
.catch(function (e) { .catch(function (e) {
console.log(e); console.log(e);
}); });
} }
function stats_orgs() { function stats_orgs() {
axios axios
.request({ .request({
method: "GET", method: "GET",
url: $api_endpoint + "api/stats/organizations/distance", url: $api_endpoint + "api/stats/organizations/distance",
headers: { Authorization: "Bearer " + $apikey }, headers: { Authorization: "Bearer " + $apikey },
}) })
.then(function ({ data }) { .then(function ({ data }) {
orgs = data; orgs = data;
}) })
.catch(function (e) { .catch(function (e) {
console.log(e); console.log(e);
}); });
} }
function stats_teams() { function stats_teams() {
axios axios
.request({ .request({
method: "GET", method: "GET",
url: $api_endpoint + "api/stats/teams/distance", url: $api_endpoint + "api/stats/teams/distance",
headers: { Authorization: "Bearer " + $apikey }, headers: { Authorization: "Bearer " + $apikey },
}) })
.then(function ({ data }) { .then(function ({ data }) {
teams = data; teams = data;
}) })
.catch(function (e) { .catch(function (e) {
console.log(e); console.log(e);
}); });
} }
Array.prototype.cycle = function (str) { Array.prototype.cycle = function (str) {
const i = this.indexOf(str); const i = this.indexOf(str);
if (i === -1) return undefined; if (i === -1) return undefined;
return this[(i + 1) % this.length]; return this[(i + 1) % this.length];
}; };
function fetch_all() { function fetch_all() {
stats_general(); stats_general();
stats_runners(); stats_runners();
// stats_runners_by_laptime(); // stats_runners_by_laptime();
stats_orgs(); stats_orgs();
stats_teams(); stats_teams();
} }
fetch_all(); fetch_all();
setInterval(() => { setInterval(() => {
time = new Date(); time = new Date();
}, 1000); }, 1000);
setInterval(() => { setInterval(() => {
fetch_all(); fetch_all();
}, 50000); }, 50000);
setInterval(() => { setInterval(() => {
current_page = pages.cycle(current_page); current_page = pages.cycle(current_page);
}, 20000); }, 20000);
</script> </script>
<div <div
class="min-h-screen flex items-center justify-center bg-gray-100" class="min-h-screen flex items-center justify-center bg-gray-100"
style="background-image: url({bg});background-position: center;background-size: contain;background-repeat:no-repeat;" style="background-image: url({bg});background-position: center;background-size: contain;background-repeat:no-repeat;"
> >
<div class="w-full"> <div class="w-full">
<div class="w-3/4 xl:w-1/2 mx-auto"> <div class="w-3/4 xl:w-1/2 mx-auto">
<!-- --> <!-- -->
{#if current_page === "general"} {#if current_page === "general"}
<div transition:slide|local> <div transition:slide|local>
<h1 <h1
class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900" class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900"
> >
Statistiken Statistiken
</h1> </h1>
<!-- --> <!-- -->
<div class="flex flex-wrap -mx-1 overflow-hidden mt-5"> <div class="flex flex-wrap -mx-1 overflow-hidden mt-5">
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3"> <div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3">
<h1 class="text-5xl font-bold text-center text-gray-900"> <h1 class="text-5xl font-bold text-center text-gray-900">
{general.total_runners || "0"} {general.total_runners || "0"}
</h1> </h1>
<h1 class="text-2xl font-semibold text-center text-gray-900"> <h1 class="text-2xl font-semibold text-center text-gray-900">
{$_("laeufer")} {$_("laeufer")}
</h1> </h1>
</div> </div>
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3"> <div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3">
<h1 class="text-5xl font-bold text-center text-gray-900"> <h1 class="text-5xl font-bold text-center text-gray-900">
{general.total_distance / 1000 || 0} {general.total_distance / 1000 || 0}
</h1> </h1>
<h1 class="text-2xl font-semibold text-center text-gray-900"> <h1 class="text-2xl font-semibold text-center text-gray-900">
{$_("kilometer-gesamt")} {$_("kilometer-gesamt")}
</h1> </h1>
</div> </div>
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3"> <div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3">
<h1 class="text-5xl font-bold text-center text-gray-900"> <h1 class="text-5xl font-bold text-center text-gray-900">
{parseFloat( {parseFloat(
((general.total_donation || 0) / 100).toFixed(2) ((general.total_donation || 0) / 100).toFixed(2)
).toLocaleString(undefined, { ).toLocaleString(undefined, {
minimumFractionDigits: 2, minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
}) || "0"} € }) || "0"} €
</h1> </h1>
<h1 class="text-2xl font-semibold text-center text-gray-900"> <h1 class="text-2xl font-semibold text-center text-gray-900">
{$_("spendensumme")} {$_("spendensumme")}
</h1> </h1>
</div> </div>
</div> </div>
</div> </div>
{:else if current_page === "runners_distance"} {:else if current_page === "runners_distance"}
<div transition:slide|local> <div transition:slide|local>
<h1 <h1
class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900 mb-3" class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900 mb-3"
> >
{$_("top-laeufer")} ({$_("distanz")}) {$_("top-laeufer")} ({$_("distanz")})
</h1> </h1>
{#if runners.length === 0} {#if runners.length === 0}
<p class="w-full text-center text-3xl font-semibold"> <p class="w-full text-center text-3xl font-semibold">
Noch keine Daten... Noch keine Daten...
</p> </p>
{:else} {:else}
<table <table
class="table font-semibold p-4 bg-white shadow rounded-lg w-full" class="table font-semibold p-4 bg-white shadow rounded-lg w-full"
> >
<thead> <thead>
<tr> <tr>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("platz")} {$_("platz")}
</th> </th>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("laeufer")} {$_("laeufer")}
</th> </th>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("organisation")} {$_("organisation")}
</th> </th>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("kilometer")} {$_("kilometer")}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#each runners as r, i} {#each runners as r, i}
<tr class="text-gray-700"> <tr class="text-gray-700">
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{i + 1} {i + 1}
</td> </td>
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{r.firstname} {r.firstname}
{r.lastname} {r.lastname}
</td> </td>
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{r.group.name} {r.group.name}
</td> </td>
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{r.distance / 1000} km {r.distance / 1000} km
</td> </td>
</tr> </tr>
{/each} {/each}
</tbody> </tbody>
</table> </table>
{/if} {/if}
</div> </div>
{:else if current_page === "runners_laptime"} {:else if current_page === "runners_laptime"}
<div transition:slide|local> <div transition:slide|local>
<h1 <h1
class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900 mb-3" class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900 mb-3"
> >
{$_("top-laeufer")} ({$_("rundenzeit")}) {$_("top-laeufer")} ({$_("rundenzeit")})
</h1> </h1>
{#if runners_by_laptime.length === 0} {#if runners_by_laptime.length === 0}
<p class="w-full text-center text-3xl font-semibold"> <p class="w-full text-center text-3xl font-semibold">
Noch keine Daten... Noch keine Daten...
</p> </p>
{:else} {:else}
<table <table
class="table font-semibold p-4 bg-white shadow rounded-lg w-full" class="table font-semibold p-4 bg-white shadow rounded-lg w-full"
> >
<thead> <thead>
<tr> <tr>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("platz")} {$_("platz")}
</th> </th>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("laeufer")} {$_("laeufer")}
</th> </th>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("organisation")} {$_("organisation")}
</th> </th>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("schnellste-rundenzeit")} {$_("schnellste-rundenzeit")}
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#each runners_by_laptime as r, i} {#each runners_by_laptime as r, i}
<tr class="text-gray-700"> <tr class="text-gray-700">
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{i + 1} {i + 1}
</td> </td>
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{r.firstname} {r.firstname}
{r.lastname} {r.lastname}
</td> </td>
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{r.group.name} {r.group.name}
</td> </td>
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{format_laptime(r.minLaptime)} {format_laptime(r.minLaptime)}
</td> </td>
</tr> </tr>
{/each} {/each}
</tbody> </tbody>
</table> </table>
{/if} {/if}
</div> </div>
{:else if current_page === "orgs_distance"} {:else if current_page === "orgs_distance"}
<div transition:slide|local> <div transition:slide|local>
<h1 <h1
class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900 mb-3" class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900 mb-3"
> >
{$_("top-organisationen")} {$_("top-organisationen")}
</h1> </h1>
<table {#if orgs.length === 0}
class="table font-semibold p-4 bg-white shadow rounded-lg w-full" <p class="w-full text-center text-3xl font-semibold">
> Noch keine Daten...
<thead> </p>
<tr> {:else}
<th <table
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="table font-semibold p-4 bg-white shadow rounded-lg w-full"
> >
{$_("platz")} <thead>
</th> <tr>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("organsiation")} {$_("platz")}
</th> </th>
<th <th
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
> >
{$_("kilometer")} {$_("organsiation")}
</th> </th>
</tr> <th
</thead> class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
<tbody> >
{#each orgs as o, i} {$_("kilometer")}
<tr class="text-gray-700"> </th>
<td class="border p-4 dark:border-dark-5"> </tr>
{i + 1} </thead>
</td> <tbody>
<td class="border p-4 dark:border-dark-5"> {#each orgs as o, i}
{o.name} <tr class="text-gray-700">
</td> <td class="border p-4 dark:border-dark-5">
<td class="border p-4 dark:border-dark-5"> {i + 1}
{o.distance / 1000} km </td>
</td> <td class="border p-4 dark:border-dark-5">
</tr> {o.name}
{/each} </td>
</tbody> <td class="border p-4 dark:border-dark-5">
</table> {o.distance / 1000} km
</div> </td>
{:else if current_page === "teams_distance"} </tr>
<div transition:slide|local> {/each}
<h1 </tbody>
class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900 mb-3" </table>
> {/if}
{$_("top-teams")} </div>
</h1> {:else if current_page === "teams_distance"}
<table <div transition:slide|local>
class="table font-semibold p-4 bg-white shadow rounded-lg w-full" <h1
> class="mr-6 text-5xl xl:text-7xl font-bold text-center text-gray-900 mb-3"
<thead> >
<tr> {$_("top-teams")}
<th </h1>
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" <table
> class="table font-semibold p-4 bg-white shadow rounded-lg w-full"
{$_("platz")} >
</th> <thead>
<th <tr>
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" <th
> class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
{$_("team")} >
</th> {$_("platz")}
<th </th>
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900" <th
> class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
{$_("kilometer")} >
</th> {$_("team")}
</tr> </th>
</thead> <th
<tbody> class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
{#each teams as t, i} >
<tr class="text-gray-700"> {$_("kilometer")}
<td class="border p-4 dark:border-dark-5"> </th>
{i + 1} </tr>
</td> </thead>
<td class="border p-4 dark:border-dark-5"> <tbody>
{t.name} {#each teams as t, i}
</td> <tr class="text-gray-700">
<td class="border p-4 dark:border-dark-5"> <td class="border p-4 dark:border-dark-5">
{t.distance / 1000} km {i + 1}
</td> </td>
</tr> <td class="border p-4 dark:border-dark-5">
{/each} {t.parent.name}<br />
</tbody> {t.name}
</table> </td>
</div> <td class="border p-4 dark:border-dark-5">
{:else} {t.distance / 1000} km
<!-- content here --> </td>
{/if} </tr>
</div> {/each}
</div> </tbody>
<h1 </table>
class="text-6xl font-semibold text-right text-gray-900 font-mono top-2 w-full fixed pr-4 xl:top-6 xl:pr-8" </div>
> {:else}
{hours}:{minutes}:{seconds} <!-- content here -->
</h1> {/if}
<h1 </div>
class="text-xl xl:text-3xl font-medium text-center text-gray-900 font-mono bottom-2 xl:bottom-4 w-full fixed" </div>
> <h1
<span class="text-black font-extrabold">Lauf für Kaya!</span> - powered by ODIT.Services class="text-6xl font-semibold text-right text-gray-900 font-mono top-2 w-full fixed pr-4 xl:top-6 xl:pr-8"
</h1> >
{hours}:{minutes}:{seconds}
</h1>
<h1
class="text-xl xl:text-3xl font-medium text-center text-gray-900 font-mono bottom-2 xl:bottom-4 w-full fixed"
>
<span class="text-black font-extrabold">Lauf für Kaya!</span> - powered by ODIT.Services
</h1>
</div> </div>