Compare commits
35 Commits
7184210ea4
...
0.1.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
7f7b743f41
|
|||
|
ee6af3e069
|
|||
|
ea08127927
|
|||
|
e0f400a800
|
|||
|
c485898b7d
|
|||
| 80f5c38c36 | |||
| 205e09e2fc | |||
| 9125dec45b | |||
| 94ceca9454 | |||
| 2119e9b231 | |||
| cfd64c2f19 | |||
| a7e84c7d42 | |||
| 70bfbfcd53 | |||
| c5e4facffa | |||
| b36764869b | |||
| de7e96cd01 | |||
| d5ce648a53 | |||
| fca7a99689 | |||
| cb559da57c | |||
| abdc510305 | |||
| fe0cba9058 | |||
| 64ce42d8a0 | |||
| fdabe4b79c | |||
| 70e5f172a6 | |||
| fa35ac8254 | |||
| 7f6134d0ef | |||
| ca48959581 | |||
| e5c51b956e | |||
| d809dcba79 | |||
| b42684f7fc | |||
| b3b06bc30e | |||
| c83ff39677 | |||
| 85b40c10bf | |||
| 10b862d43a | |||
| 3275ae2609 |
60
.drone.yml
Normal file
60
.drone.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
kind: secret
|
||||
name: docker_username
|
||||
get:
|
||||
path: odit-registry-builder
|
||||
name: username
|
||||
|
||||
---
|
||||
kind: secret
|
||||
name: docker_password
|
||||
get:
|
||||
path: odit-registry-builder
|
||||
name: password
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: build:dev
|
||||
|
||||
steps:
|
||||
- name: build dev
|
||||
image: plugins/docker
|
||||
depends_on: [clone]
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
repo: registry.odit.services/lfk/beamershow
|
||||
tags:
|
||||
- dev
|
||||
registry: registry.odit.services
|
||||
mtu: 1000
|
||||
trigger:
|
||||
branch:
|
||||
- dev
|
||||
event:
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: build:tags
|
||||
steps:
|
||||
- name: build $DRONE_TAG
|
||||
image: plugins/docker
|
||||
depends_on: [clone]
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
repo: registry.odit.services/lfk/beamershow
|
||||
tags:
|
||||
- '${DRONE_TAG}'
|
||||
registry: registry.odit.services
|
||||
mtu: 1000
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"i18n-ally.localesPaths": "src/locales",
|
||||
"i18n-ally.keystyle": "nested"
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.sourceLanguage": "de"
|
||||
}
|
||||
61
CHANGELOG.md
Normal file
61
CHANGELOG.md
Normal file
@@ -0,0 +1,61 @@
|
||||
### Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [0.1.4](https://git.odit.services/lfk/beamershow/compare/0.1.3...0.1.4)
|
||||
|
||||
- cleanup invalid track stuff (leftovers from scanclient) [`c485898`](https://git.odit.services/lfk/beamershow/commit/c485898b7db7ae09f6e405e12aa6d458833f2dcf)
|
||||
- bullet-proof login ux [`ea08127`](https://git.odit.services/lfk/beamershow/commit/ea08127927e2b1ebcbcd7907fbf51a66a43da421)
|
||||
- add rst command [`ee6af3e`](https://git.odit.services/lfk/beamershow/commit/ee6af3e06921ef33651076b8767149c2df3a1f2d)
|
||||
- Settings: reload on lang change [`e0f400a`](https://git.odit.services/lfk/beamershow/commit/e0f400a800f2652cf3edf2ac0a5f802b65d0c460)
|
||||
|
||||
#### [0.1.3](https://git.odit.services/lfk/beamershow/compare/0.1.2...0.1.3)
|
||||
|
||||
> 8 April 2021
|
||||
|
||||
- 🚀Bumped version to 0.1.3 [`80f5c38`](https://git.odit.services/lfk/beamershow/commit/80f5c38c364c02d70a99f0e06ea9153e10438bfb)
|
||||
- Fixed image name [`205e09e`](https://git.odit.services/lfk/beamershow/commit/205e09e2fc6a2a49251278a8ead31e1718ac7e44)
|
||||
|
||||
#### [0.1.2](https://git.odit.services/lfk/beamershow/compare/0.1.1...0.1.2)
|
||||
|
||||
> 8 April 2021
|
||||
|
||||
- 🚀Bumped version to 0.1.2 [`9125dec`](https://git.odit.services/lfk/beamershow/commit/9125dec45b41f80445cd6cc75436f5a63de2fd98)
|
||||
|
||||
#### 0.1.1
|
||||
|
||||
> 7 April 2021
|
||||
|
||||
- Sorted translations 🌍 [`#1`](https://git.odit.services/lfk/beamershow/issues/1)
|
||||
- 🎉 initial commit [`b902b08`](https://git.odit.services/lfk/beamershow/commit/b902b081d7e2e80fdf167657f3c2fda79b888985)
|
||||
- formatting... [`866436f`](https://git.odit.services/lfk/beamershow/commit/866436fa82882dffe6f2f45bd303effc67d92a37)
|
||||
- Added/updated settings translations [`b367648`](https://git.odit.services/lfk/beamershow/commit/b36764869bf1e302713d457b3ba3ec804c5d38f7)
|
||||
- 🚀Bumped version to 0.1.1 [`94ceca9`](https://git.odit.services/lfk/beamershow/commit/94ceca9454da77d29f975cf894d2304dcc60c481)
|
||||
- i18n run [`c5e4fac`](https://git.odit.services/lfk/beamershow/commit/c5e4facffa19578db95315d53bd0befc936016e4)
|
||||
- Added drone file for dev and tag build [`d809dcb`](https://git.odit.services/lfk/beamershow/commit/d809dcba799a94c6ed5a6cfac551d14c1a2cbadd)
|
||||
- You can now go back to config by typeing cnf [`9135090`](https://git.odit.services/lfk/beamershow/commit/9135090e73ff6fc021b4f7f80b3780b3ff73ad02)
|
||||
- Added top teams by distance page [`d78e896`](https://git.odit.services/lfk/beamershow/commit/d78e896fecf5f7975267f3a1c3faf8b5c8728c25)
|
||||
- Added nginx conf for dockerfile [`b3b06bc`](https://git.odit.services/lfk/beamershow/commit/b3b06bc30e4043d3f7b874e939a090f85841a516)
|
||||
- Implemented fix for url crashing [`7f6134d`](https://git.odit.services/lfk/beamershow/commit/7f6134d0efd1a6a1161acc2c8bc8c4496c529ffe)
|
||||
- Added html/template for the top runenry by laptime [`3275ae2`](https://git.odit.services/lfk/beamershow/commit/3275ae2609ef966183ca66a0234ff7f570eaef81)
|
||||
- Added release comand and config [`ca48959`](https://git.odit.services/lfk/beamershow/commit/ca489595812da8756629a498d673e3206cb66a2f)
|
||||
- Added track to config [`abdc510`](https://git.odit.services/lfk/beamershow/commit/abdc5103055844da73438e8dfbb0eea2b41105d1)
|
||||
- removed unused stuff from the store [`cb559da`](https://git.odit.services/lfk/beamershow/commit/cb559da57c58a1998f54beb83bee837e0a8b71e7)
|
||||
- Implemented settings dialog [`de7e96c`](https://git.odit.services/lfk/beamershow/commit/de7e96cd01f70bfff80f42e7c709e67d44681920)
|
||||
- Added js part of runners by laptime [`10b862d`](https://git.odit.services/lfk/beamershow/commit/10b862d43ac35122c1cc4eaed30e7ac8228d294f)
|
||||
- User quickstart docs README [`19cc7d0`](https://git.odit.services/lfk/beamershow/commit/19cc7d0c28ff56481fc37cc98b341259566a39ed)
|
||||
- Removed license export from drone pipelines [`e5c51b9`](https://git.odit.services/lfk/beamershow/commit/e5c51b956e210f3f4652f020edefb0de5bb789d9)
|
||||
- Formatting [`fca7a99`](https://git.odit.services/lfk/beamershow/commit/fca7a99689469f8a8b281f643346b3281036ee40)
|
||||
- added svelte transitions [`1f95b8b`](https://git.odit.services/lfk/beamershow/commit/1f95b8ba53e3152517d730ad6b3b39dc472bb386)
|
||||
- Added 2-staged dockerfile [`c83ff39`](https://git.odit.services/lfk/beamershow/commit/c83ff39677c4575346a0b7eced95796de90d6fee)
|
||||
- Precommit hooks doing their best to not die [`85b40c1`](https://git.odit.services/lfk/beamershow/commit/85b40c10bffa15ad381e51fee348bb014780d5d8)
|
||||
- Renamed Firma -> Organsiation [`3e7b120`](https://git.odit.services/lfk/beamershow/commit/3e7b1201e25da7dcc2f6be2b4b826b90d616dd67)
|
||||
- Added beamershow docker-compose [`b42684f`](https://git.odit.services/lfk/beamershow/commit/b42684f7fc8e40740a6511d895af03f7f110e2a4)
|
||||
- Updated release-it config [`cfd64c2`](https://git.odit.services/lfk/beamershow/commit/cfd64c2f19dabd8aa758aefd02342935c54e20de)
|
||||
- Renamed Firma -Y Organsiation [`662e31b`](https://git.odit.services/lfk/beamershow/commit/662e31b36674f66696a4a4bc3ca4abae3efd93bb)
|
||||
- CNF now opens settings [`d5ce648`](https://git.odit.services/lfk/beamershow/commit/d5ce648a53bb70a1c4ad7f2b12c334e328e36448)
|
||||
- Added missing let [`70e5f17`](https://git.odit.services/lfk/beamershow/commit/70e5f172a66dcad64353f8469ebb845a1b4895bb)
|
||||
- Added missing let [`fa35ac8`](https://git.odit.services/lfk/beamershow/commit/fa35ac8254028570bd3e425276a008fe83887f09)
|
||||
- Updated release-it config [`a7e84c7`](https://git.odit.services/lfk/beamershow/commit/a7e84c7d426525a5041f0ec260cd57dcfd107afb)
|
||||
- Added url validation fix [`64ce42d`](https://git.odit.services/lfk/beamershow/commit/64ce42d8a04cc4b149db7f75be5ff0d9fbfb3a75)
|
||||
- removed useless console log [`fe0cba9`](https://git.odit.services/lfk/beamershow/commit/fe0cba9058a1874058618ef3b697093fcfc78a99)
|
||||
@@ -2,4 +2,11 @@ FROM node:15.11.0-alpine3.13
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN yarn
|
||||
RUN yarn build
|
||||
RUN yarn build
|
||||
|
||||
# final image
|
||||
FROM alpine
|
||||
COPY --from=0 /app/dist /app
|
||||
FROM fholzer/nginx-brotli:v1.19.1
|
||||
COPY --from=1 /app /usr/share/nginx/html
|
||||
COPY ./nginx.conf /etc/nginx/nginx.conf
|
||||
7
docker-compose.yml
Normal file
7
docker-compose.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
version: "3"
|
||||
services:
|
||||
httpd:
|
||||
build: .
|
||||
#image: registry.odit.services/lfk/beamershow:latest
|
||||
ports:
|
||||
- 4052:80
|
||||
6050
licenses.md
6050
licenses.md
File diff suppressed because it is too large
Load Diff
60
nginx.conf
Normal file
60
nginx.conf
Normal file
@@ -0,0 +1,60 @@
|
||||
events {
|
||||
}
|
||||
http {
|
||||
include mime.types;
|
||||
sendfile on;
|
||||
server {
|
||||
error_page 404 /index.html;
|
||||
root /usr/share/nginx/html;
|
||||
location = /index.html {
|
||||
add_header Cache-Control 'no-store';
|
||||
}
|
||||
location = / {
|
||||
add_header Cache-Control 'no-store';
|
||||
}
|
||||
location = /env.js {
|
||||
add_header Cache-Control 'no-store';
|
||||
}
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
location ~* \.(?:ico|css|gif|jpe?g|png)$ {
|
||||
expires 1y;
|
||||
add_header Pragma public;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
# --- Brotli
|
||||
brotli on;
|
||||
brotli_comp_level 6;
|
||||
brotli_static on;
|
||||
brotli_types application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;
|
||||
# --- GZIP
|
||||
gzip on;
|
||||
gzip_disable "msie6";
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types application/javascript
|
||||
application/rss+xml
|
||||
application/vnd.ms-fontobject
|
||||
application/x-font
|
||||
application/x-font-opentype
|
||||
application/x-font-otf
|
||||
application/x-font-truetype
|
||||
application/x-font-ttf
|
||||
application/x-javascript
|
||||
application/xhtml+xml
|
||||
application/xml
|
||||
font/opentype
|
||||
font/otf
|
||||
font/ttf
|
||||
image/svg+xml
|
||||
image/x-icon
|
||||
text/css
|
||||
text/javascript
|
||||
text/plain
|
||||
text/xml;
|
||||
}
|
||||
}
|
||||
75
package.json
75
package.json
@@ -1,27 +1,48 @@
|
||||
{
|
||||
"name": "@lfk/beamershow",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"format": "prettier --write --plugin-search-dir=. ./**/*.html ./**/*.svelte",
|
||||
"prepare": "husky install",
|
||||
"license:export": "license-exporter --markdown && git stage licenses.md"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@odit/license-exporter": "^0.0.11",
|
||||
"@svitejs/vite-plugin-svelte": "^0.11.1",
|
||||
"@tsconfig/svelte": "^1.0.10",
|
||||
"@types/html-minifier": "^4.0.0",
|
||||
"axios": "^0.21.1",
|
||||
"html-minifier": "^4.0.0",
|
||||
"husky": "^5.1.3",
|
||||
"prettier": "^2.2.1",
|
||||
"prettier-plugin-svelte": "^2.2.0",
|
||||
"svelte": "3.36.0",
|
||||
"svelte-i18n": "3.3.9",
|
||||
"svelte-preprocess": "4.7.0",
|
||||
"vite": "2.1.4",
|
||||
"vite-plugin-windicss": "0.11.2"
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "@lfk/beamershow",
|
||||
"version": "0.1.4",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"format": "prettier --write --plugin-search-dir=. ./**/*.html ./**/*.svelte",
|
||||
"prepare": "husky install",
|
||||
"license:export": "license-exporter --markdown && git stage licenses.md",
|
||||
"release": "release-it --only-version"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@odit/license-exporter": "^0.0.11",
|
||||
"@svitejs/vite-plugin-svelte": "^0.11.1",
|
||||
"@tsconfig/svelte": "^1.0.10",
|
||||
"@types/html-minifier": "^4.0.0",
|
||||
"axios": "^0.21.1",
|
||||
"html-minifier": "^4.0.0",
|
||||
"husky": "^5.1.3",
|
||||
"prettier": "^2.2.1",
|
||||
"prettier-plugin-svelte": "^2.2.0",
|
||||
"release-it": "14.5.0",
|
||||
"svelte": "3.36.0",
|
||||
"svelte-i18n": "3.3.9",
|
||||
"svelte-preprocess": "4.7.0",
|
||||
"validator": "^13.5.2",
|
||||
"vite": "2.1.4",
|
||||
"vite-plugin-windicss": "0.11.2"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"commit": true,
|
||||
"requireCleanWorkingDir": false,
|
||||
"commitMessage": "🚀Bumped version to ${version}",
|
||||
"requireBranch": "main",
|
||||
"push": false,
|
||||
"tag": true,
|
||||
"tagName": null,
|
||||
"tagAnnotation": "${version}"
|
||||
},
|
||||
"npm": {
|
||||
"publish": false
|
||||
},
|
||||
"hooks": {
|
||||
"after:bump": "npx auto-changelog --commit-limit false -p -u --hide-credit && git add CHANGELOG.md && node order.js && git add src/locales"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { apikey, api_endpoint, lang, page, clear } from "./store.js";
|
||||
import { apikey, api_endpoint, lang, clear, laptime_track } from "./store.js";
|
||||
import { addMessages, init } from "svelte-i18n";
|
||||
import en from "./locales/en.json";
|
||||
import de from "./locales/de.json";
|
||||
@@ -11,8 +11,11 @@
|
||||
import Beamershow from "./Beamershow.svelte";
|
||||
import Login from "./Login.svelte";
|
||||
import Settings from "./Settings.svelte";
|
||||
$: is_configured = $apikey && $apikey !== "null" && $apikey !== "";
|
||||
$: settings_open = $page === "settings";
|
||||
export let settings_open = false;
|
||||
$: is_configured = $apikey?.length === 44 && $api_endpoint?.includes("://");
|
||||
// &&
|
||||
// $laptime_track != 0 &&
|
||||
// $laptime_track != null;
|
||||
init({
|
||||
fallbackLocale: "en-US",
|
||||
initialLocale: $lang,
|
||||
@@ -24,20 +27,18 @@
|
||||
if (e.key === "Escape") {
|
||||
modal_open = false;
|
||||
}
|
||||
if (e.keyCode === 13) {
|
||||
if (createbtnenabled === true) {
|
||||
createbtnenabled = false;
|
||||
submit();
|
||||
}
|
||||
}
|
||||
// if (e.keyCode === 13) {
|
||||
// if (createbtnenabled === true) {
|
||||
// createbtnenabled = false;
|
||||
// submit();
|
||||
// }
|
||||
// }
|
||||
if (command === "" && e.key === "c") {
|
||||
command = "c";
|
||||
} else if (command === "c" && e.key === "n") {
|
||||
command += "n";
|
||||
} else if (command === "cn" && e.key === "f") {
|
||||
clear();
|
||||
settings_open = true;
|
||||
is_configured = true;
|
||||
command = "";
|
||||
} else {
|
||||
command = "";
|
||||
@@ -48,7 +49,7 @@
|
||||
</script>
|
||||
|
||||
{#if settings_open && is_configured}
|
||||
<Settings />
|
||||
<Settings bind:settings_open />
|
||||
{:else if is_configured}
|
||||
<Beamershow />
|
||||
{:else}
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import { _ } from "svelte-i18n";
|
||||
import { fade, slide } from "svelte/transition";
|
||||
import { apikey, api_endpoint, page, stationinfo } from "./store.js";
|
||||
import { slide } from "svelte/transition";
|
||||
import { apikey, api_endpoint, laptime_track } from "./store.js";
|
||||
function init(el) {
|
||||
el.focus();
|
||||
}
|
||||
$: pages = ["general", "runners_distance", "orgs_distance", "teams_distance"];
|
||||
$: pages = [
|
||||
"general",
|
||||
"runners_distance",
|
||||
"runners_laptime",
|
||||
"orgs_distance",
|
||||
"teams_distance",
|
||||
];
|
||||
$: current_page = "general";
|
||||
$: general = {};
|
||||
$: runners = [];
|
||||
$: runners_by_laptime = [];
|
||||
$: orgs = [];
|
||||
$: teams = [];
|
||||
|
||||
@@ -17,6 +24,23 @@
|
||||
$: 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({
|
||||
@@ -45,6 +69,21 @@
|
||||
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({
|
||||
@@ -81,6 +120,7 @@
|
||||
function fetch_all() {
|
||||
stats_general();
|
||||
stats_runners();
|
||||
stats_runners_by_laptime();
|
||||
stats_orgs();
|
||||
stats_teams();
|
||||
}
|
||||
@@ -113,7 +153,7 @@
|
||||
{general.total_runners}
|
||||
</h1>
|
||||
<h1 class="text-2xl font-semibold text-center text-gray-900">
|
||||
Läufer
|
||||
{$_("laeufer")}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3">
|
||||
@@ -121,7 +161,7 @@
|
||||
{general.total_distance}
|
||||
</h1>
|
||||
<h1 class="text-2xl font-semibold text-center text-gray-900">
|
||||
Kilometer gesamt
|
||||
{$_("kilometer-gesamt")}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/2 md:w-1/3">
|
||||
@@ -129,7 +169,7 @@
|
||||
{general.total_donation} €
|
||||
</h1>
|
||||
<h1 class="text-2xl font-semibold text-center text-gray-900">
|
||||
Spendensumme
|
||||
{$_("spendensumme")}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,7 +177,7 @@
|
||||
{: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
|
||||
{$_("top-laeufer")} ({$_("distanz")})
|
||||
</h1>
|
||||
<table class="table p-4 bg-white shadow rounded-lg w-full">
|
||||
<thead>
|
||||
@@ -145,22 +185,22 @@
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Platz
|
||||
{$_("platz")}
|
||||
</th>
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Läufer
|
||||
{$_("laeufer")}
|
||||
</th>
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Organisation
|
||||
{$_("organisation")}
|
||||
</th>
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Kilometer
|
||||
{$_("kilometer")}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -185,10 +225,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{:else if current_page === "orgs_distance"}
|
||||
{: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-Organsiationen
|
||||
{$_("top-laeufer")} ({$_("rundenzeit")})
|
||||
</h1>
|
||||
<table class="table p-4 bg-white shadow rounded-lg w-full">
|
||||
<thead>
|
||||
@@ -196,17 +236,68 @@
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Platz
|
||||
{$_("platz")}
|
||||
</th>
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Organsiation
|
||||
{$_("laeufer")}
|
||||
</th>
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Kilometer
|
||||
{$_("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>
|
||||
@@ -230,7 +321,7 @@
|
||||
{: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
|
||||
{$_("top-teams")}
|
||||
</h1>
|
||||
<table class="table p-4 bg-white shadow rounded-lg w-full">
|
||||
<thead>
|
||||
@@ -238,17 +329,17 @@
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Platz
|
||||
{$_("platz")}
|
||||
</th>
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Team
|
||||
{$_("team")}
|
||||
</th>
|
||||
<th
|
||||
class="border p-4 dark:border-dark-5 whitespace-nowrap font-normal text-gray-900"
|
||||
>
|
||||
Kilometer
|
||||
{$_("kilometer")}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -1,39 +1,21 @@
|
||||
<script>
|
||||
import { apikey, lang, stationinfo, api_endpoint } from "./store.js";
|
||||
import { apikey, lang, api_endpoint, laptime_track, clear } from "./store.js";
|
||||
import isURL from "validator/lib/isURL";
|
||||
import isUUID from "validator/lib/isUUID";
|
||||
import axios from "axios";
|
||||
import { _, locale } from "svelte-i18n";
|
||||
let token;
|
||||
let api_endpoint_input;
|
||||
let api_endpoint_input = "";
|
||||
let track;
|
||||
$: error = false;
|
||||
$: errormessage = "";
|
||||
$: isTokenValid =
|
||||
token?.length === 44 &&
|
||||
token.split(".")[0].length === 7 &&
|
||||
isUUID(token.split(".")[1]);
|
||||
$: isEndpointValid = validURL(api_endpoint_input);
|
||||
function validURL(str) {
|
||||
var pattern = new RegExp(
|
||||
"^(https?:\\/\\/)?" + // protocol
|
||||
"((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name
|
||||
"((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address
|
||||
"(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path
|
||||
"(\\?[;&a-z\\d%_.~+=-]*)?" + // query string
|
||||
"(\\#[-a-z\\d_]*)?$",
|
||||
"i"
|
||||
); // fragment locator
|
||||
return !!pattern.test(str);
|
||||
}
|
||||
function isUUID(uuid) {
|
||||
let s = "" + uuid;
|
||||
|
||||
s = s.match(
|
||||
"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
||||
);
|
||||
if (s === null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
token === "rst" ||
|
||||
(token?.length === 44 &&
|
||||
token.split(".")[0].length === 7 &&
|
||||
isUUID(token.split(".")[1]));
|
||||
$: isEndpointValid =
|
||||
api_endpoint_input === "rst" || isURL(api_endpoint_input);
|
||||
</script>
|
||||
|
||||
<div class="w-full flex flex-wrap">
|
||||
@@ -82,13 +64,15 @@
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if $api_endpoint}
|
||||
{#if $api_endpoint?.includes("://") && (!$apikey || $apikey == null)}
|
||||
<form
|
||||
class="flex flex-col pt-3 md:pt-8"
|
||||
onsubmit="event.preventDefault();"
|
||||
on:submit={() => {
|
||||
console.log({ token });
|
||||
// return
|
||||
if (token === "rst") {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
axios
|
||||
.request({
|
||||
method: "GET",
|
||||
@@ -99,7 +83,6 @@
|
||||
error = false;
|
||||
errormessage = "";
|
||||
apikey.set(token);
|
||||
stationinfo.set(JSON.stringify(response.data));
|
||||
})
|
||||
.catch(function (e) {
|
||||
error = true;
|
||||
@@ -140,6 +123,14 @@
|
||||
class="flex flex-col pt-3 md:pt-8"
|
||||
onsubmit="event.preventDefault();"
|
||||
on:submit={() => {
|
||||
if (api_endpoint_input === "rst") {
|
||||
clear();
|
||||
api_endpoint_input = "";
|
||||
return;
|
||||
}
|
||||
if (api_endpoint_input.includes("api/")) {
|
||||
api_endpoint_input = api_endpoint_input.replace("api/", "");
|
||||
}
|
||||
if (api_endpoint_input.substr(-1) !== "/") {
|
||||
api_endpoint_input = api_endpoint_input + "/";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script>
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
import { apikey, api_endpoint, lang, page, stationinfo } from "./store.js";
|
||||
import { apikey, api_endpoint, lang, laptime_track, clear } from "./store.js";
|
||||
export let settings_open = false;
|
||||
</script>
|
||||
|
||||
<div class="p-5 min-h-screen">
|
||||
@@ -9,40 +9,17 @@
|
||||
Lauf Für Kaya! Beamershow
|
||||
</h1>
|
||||
<h1 class="text-3xl w-full text-center text-gray-900">{$_("settings")}</h1>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">{$_("api_endpoint")}</p>
|
||||
<p class="block text-sm text-gray-700">{$api_endpoint}</p>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">{$_("api_key")}</p>
|
||||
<p class="block text-sm text-gray-700">{$apikey}</p>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">
|
||||
{$_("station_description")}
|
||||
</p>
|
||||
<p class="block text-sm text-gray-700">
|
||||
{JSON.parse($stationinfo).description}
|
||||
</p>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">{$_("station_id")}</p>
|
||||
<p class="block text-sm text-gray-700">{JSON.parse($stationinfo).id}</p>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">{$_("track_id")}</p>
|
||||
<p class="block text-sm text-gray-700">{JSON.parse($stationinfo).track.id}</p>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">{$_("track_name")}</p>
|
||||
<p class="block text-sm text-gray-700">
|
||||
{JSON.parse($stationinfo).track.name}
|
||||
</p>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">
|
||||
{$_("track_distance")}
|
||||
</p>
|
||||
<p class="block text-sm text-gray-700">
|
||||
{JSON.parse($stationinfo).track.distance}
|
||||
</p>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">
|
||||
{$_("minimum_lap_time")}
|
||||
</p>
|
||||
<p class="block text-sm text-gray-700">
|
||||
{JSON.parse($stationinfo).track.minimumLapTime}s
|
||||
</p>
|
||||
<p class="block text-sm font-bold text-gray-700 mt-2">{$_("language")}</p>
|
||||
<div class="w-full">
|
||||
<div class="inline-block mr-2 mt-2">
|
||||
<button
|
||||
on:click={() => {
|
||||
lang.set("de-DE");
|
||||
location.reload();
|
||||
}}
|
||||
type="button"
|
||||
class:bg-blue-700={$lang === "de-DE"}
|
||||
@@ -68,6 +45,7 @@
|
||||
<button
|
||||
on:click={() => {
|
||||
lang.set("en-EN");
|
||||
location.reload();
|
||||
}}
|
||||
type="button"
|
||||
class:bg-blue-700={$lang === "en-EN"}
|
||||
@@ -95,16 +73,15 @@
|
||||
<br />
|
||||
<button
|
||||
on:click={() => {
|
||||
page.set("");
|
||||
settings_open = false;
|
||||
}}
|
||||
class="mb-3 w-full py-3 border-black border-3 text-black focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black"
|
||||
>{$_("back_to_scanner")}</button
|
||||
>
|
||||
<button
|
||||
on:click={() => {
|
||||
apikey.set("");
|
||||
api_endpoint.set("");
|
||||
page.set("");
|
||||
clear();
|
||||
settings_open = false;
|
||||
}}
|
||||
class="w-full py-3 bg-black text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black"
|
||||
>{$_("log_out_from_this_client")}</button
|
||||
|
||||
@@ -1,27 +1,41 @@
|
||||
{
|
||||
"api_endpoint": "API-Endpunkt",
|
||||
"api_key": "API Key",
|
||||
"back_to_scanner": "Zurück zum Scanner",
|
||||
"back_to_scanner": "Zurück zur Beamershow",
|
||||
"client_token": "Client Token",
|
||||
"configuration": "Konfiguration",
|
||||
"configure": "Konfigurieren",
|
||||
"distanz": "Distanz",
|
||||
"error": "Error!",
|
||||
"kilometer": "Kilometer",
|
||||
"kilometer-gesamt": "Kilometer gesamt",
|
||||
"laeufer": "Läufer",
|
||||
"language": "Sprache",
|
||||
"log_out_from_this_client": "Von diesem Scanner abmelden",
|
||||
"log_out_from_this_client": "Von dieser Beamershow abmelden",
|
||||
"minimum_lap_time": "minimale Rundenzeit",
|
||||
"organisation": "Organisation",
|
||||
"organsiation": "Organsiation",
|
||||
"platz": "Platz",
|
||||
"please_check_your_token_and_try_again": "Bitte überprüfe den Token und versuche es erneut...",
|
||||
"please_provide_a_valid_client_api_endpoint": "Bitte gebe einen gültigen API-Endpunkt an ...",
|
||||
"please_provide_a_valid_client_token": "Bitte gebe einen gültigen Client-Token an ...",
|
||||
"please_provide_the_scan_client_token": "Bitte gebe den Beamershow-Client-Token an.",
|
||||
"please_scan_a_card": "Bitte scanne eine Karte ...",
|
||||
"rundenzeit": "Rundenzeit",
|
||||
"runner_card": "Läuferkarte",
|
||||
"scan": "Scannen!",
|
||||
"schnellste-rundenzeit": "Schnellste Rundenzeit",
|
||||
"see_our_configuration_guide": "Siehe dir unsere Konfigurationsanleitung an.",
|
||||
"settings": "Einstellungen",
|
||||
"spendensumme": "Spendensumme",
|
||||
"station_description": "Beschreibung der Scanstation",
|
||||
"station_id": "Scanstations-ID",
|
||||
"team": "Team",
|
||||
"the_provided_scan_station_is_disabled": "Die angegebene Scanstation ist deaktiviert.",
|
||||
"the_provided_scan_station_token_is_invalid": "Der angegebene Scanstation-Token ist ungültig.",
|
||||
"top-laeufer": "Top-Läufer",
|
||||
"top-organsiationen": "Top-Organsiationen",
|
||||
"top-teams": "Top-Teams",
|
||||
"track_distance": "Länge des Tracks",
|
||||
"track_id": "Track ID",
|
||||
"track_name": "Track Name"
|
||||
|
||||
@@ -1,27 +1,41 @@
|
||||
{
|
||||
"api_endpoint": "API Endpoint",
|
||||
"api_key": "API Key",
|
||||
"back_to_scanner": "Back to Scanner",
|
||||
"back_to_scanner": "Back to Beamershow",
|
||||
"client_token": "Client Token",
|
||||
"configuration": "Configuration",
|
||||
"configure": "Configure",
|
||||
"distanz": "distance",
|
||||
"error": "Error!",
|
||||
"kilometer": "Kilometers",
|
||||
"kilometer-gesamt": "Kilometers total",
|
||||
"laeufer": "Runners",
|
||||
"language": "Language",
|
||||
"log_out_from_this_client": "Log Out from this Client",
|
||||
"minimum_lap_time": "minimum lap time",
|
||||
"organisation": "Organization",
|
||||
"organsiation": "Organization",
|
||||
"platz": "Place",
|
||||
"please_check_your_token_and_try_again": "Please check your token and try again...",
|
||||
"please_provide_a_valid_client_api_endpoint": "Please provide a valid api endpoint...",
|
||||
"please_provide_a_valid_client_token": "Please provide a valid client token...",
|
||||
"please_provide_the_scan_client_token": "Please provide the scan client token.",
|
||||
"please_scan_a_card": "please scan a card...",
|
||||
"rundenzeit": "fastetst lap",
|
||||
"runner_card": "Runner Card",
|
||||
"scan": "Scan!",
|
||||
"schnellste-rundenzeit": "Fastest lap",
|
||||
"see_our_configuration_guide": "See our configuration guide.",
|
||||
"settings": "Settings",
|
||||
"spendensumme": "Donations",
|
||||
"station_description": "Station Description",
|
||||
"station_id": "Scanstation ID",
|
||||
"team": "Team",
|
||||
"the_provided_scan_station_is_disabled": "The provided scan station is disabled.",
|
||||
"the_provided_scan_station_token_is_invalid": "The provided scan station token is invalid.",
|
||||
"top-laeufer": "Top runners",
|
||||
"top-organsiationen": "Top organizations",
|
||||
"top-teams": "Top teams",
|
||||
"track_distance": "Track Distance",
|
||||
"track_id": "Track ID",
|
||||
"track_name": "Track Name"
|
||||
|
||||
34
src/store.js
34
src/store.js
@@ -1,33 +1,39 @@
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
const stored_api_endpoint = localStorage.getItem('api_endpoint')||"";
|
||||
const stored_api_endpoint = localStorage.getItem('api_endpoint');
|
||||
export const api_endpoint = writable(stored_api_endpoint);
|
||||
api_endpoint.subscribe((value) => {
|
||||
localStorage.setItem('api_endpoint', value);
|
||||
if (value != null) {
|
||||
localStorage.setItem('api_endpoint', value);
|
||||
}
|
||||
});
|
||||
const stored_apikey = localStorage.getItem('apikey');
|
||||
export const apikey = writable(stored_apikey);
|
||||
apikey.subscribe((value) => {
|
||||
localStorage.setItem('apikey', value);
|
||||
if (value != null) {
|
||||
localStorage.setItem('apikey', value);
|
||||
}
|
||||
});
|
||||
const stored_stationinfo = localStorage.getItem('stationinfo');
|
||||
export const stationinfo = writable(stored_stationinfo);
|
||||
stationinfo.subscribe((value) => {
|
||||
localStorage.setItem('stationinfo', value);
|
||||
});
|
||||
const stored_page = localStorage.getItem('page');
|
||||
export const page = writable(stored_page);
|
||||
page.subscribe((value) => {
|
||||
localStorage.setItem('page', value);
|
||||
const stored_laptime_track = localStorage.getItem('laptime_track');
|
||||
export const laptime_track = writable(stored_laptime_track);
|
||||
laptime_track.subscribe((value) => {
|
||||
if (value != null) {
|
||||
localStorage.setItem('laptime_track', value);
|
||||
}
|
||||
});
|
||||
const stored_lang = localStorage.getItem('lang') === 'null' ? navigator.language : localStorage.getItem('lang');
|
||||
export const lang = writable(stored_lang);
|
||||
lang.subscribe((value) => {
|
||||
localStorage.setItem('lang', value);
|
||||
if (value != null) {
|
||||
localStorage.setItem('lang', value);
|
||||
}
|
||||
});
|
||||
|
||||
export function clear(){
|
||||
export function clear() {
|
||||
api_endpoint.set(null)
|
||||
api_endpoint.set("")
|
||||
apikey.set(null);
|
||||
apikey.set("");
|
||||
laptime_track.set(null)
|
||||
localStorage.clear();
|
||||
}
|
||||
Reference in New Issue
Block a user