Updated to Svelte 5

This commit is contained in:
Mawoka
2025-09-21 12:42:04 +02:00
parent fa533257b3
commit a88cf13f82
137 changed files with 2279 additions and 1948 deletions
+40 -32
View File
@@ -10,7 +10,11 @@ SPDX-License-Identifier: MPL-2.0
const { t } = getLocalization();
export let data: PageData;
interface Props {
data: PageData;
}
let { data }: Props = $props();
</script>
<div class="w-full">
@@ -20,38 +24,42 @@ SPDX-License-Identifier: MPL-2.0
<p class="text-center text-3xl mt-8">{$t('results_page.no_results_so_far')}</p>
{:else}
<table class="w-full">
<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('results_page.quiz_title')}
</th>
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
>{$t('results_page.date_played')}
</th>
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
>{$t('results_page.player_count')}
</th>
<th class="mx-auto p-1">{$t('words.note')}</th>
</tr>
{#each data.results as result}
<tr class="text-left">
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
><a href="/results/{result.id}" class="underline text-lg"
>{result.title}</a
></td
>
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{new Date(result.timestamp).toLocaleString()}</td
>
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{Object.keys(result.player_scores).length}</td
>
<td class:p-1={result.note}>
{#if result.note}
{result.note}
{/if}
</td>
<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('results_page.quiz_title')}
</th>
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
>{$t('results_page.date_played')}
</th>
<th class="border-r dark:border-gray-500 p-1 mx-auto border-gray-300"
>{$t('results_page.player_count')}
</th>
<th class="mx-auto p-1">{$t('words.note')}</th>
</tr>
{/each}
</thead>
<tbody>
{#each data.results as result}
<tr class="text-left">
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
><a href="/results/{result.id}" class="underline text-lg"
>{result.title}</a
></td
>
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{new Date(result.timestamp).toLocaleString()}</td
>
<td class="border-r dark:border-gray-500 p-1 border-gray-300"
>{Object.keys(result.player_scores).length}</td
>
<td class:p-1={result.note}>
{#if result.note}
{result.note}
{/if}
</td>
</tr>
{/each}
</tbody>
</table>
{/if}
</div>
@@ -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>