website/src/routes/register/Register.svelte
bytedream c6a9eaa27a
All checks were successful
delpoy / build-and-deploy (push) Successful in 57s
add check for existing uuid or exiting firstname, lastname + birthday (#4)
2023-11-29 02:00:13 +01:00

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>