Compare commits
5 Commits
dc21366f7a
...
9cd78231c3
Author | SHA1 | Date | |
---|---|---|---|
9cd78231c3 | |||
47867738f8 | |||
a872613f1e | |||
38906df545 | |||
05ddd05a5b |
@ -4,6 +4,5 @@
|
|||||||
"trailingComma": "none",
|
"trailingComma": "none",
|
||||||
"printWidth": 100,
|
"printWidth": 100,
|
||||||
"plugins": ["prettier-plugin-svelte"],
|
"plugins": ["prettier-plugin-svelte"],
|
||||||
"pluginSearchDirs": ["."],
|
|
||||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||||
}
|
}
|
||||||
|
949
package-lock.json
generated
949
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
60
package.json
60
package.json
@ -9,45 +9,45 @@
|
|||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
"lint": "prettier --check . && eslint .",
|
||||||
"format": "prettier --plugin-search-dir . --write ."
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-node": "^1.3.1",
|
"@sveltejs/adapter-node": "^1.3.1",
|
||||||
"@sveltejs/kit": "^1.20.4",
|
"@sveltejs/kit": "^1.27.6",
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.2",
|
||||||
"@types/node": "^20.5.6",
|
"@types/node": "^20.10.0",
|
||||||
"@types/validator": "^13.11.1",
|
"@types/validator": "^13.11.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
"@typescript-eslint/eslint-plugin": "^6.13.1",
|
||||||
"@typescript-eslint/parser": "^5.45.0",
|
"@typescript-eslint/parser": "^6.13.1",
|
||||||
"autoprefixer": "^10.4.14",
|
"autoprefixer": "^10.4.16",
|
||||||
"daisyui": "^4.4.10",
|
"daisyui": "^4.4.14",
|
||||||
"eslint": "^8.28.0",
|
"eslint": "^8.54.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-svelte": "^2.30.0",
|
"eslint-plugin-svelte": "^2.35.1",
|
||||||
"postcss": "^8.4.27",
|
"postcss": "^8.4.31",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^3.1.0",
|
||||||
"prettier-plugin-svelte": "^2.10.1",
|
"prettier-plugin-svelte": "^3.1.2",
|
||||||
"sass": "^1.66.1",
|
"sass": "^1.69.5",
|
||||||
"svelte": "^4.0.5",
|
"svelte": "^4.2.7",
|
||||||
"svelte-check": "^3.4.3",
|
"svelte-check": "^3.6.2",
|
||||||
"svelte-heros-v2": "^0.9.3",
|
"svelte-heros-v2": "^0.10.12",
|
||||||
"svelte-local-storage-store": "^0.6.0",
|
"svelte-local-storage-store": "^0.6.4",
|
||||||
"svelte-multicssclass": "^2.1.1",
|
"svelte-multicssclass": "^2.1.1",
|
||||||
"svelte-preprocess": "^5.0.4",
|
"svelte-preprocess": "^5.1.1",
|
||||||
"tailwindcss": "^3.3.3",
|
"tailwindcss": "^3.3.5",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.6.2",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.3.2",
|
||||||
"vite": "^4.4.2",
|
"vite": "^4.5.0",
|
||||||
"vitest": "^0.34.1"
|
"vitest": "^0.34.6"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"mariadb": "^3.2.0",
|
"mariadb": "^3.2.2",
|
||||||
"sequelize": "^6.32.1",
|
"sequelize": "^6.35.1",
|
||||||
"sequelize-typescript": "^2.1.5",
|
"sequelize-typescript": "^2.1.6",
|
||||||
"sqlite3": "^5.1.6"
|
"sqlite3": "^5.1.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
10
src/lib/components/CustomIcons/Crosshairs.svelte
Normal file
10
src/lib/components/CustomIcons/Crosshairs.svelte
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let size = '24';
|
||||||
|
export let fill = 'currentColor';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height={size} width={size} {fill} viewBox="0 0 512 512"
|
||||||
|
><path
|
||||||
|
d="M256 0c17.7 0 32 14.3 32 32V42.4c93.7 13.9 167.7 88 181.6 181.6H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H469.6c-13.9 93.7-88 167.7-181.6 181.6V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V469.6C130.3 455.7 56.3 381.7 42.4 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H42.4C56.3 130.3 130.3 56.3 224 42.4V32c0-17.7 14.3-32 32-32zM107.4 288c12.5 58.3 58.4 104.1 116.6 116.6V384c0-17.7 14.3-32 32-32s32 14.3 32 32v20.6c58.3-12.5 104.1-58.4 116.6-116.6H384c-17.7 0-32-14.3-32-32s14.3-32 32-32h20.6C392.1 165.7 346.3 119.9 288 107.4V128c0 17.7-14.3 32-32 32s-32-14.3-32-32V107.4C165.7 119.9 119.9 165.7 107.4 224H128c17.7 0 32 14.3 32 32s-14.3 32-32 32H107.4zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"
|
||||||
|
/></svg
|
||||||
|
>
|
10
src/lib/components/CustomIcons/Skull.svelte
Normal file
10
src/lib/components/CustomIcons/Skull.svelte
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let size = '24';
|
||||||
|
export let fill = 'currentColor';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height={size} width={size} {fill} viewBox="0 0 512 512"
|
||||||
|
><path
|
||||||
|
d="M416 398.9c58.5-41.1 96-104.1 96-174.9C512 100.3 397.4 0 256 0S0 100.3 0 224c0 70.7 37.5 133.8 96 174.9c0 .4 0 .7 0 1.1v64c0 26.5 21.5 48 48 48h48V464c0-8.8 7.2-16 16-16s16 7.2 16 16v48h64V464c0-8.8 7.2-16 16-16s16 7.2 16 16v48h48c26.5 0 48-21.5 48-48V400c0-.4 0-.7 0-1.1zM96 256a64 64 0 1 1 128 0A64 64 0 1 1 96 256zm256-64a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"
|
||||||
|
/></svg
|
||||||
|
>
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IconSolid } from 'svelte-heros-v2';
|
import { Eye, EyeSlash } from 'svelte-heros-v2';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
export let id: string | null = null;
|
export let id: string | null = null;
|
||||||
@ -12,6 +12,7 @@
|
|||||||
export let readonly = false;
|
export let readonly = false;
|
||||||
export let size: 'xs' | 'sm' | 'md' | 'lg' = 'md';
|
export let size: 'xs' | 'sm' | 'md' | 'lg' = 'md';
|
||||||
export let pickyWidth = true;
|
export let pickyWidth = true;
|
||||||
|
export let containerClass = '';
|
||||||
|
|
||||||
export let inputElement: HTMLInputElement | undefined = undefined;
|
export let inputElement: HTMLInputElement | undefined = undefined;
|
||||||
|
|
||||||
@ -34,7 +35,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- the cursor-not-allowed class must be set here because a disabled button does not respect the 'cursor' css property -->
|
<!-- the cursor-not-allowed class must be set here because a disabled button does not respect the 'cursor' css property -->
|
||||||
<div class={type === 'submit' && disabled ? 'cursor-not-allowed' : ''}>
|
<div class={containerClass} class:cursor-not-allowed={type === 'submit' && disabled}>
|
||||||
{#if type === 'submit'}
|
{#if type === 'submit'}
|
||||||
<input
|
<input
|
||||||
class="btn"
|
class="btn"
|
||||||
@ -106,17 +107,9 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{#if type === 'password'}
|
{#if type === 'password'}
|
||||||
<IconSolid
|
<EyeSlash variation="solid" size={passwordEyeSize[size]} />
|
||||||
name="eye-slash-solid"
|
|
||||||
width={passwordEyeSize[size]}
|
|
||||||
height={passwordEyeSize[size]}
|
|
||||||
/>
|
|
||||||
{:else}
|
{:else}
|
||||||
<IconSolid
|
<Eye variation="solid" size={passwordEyeSize[size]} />
|
||||||
name="eye-solid"
|
|
||||||
width={passwordEyeSize[size]}
|
|
||||||
height={passwordEyeSize[size]}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher, getContext, onDestroy } from 'svelte';
|
import { createEventDispatcher, getContext, onDestroy } from 'svelte';
|
||||||
import type { Writable } from 'svelte/store';
|
import type { Writable } from 'svelte/store';
|
||||||
import { IconSolid } from 'svelte-heros-v2';
|
import { ChevronDown, ChevronUp } from 'svelte-heros-v2';
|
||||||
|
|
||||||
let id = crypto.randomUUID();
|
let id = crypto.randomUUID();
|
||||||
let asc = false;
|
let asc = false;
|
||||||
@ -26,10 +26,10 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span class="mr-1"><slot /></span>
|
<span class="mr-1"><slot /></span>
|
||||||
<IconSolid
|
{#if $ascHeader === id && asc}
|
||||||
name={$ascHeader === id && asc ? 'chevron-up-solid' : 'chevron-down-solid'}
|
<ChevronUp variation="solid" />
|
||||||
width="12"
|
{:else}
|
||||||
height="12"
|
<ChevronDown variation="solid" />
|
||||||
/>
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
</th>
|
</th>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IconOutline } from 'svelte-heros-v2';
|
import { ExclamationCircle } from 'svelte-heros-v2';
|
||||||
import { fly } from 'svelte/transition';
|
import { fly } from 'svelte/transition';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
|
|
||||||
@ -45,7 +45,7 @@
|
|||||||
>
|
>
|
||||||
<div class="alert alert-error border-none relative text-gray-900 overflow-hidden">
|
<div class="alert alert-error border-none relative text-gray-900 overflow-hidden">
|
||||||
<div class="flex gap-2 z-10">
|
<div class="flex gap-2 z-10">
|
||||||
<IconOutline name="exclamation-circle-outline" />
|
<ExclamationCircle />
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
<progress
|
<progress
|
||||||
|
106
src/lib/rules.ts
106
src/lib/rules.ts
@ -1,4 +1,108 @@
|
|||||||
export const rules = {
|
export const rulesShort = {
|
||||||
|
header: `
|
||||||
|
Das Lesen der Regeln ist für alle Teilnehmer verpflichtend. Die Regeln sollen für einen reibungslosen und
|
||||||
|
strukturierte Ablauf des Projekts sorgen, weshalb das Lesen der Regeln ein essenzieller Bestandteil für das Gelingen
|
||||||
|
von CraftAttack 6 ist. Die Regeln sind wörtlich zu verstehen und sind Grundlage für das Projekt. Zur Vereinfachung
|
||||||
|
gehen sie nicht zu weit ins Detail und deuten teils nur umfangreiche Themengebiete an. Entscheidungen werden, wenn
|
||||||
|
von Spielern angeregt, dann durch die Administratoren getroffen, die sich an den Regeln orientieren.
|
||||||
|
`,
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
title: 'Respektvoller Umgang',
|
||||||
|
content: `
|
||||||
|
Oberste Priorität hat der respektvolle und tolerante Umgang der Spieler untereinander. Der Spielspaß, der
|
||||||
|
offene Umgang miteinander und die Interaktion aller steht im Vordergrund, weshalb Drohungen, Belästigungen
|
||||||
|
oder sonstige gegenüber anderen Spielern respektlose Aktivitäten strengstens verboten sind und auch hart
|
||||||
|
geahndet werden.`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Einschränkungen von Minecraft-Namen, Skins, Chat-Nachrichten, Links, etc.',
|
||||||
|
content: `
|
||||||
|
Selbstverständlich sind sämtliche Inhalte (Minecraft-Namen, Skins, Chat-Nachrichten, Links, etc.) mit
|
||||||
|
sexistischen, diskriminierenden, rassistischen, pornographischen oder illegalen Inhalten nicht erlaubt.
|
||||||
|
Außerdem ist es nicht gestattet, den Chat mit Nachrichten jeglicher Art vollzuspammen. Des Weiteren sollte
|
||||||
|
der MC-Name des Spielers, der bei der Anmeldung angegeben wird, bis zum Ende des Projekts nicht geändert
|
||||||
|
werden. Das Nutzen bzw. Anmelden von Zweitaccounts ist nicht gestattet.
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Clientmodifikationen',
|
||||||
|
content: `
|
||||||
|
Jegliche Clientmodifications, die deutliche Vorteile gegenüber anderen Spielern erbringen, sind nicht
|
||||||
|
gestattet.
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Redstone bauten und überdimensionierte Villager-Baukomplexe',
|
||||||
|
content: `
|
||||||
|
Das Erbauen und Betreiben lag-erzeugender Maschinen, Farmen (Zero-Tick-Farmen etc.) oder andere Bauten, die
|
||||||
|
den Spielfluss stören könnten, ist verboten.
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Verkauf von Items',
|
||||||
|
content: `
|
||||||
|
Das Verkaufen von Items ist allgemein jedem Spieler überall gestattet. Jedoch bietet es sich an und ist
|
||||||
|
wünschenswert, die Shops aller Spieler in einem Shoppingdistrict beim Spawn gemeinsam anzusiedeln, um die
|
||||||
|
Interaktion zu fördern. Ein angemessener Abstand der privaten Strukturen vom Shoppingdisrict ist
|
||||||
|
inzuhalten.
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Abstecken von Gebieten und Grundstücken',
|
||||||
|
content: `
|
||||||
|
Das Abstecken bestimmter Gebiete ist grundsätzlich erlaubt, jedoch sind unangemessen große Grundstücke
|
||||||
|
untersagt. Das maximale Maß ist im Einzelfall zu entscheiden. Die Grenzen bereits abgesteckter Grundstücke
|
||||||
|
sind unveränderlich.
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Verhalten gegenüber anderen Spielern',
|
||||||
|
content: `
|
||||||
|
Das Töten, und Beklauen von Spielern ist verboten. Ebenso ist es nicht erlaubt, andere Bauten zu zerstören
|
||||||
|
(Griefing). Ein gewisser Toleranzspielraum besteht, der im Einzelfall zu bewerten ist.
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Rolle der Administratoren',
|
||||||
|
content: `
|
||||||
|
Allgemein liegt es in der Hand der Administratoren einzelne Situation zu bewerten, Strafen zu verhängen und
|
||||||
|
Entscheidungen zu treffen. Den Entscheidungen und Anweisungen der Administratoren ist stets Folge zu
|
||||||
|
leisten. Allgemein gilt immer der Grundsatz, dass ein Eingriff der Administratoren nur dann erfolgt, wenn
|
||||||
|
dies die Spieler auch fordern. Solange beide Parteien zufrieden sind und sich niemand beschwert, passiert
|
||||||
|
natürlich auch nichts.
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Kontakt zum Administratoren-Team',
|
||||||
|
content: `
|
||||||
|
Jedem Teilnehmer ist es möglich sich an den Support/das Administratoren-Team zu wenden. Zu den
|
||||||
|
Administratoren gehören die Spieler, die auf dem Server mit einem Admin-Tag versehen sind. Zwei von diesen
|
||||||
|
sind außerdem Administrator der WhatsApp-Gruppe. Eine Kontaktaufnahme ist direkt auf dem Server im Chat
|
||||||
|
oder auf dem Teamspeak: „mhsl.eu“ möglich. Außerdem können sie über WhatsApp angeschrieben werden, wenn
|
||||||
|
sich z.B. gerade kein Administrator auf dem Server befindet oder bei anderen Rückfragen. Bei
|
||||||
|
Unzufriedenheit, Meldung eines Regelverstoßen, Anregungen oder Fragen steht das Administratoren-Team allen
|
||||||
|
Spielern jederzeit zu Verfügung.
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Konfliktlösung und mögliche Konsequenzen',
|
||||||
|
content: `
|
||||||
|
Konflikte sollen grundlegend zuerst auf einer Ebene zwischen den Spielern geschlichtet werden, bevor ein
|
||||||
|
Administrator kontaktiert wird. Jeder Regelverstoß zieht unterschiedliche Folgen nach sich, die von
|
||||||
|
Ermahnungen, über Tagesbänne bis zum permanenten Bann führen können. Diese möglichen Konsequenzen sind von
|
||||||
|
allen Teilnehmern zu akzeptieren.
|
||||||
|
`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
footer: `
|
||||||
|
Alle aufgeführten Regeln und die damit in Verbindung stehende Angaben erfolgen ohne Gewähr auf Vollständigkeit,
|
||||||
|
Richtigkeit und Aktualität. Das Durchsetzen der Regeln liegt im Ermessen der Administratoren, die vorher in
|
||||||
|
Absprache mit dem Geschädigten eine der Situation angemessene Maßnahmen getroffen haben.
|
||||||
|
`
|
||||||
|
};
|
||||||
|
|
||||||
|
export const rulesLong = {
|
||||||
header: `
|
header: `
|
||||||
Das Lesen der Regeln ist für alle Teilnehmer verpflichtend. Die Regeln sollen für einen reibungslosen und
|
Das Lesen der Regeln ist für alle Teilnehmer verpflichtend. Die Regeln sollen für einen reibungslosen und
|
||||||
strukturierte Ablauf des Projekts sorgen, weshalb das Lesen der Regeln ein essenzieller Bestandteil für das Gelingen
|
strukturierte Ablauf des Projekts sorgen, weshalb das Lesen der Regeln ein essenzieller Bestandteil für das Gelingen
|
||||||
|
@ -25,13 +25,6 @@
|
|||||||
active: false
|
active: false
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
let footerLinks = [
|
|
||||||
{
|
|
||||||
name: 'Teamspeak',
|
|
||||||
icon: '<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 576 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M152.8 37.2c-32.2 38.1-56.1 82.6-69.9 130.5c0 .2-.1 .3-.1 .5C43.5 184.4 16 223 16 268c0 59.6 48.4 108 108 108s108-48.4 108-108c0-53.5-38.9-97.9-90-106.5c15.7-41.8 40.4-79.6 72.3-110.7c1.8-1.6 4-2.6 6.3-3.1c37.2-11.5 76.7-13.3 114.8-5.2C454.7 67.6 534 180.7 517.1 301.3c-8.4 62.6-38.6 112.7-87.7 151.4c-50.1 39.7-107.5 54.3-170.2 52.2l-24-1c12.4 2.8 25 4.9 37.6 6.3c40.7 4.2 81.4 2.1 120.1-12.5c94-35.5 149.3-102.3 162.9-202.5c4.8-52.6-5.8-105.4-30.8-152C454.6 11.3 290.8-38.4 159 32c-2.4 1.4-4.5 3.1-6.3 5.2zM309.4 433.9c-2.1 11.5-4.2 21.9-14.6 31.3c53.2-1 123.2-29.2 161.8-97.1c39.7-69.9 37.6-139.9-6.3-207.8C413.8 105 360.5 77.9 293.7 73.7c1.5 2.3 3.2 4.4 5.2 6.3l5.2 6.3c25.1 31.3 37.6 67.9 42.8 107.5c2.1 15.7-1 30.3-13.6 41.8c-4.2 3.1-5.2 6.3-4.2 10.4l7.3 17.7L365.7 318c5.2 11.5 4.2 19.8-6.3 28.2c-3.2 2.5-6.7 4.6-10.4 6.3l-18.8 8.4 3.1 13.6c3.1 6.3 1 12.5-3.1 17.7c-2.5 2.4-3.8 5.9-3.1 9.4c2.1 11.5-2.1 19.8-12.5 25.1c-2.1 1-4.2 5.2-5.2 7.3zm-133.6-3.1c16.7 11.5 34.5 20.9 53.2 26.1c24 5.2 41.8-6.3 44.9-30.3c1-8.4 5.2-14.6 12.5-17.7c7.3-4.2 8.4-7.3 2.1-13.6l-9.4-8.4 13.6-4.2c6.3-2.1 7.3-5.2 5.2-11.5c-1.4-3-2.4-6.2-3.1-9.4c-3.1-14.6-2.1-15.7 11.5-18.8c8.4-3.1 15.7-6.3 21.9-12.5c3.1-2.1 3.1-4.2 1-8.4l-16.7-30.3c-1-1.9-2.1-3.8-3.1-5.7c-6.4-11.7-13-23.6-15.7-37.1c-2.1-9.4-1-17.7 8.4-24c5.2-4.2 8.4-9.4 8.4-16.7c-.4-10.1-1.5-20.3-3.1-30.3c-6.3-37.6-23-68.9-51.2-95c-5.2-4.2-9.4-6.3-16.7-4.2L203.9 91.5c2 1.2 4 2.4 6 3.6l0 0c6.3 3.7 12.2 7.3 17 12.1c30.3 26.1 41.8 61.6 45.9 100.2c1 8.4 0 16.7-7.3 21.9c-8.4 5.2-10.4 12.5-7.3 20.9c4.9 13.2 10.4 26 16.7 38.6L291.6 318c-6.3 8.4-13.6 11.5-21.9 14.6c-12.5 3.1-14.6 7.3-10.4 20.9c.6 1.5 1.4 2.8 2.1 4.2c2.1 5.2 1 8.4-4.2 10.4l-12.5 3.1 5.2 4.2 4.2 4.2c4.2 5.2 4.2 8.4-2.1 10.4c-7.3 4.2-11.5 9.4-11.5 17.7c0 12.5-7.3 19.8-18.8 24c-3.8 1-7.6 1.5-11.5 1l-34.5-2.1z"/></svg>',
|
|
||||||
href: 'ts3server://mhsl.eu'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
let showMenuPermanent = false;
|
let showMenuPermanent = false;
|
||||||
let menuButtonScrollIndex: number | null = null;
|
let menuButtonScrollIndex: number | null = null;
|
||||||
@ -81,7 +74,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div class="min-h-screen w-full">
|
<div class="h-screen w-full">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import Countdown from '$lib/components/Countdown/Countdown.svelte';
|
import Countdown from '$lib/components/Countdown/Countdown.svelte';
|
||||||
import { IconOutline } from 'svelte-heros-v2';
|
import { User, WrenchScrewdriver } from 'svelte-heros-v2';
|
||||||
|
import Crosshairs from '$lib/components/CustomIcons/Crosshairs.svelte';
|
||||||
|
import Skull from '$lib/components/CustomIcons/Skull.svelte';
|
||||||
|
|
||||||
let information = [
|
let information = [
|
||||||
{
|
{
|
||||||
@ -83,25 +85,40 @@
|
|||||||
<div class="flex flex-col xl:flex-row justify-center items-center py-20 bg-base-100">
|
<div class="flex flex-col xl:flex-row justify-center items-center py-20 bg-base-100">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-center text-2xl mb-6">2022 in Zahlen</h3>
|
<h3 class="text-center text-2xl mb-6">2022 in Zahlen</h3>
|
||||||
|
<div class="flex flex-col lg:flex-row gap-4">
|
||||||
<div class="stats stats-vertical sm:stats-horizontal shadow">
|
<div class="stats stats-vertical sm:stats-horizontal shadow">
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
<div class="stat-figure">
|
<div class="stat-figure">
|
||||||
<img
|
<WrenchScrewdriver />
|
||||||
class="w-8 h-8"
|
|
||||||
src="{env.PUBLIC_BASE_PATH}/img/netherrack.webp"
|
|
||||||
alt=""
|
|
||||||
title="Netherrack"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-title">Meistabgebauter Block</div>
|
<div class="stat-title">Abgebaute Blöcke</div>
|
||||||
<div class="stat-value">2.3M</div>
|
<div class="stat-value">26.5M</div>
|
||||||
|
<div class="stat-desc"><span class="underline">2.3M</span> davon Netherrack</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
<div class="stat-figure">
|
<div class="stat-figure">
|
||||||
<IconOutline name="user-outline" />
|
<User />
|
||||||
|
</div>
|
||||||
|
<div class="stat-title">Teilnehmer</div>
|
||||||
|
<div class="stat-value">135</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="stats stats-vertical sm:stats-horizontal shadow">
|
||||||
|
<div class="stat">
|
||||||
|
<div class="stat-figure">
|
||||||
|
<Crosshairs />
|
||||||
|
</div>
|
||||||
|
<div class="stat-title">Getötete Mobs</div>
|
||||||
|
<div class="stat-value">1.2M</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat">
|
||||||
|
<div class="stat-figure">
|
||||||
|
<Skull />
|
||||||
|
</div>
|
||||||
|
<div class="stat-title">Spieler Tode</div>
|
||||||
|
<div class="stat-value">3996</div>
|
||||||
|
<div class="stat-desc"><span class="underline">578</span> davon durch andere Spieler</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-title">Angemeldete Spieler</div>
|
|
||||||
<div class="stat-value">156</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import { IconOutline } from 'svelte-heros-v2';
|
import { ArrowLeftOnRectangle, Flag, UserGroup, Users } from 'svelte-heros-v2';
|
||||||
import { buttonTriggeredRequest } from '$lib/components/utils';
|
import { buttonTriggeredRequest } from '$lib/components/utils';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import type { LayoutData } from './$types';
|
import type { LayoutData } from './$types';
|
||||||
@ -26,21 +26,21 @@
|
|||||||
let tabs = [
|
let tabs = [
|
||||||
{
|
{
|
||||||
path: `${env.PUBLIC_BASE_PATH}/admin/users`,
|
path: `${env.PUBLIC_BASE_PATH}/admin/users`,
|
||||||
icon: 'user-group-outline',
|
icon: UserGroup,
|
||||||
name: 'Registrierte Nutzer',
|
name: 'Registrierte Nutzer',
|
||||||
badge: data.userCount,
|
badge: data.userCount,
|
||||||
enabled: data.userCount != null
|
enabled: data.userCount != null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: `${env.PUBLIC_BASE_PATH}/admin/reports`,
|
path: `${env.PUBLIC_BASE_PATH}/admin/reports`,
|
||||||
icon: 'flag-outline',
|
icon: Flag,
|
||||||
name: 'Reports',
|
name: 'Reports',
|
||||||
badge: $reportCount,
|
badge: $reportCount,
|
||||||
enabled: data.reportCount != null
|
enabled: data.reportCount != null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: `${env.PUBLIC_BASE_PATH}/admin/admin`,
|
path: `${env.PUBLIC_BASE_PATH}/admin/admin`,
|
||||||
icon: 'users-outline',
|
icon: Users,
|
||||||
name: 'Website Admins',
|
name: 'Website Admins',
|
||||||
badge: $adminCount,
|
badge: $adminCount,
|
||||||
enabled: data.adminCount != null
|
enabled: data.adminCount != null
|
||||||
@ -55,7 +55,7 @@
|
|||||||
{#if tab.enabled}
|
{#if tab.enabled}
|
||||||
<li>
|
<li>
|
||||||
<a href={tab.path}>
|
<a href={tab.path}>
|
||||||
<IconOutline name={tab.icon} />
|
<svelte:component this={tab.icon} />
|
||||||
<span class="mr-1" class:underline={$page.url.pathname === tab.path}>{tab.name}</span>
|
<span class="mr-1" class:underline={$page.url.pathname === tab.path}>{tab.name}</span>
|
||||||
<div class="badge">{tab.badge}</div>
|
<div class="badge">{tab.badge}</div>
|
||||||
</a>
|
</a>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
<ul class="menu menu-vertical">
|
<ul class="menu menu-vertical">
|
||||||
<li>
|
<li>
|
||||||
<button on:click={(e) => buttonTriggeredRequest(e, logout())}>
|
<button on:click={(e) => buttonTriggeredRequest(e, logout())}>
|
||||||
<IconOutline name="arrow-left-on-rectangle-outline" />
|
<ArrowLeftOnRectangle />
|
||||||
<span>Ausloggen</span>
|
<span>Ausloggen</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import { IconOutline } from 'svelte-heros-v2';
|
import { Flag, UserGroup, Users } from 'svelte-heros-v2';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
let tabs = [
|
let tabs = [
|
||||||
{
|
{
|
||||||
path: `${env.PUBLIC_BASE_PATH}/admin/users`,
|
path: `${env.PUBLIC_BASE_PATH}/admin/users`,
|
||||||
icon: 'user-group-outline',
|
icon: UserGroup,
|
||||||
name: 'Registrierte Nutzer',
|
name: 'Registrierte Nutzer',
|
||||||
enabled: data.userCount != null
|
enabled: data.userCount != null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: `${env.PUBLIC_BASE_PATH}/admin/reports`,
|
path: `${env.PUBLIC_BASE_PATH}/admin/reports`,
|
||||||
icon: 'flag-outline',
|
icon: Flag,
|
||||||
name: 'Reports',
|
name: 'Reports',
|
||||||
enabled: data.reportCount != null
|
enabled: data.reportCount != null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: `${env.PUBLIC_BASE_PATH}/admin/admin`,
|
path: `${env.PUBLIC_BASE_PATH}/admin/admin`,
|
||||||
icon: 'users-outline',
|
icon: Users,
|
||||||
name: 'Website Admins',
|
name: 'Website Admins',
|
||||||
enabled: data.adminCount != null
|
enabled: data.adminCount != null
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@
|
|||||||
href={tab.path}
|
href={tab.path}
|
||||||
title={tab.name}
|
title={tab.name}
|
||||||
>
|
>
|
||||||
<IconOutline width="5rem" height="5rem" name={tab.icon} />
|
<svelte:component this={tab.icon} width="5rem" height="5rem" />
|
||||||
</a>
|
</a>
|
||||||
<span>{tab.name}</span>
|
<span>{tab.name}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
import Badges from '$lib/components/Input/Badges.svelte';
|
import Badges from '$lib/components/Input/Badges.svelte';
|
||||||
import { IconOutline } from 'svelte-heros-v2';
|
import { Check, NoSymbol, PencilSquare, Trash, UserPlus } from 'svelte-heros-v2';
|
||||||
import Input from '$lib/components/Input/Input.svelte';
|
import Input from '$lib/components/Input/Input.svelte';
|
||||||
import { Permissions } from '$lib/permissions';
|
import { Permissions } from '$lib/permissions';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
@ -155,7 +155,7 @@
|
|||||||
admin.edit = false;
|
admin.edit = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconOutline name="check-outline" width="18" height="18" />
|
<Check size="18" />
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<span class="w-min" class:cursor-not-allowed={!permissions.adminWrite()}>
|
<span class="w-min" class:cursor-not-allowed={!permissions.adminWrite()}>
|
||||||
@ -167,7 +167,7 @@
|
|||||||
admin = admin.before;
|
admin = admin.before;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconOutline name="no-symbol-outline" width="18" height="18" />
|
<NoSymbol size="18" />
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
{:else}
|
{:else}
|
||||||
@ -180,7 +180,7 @@
|
|||||||
admin.before = structuredClone(admin);
|
admin.before = structuredClone(admin);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconOutline name="pencil-square-outline" width="18" height="18" />
|
<PencilSquare size="18" />
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<span class="w-min" class:cursor-not-allowed={!permissions.adminWrite()}>
|
<span class="w-min" class:cursor-not-allowed={!permissions.adminWrite()}>
|
||||||
@ -189,7 +189,7 @@
|
|||||||
disabled={!permissions.adminWrite()}
|
disabled={!permissions.adminWrite()}
|
||||||
on:click={(e) => buttonTriggeredRequest(e, deleteAdmin(admin.id))}
|
on:click={(e) => buttonTriggeredRequest(e, deleteAdmin(admin.id))}
|
||||||
>
|
>
|
||||||
<IconOutline name="trash-outline" width="18" height="18" />
|
<Trash size="18" />
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
@ -228,7 +228,7 @@
|
|||||||
newAdminPermissions = [];
|
newAdminPermissions = [];
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconOutline name="user-plus-outline" width="18" height="18" />
|
<UserPlus size="18" />
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import Textarea from '$lib/components/Input/Textarea.svelte';
|
import Textarea from '$lib/components/Input/Textarea.svelte';
|
||||||
import { reportCount } from '$lib/stores';
|
import { reportCount } from '$lib/stores';
|
||||||
import HeaderBar from './HeaderBar.svelte';
|
import HeaderBar from './HeaderBar.svelte';
|
||||||
import { IconOutline } from 'svelte-heros-v2';
|
import { MagnifyingGlass, Plus, Share } from 'svelte-heros-v2';
|
||||||
import NewReportModal from './NewReportModal.svelte';
|
import NewReportModal from './NewReportModal.svelte';
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy, onMount } from 'svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
@ -139,7 +139,7 @@
|
|||||||
title="Nach Ersteller filtern"
|
title="Nach Ersteller filtern"
|
||||||
on:click|stopPropagation={() => (reportFilter.reporter = report.reporter.username)}
|
on:click|stopPropagation={() => (reportFilter.reporter = report.reporter.username)}
|
||||||
>
|
>
|
||||||
<IconOutline name="magnifying-glass-outline" width="14" height="14" />
|
<MagnifyingGlass size="14" />
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -151,7 +151,7 @@
|
|||||||
on:click|stopPropagation={() =>
|
on:click|stopPropagation={() =>
|
||||||
(reportFilter.reported = report.reported.username)}
|
(reportFilter.reported = report.reported.username)}
|
||||||
>
|
>
|
||||||
<IconOutline name="magnifying-glass-outline" width="14" height="14" />
|
<MagnifyingGlass size="14" />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
@ -180,7 +180,7 @@
|
|||||||
<td colspan="100">
|
<td colspan="100">
|
||||||
<div class="flex justify-center items-center">
|
<div class="flex justify-center items-center">
|
||||||
<button class="btn btn-sm" on:click={() => newReportModal.show()}>
|
<button class="btn btn-sm" on:click={() => newReportModal.show()}>
|
||||||
<IconOutline name="plus-outline" />
|
<Plus />
|
||||||
<span>Neuer Report</span>
|
<span>Neuer Report</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -198,7 +198,7 @@
|
|||||||
<form class="dropdown dropdown-end">
|
<form class="dropdown dropdown-end">
|
||||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex a11y-label-has-associated-control -->
|
<!-- svelte-ignore a11y-no-noninteractive-tabindex a11y-label-has-associated-control -->
|
||||||
<label tabindex="0" class="btn btn-sm btn-circle btn-ghost text-center">
|
<label tabindex="0" class="btn btn-sm btn-circle btn-ghost text-center">
|
||||||
<IconOutline name="share-outline" height="1rem" width="auto" />
|
<Share size="1rem" />
|
||||||
</label>
|
</label>
|
||||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||||
<ul
|
<ul
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
import { IconOutline } from 'svelte-heros-v2';
|
import { Check, NoSymbol, PencilSquare, Trash } from 'svelte-heros-v2';
|
||||||
import Input from '$lib/components/Input/Input.svelte';
|
import Input from '$lib/components/Input/Input.svelte';
|
||||||
import Select from '$lib/components/Input/Select.svelte';
|
import Select from '$lib/components/Input/Select.svelte';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
@ -172,7 +172,7 @@
|
|||||||
user.edit = false;
|
user.edit = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconOutline name="check-outline" width="18" height="18" />
|
<Check size="18" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-square"
|
class="btn btn-sm btn-square"
|
||||||
@ -181,7 +181,7 @@
|
|||||||
user = user.before;
|
user = user.before;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconOutline name="no-symbol-outline" width="18" height="18" />
|
<NoSymbol size="18" />
|
||||||
</button>
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
@ -191,13 +191,13 @@
|
|||||||
user.edit = true;
|
user.edit = true;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconOutline name="pencil-square-outline" width="18" height="18" />
|
<PencilSquare size="18" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-square"
|
class="btn btn-sm btn-square"
|
||||||
on:click={(e) => buttonTriggeredRequest(e, deleteUser(user.id))}
|
on:click={(e) => buttonTriggeredRequest(e, deleteUser(user.id))}
|
||||||
>
|
>
|
||||||
<IconOutline name="trash-outline" width="18" height="18" />
|
<Trash size="18" />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,23 +1,3 @@
|
|||||||
<script>
|
<div class="flex justify-center w-full bg-base-200">
|
||||||
import { env } from '$env/dynamic/public';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="fixed top-0 left-0 h-full w-full bg-[#050505]" />
|
|
||||||
<img
|
|
||||||
class="bg-snipped bg-black fixed top-0 left-0 h-full w-full object-cover pointer-events-none blur-[2px]"
|
|
||||||
src="{env.PUBLIC_BASE_PATH}/img/register-background.webp"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
<div class="flex justify-center w-full">
|
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
.bg-snipped {
|
|
||||||
/* prettier-ignore */
|
|
||||||
clip-path: polygon(
|
|
||||||
0 20%, 100% -35%, 100% -5%, 0 50%,
|
|
||||||
0 110%, 100% 50%, 100% 80%, 0 140%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<!--the tooltip when not all fields are correctly filled won't completely show if the overflow is hidden-->
|
<!--the tooltip when not all fields are correctly filled won't completely show if the overflow is hidden-->
|
||||||
<div
|
<div
|
||||||
class="grid card w-11/12 xl:w-2/3 2xl:w-1/2 p-6 my-12 bg-base-100 shadow-[0_0_10px_10px_rgba(0,0,0,0.7)]"
|
class="grid card w-11/12 xl:w-2/3 2xl:w-1/2 p-6 my-12 bg-base-100 shadow-lg"
|
||||||
class:overflow-hidden={registered}
|
class:overflow-hidden={registered}
|
||||||
>
|
>
|
||||||
{#if !registered}
|
{#if !registered}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import Input from '$lib/components/Input/Input.svelte';
|
import Input from '$lib/components/Input/Input.svelte';
|
||||||
import { createEventDispatcher, onMount } from 'svelte';
|
import { createEventDispatcher, onMount } from 'svelte';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import { rules } from '$lib/rules';
|
import { rulesShort } from '$lib/rules';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@ -55,7 +55,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let rulesAccepted = false;
|
let rulesAccepted = false;
|
||||||
let rulesModal: HTMLDialogElement | null = null;
|
let rulesModal: HTMLDialogElement;
|
||||||
|
let rulesModalSecondsOpened = 0;
|
||||||
|
let rulesModalTimer: number | null = null;
|
||||||
|
|
||||||
let inputsInvalidMessage: string | null = 'Bitte fülle alle erforderlichen Felder aus';
|
let inputsInvalidMessage: string | null = 'Bitte fülle alle erforderlichen Felder aus';
|
||||||
let registerRequest: Promise<void> | null = null;
|
let registerRequest: Promise<void> | null = null;
|
||||||
@ -162,6 +164,7 @@
|
|||||||
if (!rulesAccepted) {
|
if (!rulesAccepted) {
|
||||||
e.detail.target.checked = false;
|
e.detail.target.checked = false;
|
||||||
rulesModal.show();
|
rulesModal.show();
|
||||||
|
rulesModalTimer = setInterval(() => rulesModalSecondsOpened++, 1000);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
bind:inputElement={rulesInput}
|
bind:inputElement={rulesInput}
|
||||||
@ -219,7 +222,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<dialog class="modal" bind:this={rulesModal}>
|
<dialog
|
||||||
|
class="modal"
|
||||||
|
on:close={() => {
|
||||||
|
clearInterval(rulesModalTimer);
|
||||||
|
rulesModalTimer = null;
|
||||||
|
}}
|
||||||
|
bind:this={rulesModal}
|
||||||
|
>
|
||||||
<form method="dialog" class="modal-box flex max-w-[95%] md:max-w-[90%] lg:max-w-[75%]">
|
<form method="dialog" class="modal-box flex max-w-[95%] md:max-w-[90%] lg:max-w-[75%]">
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
||||||
<div class="overflow-auto">
|
<div class="overflow-auto">
|
||||||
@ -230,12 +240,12 @@
|
|||||||
<p>0. Vorwort</p>
|
<p>0. Vorwort</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse-content">
|
<div class="collapse-content">
|
||||||
<p>{rules.header}</p>
|
<p>{rulesShort.header}</p>
|
||||||
<p class="mt-1 text-[.75rem]">{rules.footer}</p>
|
<p class="mt-1 text-[.75rem]">{rulesShort.footer}</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600" />
|
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600" />
|
||||||
</div>
|
</div>
|
||||||
{#each rules.sections as section, i}
|
{#each rulesShort.sections as section, i}
|
||||||
<div class="collapse collapse-arrow">
|
<div class="collapse collapse-arrow">
|
||||||
<input type="checkbox" autocomplete="off" />
|
<input type="checkbox" autocomplete="off" />
|
||||||
<div class="collapse-title">
|
<div class="collapse-title">
|
||||||
@ -248,15 +258,30 @@
|
|||||||
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600" />
|
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div
|
||||||
|
class="relative w-min"
|
||||||
|
title={rulesModalSecondsOpened < 30
|
||||||
|
? `Regeln können in ${Math.max(
|
||||||
|
30 - rulesModalSecondsOpened,
|
||||||
|
0
|
||||||
|
)} Sekunden akzeptiert werden`
|
||||||
|
: ''}
|
||||||
|
>
|
||||||
|
<div class="absolute top-0 left-0 h-full w-full overflow-hidden rounded-lg">
|
||||||
|
<div
|
||||||
|
style="width: {Math.min((rulesModalSecondsOpened / 30) * 100, 100)}%"
|
||||||
|
class="h-full bg-base-300"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<Input
|
<Input
|
||||||
id="rules-accept"
|
id="rules-accept"
|
||||||
type="submit"
|
type="submit"
|
||||||
value="Akzeptieren"
|
value="Akzeptieren"
|
||||||
|
disabled={rulesModalSecondsOpened < 30}
|
||||||
|
containerClass="bg-transparent z-[1] relative"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
rulesAccepted = true;
|
rulesAccepted = true;
|
||||||
rulesInput.checked = true;
|
rulesInput.checked = true;
|
||||||
// doesn't get triggered by `rulesInput.checked = true` so it must be called manually
|
|
||||||
checkInputs();
|
checkInputs();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IconSolid } from 'svelte-heros-v2';
|
import { ChevronRight } from 'svelte-heros-v2';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
|
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<div class="flex items-center h-12 mb-2">
|
<div class="flex items-center h-12 mb-2">
|
||||||
<button class="sm:absolute btn btn-sm btn-square" on:click={() => dispatch('close')}>
|
<button class="sm:absolute btn btn-sm btn-square" on:click={() => dispatch('close')}>
|
||||||
<IconSolid name="chevron-left-solid" />
|
<ChevronRight variation="outline" />
|
||||||
</button>
|
</button>
|
||||||
<h1 class="text-center text-xl sm:text-3xl m-auto">Registrierung erfolgreich</h1>
|
<h1 class="text-center text-xl sm:text-3xl m-auto">Registrierung erfolgreich</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<div class="mx-4 sm:mx-48">
|
<div class="mx-4 my-6 sm:mx-48 sm:my-12">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { rules } from '$lib/rules';
|
import { rulesLong } from '$lib/rules';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@ -7,14 +7,14 @@
|
|||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<h1 class="text-3xl lg:text-5xl mb-4">CraftAttack 6 Regelwerk</h1>
|
<h1 class="text-3xl lg:text-5xl mb-4">CraftAttack 6 Regelwerk</h1>
|
||||||
<p>{rules.header}</p>
|
<p>{rulesLong.header}</p>
|
||||||
<ol class="p-[revert] list-decimal my-6">
|
<ol class="p-[revert] list-decimal my-6">
|
||||||
{#each rules.sections as section}
|
{#each rulesLong.sections as section}
|
||||||
<li class="mb-2">
|
<li class="mb-2">
|
||||||
{section.content}
|
{section.content}
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ol>
|
</ol>
|
||||||
<p>
|
<p>
|
||||||
{rules.footer}
|
{rulesLong.footer}
|
||||||
</p>
|
</p>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user