Dieser Commit ist enthalten in:
Ursprung
361d7dae6a
Commit
678746c89b
@ -56,6 +56,7 @@
|
||||
"flowbite": "^1.8.1",
|
||||
"flowbite-svelte": "^0.44.24",
|
||||
"flowbite-svelte-icons": "^0.4.5",
|
||||
"qs": "^6.11.2",
|
||||
"sharp": "^0.32.6",
|
||||
"svelte-awesome": "^3.3.1",
|
||||
"svelte-codemirror-editor": "^1.2.0",
|
||||
|
22
pnpm-lock.yaml
generiert
22
pnpm-lock.yaml
generiert
@ -56,6 +56,9 @@ dependencies:
|
||||
flowbite-svelte-icons:
|
||||
specifier: ^0.4.5
|
||||
version: 0.4.5(svelte@4.2.12)(tailwind-merge@2.2.1)(tailwindcss@3.4.1)
|
||||
qs:
|
||||
specifier: ^6.11.2
|
||||
version: 6.11.2
|
||||
sharp:
|
||||
specifier: ^0.32.6
|
||||
version: 0.32.6
|
||||
@ -1985,7 +1988,6 @@ packages:
|
||||
function-bind: 1.1.2
|
||||
get-intrinsic: 1.2.4
|
||||
set-function-length: 1.2.1
|
||||
dev: true
|
||||
|
||||
/callsites@3.1.0:
|
||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||
@ -2400,7 +2402,6 @@ packages:
|
||||
es-define-property: 1.0.0
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.0.1
|
||||
dev: true
|
||||
|
||||
/define-properties@1.2.1:
|
||||
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
||||
@ -2581,12 +2582,10 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.4
|
||||
dev: true
|
||||
|
||||
/es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: true
|
||||
|
||||
/es-iterator-helpers@1.0.17:
|
||||
resolution: {integrity: sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==}
|
||||
@ -3135,7 +3134,6 @@ packages:
|
||||
has-proto: 1.0.3
|
||||
has-symbols: 1.0.3
|
||||
hasown: 2.0.1
|
||||
dev: true
|
||||
|
||||
/get-stream@8.0.1:
|
||||
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
|
||||
@ -3224,7 +3222,6 @@ packages:
|
||||
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.4
|
||||
dev: true
|
||||
|
||||
/graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
@ -3259,17 +3256,14 @@ packages:
|
||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||
dependencies:
|
||||
es-define-property: 1.0.0
|
||||
dev: true
|
||||
|
||||
/has-proto@1.0.3:
|
||||
resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: true
|
||||
|
||||
/has-symbols@1.0.3:
|
||||
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: true
|
||||
|
||||
/has-tostringtag@1.0.2:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
@ -4592,7 +4586,6 @@ packages:
|
||||
|
||||
/object-inspect@1.13.1:
|
||||
resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
|
||||
dev: true
|
||||
|
||||
/object-keys@1.1.1:
|
||||
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
||||
@ -5287,6 +5280,13 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/qs@6.11.2:
|
||||
resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==}
|
||||
engines: {node: '>=0.6'}
|
||||
dependencies:
|
||||
side-channel: 1.0.5
|
||||
dev: false
|
||||
|
||||
/queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
@ -5598,7 +5598,6 @@ packages:
|
||||
get-intrinsic: 1.2.4
|
||||
gopd: 1.0.1
|
||||
has-property-descriptors: 1.0.2
|
||||
dev: true
|
||||
|
||||
/set-function-name@2.0.2:
|
||||
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
|
||||
@ -5650,7 +5649,6 @@ packages:
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.2.4
|
||||
object-inspect: 1.13.1
|
||||
dev: true
|
||||
|
||||
/signal-exit@3.0.7:
|
||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||
|
@ -21,6 +21,7 @@
|
||||
import {l} from "@utils/util.ts";
|
||||
import {t} from "astro-i18n";
|
||||
import {get} from "svelte/store";
|
||||
import {navigate} from "astro:transitions/client";
|
||||
|
||||
let username: string = "";
|
||||
let pw: string = "";
|
||||
@ -45,7 +46,7 @@
|
||||
}
|
||||
|
||||
tokenStore.set(auth);
|
||||
window.location.href = l("/dashboard");
|
||||
navigate(l("/dashboard"));
|
||||
} catch (e: any) {
|
||||
pw = "";
|
||||
error = t("login.error");
|
||||
|
@ -105,7 +105,7 @@
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<a class="btn my-1" href={l("/login")}>
|
||||
<a class="btn my-1" href={l("/login")} data-astro-reload>
|
||||
<span class="btn__text">{t("navbar.links.account")}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -46,6 +46,10 @@
|
||||
asyncComponent: () => import("./pages/Edit.svelte"),
|
||||
conditions: detail => get(tokenStore) != ""
|
||||
}),
|
||||
"/display/:event": wrap({
|
||||
asyncComponent: () => import("./pages/Display.svelte"),
|
||||
conditions: detail => get(tokenStore) != ""
|
||||
}),
|
||||
"*": wrap({asyncComponent: () => import("./pages/NotFound.svelte")})
|
||||
};
|
||||
|
||||
|
43
src/components/admin/pages/Display.svelte
Normale Datei
43
src/components/admin/pages/Display.svelte
Normale Datei
@ -0,0 +1,43 @@
|
||||
<!--
|
||||
- This file is a part of the SteamWar software.
|
||||
-
|
||||
- Copyright (C) 2024 SteamWar.de-Serverteam
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as published by
|
||||
- the Free Software Foundation, either version 3 of the License, or
|
||||
- (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import {eventRepo} from "@repo/event.ts";
|
||||
import EventDisplay from "@components/admin/pages/display/EventDisplay.svelte";
|
||||
|
||||
export let params: { event: number };
|
||||
|
||||
let eventFuture = getEvent();
|
||||
|
||||
function getEvent() {
|
||||
return $eventRepo.getEvent(params.event)
|
||||
}
|
||||
|
||||
function refreshEvent() {
|
||||
eventFuture = getEvent();
|
||||
}
|
||||
</script>
|
||||
|
||||
{#await eventFuture}
|
||||
<p>Loading...</p>
|
||||
{:then event}
|
||||
<EventDisplay {event} />
|
||||
{:catch error}
|
||||
<p>{error.message}</p>
|
||||
{/await}
|
@ -139,6 +139,10 @@
|
||||
<ul>
|
||||
{#if (selectedPath)}
|
||||
{@const value = pagesMap.get(selectedPath) || []}
|
||||
{#if value.length === 0}
|
||||
<li class="p-4">No pages found</li>
|
||||
<li class="p-4">Select a path on the top</li>
|
||||
{/if}
|
||||
{#each value as page}
|
||||
{@const nameRegexExec = nameRegex.exec(page.path)}
|
||||
{@const match = nameRegexExec ? nameRegexExec[0] : ""}
|
||||
|
103
src/components/admin/pages/display/EventDisplay.svelte
Normale Datei
103
src/components/admin/pages/display/EventDisplay.svelte
Normale Datei
@ -0,0 +1,103 @@
|
||||
<!--
|
||||
- This file is a part of the SteamWar software.
|
||||
-
|
||||
- Copyright (C) 2024 SteamWar.de-Serverteam
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as published by
|
||||
- the Free Software Foundation, either version 3 of the License, or
|
||||
- (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type {ExtendedEvent} from "@type/event.ts";
|
||||
import {onMount} from "svelte";
|
||||
|
||||
export let event: ExtendedEvent;
|
||||
export let group: string | null = null;
|
||||
|
||||
const scrollTime = 10000;
|
||||
|
||||
$: groupFights = event.fights.filter(fight => group === null || fight.group === group);
|
||||
|
||||
let clock = new Date();
|
||||
let scrollContainer: HTMLDivElement;
|
||||
let scroll = 0;
|
||||
|
||||
onMount(() => {
|
||||
const interval = setInterval(() => {
|
||||
clock = new Date();
|
||||
}, 1000);
|
||||
const scrollinterval = setInterval(() => {
|
||||
if (scroll >= scrollTime / 10) {
|
||||
if (scrollContainer.scrollHeight - scrollContainer.scrollTop === scrollContainer.clientHeight) {
|
||||
scrollContainer.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth"
|
||||
})
|
||||
} else {
|
||||
scrollContainer.scrollBy({
|
||||
top: scrollContainer.clientHeight,
|
||||
behavior: "smooth"
|
||||
})
|
||||
}
|
||||
scroll = 0;
|
||||
} else {
|
||||
scroll += 1;
|
||||
}
|
||||
}, 10);
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
clearInterval(scrollinterval);
|
||||
};
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="bg-black text-white h-screen w-screen p-4 flex flex-col">
|
||||
<div class="w-full border rounded-xl flex flex-col">
|
||||
<div class="flex justify-between p-2">
|
||||
<h1 class="self-center">{event.event.name}</h1>
|
||||
<h1 class="self-start">{new Intl.DateTimeFormat("de-DE", {hour: "2-digit", minute: "2-digit"}).format(clock)}</h1>
|
||||
</div>
|
||||
<div role="progressbar" class="w-full h-2 rounded-b-full overflow-hidden border-t">
|
||||
<div class="h-full bg-white" style="width: {scroll / (scrollTime / 1000)}%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex mt-4 flex-col gap-96 overflow-y-scroll overflow-x-hidden" bind:this={scrollContainer}>
|
||||
{#each groupFights as fight (fight.id)}
|
||||
<div class="flex justify-between border rounded-xl p-2 mb-96">
|
||||
<h1>{fight.blueTeam.name} vs {fight.redTeam.name}</h1>
|
||||
{#if fight.ergebnis !== 0}
|
||||
{#if fight.ergebnis === 1}
|
||||
<h1>{fight.blueTeam.name} gewinnt</h1>
|
||||
{:else if fight.ergebnis === 2}
|
||||
<h1>{fight.redTeam.name} gewinnt</h1>
|
||||
{:else}
|
||||
<h1>Unentschieden</h1>
|
||||
{/if}
|
||||
{:else}
|
||||
<h1>{new Intl.DateTimeFormat("de-DE", {day: "2-digit", month: "2-digit", "year": "2-digit", hour: "2-digit", minute: "2-digit"}).format(fight.start)}</h1>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="flex-grow"></div>
|
||||
<div class="w-full mt-4 flex justify-between border rounded-xl p-2 self-end">
|
||||
<h1 class="self-center">{event.event.name}</h1>
|
||||
<h1 class="self-start">{new Intl.DateTimeFormat("de-DE", {hour: "2-digit", minute: "2-digit"}).format(clock)}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
</style>
|
@ -37,7 +37,7 @@
|
||||
<p>{t("dashboard.stats.playtime", {playtime: new Intl.NumberFormat(astroI18n.locale, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
}).format(data.playtime)})}</p>
|
||||
}).format(data.playtime)})}h</p>
|
||||
<p>{t("dashboard.stats.fights", {fights: data.fights})}</p>
|
||||
{#if user.perms.includes("CHECK")}
|
||||
<p>{t("dashboard.stats.checked", {checked: data.acceptedSchematics})}</p>
|
||||
|
@ -91,5 +91,76 @@
|
||||
"draw": "Unentschieden",
|
||||
"points": "Punkte"
|
||||
}
|
||||
},
|
||||
"blog": {
|
||||
"title": "Ankündigungen - SteamWar"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "Hallo, {# name #}!",
|
||||
"rank": "Rang: {# rank #}",
|
||||
"permissions": "Berechtigungen:",
|
||||
"buttons": {
|
||||
"logout": "Abmelden"
|
||||
},
|
||||
"stats": {
|
||||
"playtime": "Spielzeit: {# playtime #}",
|
||||
"fights": "Kämpfe: {# fights #}",
|
||||
"checked": "Schematics Geprüft: {# checked #}"
|
||||
},
|
||||
"schematic": {
|
||||
"upload": "Hochladen",
|
||||
"dir": "Ordner",
|
||||
"head": {
|
||||
"type": "Typ",
|
||||
"owner": "Besitzer",
|
||||
"updated": "Aktualisiert",
|
||||
"replaceColor": "Farbe ersetzen",
|
||||
"allowReplay": "Wiederholung erlauben"
|
||||
},
|
||||
"cancel": "Abbrechen",
|
||||
"title": "Schematic hochladen"
|
||||
}
|
||||
},
|
||||
"login": {
|
||||
"title": "Login",
|
||||
"placeholder": {
|
||||
"username": "Nutzername...",
|
||||
"password": "***************"
|
||||
},
|
||||
"label": {
|
||||
"username": "Nutzername",
|
||||
"password": "Passwort"
|
||||
},
|
||||
"setPassword": "Wie setzte ich mein Passwort?",
|
||||
"submit": "Login",
|
||||
"error": "Falscher Nutzername oder falsches Passwort"
|
||||
},
|
||||
"ranked": {
|
||||
"title": "{# mode #} - Rangliste"
|
||||
},
|
||||
"rules": {
|
||||
"page": "SteamWar - Regelwerke",
|
||||
"wg": {
|
||||
"description": "Heute werden die Schlachtfelder der Erde von schwerem Geschütz bestimmt. Mit unserem traditionellen Regelwerk sind auch die WarGears arenenverwüstende Schwergewichte. Aufgrund der Kanonentechnik mit den meisten Projektilen erwarten dich bei WarGears harte und kurzweilige Kämpfe."
|
||||
},
|
||||
"mwg": {
|
||||
"description": "Im heutigen Straßenkampf hat massives Gerät keinen Platz, weswegen kleinere Maschinen auch heute noch ihre Berechtigung haben. Mit den etwas kleineren Kanonen sind MiniWarGears genau das richtige für Einsteiger, Gelegenheitsspieler und Experimentierfreudige."
|
||||
},
|
||||
"ws": {
|
||||
"description": "Lange Zeit waren Kriegsschiffe das Nonplusultra der Kriegsführung. In Sachen Raketen- und Slimetechnik gilt das auch heute noch für Warships. Durch die begrenzte Kanonenstärke bieten WarShips lange, intensive und abwechslungsreiche Kämpfe, womit es immer neue Technik in der Arena gibt. Durch das Entern verlagert sich ein WarShip-Kampf nach einiger Zeit in das Wasser und bietet damit spannende PvP-Action."
|
||||
},
|
||||
"as": {
|
||||
"description": "Der Traum vom Fliegen beflügelt die Menschheit schon seit Jahrtausenden. Der Spielmodus AirShips bietet dir die nahezu unbegrenzten Möglichkeiten des Himmels. Egal, ob du mit 15 2 Projektil-Kanonen oder 2 15 Projektil-Kanonen antrittst, du hast stets eine realistische Chance auf den Sieg. Denn: Alles hat seinen Preis."
|
||||
},
|
||||
"qg": {
|
||||
"description": "Nicht immer besteht die Zeit für einen langen Bau. Manchmal muss es schnell gehen. Für diese Fälle gibt es QuickGears. Ohne Qualitätsprüfung und mit nur einem Klick kannst du hier ein Gefährt erstellen. Die Qualität ist dabei nicht immer die beste, aber für einen schnellen Kampf reicht es allemal."
|
||||
},
|
||||
"rules": "Regelwerk »",
|
||||
"announcements": "Ankündigungen »",
|
||||
"ranking": "Rangliste »",
|
||||
"title": "{# mode #} - Regelwerk"
|
||||
},
|
||||
"stats": {
|
||||
"title": "Kampf Statistiken"
|
||||
}
|
||||
}
|
||||
|
@ -141,5 +141,97 @@
|
||||
"warning": {
|
||||
"title": "This page is not available in your language.",
|
||||
"text": "The page you are trying to access is not available in your language. You can still access the original page in German."
|
||||
},
|
||||
"tag": {
|
||||
"title": "Tag: {# tag #} - SteamWar"
|
||||
},
|
||||
"blog": {
|
||||
"title": "Announcements - SteamWar"
|
||||
},
|
||||
"dashboard": {
|
||||
"page": "SteamWar - Dashboard",
|
||||
"title": "Hello, {# name #}!",
|
||||
"rank": "Rank: {# rank #}",
|
||||
"permissions": "Permssions:",
|
||||
"buttons": {
|
||||
"logout": "Logout",
|
||||
"admin": "Admin Panel"
|
||||
},
|
||||
"stats": {
|
||||
"playtime": "Playtime: {# playtime #}h",
|
||||
"fights": "Fights: {# fights #}",
|
||||
"checked": "Schematics Checked: {# checked #}"
|
||||
},
|
||||
"schematic": {
|
||||
"upload": "Upload",
|
||||
"cancel": "Cancel",
|
||||
"title": "Upload Schematic",
|
||||
"home": "Schematics",
|
||||
"dir": "Directory",
|
||||
"head": {
|
||||
"type": "Type",
|
||||
"name": "Name",
|
||||
"owner": "Owner",
|
||||
"updated": "Updated",
|
||||
"replaceColor": "Replace Color",
|
||||
"allowReplay": "Allow Replay"
|
||||
},
|
||||
"info": {
|
||||
"path": "Path: {# path #}",
|
||||
"replaceColor": "Replace Color: ",
|
||||
"allowReplay": "Allow Replay: ",
|
||||
"type": "Type: {# type #}",
|
||||
"updated": "Updated: {# updated #}",
|
||||
"item": "Item: {# item #}",
|
||||
"members": "Members: {# members #}",
|
||||
"btn": {
|
||||
"download": "Download",
|
||||
"close": "Close"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"login": {
|
||||
"page": "SteamWar - Login",
|
||||
"title": "Login",
|
||||
"placeholder": {
|
||||
"username": "Username...",
|
||||
"password": "***************"
|
||||
},
|
||||
"label": {
|
||||
"username": "Username",
|
||||
"password": "Password"
|
||||
},
|
||||
"setPassword": "How to set a Password",
|
||||
"submit": "Login",
|
||||
"error": "Invalid username or password"
|
||||
},
|
||||
"ranked": {
|
||||
"title": "{# mode #} - Ranking"
|
||||
},
|
||||
"rules": {
|
||||
"page": "SteamWar - Rules",
|
||||
"wg": {
|
||||
"description": "Today, the battlefields of Earth are dominated by heavy artillery. With our traditional rules, WarGears are also arena-wrecking heavyweights. Due to the cannon technology with the most projectiles, you can expect hard and short-lived battles in WarGears."
|
||||
},
|
||||
"as": {
|
||||
"description": "The dream of flying has inspired humanity for millennia. The AirShips game mode offers you the almost unlimited possibilities of the sky. Whether you compete with 15 2-projectile cannons or 2 15-projectile cannons, you always have a realistic chance of winning. Because: Everything has its price."
|
||||
},
|
||||
"ws": {
|
||||
"description": "For a long time, warships were the ultimate weapon of war. This is still true for Warships today in terms of rocket and slime technology. Due to the limited cannon power, WarShips offer long, intense and varied battles, with new techniques always being introduced in the arena. After a while, a WarShip battle shifts to the water through boarding, providing exciting PvP action."
|
||||
},
|
||||
"mwg": {
|
||||
"description": "In today's urban warfare, there is no place for heavy equipment, which is why smaller machines still have their place today. With their slightly smaller cannons, MiniWarGears are the perfect choice for beginners, casual players, and those who like to experiment."
|
||||
},
|
||||
"qg": {
|
||||
"description": "Sometimes there is no time for a long construction. Sometimes it has to be quick. For these cases there are QuickGears. Without quality control and with just one click you can create a vehicle here. The quality is not always the best, but for a quick fight it is enough."
|
||||
},
|
||||
"rules": "Rules »",
|
||||
"announcements": "Announcements »",
|
||||
"ranking": "Ranking »",
|
||||
"title": "{# mode #} - Rules"
|
||||
},
|
||||
"stats": {
|
||||
"title": "Fight Statistics"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"blog": {
|
||||
"title": "Ankündigungen - SteamWar"
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"blog": {
|
||||
"title": "Announcements - SteamWar"
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"tag": {
|
||||
"title": "Tag: {# tag #} - SteamWar"
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"dashboard": {
|
||||
"title": "Hallo, {# name #}!",
|
||||
"rank": "Rang: {# rank #}",
|
||||
"permissions": "Berechtigungen:",
|
||||
"buttons": {
|
||||
"logout": "Abmelden"
|
||||
},
|
||||
"stats": {
|
||||
"playtime": "Spielzeit: {# playtime #}",
|
||||
"fights": "Kämpfe: {# fights #}",
|
||||
"checked": "Schematics Geprüft: {# checked #}"
|
||||
},
|
||||
"schematic": {
|
||||
"upload": "Hochladen",
|
||||
"dir": "Ordner",
|
||||
"head": {
|
||||
"type": "Typ",
|
||||
"owner": "Besitzer",
|
||||
"updated": "Aktualisiert",
|
||||
"replaceColor": "Farbe ersetzen",
|
||||
"allowReplay": "Wiederholung erlauben"
|
||||
},
|
||||
"cancel": "Abbrechen",
|
||||
"title": "Schematic hochladen"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
{
|
||||
"dashboard": {
|
||||
"page": "SteamWar - Dashboard",
|
||||
"title": "Hello, {# name #}!",
|
||||
"rank": "Rank: {# rank #}",
|
||||
"permissions": "Permssions:",
|
||||
"buttons": {
|
||||
"logout": "Logout",
|
||||
"admin": "Admin Panel"
|
||||
},
|
||||
"stats": {
|
||||
"playtime": "Playtime: {# playtime #}h",
|
||||
"fights": "Fights: {# fights #}",
|
||||
"checked": "Schematics Checked: {# checked #}"
|
||||
},
|
||||
"schematic": {
|
||||
"upload": "Upload",
|
||||
"cancel": "Cancel",
|
||||
"title": "Upload Schematic",
|
||||
"home": "Schematics",
|
||||
"dir": "Directory",
|
||||
"head": {
|
||||
"type": "Type",
|
||||
"name": "Name",
|
||||
"owner": "Owner",
|
||||
"updated": "Updated",
|
||||
"replaceColor": "Replace Color",
|
||||
"allowReplay": "Allow Replay"
|
||||
},
|
||||
"info": {
|
||||
"path": "Path: {# path #}",
|
||||
"replaceColor": "Replace Color: ",
|
||||
"allowReplay": "Allow Replay: ",
|
||||
"type": "Type: {# type #}",
|
||||
"updated": "Updated: {# updated #}",
|
||||
"item": "Item: {# item #}",
|
||||
"members": "Members: {# members #}",
|
||||
"btn": {
|
||||
"download": "Download",
|
||||
"close": "Close"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"login": {
|
||||
"title": "Login",
|
||||
"placeholder": {
|
||||
"username": "Nutzername...",
|
||||
"password": "***************"
|
||||
},
|
||||
"label": {
|
||||
"username": "Nutzername",
|
||||
"password": "Passwort"
|
||||
},
|
||||
"setPassword": "Wie setzte ich mein Passwort?",
|
||||
"submit": "Login",
|
||||
"error": "Falscher Nutzername oder falsches Passwort"
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"login": {
|
||||
"page": "SteamWar - Login",
|
||||
"title": "Login",
|
||||
"placeholder": {
|
||||
"username": "Username...",
|
||||
"password": "***************"
|
||||
},
|
||||
"label": {
|
||||
"username": "Username",
|
||||
"password": "Password"
|
||||
},
|
||||
"setPassword": "How to set a Password",
|
||||
"submit": "Login",
|
||||
"error": "Invalid username or password"
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"ranked": {
|
||||
"title": "{# mode #} - Rangliste"
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"ranked": {
|
||||
"title": "{# mode #} - Ranking"
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"page": "SteamWar - Regelwerke",
|
||||
"wg": {
|
||||
"description": "Heute werden die Schlachtfelder der Erde von schwerem Geschütz bestimmt. Mit unserem traditionellen Regelwerk sind auch die WarGears arenenverwüstende Schwergewichte. Aufgrund der Kanonentechnik mit den meisten Projektilen erwarten dich bei WarGears harte und kurzweilige Kämpfe."
|
||||
},
|
||||
"mwg": {
|
||||
"description": "Im heutigen Straßenkampf hat massives Gerät keinen Platz, weswegen kleinere Maschinen auch heute noch ihre Berechtigung haben. Mit den etwas kleineren Kanonen sind MiniWarGears genau das richtige für Einsteiger, Gelegenheitsspieler und Experimentierfreudige."
|
||||
},
|
||||
"ws": {
|
||||
"description": "Lange Zeit waren Kriegsschiffe das Nonplusultra der Kriegsführung. In Sachen Raketen- und Slimetechnik gilt das auch heute noch für Warships. Durch die begrenzte Kanonenstärke bieten WarShips lange, intensive und abwechslungsreiche Kämpfe, womit es immer neue Technik in der Arena gibt. Durch das Entern verlagert sich ein WarShip-Kampf nach einiger Zeit in das Wasser und bietet damit spannende PvP-Action."
|
||||
},
|
||||
"as": {
|
||||
"description": "Der Traum vom Fliegen beflügelt die Menschheit schon seit Jahrtausenden. Der Spielmodus AirShips bietet dir die nahezu unbegrenzten Möglichkeiten des Himmels. Egal, ob du mit 15 2 Projektil-Kanonen oder 2 15 Projektil-Kanonen antrittst, du hast stets eine realistische Chance auf den Sieg. Denn: Alles hat seinen Preis."
|
||||
},
|
||||
"qg": {
|
||||
"description": "Nicht immer besteht die Zeit für einen langen Bau. Manchmal muss es schnell gehen. Für diese Fälle gibt es QuickGears. Ohne Qualitätsprüfung und mit nur einem Klick kannst du hier ein Gefährt erstellen. Die Qualität ist dabei nicht immer die beste, aber für einen schnellen Kampf reicht es allemal."
|
||||
},
|
||||
"rules": "Regelwerk »",
|
||||
"announcements": "Ankündigungen »",
|
||||
"ranking": "Rangliste »",
|
||||
"title": "{# mode #} - Regelwerk"
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"page": "SteamWar - Rules",
|
||||
"wg": {
|
||||
"description": "Today, the battlefields of Earth are dominated by heavy artillery. With our traditional rules, WarGears are also arena-wrecking heavyweights. Due to the cannon technology with the most projectiles, you can expect hard and short-lived battles in WarGears."
|
||||
},
|
||||
"as": {
|
||||
"description": "The dream of flying has inspired humanity for millennia. The AirShips game mode offers you the almost unlimited possibilities of the sky. Whether you compete with 15 2-projectile cannons or 2 15-projectile cannons, you always have a realistic chance of winning. Because: Everything has its price."
|
||||
},
|
||||
"ws": {
|
||||
"description": "For a long time, warships were the ultimate weapon of war. This is still true for Warships today in terms of rocket and slime technology. Due to the limited cannon power, WarShips offer long, intense and varied battles, with new techniques always being introduced in the arena. After a while, a WarShip battle shifts to the water through boarding, providing exciting PvP action."
|
||||
},
|
||||
"mwg": {
|
||||
"description": "In today's urban warfare, there is no place for heavy equipment, which is why smaller machines still have their place today. With their slightly smaller cannons, MiniWarGears are the perfect choice for beginners, casual players, and those who like to experiment."
|
||||
},
|
||||
"qg": {
|
||||
"description": "Sometimes there is no time for a long construction. Sometimes it has to be quick. For these cases there are QuickGears. Without quality control and with just one click you can create a vehicle here. The quality is not always the best, but for a quick fight it is enough."
|
||||
},
|
||||
"rules": "Rules »",
|
||||
"announcements": "Announcements »",
|
||||
"ranking": "Ranking »",
|
||||
"title": "{# mode #} - Rules"
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"stats": {
|
||||
"title": "Kampf Statistiken"
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"stats": {
|
||||
"title": "Fight Statistics"
|
||||
}
|
||||
}
|
@ -2,8 +2,9 @@
|
||||
import icon from "../images/logo.png";
|
||||
import {getImage} from "astro:assets";
|
||||
import {astroI18n} from "astro-i18n";
|
||||
const {title, description} = Astro.props.frontmatter || Astro.props;
|
||||
import {SEO} from "astro-seo";
|
||||
import {ViewTransitions} from "astro:transitions";
|
||||
const {title, description} = Astro.props.frontmatter || Astro.props;
|
||||
|
||||
import "../../public/fonts/roboto/roboto.css";
|
||||
|
||||
@ -38,6 +39,8 @@ if (localStorage["theme-mode"] === "light" || (!("theme-mode" in localStorage) &
|
||||
</script>
|
||||
|
||||
<slot name="head"/>
|
||||
|
||||
<ViewTransitions />
|
||||
</head>
|
||||
<body class="dark:bg-zinc-800">
|
||||
<slot/>
|
||||
|
@ -29,7 +29,7 @@ const {title, description} = Astro.props;
|
||||
<div class="flex-1 flex justify-evenly items-center md:items-start mt-4 md:flex-row flex-col gap-y-4">
|
||||
<div class="footer-card">
|
||||
<h1>Serverstatus</h1>
|
||||
<ServerStatus client:only="svelte"/>
|
||||
<ServerStatus transition:persist client:only="svelte"/>
|
||||
</div>
|
||||
<div class="footer-card">
|
||||
<h1>Links</h1>
|
||||
|
@ -11,7 +11,7 @@ const {title, description, image} = Astro.props;
|
||||
<Image src={image || localBau} alt="Bau" width="1920" height="1080" densities={[1.5, 2, 3, 4]}
|
||||
class="w-full h-screen dark:brightness-75 fixed -z-10 object-cover" draggable="false" />
|
||||
<div class="mx-auto bg-gray-100 p-8 rounded-b-md shadow-md pt-40 sm:pt-28 md:pt-14 relative
|
||||
dark:text-white dark:bg-neutral-900" style="width: min(100vw, 75em);">
|
||||
dark:text-white dark:bg-neutral-900" style="width: min(100%, 75em);">
|
||||
<slot/>
|
||||
</div>
|
||||
</NavbarLayout>
|
@ -7,10 +7,11 @@ import {t} from "astro-i18n";
|
||||
<PageLayout title={t("dashboard.page")}>
|
||||
<script>
|
||||
import {l} from "../util/util";
|
||||
import {navigate} from "astro:transitions/client";
|
||||
|
||||
if (window.location.href.endsWith("/dashboard") || window.location.href.endsWith("/dashboard/")) {
|
||||
if ((localStorage.getItem("sw-session") ?? "") === "") {
|
||||
window.location.href = l("/login");
|
||||
navigate(l("/login"), {});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -9,10 +9,11 @@ import localBau from "@images/2023-10-08_20.43.43.png";
|
||||
<NavbarLayout title={t("login.page")}>
|
||||
<script>
|
||||
import {l} from "../util/util";
|
||||
import {navigate} from "astro:transitions/client";
|
||||
|
||||
if (window.location.href.endsWith("/login") || window.location.href.endsWith("/login/")) {
|
||||
if ((localStorage.getItem("sw-session") ?? "") !== "") {
|
||||
window.location.href = l("/dashboard");
|
||||
navigate(l("/dashboard"));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -31,7 +31,7 @@ const {page, german} = Astro.props;
|
||||
const {Content} = await page.render();
|
||||
---
|
||||
|
||||
<PageLayout title={t("title", {mode: t(`${page.data.translationKey}.title`)}, {route: "/rules"})}>
|
||||
<PageLayout title={t("rules.title", {mode: t(`${page.data.translationKey}.title`)})}>
|
||||
<article>
|
||||
{german && (
|
||||
<LanguageWarning/>
|
||||
|
@ -20,22 +20,22 @@ const imageMap = {
|
||||
const modes = await getCollection("modes", entry => entry.data.main);
|
||||
---
|
||||
|
||||
<PageLayout title={t("page")}>
|
||||
<PageLayout title={t("rules.page")}>
|
||||
{modes.map(value => (
|
||||
<div class="dark:bg-neutral-800 rounded-md p-4 border border-neutral-400 shadow-md my-4 flex flex-col
|
||||
md:flex-row">
|
||||
<Image height="300" width="300" src={imageMap[value.data.translationKey]}
|
||||
alt={t(value.data.translationKey + ".title")} class="dark:invert"></Image>
|
||||
alt={t("rules." + value.data.translationKey + ".title")} class="dark:invert"></Image>
|
||||
<div class="ml-4">
|
||||
<h1 class="text-2xl font-bold">{t(value.data.translationKey + ".title")}</h1>
|
||||
<div>{t(value.data.translationKey + ".description")}</div>
|
||||
<div>{t("rules." + value.data.translationKey + ".description")}</div>
|
||||
<div class="mt-2 flex flex-col">
|
||||
<a href={l(`/rules/${value.id}`)} class="text-yellow-300 hover:underline w-fit">{t("rules")}</a>
|
||||
<a href={l(`/rules/${value.id}`)} class="text-yellow-300 hover:underline w-fit">{t("rules.rules")}</a>
|
||||
<a href={l(`/announcements/tags/${value.id}`)}
|
||||
class="text-yellow-300 hover:underline w-fit">{t("announcements")}</a>
|
||||
class="text-yellow-300 hover:underline w-fit">{t("rules.announcements")}</a>
|
||||
{value.data.ranked
|
||||
? <a href={l(`/ranked/${value.id}`)}
|
||||
class="text-yellow-300 hover:underline w-fit">{t("ranking")}</a>
|
||||
class="text-yellow-300 hover:underline w-fit">{t("rules.ranking")}</a>
|
||||
: null}
|
||||
</div>
|
||||
</div>
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren