295 lines
8.2 KiB
Svelte
295 lines
8.2 KiB
Svelte
<script lang="ts">
|
|
import Select from '$lib/components/Input/Select.svelte';
|
|
import Input from '$lib/components/Input/Input.svelte';
|
|
import { createEventDispatcher, onMount } from 'svelte';
|
|
import { env } from '$env/dynamic/public';
|
|
import { rulesShort } from '$lib/rules';
|
|
|
|
const dispatch = createEventDispatcher();
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
let checkInputs = () => {};
|
|
let playertype = 'java';
|
|
let firstnameInput: HTMLInputElement;
|
|
let lastnameInput: HTMLInputElement;
|
|
let birthdayInput: HTMLInputElement;
|
|
let usernameInput: HTMLInputElement;
|
|
let privacyInput: HTMLInputElement;
|
|
let logsInput: HTMLInputElement;
|
|
let rulesInput: HTMLInputElement;
|
|
onMount(() => {
|
|
checkInputs = () => {
|
|
let allInputs = [
|
|
firstnameInput,
|
|
lastnameInput,
|
|
birthdayInput,
|
|
usernameInput,
|
|
privacyInput,
|
|
logsInput,
|
|
rulesInput
|
|
];
|
|
if (!allInputs.every((v) => v.value || v.checked)) {
|
|
inputsInvalidMessage = 'Bitte fülle alle erforderlichen Felder aus';
|
|
} else {
|
|
inputsInvalidMessage = null;
|
|
}
|
|
};
|
|
});
|
|
|
|
async function sendRegister() {
|
|
// eslint-disable-next-line no-async-promise-executor
|
|
registerRequest = new Promise(async (resolve, reject) => {
|
|
const response = await fetch(`${env.PUBLIC_BASE_PATH}/register`, {
|
|
method: 'POST',
|
|
body: new FormData(document.forms[0])
|
|
});
|
|
if (response.ok) {
|
|
dispatch('submit', {});
|
|
resolve();
|
|
} else if (response.status < 500) {
|
|
reject(Error((await response.json()).message));
|
|
} else {
|
|
reject(Error(`${response.statusText} (${response.status})`));
|
|
}
|
|
});
|
|
}
|
|
|
|
let rulesAccepted = false;
|
|
let rulesModal: HTMLDialogElement;
|
|
let rulesModalSecondsOpened = 0;
|
|
let rulesModalTimer: number | null = null;
|
|
|
|
let inputsInvalidMessage: string | null = 'Bitte fülle alle erforderlichen Felder aus';
|
|
let registerRequest: Promise<void> | null = null;
|
|
</script>
|
|
|
|
<h1 class="text-center text-3xl lg:text-5xl">Anmeldung</h1>
|
|
<form id="form" on:input={checkInputs} on:submit|preventDefault={sendRegister}>
|
|
<div class="divider">Persönliche Angaben</div>
|
|
<div class="mx-2 grid grid-cols-1 sm:grid-cols-2 gap-y-4">
|
|
<Input
|
|
id="firstname"
|
|
name="firstname"
|
|
type="text"
|
|
required={true}
|
|
bind:inputElement={firstnameInput}
|
|
>
|
|
<span slot="label">Vorname</span>
|
|
</Input>
|
|
<Input
|
|
id="lastname"
|
|
name="lastname"
|
|
type="text"
|
|
required={true}
|
|
bind:inputElement={lastnameInput}
|
|
>
|
|
<span slot="label">Nachname</span>
|
|
</Input>
|
|
<Input
|
|
id="birthday"
|
|
name="birthday"
|
|
type="date"
|
|
required={true}
|
|
bind:inputElement={birthdayInput}
|
|
>
|
|
<span slot="label">Geburtstag</span>
|
|
<span slot="notice">Die Angabe hat keine Auswirkungen auf das Spielgeschehen</span>
|
|
</Input>
|
|
<Input id="telephone" name="telephone" type="tel">
|
|
<span slot="label">Telefonnummer</span>
|
|
<p slot="notice">
|
|
Diese nutzen wir, um Dich in der Whatsapp-Gruppe zuzuordnen und kontaktieren zu können.
|
|
<br />
|
|
<b>Die Angabe ist freiwillig, hilft den Administratoren jedoch sehr!</b>
|
|
</p>
|
|
</Input>
|
|
</div>
|
|
<div class="divider">Spiel</div>
|
|
<div class="mx-2 grid grid-cols-1 sm:grid-cols-2 gap-y-4">
|
|
<Input
|
|
id="username"
|
|
name="username"
|
|
type="text"
|
|
required={true}
|
|
bind:inputElement={usernameInput}
|
|
>
|
|
<span slot="label">Minecraft-Spielername</span>
|
|
</Input>
|
|
<Select
|
|
id="playertype"
|
|
name="playertype"
|
|
label="Edition"
|
|
bind:value={playertype}
|
|
required={true}
|
|
>
|
|
<option value="java">Java Edition</option>
|
|
<option value="bedrock">Bedrock Edition</option>
|
|
</Select>
|
|
</div>
|
|
<div class="divider" />
|
|
<div class="mx-2 grid gap-y-3 mb-6">
|
|
<div class="flex gap-4">
|
|
<Input
|
|
id="privacy"
|
|
name="privacy"
|
|
type="checkbox"
|
|
required={true}
|
|
bind:inputElement={privacyInput}
|
|
/>
|
|
<label for="privacy">
|
|
<span>
|
|
Ich bin mit der Speicherung meiner in der Anmeldung angegebenen, persönlichen Daten
|
|
einverstanden. Siehe <a class="link" href="https://mhsl.eu/id.html">Datenschutz</a>
|
|
</span>
|
|
<span class="text-red-700">*</span>
|
|
</label>
|
|
</div>
|
|
<div class="flex gap-4">
|
|
<Input id="logs" name="logs" type="checkbox" required={true} bind:inputElement={logsInput} />
|
|
<label for="logs">
|
|
<span>
|
|
Ich bin mit der Speicherung in Form von Logs aller meiner, beim Spielen anfallenden,
|
|
persönlichen Daten durch den Server einverstanden
|
|
</span>
|
|
<span class="text-red-700">*</span>
|
|
</label>
|
|
</div>
|
|
<div class="flex gap-4">
|
|
<Input
|
|
id="rules"
|
|
name="rules"
|
|
type="checkbox"
|
|
required={true}
|
|
on:input={(e) => {
|
|
if (!rulesAccepted) {
|
|
e.detail.target.checked = false;
|
|
rulesModal.show();
|
|
rulesModalTimer = setInterval(() => rulesModalSecondsOpened++, 1000);
|
|
}
|
|
}}
|
|
bind:inputElement={rulesInput}
|
|
/>
|
|
<label for="rules">
|
|
Ich bin mit den <a target="_blank" class="link" href="{env.PUBLIC_BASE_PATH}/rules"
|
|
>Regeln</a
|
|
>
|
|
einverstanden und achte sie
|
|
<span class="text-red-700">*</span>
|
|
<br />
|
|
<p class="text-[.75rem]">
|
|
Dies betrifft jede Interaktion im Spiel und zugehörige Daten wie z.B. Chatnachrichten
|
|
welche vom Minecraft Client an den Server übermittelt werden
|
|
</p>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class={inputsInvalidMessage !== null ? 'tooltip tooltip-top' : 'grid w-min'}
|
|
data-tip={inputsInvalidMessage}
|
|
>
|
|
<div class="row-[1] col-[1]">
|
|
<Input
|
|
id="submit"
|
|
type="submit"
|
|
value="Anmeldung absenden"
|
|
disabled={inputsInvalidMessage !== null || registerRequest !== null}
|
|
/>
|
|
</div>
|
|
{#key registerRequest}
|
|
{#if registerRequest}
|
|
{#await registerRequest}
|
|
<span
|
|
class="relative top-[calc(50%-12px)] left-[calc(50%-12px)] row-[1] col-[1] loading loading-ring"
|
|
/>
|
|
{:catch error}
|
|
<dialog
|
|
class="modal"
|
|
on:close={() => setTimeout(() => (registerRequest = null), 200)}
|
|
open
|
|
>
|
|
<form method="dialog" class="modal-box">
|
|
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
<h3 class="font-bold text-lg">Fehler</h3>
|
|
<p class="py-4">{error.message}</p>
|
|
</form>
|
|
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.2)]">
|
|
<button>close</button>
|
|
</form>
|
|
</dialog>
|
|
{/await}
|
|
{/if}
|
|
{/key}
|
|
</div>
|
|
</form>
|
|
|
|
<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%]">
|
|
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
<div class="overflow-auto">
|
|
<div class="mb-4">
|
|
<div class="collapse collapse-arrow">
|
|
<input type="checkbox" autocomplete="off" checked />
|
|
<div class="collapse-title">
|
|
<p>0. Vorwort</p>
|
|
</div>
|
|
<div class="collapse-content">
|
|
<p>{rulesShort.header}</p>
|
|
<p class="mt-1 text-[.75rem]">{rulesShort.footer}</p>
|
|
</div>
|
|
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600" />
|
|
</div>
|
|
{#each rulesShort.sections as section, i}
|
|
<div class="collapse collapse-arrow">
|
|
<input type="checkbox" autocomplete="off" />
|
|
<div class="collapse-title">
|
|
<p>{i + 1}. {section.title}</p>
|
|
</div>
|
|
<div class="collapse-content">
|
|
<p>{section.content}</p>
|
|
</div>
|
|
</div>
|
|
<span class="block w-full h-[1px] mx-auto mb-1 bg-gray-600" />
|
|
{/each}
|
|
</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
|
|
id="rules-accept"
|
|
type="submit"
|
|
value="Akzeptieren"
|
|
disabled={rulesModalSecondsOpened < 30}
|
|
containerClass="bg-transparent z-[1] relative"
|
|
on:click={() => {
|
|
rulesAccepted = true;
|
|
rulesInput.checked = true;
|
|
checkInputs();
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
|
<button>close</button>
|
|
</form>
|
|
</dialog>
|