<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>