Finished game-results

This commit is contained in:
Mawoka
2023-02-13 17:37:05 +01:00
parent f0c2c4250f
commit 3646fcf90b
16 changed files with 355 additions and 154 deletions
@@ -7,6 +7,11 @@
import type { PageData } from './$types';
import PlayerOverview from './player_overview.svelte';
import QuestionOverview from './question_overview.svelte';
import GeneralOverview from './general_overview.svelte';
import { fade } from 'svelte/transition';
import { getLocalization } from '$lib/i18n';
const { t } = getLocalization();
export let data: PageData;
@@ -35,7 +40,7 @@
selected_tab = SelectedTab.Overview;
}}
class="m-auto w-full h-full"
>Overview
>{$t('words.overview')}
</button>
</div>
<div
@@ -49,7 +54,7 @@
}}
class="m-auto w-full h-full"
>
Players
{$t('words.player', { count: 2 })}
</button>
</div>
<div
@@ -62,16 +67,26 @@
selected_tab = SelectedTab.Questions;
}}
class="m-auto w-full h-full"
>Questions
>{$t('words.question', { count: 2 })}
</button>
</div>
</div>
{#if selected_tab === SelectedTab.Overview}{:else if selected_tab === SelectedTab.Questions}
<div>
<QuestionOverview quiz={data.results.quiz} answers={data.results.answers} />
{#if selected_tab === SelectedTab.Overview}
<div in:fade={{ duration: 150 }}>
<GeneralOverview
questions={data.results.questions}
answers={data.results.answers}
scores={data.results.player_scores}
title={data.results.title}
timestamp={data.results.timestamp}
/>
</div>
{:else if selected_tab === SelectedTab.Questions}
<div in:fade={{ duration: 150 }}>
<QuestionOverview questions={data.results.questions} answers={data.results.answers} />
</div>
{:else if selected_tab === SelectedTab.Players}
<div>
<div in:fade={{ duration: 150 }}>
<PlayerOverview
custom_field={data.results.custom_field_data}
scores={data.results.player_scores}
@@ -4,9 +4,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import type { PageLoad } from './$types';
// import type { PageLoad } from './$types';
export const load = (async ({ params, fetch }) => {
export const load = async ({ params, fetch }) => {
const res = await fetch(`/api/v1/results/${params.result_id}?include_quiz=true`);
let json;
if (res.ok) {
@@ -17,4 +17,4 @@ export const load = (async ({ params, fetch }) => {
return {
results: json
};
}) satisfies PageLoad;
}; //satisfies PageLoad;
@@ -0,0 +1,56 @@
<!--
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<script lang="ts">
import type { Question } from '$lib/quiz_types';
export let questions: Question[];
export let answers: {
username: string;
answer: string;
right: boolean;
tike_taken: number;
score: number;
}[][];
export let scores: {
[key: string]: string;
};
export let title: string;
export let timestamp: string;
const usernames = Object.keys(scores);
const get_average_final_score = () => {
let score_data = 0;
for (const username of usernames) {
score_data += parseInt(scores[username]);
}
return score_data / usernames.length;
};
</script>
<!--
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<div class="w-full">
<div class="flex justify-center w-full">
<p class="text-3xl w-5/6 text-center">
The quiz with the title '<strong>{title}</strong>' was played on
<strong>{new Date(timestamp).toLocaleString()}</strong>
with <strong>{usernames.length}</strong> players. The players achieved an average score
of <strong>{get_average_final_score()}</strong>.
</p>
</div>
</div>
<style>
underline {
text-decoration: underline;
}
</style>
@@ -4,6 +4,9 @@
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<script lang="ts">
import { getLocalization } from '$lib/i18n';
const { t } = getLocalization();
export let scores: {
[key: string]: string;
};
@@ -20,13 +23,13 @@
<table class="w-11/12 m-auto">
<tr class="border-b-2 dark:border-gray-500 text-left border-gray-300">
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
>Player name</th
>
>{$t('result_page.player_name')}
</th>
<th class="p-1 mx-auto">Player Score</th>
{#if Object.keys(custom_field).length !== 0}
<th class="border-l dark:border-gray-500 p-1 mx-auto border-gray-300"
>Custom field</th
>
>{$t('result_page.custom_field')}
</th>
{/if}
</tr>
{#each usernames as uname}
@@ -4,11 +4,15 @@
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<script lang="ts">
import type { QuizData } from '$lib/quiz_types';
import type { Question } from '$lib/quiz_types';
import { fly } from 'svelte/transition';
import QuestionTab from './question_tab_thing.svelte';
import { QuizQuestionType } from '$lib/quiz_types';
import { getLocalization } from '$lib/i18n';
export let quiz: QuizData;
const { t } = getLocalization();
export let questions: Question[];
export let answers: {
username: string;
answer: string;
@@ -48,23 +52,32 @@
</script>
<div class="w-full flex justify-center">
<div class="w-11/12 flex flex-col w-full">
{#each quiz.questions as question, i}
<div>
<div class="w-11/12 flex flex-col w-full gap-4">
{#each questions as question, i}
<div class="transition-all">
<div class="w-full bg-white bg-opacity-60 p-2 rounded grid grid-cols-3 z-40">
<button
class="text-center underline text-xl"
on:click={() => {
toggle_dropdown(i);
}}>{question.question}</button
}}>{@html question.question}</button
>
<p class="text-center text-sm my-auto">Average Score: {get_average_score(i)}</p>
<p class="text-center text-sm my-auto">
{get_number_of_correct_answers(i)} correct Answer(s)
</p>
{#if question.type !== QuizQuestionType.VOTING}
{@const correct_answers = get_number_of_correct_answers(i)}
<p class="text-center text-sm my-auto">
{$t('result_page.average_score', {
average_score: get_average_score(i)
})}
</p>
<p class="text-center text-sm my-auto">
{$t('result_page.correct_answer', { count: correct_answers })}
<!-- {correct_answers} correct
{#if correct_answers === 1}Answer{:else}Answers{/if}-->
</p>
{/if}
</div>
{#if question_open === i}
<div transition:fly|local={{ y: -10 }}>
<div in:fly|local={{ y: -10 }}>
<QuestionTab {question} answers={answers[i]} />
</div>
{/if}
@@ -4,6 +4,11 @@
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<script lang="ts">
import { QuizQuestionType } from '$lib/quiz_types';
import { getLocalization } from '$lib/i18n';
const { t } = getLocalization();
export let question;
interface Answer {
@@ -15,7 +20,7 @@
}
export let answers: Answer[];
console.log(question);
// console.log(question);
const get_answer_count_for_answer = (answer: string): number => {
let count = 0;
@@ -30,60 +35,73 @@
<div class="flex justify-center">
<div class="bg-white p-2 -z-10 w-10/12 rounded">
<div class="flex flex-col">
{#each question.answers as answer}
<div class="grid grid-cols-4">
<p>{answer.answer}</p>
<div
class="col-span-3 flex w-full border-l border-gray-300 px-1 dark:border-gray-500"
>
<div class="my-auto w-full mr-1">
<span
class="h-1 block bg-green-600 my-auto"
style="width: {(get_answer_count_for_answer(answer.answer) /
answers.length) *
100}%"
/>
{#if question.type !== QuizQuestionType.ORDER && question.type !== QuizQuestionType.RANGE}
<div class="flex flex-col mb-4">
{#each question.answers as answer}
<div class="grid grid-cols-4">
<p>{answer.answer}</p>
<div
class="col-span-3 flex w-full border-l border-gray-300 px-1 dark:border-gray-500"
>
<div class="my-auto w-full mr-1">
<span
class="h-1 block bg-green-600 my-auto"
style="width: {(get_answer_count_for_answer(answer.answer) /
answers.length) *
100}%"
/>
</div>
<p>{get_answer_count_for_answer(answer.answer)}</p>
{#if question.type !== QuizQuestionType.VOTING && question.type !== QuizQuestionType.TEXT}
<p class="ml-1">
{#if answer.right}{:else}{/if}
</p>
{/if}
</div>
<p>{get_answer_count_for_answer(answer.answer)}</p>
<p class="ml-1">
{#if answer.right}{:else}{/if}
</p>
</div>
</div>
{/each}
</div>
<div class="mt-4">
{/each}
</div>
{/if}
<div>
<table class="w-full text-left">
<tr class="border-b-2 dark:border-gray-500 text-left border-gray-300">
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
>Player Name</th
>
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300">Score</th>
>{$t('result_page.player_name')}
</th>
{#if question.type !== QuizQuestionType.VOTING}
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
>{$t('words.score')}</th
>
{/if}
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
>Time Taken</th
>
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300">Answer</th
>
<th class="p-1">Correct?</th>
>{$t('result_page.time_taken')}
</th>
<th class="p-1 mx-auto">{$t('words.answer')} </th>
{#if question.type !== QuizQuestionType.VOTING}
<th class="border-l dark:border-gray-500 p-1 mx-auto border-gray-300"
>{$t('words.correct')}?</th
>
{/if}
</tr>
{#each answers as answer}
<tr>
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{answer.username}</td
>
{#if question.type !== QuizQuestionType.VOTING}
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{answer.score}</td
>
{/if}
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{answer.score}</td
>
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{(answer.time_taken / 1000).toFixed(3)}s</td
>
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{answer.answer}</td
>
<td class="p-1"
>{#if answer.right}{:else}{/if}</td
>
>{(answer.time_taken / 1000).toFixed(3)}s
</td>
<td class="p-1">{answer.answer}</td>
{#if question.type !== QuizQuestionType.VOTING}
<td class="p-1 border-l dark:border-gray-500 border-gray-300">
{#if answer.right}{:else}{/if}
</td>
{/if}
</tr>
{/each}
</table>