372 lines
11 KiB
Svelte
372 lines
11 KiB
Svelte
<script>
|
|
import axios from "axios";
|
|
import { _ } from "svelte-i18n";
|
|
import { fade, slide } from "svelte/transition";
|
|
import {
|
|
apikey,
|
|
api_endpoint,
|
|
laptime_track
|
|
} from "./store.js";
|
|
function init(el) {
|
|
el.focus();
|
|
}
|
|
$: pages = [
|
|
"general",
|
|
"runners_distance",
|
|
"runners_laptime",
|
|
"orgs_distance",
|
|
"teams_distance",
|
|
];
|
|
$: current_page = "general";
|
|
$: general = {};
|
|
$: runners = [];
|
|
$: runners_by_laptime = [];
|
|
$: orgs = [];
|
|
$: teams = [];
|
|
|
|
let time = new Date();
|
|
$: hours = (time.getHours() + "").padStart(2, "0");
|
|
$: minutes = (time.getMinutes() + "").padStart(2, "0");
|
|
$: seconds = (time.getSeconds() + "").padStart(2, "0");
|
|
function format_laptime(laptime) {
|
|
if (laptime < 60) {
|
|
return `${laptime}s`;
|
|
}
|
|
if (laptime < 3600) {
|
|
return `${Math.floor(laptime / 60)}min ${
|
|
laptime - Math.floor(laptime / 60) * 60
|
|
}s`;
|
|
}
|
|
return `${Math.floor(laptime / 3600)}h ${
|
|
laptime - Math.floor(laptime / 3600) * 3600
|
|
}min ${
|
|
laptime -
|
|
Math.floor(laptime / 3600) * 3600 -
|
|
Math.floor(laptime / 60) * 60
|
|
}`;
|
|
}
|
|
function stats_general() {
|
|
axios
|
|
.request({
|
|
method: "GET",
|
|
url: $api_endpoint + "api/stats/",
|
|
headers: { Authorization: "Bearer " + $apikey },
|
|
})
|
|
.then(function ({ data }) {
|
|
general = data;
|
|
})
|
|
.catch(function (e) {
|
|
console.log(e);
|
|
});
|
|
}
|
|
function stats_runners() {
|
|
axios
|
|
.request({
|
|
method: "GET",
|
|
url: $api_endpoint + "api/stats/runners/distance",
|
|
headers: { Authorization: "Bearer " + $apikey },
|
|
})
|
|
.then(function ({ data }) {
|
|
runners = data;
|
|
})
|
|
.catch(function (e) {
|
|
console.log(e);
|
|
});
|
|
}
|
|
function stats_runners_by_laptime() {
|
|
axios
|
|
.request({
|
|
method: "GET",
|
|
url:
|
|
$api_endpoint + "api/stats/runners/laptime?track=" + $laptime_track,
|
|
headers: { Authorization: "Bearer " + $apikey },
|
|
})
|
|
.then(function ({ data }) {
|
|
runners_by_laptime = data;
|
|
})
|
|
.catch(function (e) {
|
|
console.log(e);
|
|
});
|
|
}
|
|
function stats_orgs() {
|
|
axios
|
|
.request({
|
|
method: "GET",
|
|
url: $api_endpoint + "api/stats/organizations/distance",
|
|
headers: { Authorization: "Bearer " + $apikey },
|
|
})
|
|
.then(function ({ data }) {
|
|
orgs = data;
|
|
})
|
|
.catch(function (e) {
|
|
console.log(e);
|
|
});
|
|
}
|
|
function stats_teams() {
|
|
axios
|
|
.request({
|
|
method: "GET",
|
|
url: $api_endpoint + "api/stats/teams/distance",
|
|
headers: { Authorization: "Bearer " + $apikey },
|
|
})
|
|
.then(function ({ data }) {
|
|
teams = data;
|
|
})
|
|
.catch(function (e) {
|
|
console.log(e);
|
|
});
|
|
}
|
|
Array.prototype.cycle = function (str) {
|
|
const i = this.indexOf(str);
|
|
if (i === -1) return undefined;
|
|
return this[(i + 1) % this.length];
|
|
};
|
|
function fetch_all() {
|
|
stats_general();
|
|
stats_runners();
|
|
stats_runners_by_laptime();
|
|
stats_orgs();
|
|
stats_teams();
|
|
}
|
|
fetch_all();
|
|
setInterval(() => {
|
|
time = new Date();
|
|
}, 1000);
|
|
setInterval(() => {
|
|
fetch_all();
|
|
}, 15000);
|
|
setInterval(() => {
|
|
current_page = pages.cycle(current_page);
|
|
}, 20000);
|
|
</script>
|
|
|
|
<div
|
|
class="min-h-screen flex items-center justify-center bg-gray-100"
|
|
style="background-image: url('/beamershow_background.png');background-position: center;background-size: contain;background-repeat:no-repeat;"
|
|
>
|
|
<div class="max-w-xl w-full">
|
|
{#if current_page === "general"}
|
|
<div transition:slide|local>
|
|
<h1 class="mr-6 text-7xl font-semibold text-center text-gray-900">
|
|
{hours}:{minutes}:{seconds}
|
|
</h1>
|
|
<!-- -->
|
|
<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">
|
|
<h1 class="text-5xl font-semibold text-center text-gray-900">
|
|
{general.total_runners}
|
|
</h1>
|
|
<h1 class="text-2xl font-semibold text-center text-gray-900">
|
|
Läufer
|
|
</h1>
|
|
</div>
|
|
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3">
|
|
<h1 class="text-5xl font-semibold text-center text-gray-900">
|
|
{general.total_distance}
|
|
</h1>
|
|
<h1 class="text-2xl font-semibold text-center text-gray-900">
|
|
Kilometer gesamt
|
|
</h1>
|
|
</div>
|
|
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3">
|
|
<h1 class="text-5xl font-semibold text-center text-gray-900">
|
|
{general.total_donation} €
|
|
</h1>
|
|
<h1 class="text-2xl font-semibold text-center text-gray-900">
|
|
Spendensumme
|
|
</h1>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{:else if current_page === "runners_distance"}
|
|
<div transition:slide|local>
|
|
<h1 class="mr-6 text-7xl font-semibold text-center text-gray-900 mb-5">
|
|
Top-Läufer (Distanz)
|
|
</h1>
|
|
<table class="table p-4 bg-white shadow rounded-lg w-full">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Platz
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Läufer
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Organisation
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Kilometer
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{#each runners as r, i}
|
|
<tr class="text-gray-700">
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{i + 1}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{r.firstname}
|
|
{r.lastname}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{r.group.name}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{r.distance / 1000} km
|
|
</td>
|
|
</tr>
|
|
{/each}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{:else if current_page === "runners_laptime"}
|
|
<div transition:slide|local>
|
|
<h1 class="mr-6 text-7xl font-semibold text-center text-gray-900 mb-5">
|
|
Top-Läufer (Rundenzeit)
|
|
</h1>
|
|
<table class="table p-4 bg-white shadow rounded-lg w-full">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Platz
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Läufer
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Organisation
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Schnellste Rundenzeit
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{#each runners_by_laptime as r, i}
|
|
<tr class="text-gray-700">
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{i + 1}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{r.firstname}
|
|
{r.lastname}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{r.group.name}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{format_laptime(r.minLaptime)}
|
|
</td>
|
|
</tr>
|
|
{/each}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{:else if current_page === "orgs_distance"}
|
|
<div transition:slide|local>
|
|
<h1 class="mr-6 text-7xl font-semibold text-center text-gray-900 mb-5">
|
|
Top-Organsiationen
|
|
</h1>
|
|
<table class="table p-4 bg-white shadow rounded-lg w-full">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Platz
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Organsiation
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Kilometer
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{#each orgs as o, i}
|
|
<tr class="text-gray-700">
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{i + 1}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{o.name}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{o.distance / 1000} km
|
|
</td>
|
|
</tr>
|
|
{/each}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{:else if current_page === "teams_distance"}
|
|
<div transition:slide|local>
|
|
<h1 class="mr-6 text-7xl font-semibold text-center text-gray-900 mb-5">
|
|
Top-Teams
|
|
</h1>
|
|
<table class="table p-4 bg-white shadow rounded-lg w-full">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Platz
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Team
|
|
</th>
|
|
<th
|
|
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
|
>
|
|
Kilometer
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{#each teams as t, i}
|
|
<tr class="text-gray-700">
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{i + 1}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{t.name}
|
|
</td>
|
|
<td class="border p-4 dark:border-dark-5">
|
|
{t.distance / 1000} km
|
|
</td>
|
|
</tr>
|
|
{/each}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{:else}
|
|
<!-- content here -->
|
|
{/if}
|
|
</div>
|
|
</div>
|