Updated to Svelte 5
This commit is contained in:
@@ -14,7 +14,11 @@ SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
const { t } = getLocalization();
|
||||
|
||||
export let data: PageData;
|
||||
interface Props {
|
||||
data: PageData;
|
||||
}
|
||||
|
||||
let { data }: Props = $props();
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
enum SelectedTab {
|
||||
@@ -26,7 +30,7 @@ SPDX-License-Identifier: MPL-2.0
|
||||
Questions
|
||||
}
|
||||
|
||||
let selected_tab: SelectedTab = SelectedTab.Overview;
|
||||
let selected_tab: SelectedTab = $state(SelectedTab.Overview);
|
||||
</script>
|
||||
|
||||
<div class="w-full">
|
||||
@@ -37,7 +41,7 @@ SPDX-License-Identifier: MPL-2.0
|
||||
class:opacity-60={selected_tab !== SelectedTab.Overview}
|
||||
>
|
||||
<button
|
||||
on:click={() => {
|
||||
onclick={() => {
|
||||
selected_tab = SelectedTab.Overview;
|
||||
}}
|
||||
class="m-auto w-full h-full"
|
||||
@@ -50,7 +54,7 @@ SPDX-License-Identifier: MPL-2.0
|
||||
class:opacity-60={selected_tab !== SelectedTab.Players}
|
||||
>
|
||||
<button
|
||||
on:click={() => {
|
||||
onclick={() => {
|
||||
selected_tab = SelectedTab.Players;
|
||||
}}
|
||||
class="m-auto w-full h-full"
|
||||
@@ -64,7 +68,7 @@ SPDX-License-Identifier: MPL-2.0
|
||||
class:opacity-60={selected_tab !== SelectedTab.Questions}
|
||||
>
|
||||
<button
|
||||
on:click={() => {
|
||||
onclick={() => {
|
||||
selected_tab = SelectedTab.Questions;
|
||||
}}
|
||||
class="m-auto w-full h-full"
|
||||
|
||||
@@ -10,20 +10,30 @@ SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
const { t } = getLocalization();
|
||||
|
||||
export let questions: Question[];
|
||||
export let answers: {
|
||||
|
||||
interface Props {
|
||||
questions: Question[];
|
||||
answers: {
|
||||
username: string;
|
||||
answer: string;
|
||||
right: boolean;
|
||||
tike_taken: number;
|
||||
score: number;
|
||||
}[][];
|
||||
|
||||
export let scores: {
|
||||
scores: {
|
||||
[key: string]: string;
|
||||
};
|
||||
export let title: string;
|
||||
export let timestamp: string;
|
||||
title: string;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
let {
|
||||
questions,
|
||||
answers,
|
||||
scores,
|
||||
title,
|
||||
timestamp
|
||||
}: Props = $props();
|
||||
|
||||
const usernames = Object.keys(scores);
|
||||
|
||||
|
||||
@@ -8,12 +8,16 @@ SPDX-License-Identifier: MPL-2.0
|
||||
import { getLocalization } from '$lib/i18n';
|
||||
|
||||
const { t } = getLocalization();
|
||||
export let scores: {
|
||||
interface Props {
|
||||
scores: {
|
||||
[key: string]: string;
|
||||
};
|
||||
export let custom_field: {
|
||||
custom_field: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
|
||||
let { scores, custom_field }: Props = $props();
|
||||
|
||||
let usernames = Object.keys(scores);
|
||||
console.log(custom_field);
|
||||
@@ -22,28 +26,32 @@ SPDX-License-Identifier: MPL-2.0
|
||||
<div class="w-full">
|
||||
<div class="flex justify-center w-full">
|
||||
<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"
|
||||
>{$t('result_page.player_name')}
|
||||
</th>
|
||||
<th class="p-1 mx-auto">{$t('result_page.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"
|
||||
>{$t('result_page.custom_field')}
|
||||
<thead>
|
||||
<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"
|
||||
>{$t('result_page.player_name')}
|
||||
</th>
|
||||
{/if}
|
||||
</tr>
|
||||
{#each usernames as uname}
|
||||
<tr class="text-left">
|
||||
<td class="border-r dark:border-gray-500 p-1 border-gray-300">{uname}</td>
|
||||
<td class="p-1">{scores[uname]}</td>
|
||||
{#if custom_field[uname]}
|
||||
<td class="border-l dark:border-gray-500 p-1 border-gray-300"
|
||||
>{custom_field[uname]}</td
|
||||
>
|
||||
<th class="p-1 mx-auto">{$t('result_page.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"
|
||||
>{$t('result_page.custom_field')}
|
||||
</th>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each usernames as uname}
|
||||
<tr class="text-left">
|
||||
<td class="border-r dark:border-gray-500 p-1 border-gray-300">{uname}</td>
|
||||
<td class="p-1">{scores[uname]}</td>
|
||||
{#if custom_field[uname]}
|
||||
<td class="border-l dark:border-gray-500 p-1 border-gray-300"
|
||||
>{custom_field[uname]}</td
|
||||
>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,14 +13,18 @@ SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
const { t } = getLocalization();
|
||||
|
||||
export let questions: Question[];
|
||||
export let answers: {
|
||||
interface Props {
|
||||
questions: Question[];
|
||||
answers: {
|
||||
username: string;
|
||||
answer: string;
|
||||
right: boolean;
|
||||
tike_taken: number;
|
||||
score: number;
|
||||
}[][];
|
||||
}
|
||||
|
||||
let { questions, answers }: Props = $props();
|
||||
|
||||
const get_average_score = (q_index: number): number => {
|
||||
const q_answers = answers[q_index];
|
||||
@@ -49,7 +53,7 @@ SPDX-License-Identifier: MPL-2.0
|
||||
question_open = q_index;
|
||||
}
|
||||
};
|
||||
let question_open: number | boolean = false;
|
||||
let question_open: number | boolean = $state(false);
|
||||
</script>
|
||||
|
||||
<div class="w-full flex justify-center">
|
||||
@@ -61,7 +65,7 @@ SPDX-License-Identifier: MPL-2.0
|
||||
>
|
||||
<button
|
||||
class="text-center underline text-xl"
|
||||
on:click={() => {
|
||||
onclick={() => {
|
||||
toggle_dropdown(i);
|
||||
}}>{@html question.question}</button
|
||||
>
|
||||
|
||||
@@ -11,7 +11,6 @@ SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
const { t } = getLocalization();
|
||||
|
||||
export let question: Question;
|
||||
|
||||
interface Answer {
|
||||
username: string;
|
||||
@@ -21,7 +20,12 @@ SPDX-License-Identifier: MPL-2.0
|
||||
score: number;
|
||||
}
|
||||
|
||||
export let answers: Answer[];
|
||||
interface Props {
|
||||
question: Question;
|
||||
answers: Answer[];
|
||||
}
|
||||
|
||||
let { question, answers }: Props = $props();
|
||||
// console.log(question);
|
||||
|
||||
const get_answer_count_for_answer = (answer: string): number => {
|
||||
@@ -66,7 +70,7 @@ SPDX-License-Identifier: MPL-2.0
|
||||
style="width: {(get_answer_count_for_answer(answer.answer) /
|
||||
answers.length) *
|
||||
100}%"
|
||||
/>
|
||||
></span>
|
||||
</div>
|
||||
<p>{get_answer_count_for_answer(answer.answer)}</p>
|
||||
{#if question.type !== QuizQuestionType.VOTING && question.type !== QuizQuestionType.TEXT}
|
||||
@@ -81,46 +85,50 @@ SPDX-License-Identifier: MPL-2.0
|
||||
{/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"
|
||||
>{$t('result_page.player_name')}
|
||||
</th>
|
||||
{#if question.type !== QuizQuestionType.VOTING}
|
||||
<thead>
|
||||
<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"
|
||||
>{$t('words.score')}</th
|
||||
>
|
||||
{/if}
|
||||
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
|
||||
>{$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')}?
|
||||
>{$t('result_page.player_name')}
|
||||
</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
|
||||
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
|
||||
>{$t('words.score')}</th
|
||||
>
|
||||
{/if}
|
||||
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
|
||||
>{(answer.time_taken / 1000).toFixed(3)}s
|
||||
</td>
|
||||
<td class="p-1">{answer.answer}</td>
|
||||
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
|
||||
>{$t('result_page.time_taken')}
|
||||
</th>
|
||||
<th class="p-1 mx-auto">{$t('words.answer')} </th>
|
||||
{#if question.type !== QuizQuestionType.VOTING}
|
||||
<td class="p-1 border-l dark:border-gray-500 border-gray-300">
|
||||
{#if answer.right}✅{:else}❌{/if}
|
||||
</td>
|
||||
<th class="border-l dark:border-gray-500 p-1 mx-auto border-gray-300"
|
||||
>{$t('words.correct')}?
|
||||
</th>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</thead>
|
||||
<tbody>
|
||||
{#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.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}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user