📝 Updated docs with warning

This commit is contained in:
Mawoka
2022-04-01 22:30:40 +02:00
parent 0ec7c2b519
commit 70ccf6359d
3 changed files with 80 additions and 65 deletions
+4 -2
View File
@@ -1,7 +1,9 @@
# ClassQuiz # ClassQuiz
ClassQuiz is a quiz-application like KAHOOT!, but open-source which is very important if it is a product for educational ClassQuiz is a quiz-application like KAHOOT!, but open-source which is very important if it is a product for educational
purposes. You can create quizzes and play them remotely with other people. It is mainly made for teachers, who create a purposes.
You can create quizzes and play them remotely with other people.
It is mainly made for teachers, who create a
quiz, so students can compete with their knowledge against each other. quiz, so students can compete with their knowledge against each other.
## Try it ## Try it
@@ -20,7 +22,7 @@ See https://classquiz.mawoka.eu/docs/develop
## Docs ## Docs
The docs are https://classquiz.mawoka.eu/docs on the website The docs are online at https://classquiz.mawoka.eu/docs
### Things to know about the structure ### Things to know about the structure
+43 -43
View File
@@ -1,4 +1,4 @@
<script lang='ts'> <script lang="ts">
import { getLocalization } from '$lib/i18n'; import { getLocalization } from '$lib/i18n';
const { t } = getLocalization(); const { t } = getLocalization();
@@ -62,82 +62,82 @@
}; };
</script> </script>
<label class='pl-2 w-2/6 flex gap-2 flex-row'> <label class="pl-2 w-2/6 flex gap-2 flex-row">
<input type='checkbox' class='w-fit' bind:checked={data.public} /> <input type="checkbox" class="w-fit" bind:checked={data.public} />
<span class='w-fit'>{$t('words.public')}?</span> <span class="w-fit">{$t('words.public')}?</span>
</label> </label>
<label class='pl-2 flex flex-row gap-2 w-3/5'> <label class="pl-2 flex flex-row gap-2 w-3/5">
<span class='w-fit'>{$t('words.title')}:</span> <span class="w-fit">{$t('words.title')}:</span>
<input <input
type='text' type="text"
placeholder={$t('words.title')} placeholder={$t('words.title')}
bind:value={data.title} bind:value={data.title}
class='text-black bg-inherit border-dotted border-b-2 border-black w-full' class="text-black bg-inherit border-dotted border-b-2 border-black w-full"
/> />
</label> </label>
<label class='pl-2 flex flex-row gap-2 w-3/5'> <label class="pl-2 flex flex-row gap-2 w-3/5">
{$t('words.description')}: {$t('words.description')}:
<textarea <textarea
placeholder={$t('words.description')} placeholder={$t('words.description')}
bind:value={data.description} bind:value={data.description}
class='text-black w-full' class="text-black w-full"
/> />
</label> </label>
{#each data.questions as question, index_question} {#each data.questions as question, index_question}
<div class='ml-8 grid grid-cols-1 gap-2 m-2 border border-black border-2'> <div class="ml-8 grid grid-cols-1 gap-2 m-2 border border-black border-2">
<h1 class='text-3xl m-1'>{$t('words.question')} {index_question + 1}</h1> <h1 class="text-3xl m-1">{$t('words.question')} {index_question + 1}</h1>
<label class='m-1 flex flex-row gap-2 w-3/5'> <label class="m-1 flex flex-row gap-2 w-3/5">
{$t('words.question')}: {$t('words.question')}:
<input <input
type='text' type="text"
placeholder={$t('words.question')} placeholder={$t('words.question')}
bind:value={question.question} bind:value={question.question}
class='text-black w-full bg-inherit border-dotted border-b-2 border-black' class="text-black w-full bg-inherit border-dotted border-b-2 border-black"
/> />
</label> </label>
<label class='m-1 flex flex-row gap-2 w-3/5'> <label class="m-1 flex flex-row gap-2 w-3/5">
{$t('words.image')}: {$t('words.image')}:
<input <input
type='text' type="text"
placeholder='https://i.imgur.com/kSPCidY.png' placeholder="https://i.imgur.com/kSPCidY.png"
bind:value={question.image} bind:value={question.image}
class='text-black w-full bg-inherit border-dotted border-b-2 border-black' class="text-black w-full bg-inherit border-dotted border-b-2 border-black"
/> />
</label> </label>
<label class='m-1 flex flex-row gap-2 w-3/5 flex-nowrap whitespace-nowrap'> <label class="m-1 flex flex-row gap-2 w-3/5 flex-nowrap whitespace-nowrap">
{$t('editor.time_in_seconds')}: {$t('editor.time_in_seconds')}:
<input <input
type='text' type="text"
placeholder='20' placeholder="20"
bind:value={question.time} bind:value={question.time}
class='text-black w-full bg-inherit border-dotted border-b-2 border-black' class="text-black w-full bg-inherit border-dotted border-b-2 border-black"
/> />
</label> </label>
{#each question.answers as answer, index_answer} {#each question.answers as answer, index_answer}
<div class='ml-8 grid grid-cols-1 gap-2 m-2 border border-black border-2 m-1'> <div class="ml-8 grid grid-cols-1 gap-2 m-2 border border-black border-2 m-1">
<h1 class='text-3xl m-1'>{$t('words.answer')} {index_answer + 1}</h1> <h1 class="text-3xl m-1">{$t('words.answer')} {index_answer + 1}</h1>
<p class='m-1'> <p class="m-1">
{$t('words.answer')}: {index_answer + 1} {$t('words.answer')}: {index_answer + 1}
{$t('words.question')}: {index_question + 1} {$t('words.question')}: {index_question + 1}
</p> </p>
<label class='m-1 flex flex-row gap-2 w-3/5 flex-nowrap whitespace-nowrap'> <label class="m-1 flex flex-row gap-2 w-3/5 flex-nowrap whitespace-nowrap">
{$t('words.answer')}: {$t('words.answer')}:
<input <input
type='text' type="text"
placeholder={$t('words.answer')} placeholder={$t('words.answer')}
bind:value={data.questions[index_question].answers[index_answer].answer} bind:value={data.questions[index_question].answers[index_answer].answer}
class='text-black w-full bg-inherit border-dotted border-b-2 border-black' class="text-black w-full bg-inherit border-dotted border-b-2 border-black"
/> />
</label> </label>
<label class='m-1 flex flex-row gap-2 w-2/6 flex-nowrap whitespace-nowrap'> <label class="m-1 flex flex-row gap-2 w-2/6 flex-nowrap whitespace-nowrap">
<input type='checkbox' bind:checked={answer.right} class='text-black w-fit' /> <input type="checkbox" bind:checked={answer.right} class="text-black w-fit" />
<span class='w-fit'>{$t('editor.right_or_true?')}</span> <span class="w-fit">{$t('editor.right_or_true?')}</span>
</label> </label>
<button <button
class='text-left border-yellow-500 border-2 w-fit m-1' class="text-left border-yellow-500 border-2 w-fit m-1"
type='button' type="button"
on:click={() => { on:click={() => {
data.questions[index_question].answers.splice(index_answer, 1); data.questions[index_question].answers.splice(index_answer, 1);
data.questions[index_question].answers = data.questions[index_question].answers =
@@ -149,8 +149,8 @@
</div> </div>
{/each} {/each}
<button <button
class='text-left border-green-500 border-2 w-fit m-1' class="text-left border-green-500 border-2 w-fit m-1"
type='button' type="button"
on:click={() => { on:click={() => {
data.questions[index_question].answers = [ data.questions[index_question].answers = [
...data.questions[index_question].answers, ...data.questions[index_question].answers,
@@ -161,8 +161,8 @@
{$t('editor.add_new_answer')} {$t('editor.add_new_answer')}
</button> </button>
<button <button
class='text-left border-red-500 border-2 w-fit m-1' class="text-left border-red-500 border-2 w-fit m-1"
type='button' type="button"
on:click={() => { on:click={() => {
data.questions.splice(index_question, 1); data.questions.splice(index_question, 1);
data.questions = data.questions; data.questions = data.questions;
@@ -173,8 +173,8 @@
</div> </div>
{/each} {/each}
<button <button
class='text-left' class="text-left"
type='button' type="button"
on:click={() => { on:click={() => {
data.questions = [...data.questions, { ...empty_question }]; data.questions = [...data.questions, { ...empty_question }];
}} }}
@@ -182,12 +182,12 @@
{$t('editor.add_new_question')} {$t('editor.add_new_question')}
</button> </button>
{#if imgur_links_valid} {#if imgur_links_valid}
<p class='text-blue-600 text-xl text-center w-fit mx-auto'> <p class="text-blue-600 text-xl text-center w-fit mx-auto">
Not all links are imgur-links! <!-- TODO: Add translation --> Not all links are imgur-links! <!-- TODO: Add translation -->
</p> </p>
{/if} {/if}
<button <button
type='submit' type="submit"
class='text-xl disabled:cursor-not-allowed disabled:border disabled:border-red-500 w-fit mx-auto' class="text-xl disabled:cursor-not-allowed disabled:border disabled:border-red-500 w-fit mx-auto"
disabled={imgur_links_valid}>{submit_button_text}</button disabled={imgur_links_valid}>{submit_button_text}</button
> >
+33 -20
View File
@@ -1,4 +1,4 @@
<script lang='ts'> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import '$lib/hljs.css'; import '$lib/hljs.css';
@@ -11,33 +11,42 @@
<svelte:head> <svelte:head>
<title>ClassQuiz/docs - Self-Host</title> <title>ClassQuiz/docs - Self-Host</title>
<meta <meta
name='description' name="description"
content='How to self-host ClassQuiz, the open-source quiz-application' content="How to self-host ClassQuiz, the open-source quiz-application"
/> />
</svelte:head> </svelte:head>
<article <article
class='prose prose-sm sm:prose lg:prose-lg xl:prose-xl mx-auto mt-10 prose-pink text-yellow-50 px-4' class="prose prose-sm sm:prose lg:prose-lg xl:prose-xl mx-auto mt-10 prose-pink text-yellow-50 px-4"
> >
<h1>Self-Hosting</h1> <h1>Self-Hosting</h1>
<p>Since ClassQuiz is open-source, it can also be self-hosted.</p> <p>Since ClassQuiz is open-source, it can also be self-hosted.</p>
<h2>Warning</h2>
<p>
Since ClassQuiz is in pretty early development, breaking changes come and go! Please check
these docs again before updating your instance. I may also add more dependencies like <a
href="https://typesense.org/">Typesense</a
>
ore something similar in the future, but I'll always provide a
<code>docker-compose.yml</code> file, so the self-hosting process is still easy.
</p>
<h2>Requirements</h2> <h2>Requirements</h2>
<ul> <ul>
<li><a href='https://docker.com'>Docker</a></li> <li><a href="https://docker.com">Docker</a></li>
<li><a href='https://git-scm.com/'>Git</a></li> <li><a href="https://git-scm.com/">Git</a></li>
<li> <li>
A <a href='https://redis.com'>Redis</a>-Server (I recommend A <a href="https://redis.com">Redis</a>-Server (I recommend
<a href='https://upstash.com'>Upstash</a>) <a href="https://upstash.com">Upstash</a>)
</li> </li>
</ul> </ul>
<h2>Installation</h2> <h2>Installation</h2>
<p>At first, clone the repo:</p> <p>At first, clone the repo:</p>
<pre><code class='language-bash' <pre><code class="language-bash"
>git clone https://github.com/mawoka-myblock/classquiz && cd ClassQuiz</code >git clone https://github.com/mawoka-myblock/classquiz && cd ClassQuiz</code
></pre> ></pre>
<p> <p>
Now, set a <b>VALID</b> Redis-URI in <code>frontend/Dockerfile</code> and, if you want Sentry, Now, set a <b>VALID</b> Redis-URI in <code>frontend/Dockerfile</code> and, if you want Sentry,
set a valid Sentry-DSN. set a valid Sentry-DSN.
@@ -49,25 +58,29 @@
<h2>Configuration</h2> <h2>Configuration</h2>
<h3>Storage Provider</h3> <h3>Storage Provider</h3>
<p> <p>
You'll have to set up a storage provider for some pictures (these getting imported from KAHOOT!). For now, you You'll have to set up a storage provider for some pictures (these getting imported from
can use <a href='https://deta.sh'>Deta</a> or the local filesystem. Please note that I would <b>NOT</b> use it KAHOOT!). For now, you can use <a href="https://deta.sh">Deta</a> or the local filesystem.
because of these funny path-things. I tried to prevent these attacks, but i really wouldn't trust it. Please note that I would <b>NOT</b> use it because of these funny path-things. I tried to
You'll have to set the <code>STORAGE_BACKEND</code>-environment-variable to either <code>deta</code> or <code>local</code>. prevent these attacks, but i really wouldn't trust it. You'll have to set the
<code>STORAGE_BACKEND</code>-environment-variable to either <code>deta</code> or
<code>local</code>.
</p> </p>
<h4>If you chose Deta...</h4> <h4>If you chose Deta...</h4>
<p> <p>
...you'll also have to set the <code>DETA_PROJECT_KEY</code> and the <code>DETA_PROJECT_ID</code>. ...you'll also have to set the <code>DETA_PROJECT_KEY</code> and the
<code>DETA_PROJECT_ID</code>.
</p> </p>
<h4>If you chose the local filesystem...</h4> <h4>If you chose the local filesystem...</h4>
<p> <p>
...you'll have to set the <code>STORAGE_PATH</code> enviromnent variable. The path must be absolute (so start with a <code>/</code>). ...you'll have to set the <code>STORAGE_PATH</code> enviromnent variable. The path must be
absolute (so start with a <code>/</code>).
</p> </p>
<p> <p>
Before you can start your stack, you have to set some environment-variables in your Before you can start your stack, you have to set some environment-variables in your
<code>docker-compose.yml</code>. <code>docker-compose.yml</code>.
</p> </p>
<pre><code class='language-yaml' <pre><code class="language-yaml"
>version: "3" >version: "3"
services: services:
frontend: frontend:
@@ -143,5 +156,5 @@ volumes:
data: data:
</code></pre> </code></pre>
<p>Now build and deploy:</p> <p>Now build and deploy:</p>
<pre><code class='language-bash'>docker compose build && docker compose up -d</code></pre> <pre><code class="language-bash">docker compose build && docker compose up -d</code></pre>
</article> </article>