add option to add user manually (#22)
All checks were successful
delpoy / build-and-deploy (push) Successful in 1m25s

This commit is contained in:
bytedream 2023-12-23 00:41:49 +01:00
parent 7878fef301
commit b92e494ecb
4 changed files with 223 additions and 2 deletions

View File

@ -363,6 +363,7 @@
if (!e.detail.draft) $reportCount += 1;
currentPageReports = [e.detail, ...currentPageReports];
activeReport = currentPageReports[0];
newReportModal.close();
}}
/>
</dialog>

View File

@ -1,6 +1,6 @@
<script lang="ts">
import type { PageData } from './$types';
import { Check, NoSymbol, PencilSquare, Trash } from 'svelte-heros-v2';
import { Check, NoSymbol, PencilSquare, Plus, Trash } from 'svelte-heros-v2';
import Input from '$lib/components/Input/Input.svelte';
import Select from '$lib/components/Input/Select.svelte';
import { env } from '$env/dynamic/public';
@ -10,6 +10,7 @@
import HeaderBar from './HeaderBar.svelte';
import SortableTr from '$lib/components/Table/SortableTr.svelte';
import SortableTh from '$lib/components/Table/SortableTh.svelte';
import NewUserModal from './NewUserModal.svelte';
export let data: PageData;
@ -19,6 +20,7 @@
let userPage = 0;
let userFilter = { name: null, playertype: null };
let userTableContainerElement: HTMLDivElement;
let newUserModal: HTMLDialogElement;
function fetchPageUsers(page: number) {
if (!browser) return;
@ -208,6 +210,16 @@
</tr>
{/each}
{/await}
<tr>
<td colspan="100">
<div class="flex justify-center items-center">
<button class="btn btn-sm" on:click={() => newUserModal.show()}>
<Plus />
<span>Neuer Spieler</span>
</button>
</div>
</td>
</tr>
{/key}
</tbody>
</table>
@ -227,3 +239,12 @@
</div>
</div>
</div>
<dialog class="modal" bind:this={newUserModal}>
<NewUserModal
on:submit={(e) => {
currentPageUsers = [...currentPageUsers, e.detail];
newUserModal.close();
}}
/>
</dialog>

View File

@ -1,8 +1,9 @@
import { getSession } from '$lib/server/session';
import { Permissions } from '$lib/permissions';
import type { RequestHandler } from '@sveltejs/kit';
import { error, type RequestHandler } from '@sveltejs/kit';
import { User } from '$lib/server/database';
import { type Attributes, Op } from 'sequelize';
import { ApiError, getJavaUuid, getNoAuthUuid, UserNotFoundError } from '$lib/server/minecraft';
export const POST = (async ({ request, cookies }) => {
if (getSession(cookies, { permissions: [Permissions.UserRead] }) == null) {
@ -88,6 +89,90 @@ export const PATCH = (async ({ request, cookies }) => {
return new Response();
}) satisfies RequestHandler;
export const PUT = (async ({ request, cookies }) => {
if (getSession(cookies, { permissions: [Permissions.UserWrite] }) == null) {
return new Response(null, {
status: 401
});
}
const data: {
firstname: string;
lastname: string;
birthday: string;
telephone: string;
username: string;
playertype: string;
} = await request.json();
if (
data.firstname == null ||
data.lastname == null ||
data.birthday == null ||
data.username == null ||
data.playertype == null
) {
return new Response(null, { status: 400 });
}
let uuid: string | null;
try {
switch (data.playertype) {
case 'java':
uuid = await getJavaUuid(data.username);
break;
case 'bedrock':
uuid = null;
// uuid = await getBedrockUuid(username);
break;
case 'noauth':
uuid = getNoAuthUuid(data.username);
break;
default:
throw new Error(`invalid player type (${data.playertype})`);
}
} catch (e) {
if (e instanceof UserNotFoundError) {
throw error(400, `Der Spielername ${data.username} existiert nicht`);
} else if (e instanceof ApiError) {
console.error((e as Error).message);
uuid = null;
} else {
console.error((e as Error).message);
throw error(500);
}
}
if (uuid && (await User.findOne({ where: { uuid: uuid } }))) {
throw error(400, 'Dieser Minecraft-Account wurde bereits registriert');
} else if (
await User.findOne({
where: {
firstname: data.firstname,
lastname: data.lastname,
birthday: new Date(data.birthday).toUTCString()
}
})
) {
throw error(400, 'Ein Nutzer mit demselben Namen und Geburtstag wurde bereits registriert');
}
await User.create({
firstname: data.firstname,
lastname: data.lastname,
birthday: new Date(data.birthday).toUTCString(),
telephone: data.telephone,
username: data.username,
playertype: data.playertype,
password: null,
uuid: uuid
});
return new Response();
}) satisfies RequestHandler;
export const DELETE = (async ({ request, cookies }) => {
if (getSession(cookies, { permissions: [Permissions.UserWrite] }) == null) {
return new Response(null, {

View File

@ -0,0 +1,114 @@
<script lang="ts">
import Input from '$lib/components/Input/Input.svelte';
import { env } from '$env/dynamic/public';
import Select from '$lib/components/Input/Select.svelte';
import { errorMessage } from '$lib/stores';
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
let firstname: string;
let lastname: string;
let birthday: string;
let phone: string;
let username: string;
let playertype = 'java';
async function newUser() {
const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/users`, {
method: 'PUT',
body: JSON.stringify({
firstname: firstname,
lastname: lastname,
birthday: birthday,
telephone: phone,
username: username,
playertype: playertype
})
});
if (response.ok) {
dispatch('submit', {
firstname: firstname,
lastname: lastname,
birthday: birthday,
telephone: phone,
username: username,
playertype: playertype
});
globalCloseForm.submit();
} else {
$errorMessage = (await response.json()).message;
}
}
let globalCloseForm: HTMLFormElement;
let reportForm: HTMLFormElement;
let confirmDialog: HTMLDialogElement;
</script>
<form method="dialog" class="modal-box" bind:this={reportForm}>
<button
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
on:click|preventDefault={() => globalCloseForm.submit()}>✕</button
>
<h3 class="font-roboto text-xl">Neuer Spieler</h3>
<div class="grid grid-cols-2 gap-4">
<Input type="text" required bind:value={firstname}>
<span slot="label">Vorname</span>
</Input>
<Input type="text" required bind:value={lastname}>
<span slot="label">Nachname</span>
</Input>
<Input type="date" required bind:value={birthday}>
<span slot="label">Geburtstag</span>
</Input>
<Input type="tel" bind:value={phone}>
<span slot="label">Telefonnummer</span>
</Input>
<Input type="text" required bind:value={username}>
<span slot="label">Minecraft-Spielername</span>
</Input>
<Select required label="Edition" bind:value={playertype}>
<option value="java">Java Edition</option>
<option value="bedrock">Bedrock Edition</option>
</Select>
</div>
<div class="flex flex-row space-x-2 mt-6">
<Input
type="submit"
value="Hinzufügen"
on:click={(e) => {
if (reportForm.checkValidity()) {
e.detail.preventDefault();
confirmDialog.show();
}
}}
/>
<Input
type="submit"
value="Abbrechen"
on:click={(e) => {
e.detail.preventDefault();
globalCloseForm.submit();
}}
/>
</div>
</form>
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]" bind:this={globalCloseForm}>
<button>close</button>
</form>
<dialog class="modal" bind:this={confirmDialog}>
<form method="dialog" class="modal-box">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
<h3 class="font-roboto text-xl mb-2">Spieler hinzufügen?</h3>
<div class="flex flex-row space-x-2 mt-6">
<Input type="submit" value="Hinzufügen" on:click={newUser} />
<Input type="submit" value="Abbrechen" />
</div>
</form>
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
<button>close</button>
</form>
</dialog>