Finished new editor and deprecated old endpoints

This commit is contained in:
Mawoka
2022-06-17 12:12:22 +02:00
parent 6d5fac39fd
commit f39e2bee89
10 changed files with 207 additions and 135 deletions
+78 -41
View File
@@ -66,6 +66,7 @@
answer: ''
};
let edit_id;
let confirm_to_leave = true;
const getEditID = async () => {
let res;
@@ -86,54 +87,90 @@
alert('Error!');
}
};
const confirmUnload = (event) => {
console.log(confirm_to_leave);
if (!confirm_to_leave) {
return;
}
event.preventDefault();
event.returnValue = 'Are you sure you want to leave?';
localStorage.setItem('edit_game', JSON.stringify(data));
return 'unload';
};
const saveQuiz = async () => {
if (schemaInvalid) {
return;
}
const res = await fetch(`/api/v1/editor/finish?edit_id=${edit_id}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (res.ok) {
console.log('Hier');
confirm_to_leave = false;
console.log(confirm_to_leave);
window.location.href = '/overview';
} else {
alert('Error');
}
};
</script>
<svelte:window on:beforeunload={confirmUnload} />
{#await getEditID()}
<Spinner />
{:then _}
<div class="grid grid-cols-6 h-screen w-screen">
<div>
<Sidebar bind:data bind:selected_question />
</div>
<div class="col-span-5 flex flex-col">
<div class="h-10 w-full bg-white mb-10 flex align-middle justify-center rounded-br-lg">
{#if schemaInvalid}
<p class="text-center w-full text-red-600 h-full mt-0.5 font-semibold">
{yupErrorMessage}
</p>
{:else}
<p class="text-center w-full text-black h-full align-bottom mt-0.5">
{data.title}
</p>
{/if}
<button
class="pr-2 align-middle bg-purple-400 pl-2 ml-auto whitespace-nowrap disabled:opacity-60 rounded-br-lg"
disabled={schemaInvalid}
<form on:submit|preventDefault={saveQuiz}>
<div class="grid grid-cols-6 h-screen w-screen">
<div>
<Sidebar bind:data bind:selected_question />
</div>
<div class="col-span-5 flex flex-col">
<div
class="h-10 w-full bg-white mb-10 flex align-middle justify-center rounded-br-lg"
>
<span>Save</span>
<svg
class="w-6 h-6 inline-block"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
{#if schemaInvalid}
<p class="text-center w-full text-red-600 h-full mt-0.5 font-semibold">
{yupErrorMessage}
</p>
{:else}
<p class="text-center w-full text-black h-full align-bottom mt-0.5">
{data.title}
</p>
{/if}
<button
class="pr-2 align-middle bg-purple-400 pl-2 ml-auto whitespace-nowrap disabled:opacity-60 rounded-br-lg"
disabled={schemaInvalid}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"
/>
</svg>
</button>
</div>
<div class="w-full h-full">
{#if selected_question === -1}
<SettingsCard bind:data />
{:else}
<QuizCard bind:data bind:selected_question bind:edit_id />
{/if}
<span>Save</span>
<svg
class="w-6 h-6 inline-block"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"
/>
</svg>
</button>
</div>
<div class="w-full h-full">
{#if selected_question === -1}
<SettingsCard bind:data />
{:else}
<QuizCard bind:data bind:selected_question bind:edit_id />
{/if}
</div>
</div>
</div>
</div>
</form>
{/await}
+14 -6
View File
@@ -4,6 +4,7 @@
import { reach } from 'yup';
import { dataSchema } from '$lib/yupSchemas';
import Spinner from '../Spinner.svelte';
import { fade } from 'svelte/transition';
export let data: EditorData;
export let selected_question: number;
@@ -49,7 +50,14 @@
</div>
{#if question.image != undefined && question.image !== ''}
<div class="flex justify-center pt-10 w-full max-h-72 w-full">
<img src={question.image} alt="not available" class="max-h-72 h-auto w-auto" />
<img
src={question.image}
alt="not available"
class="max-h-72 h-auto w-auto"
on:contextmenu|preventDefault={() => {
question.image = '';
}}
/>
</div>
{:else}
{#await import('$lib/editor/uploader.svelte')}
@@ -60,6 +68,7 @@
bind:modalOpen={uppyOpen}
bind:edit_id
bind:data
bind:selected_question
/>
{/await}
{/if}
@@ -71,7 +80,8 @@
question.answers.splice(index, 1);
question.answers = question.answers;
}}
class="p-4 rounded-lg flex justify-center w-full"
out:fade={{ duration: 150 }}
class="p-4 rounded-lg flex justify-center w-full transition"
class:bg-red-500={!answer.right}
class:bg-green-500={answer.right}
class:bg-yellow-500={!reach(
@@ -127,8 +137,9 @@
{/each}
{#if question.answers.length < 4}
<button
class="p-4 rounded-lg bg-transparent border-gray-500 border-2"
class="p-4 rounded-lg bg-transparent border-gray-500 border-2 hover:bg-gray-300 transition dark:hover:bg-gray-600"
type="button"
in:fade={{ duration: 150 }}
on:click={() => {
question.answers = [...question.answers, { empty_answer }];
}}
@@ -142,6 +153,3 @@
</div>
</div>
</div>
{#if uppyOpen}
<span class="fixed w-screen h-screen bg-opacity-60 z-10">1</span>
{/if}
+2 -2
View File
@@ -34,13 +34,13 @@
class="p-3 rounded-lg border-gray-500 border text-center w-1/3 h-20 resize-none dark:bg-gray-500"
/>
</div>
<div class="pt-10">
<div class="pt-10 w-full flex justify-center">
<button
type="button"
on:click={() => {
data.public = !data.public;
}}
class="text-center w-full"
class="text-center w-fit"
>
{#if data.public}
<svg
+15 -7
View File
@@ -60,7 +60,8 @@
>
<input
type="text"
class="whitespace-nowrap truncate text-center w-full bg-transparent rounded font-semibold dark:text-black"
class="whitespace-nowrap truncate text-center w-full bg-transparent rounded font-semibold dark:text-white"
class:dark:text-black={selected_question === -1}
bind:value={data.title}
/>
</div>
@@ -73,10 +74,14 @@
>
<textarea
bind:value={data.description}
class="bg-transparent resize-none w-full rounded text-sm dark:text-black"
class="bg-transparent resize-none w-full rounded text-sm dark:text-white"
class:dark:text-black={selected_question === -1}
/>
</div>
<div class="w-full flex justify-center dark:text-black">
<div
class="w-full flex justify-center dark:text-white"
class:dark:text-black={selected_question === -1}
>
<button
type="button"
on:click={() => {
@@ -126,8 +131,10 @@
class:bg-green-300={index === selected_question}
class:dark:bg-green-500={index === selected_question}
on:contextmenu|preventDefault={() => {
data.questions.splice(index, 1);
data.questions = data.questions;
if (confirm('Do you really want to delete this Question?')) {
data.questions.splice(index, 1);
data.questions = data.questions;
}
}}
on:click={() => {
setSelectedQuestion(index);
@@ -139,10 +146,11 @@
class="m-1 border border-gray-500 rounded-lg p-0.5"
>
<h1
class="whitespace-nowrap truncate text-center rounded-lg dark:text-black"
class="whitespace-nowrap truncate text-center rounded-lg dark:text-white transition"
class:bg-yellow-500={!reach(dataSchema, 'questions[].question').isValidSync(
question.question
)}
class:dark:text-black={index === selected_question}
>
{#if question.question === ''}
<span class="italic text-gray-500">No title...</span>
@@ -152,7 +160,7 @@
</h1>
</div>
{#if question.image}
<div class="flex justify-center align-middle">
<div class="flex justify-center align-middle pb-0.5">
<img
src={question.image}
class="h-10 border rounded-lg"
+32 -8
View File
@@ -6,6 +6,7 @@
import ImageEditor from '@uppy/image-editor';
import Dashboard from '@uppy/dashboard';
import Compressor from '@uppy/compressor';
import { fade } from 'svelte/transition';
// CSS imports
import '@uppy/core/dist/style.css';
@@ -43,30 +44,53 @@
uppy.on('complete', (res) => {
data.questions[
selected_question
].image = `https://${window.location.hostname}/api/v1/storage/download/${image_id}`;
].image = `${window.location.origin}/api/v1/storage/download/${image_id}`;
modalOpen = false;
});
console.log(edit_id);
</script>
{#if modalOpen}
<div class="w-full h-full absolute top-0 left-0 bg-opacity-60 z-20 flex justify-center">
<div
class="w-full h-full absolute top-0 left-0 bg-opacity-60 z-20 flex justify-center"
transition:fade
>
<div>
<button
type="button"
class="rounded-t-lg bg-black text-white px-1"
on:click={() => {
modalOpen = false;
}}>Close</button
>
}}
>Close
</button>
<div>
<SvelteDashboard {uppy} width="100%" {props} />
</div>
</div>
</div>
{:else}
{/if}
<div class="flex justify-center w-full pt-10" transition:fade>
<button
class="rounded-lg p-4 flex justify-center bg-transparent border-gray-500 border-2 w-1/2 hover:bg-gray-300 dark:hover:bg-gray-600 transition"
type="button"
on:click={() => {
modalOpen = true;
}}>Add Image</button
>
{/if}
}}
><span class="italic">Add Image</span>
<svg
class="w-6 h-6 inline-block"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
/>
</svg>
</button>
</div>
+1 -32
View File
@@ -64,45 +64,14 @@
data = JSON.parse(from_localstorage);
}
});
const submit = async () => {
if (!(await dataSchema.isValid(data))) {
return;
}
const res = await fetch('/api/v1/quiz/create', {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
});
if (res.status === 401) {
localStorage.setItem('create_game', JSON.stringify(data));
window.location.href = '/account/login';
} else if (res.status === 200) {
localStorage.removeItem('create_game');
responseData.open = true;
}
};
const confirmUnload = () => {
if (!confirm_to_leave) {
return;
}
event.preventDefault();
event.returnValue = '';
localStorage.setItem('create_game', JSON.stringify(data));
};
</script>
<svelte:window on:beforeunload={confirmUnload} />
<svelte:head>
<title>ClassQuiz - Create</title>
</svelte:head>
{#if data !== undefined}
<form on:submit|preventDefault={submit} class="grid grid-cols-1 gap-2">
<Editor bind:data bind:quiz_id />
</form>
<Editor bind:data bind:quiz_id />
{/if}
<div
+1 -33
View File
@@ -73,38 +73,8 @@
return;
}
};
const submit = async () => {
if (!(await dataSchema.isValid(data))) {
return;
}
const res = await fetch(`/api/v1/quiz/update/${quiz_id}`, {
method: 'PUT',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
});
if (res.status === 401) {
throw new Error('Unauthorized');
} else if (res.status === 404) {
throw new Error('Quiz not found');
} else if (res.status === 200) {
localStorage.removeItem('edit_game');
responseData.data = '200';
responseData.open = true;
}
};
const confirmUnload = () => {
if (!confirm_to_leave) {
return;
}
event.preventDefault();
event.returnValue = '';
localStorage.setItem('edit_game', JSON.stringify(data));
};
</script>
<svelte:window on:beforeunload={confirmUnload} />
<svelte:head>
<title>ClassQuiz - Edit</title>
</svelte:head>
@@ -121,9 +91,7 @@
</svg>
{:then _}
{#if data !== undefined}
<form on:submit|preventDefault={submit} class="grid grid-cols-1 gap-2">
<Editor bind:data submit_button_text={$t('words.save')} bind:quiz_id />
</form>
<Editor bind:data submit_button_text={$t('words.save')} bind:quiz_id />
{/if}
{:catch err}
<div class="text-center">