Editor: added game creation and deletion
This commit is contained in:
@@ -27,6 +27,9 @@
|
|||||||
let showDeleteDir = $state(false);
|
let showDeleteDir = $state(false);
|
||||||
let dirToDelete: Directory | undefined = $state();
|
let dirToDelete: Directory | undefined = $state();
|
||||||
|
|
||||||
|
let showDeleteRessource = $state(false);
|
||||||
|
let resToDelete: Ressource | undefined = $state();
|
||||||
|
|
||||||
let showRenameFile = $state(false);
|
let showRenameFile = $state(false);
|
||||||
let fileToRename: Ressource | undefined = $state();
|
let fileToRename: Ressource | undefined = $state();
|
||||||
let newFileName = $state("");
|
let newFileName = $state("");
|
||||||
@@ -73,23 +76,35 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteRessource(res: Ressource | Directory) {
|
async function deleteRessource(res: Ressource | Directory): Promise<boolean> {
|
||||||
if (isRessource(res)) {
|
if (isRessource(res)) {
|
||||||
axios
|
return axios
|
||||||
.delete(url("/cdn/" + res.user + "/" + res.filename), {
|
.delete(url("/cdn/" + res.user + "/" + res.filename), {
|
||||||
withCredentials: true
|
withCredentials: true
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
fetchDirectory();
|
fetchDirectory();
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
alert("Something went wrong: " + response.status);
|
alert("Something went wrong: " + response.status);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
} else if (isDir(res)) {
|
} else if (isDir(res)) {
|
||||||
showDeleteDir = true;
|
showDeleteDir = true;
|
||||||
dirToDelete = res;
|
dirToDelete = res;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteRessourceCancel() {
|
||||||
|
resToDelete = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteDir() {
|
async function deleteDir() {
|
||||||
@@ -313,7 +328,10 @@
|
|||||||
class="btn border-red-600 text-red-600"
|
class="btn border-red-600 text-red-600"
|
||||||
onclick={(event) => {
|
onclick={(event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
deleteRessource(ressource);
|
if (isRessource(ressource)) {
|
||||||
|
showDeleteRessource = true;
|
||||||
|
resToDelete = ressource;
|
||||||
|
}
|
||||||
}}><i class="fa-solid fa-trash"></i></button
|
}}><i class="fa-solid fa-trash"></i></button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -365,6 +383,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
bind:showModal={showDeleteRessource}
|
||||||
|
okFn={async () => {
|
||||||
|
if (resToDelete === undefined) return false;
|
||||||
|
return deleteRessource(resToDelete);
|
||||||
|
}}
|
||||||
|
cancelFn={deleteRessourceCancel}
|
||||||
|
>
|
||||||
|
{#snippet header()}
|
||||||
|
<h2 class="text-3xl">Ressource löschen</h2>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Soll die Ressource {resToDelete?.name} wirklich gelöscht werden?
|
||||||
|
</div>
|
||||||
|
{#if error.length > 0}
|
||||||
|
<div class="text-red-700">{error}</div>
|
||||||
|
{/if}
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<Modal bind:showModal={showDeleteDir} okFn={deleteDir} cancelFn={deleteDirCancel}>
|
<Modal bind:showModal={showDeleteDir} okFn={deleteDir} cancelFn={deleteDirCancel}>
|
||||||
{#snippet header()}
|
{#snippet header()}
|
||||||
<h2 class="text-3xl">Ordner löschen</h2>
|
<h2 class="text-3xl">Ordner löschen</h2>
|
||||||
|
|||||||
@@ -22,3 +22,14 @@ export function isDir(dir: Directory | Ressource): dir is Directory {
|
|||||||
export function isRessource(ressource: Ressource | Directory): ressource is Ressource {
|
export function isRessource(ressource: Ressource | Directory): ressource is Ressource {
|
||||||
return (ressource as Directory).isDir === undefined;
|
return (ressource as Directory).isDir === undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type GameId = string;
|
||||||
|
|
||||||
|
export type Game = {
|
||||||
|
name: string;
|
||||||
|
owner: string;
|
||||||
|
_id: GameId;
|
||||||
|
walls: WallId[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type WallId = string;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
<button type="button" class="btn" onclick={() => (showRessourceManager = true)}
|
<button type="button" class="btn" onclick={() => (showRessourceManager = true)}
|
||||||
>Ressourcen</button
|
>Ressourcen</button
|
||||||
>
|
>
|
||||||
|
<button type="button" class="btn" onclick={() => goto("/editor")}>Editor</button>
|
||||||
<button type="button" class="btn" onclick={() => goto("/settings")}>Einstellungen</button>
|
<button type="button" class="btn" onclick={() => goto("/settings")}>Einstellungen</button>
|
||||||
<button type="button" class="btn" onclick={logoutFromAllDevices}>Logout</button>
|
<button type="button" class="btn" onclick={logoutFromAllDevices}>Logout</button>
|
||||||
<div class="btn profile ps-2 pe-2">
|
<div class="btn profile ps-2 pe-2">
|
||||||
|
|||||||
146
src/routes/editor/+page.svelte
Normal file
146
src/routes/editor/+page.svelte
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Modal from "$lib/Modal.svelte";
|
||||||
|
import type { Game } from "$lib/Types";
|
||||||
|
import { url } from "$lib/util";
|
||||||
|
import axios from "axios";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
let games: Game[] = $state([]);
|
||||||
|
|
||||||
|
let error = $state("");
|
||||||
|
|
||||||
|
let showNewGame = $state(false);
|
||||||
|
let newGameName = $state("");
|
||||||
|
|
||||||
|
let showDeleteGame = $state(false);
|
||||||
|
let gameToDelete: Game | undefined = $state();
|
||||||
|
|
||||||
|
async function addNewGame() {
|
||||||
|
if (!newGameName) return false;
|
||||||
|
return axios
|
||||||
|
.post(url("game"), { name: newGameName }, { withCredentials: true })
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
fetchGames();
|
||||||
|
newGameName = "";
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addNewGameCancel() {
|
||||||
|
newGameName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteGame() {
|
||||||
|
if (gameToDelete === undefined) return false;
|
||||||
|
return axios
|
||||||
|
.delete(url("/game/" + gameToDelete._id), { withCredentials: true })
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
fetchGames();
|
||||||
|
gameToDelete = undefined;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.error("Failed to delete Game: " + response.status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteGameCancel() {
|
||||||
|
gameToDelete = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchGames() {
|
||||||
|
axios
|
||||||
|
.get(url("games"), { withCredentials: true })
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
games = response.data;
|
||||||
|
} else {
|
||||||
|
console.error("Could not fetch games: " + response.status);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
fetchGames();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex h-full flex-col">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<h1 class="m-4 mb-8 text-7xl font-bold">Editor</h1>
|
||||||
|
<button class="btn" type="button" onclick={() => (showNewGame = true)}
|
||||||
|
><i class="fa-solid fa-plus"></i> Neues Spiel</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col space-y-4 overflow-y-auto">
|
||||||
|
{#each games as game}
|
||||||
|
<div
|
||||||
|
class="ms-4 me-4 flex items-center justify-between rounded-xl border-2 p-2 hover:cursor-pointer hover:bg-emerald-200"
|
||||||
|
>
|
||||||
|
<a class="" href={`${game._id}`}>{game.name}</a>
|
||||||
|
<!-- svelte-ignore a11y_consider_explicit_label -->
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn border-red-600 text-red-600"
|
||||||
|
onclick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
gameToDelete = game;
|
||||||
|
showDeleteGame = true;
|
||||||
|
}}><i class="fa-solid fa-trash"></i></button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Modal bind:showModal={showNewGame} okFn={addNewGame} cancelFn={addNewGameCancel}>
|
||||||
|
{#snippet header()}
|
||||||
|
<h2 class="text-3xl">Neues Spiel</h2>
|
||||||
|
{/snippet}
|
||||||
|
<div>
|
||||||
|
<label for="directory" class="">Name</label>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="directory"
|
||||||
|
id="directory"
|
||||||
|
class="borders mt-2 mb-2 w-full"
|
||||||
|
bind:value={newGameName}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{#if error.length > 0}
|
||||||
|
<div class="text-red-700">{error}</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<Modal bind:showModal={showDeleteGame} okFn={deleteGame} cancelFn={deleteGameCancel}>
|
||||||
|
{#snippet header()}
|
||||||
|
<h2 class="text-3xl">Spiel löschen</h2>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<div>Soll das Spiel {gameToDelete?.name} wirklich gelöscht werden?</div>
|
||||||
|
{#if error.length > 0}
|
||||||
|
<div class="text-red-700">{error}</div>
|
||||||
|
{/if}
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.borders {
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user