This commit is contained in:
2025-09-06 12:25:18 +02:00
parent 985f6d9bf9
commit 6f55dedbaa
8 changed files with 212 additions and 25 deletions

View File

@@ -4,5 +4,7 @@ export enum MessageType {
GOTO = "GOTO",
SHOW_ANSWER = "SHOW_ANSWER",
HIDE_ANSWER = "HIDE_ANSWER",
SHOW_QUESTION = "SHOW_QUESTION",
HIDE_QUESTION = "HIDE_QUESTION",
VISITED_QUESTIONS = "VISITED_QUESTIONS"
}

View File

@@ -0,0 +1,67 @@
<script lang="ts">
import type { MultipleChoiceQuestion } from "./games/games";
interface Props {
question: MultipleChoiceQuestion;
showAnswer: boolean;
showQuestion: boolean;
[key: string]: unknown;
}
function shuffle<T>(array: T[]) {
let currentIndex = array.length;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
let randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
}
}
let { question, showAnswer, showQuestion }: Props = $props();
const answer = question.data.choices[0];
let _choices = [...question.data.choices];
shuffle(_choices);
</script>
<div class="mb-4 flex grow flex-col items-center text-6xl">
{#if showQuestion}
<div class="flex grow-1 items-center">
<div>{question.data.question}</div>
</div>
<div class="flex w-full grow-1 flex-wrap items-center justify-around gap-2">
{#each _choices as choice}
<div class="choiceCard {showAnswer && choice === answer ? 'answer' : ''}">
{choice}
</div>
{/each}
</div>
{/if}
</div>
<style>
.choiceCard {
border: 1px solid black;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
height: fit-content;
padding: 32px;
/* font-size: larger;
font-weight: bold;
cursor: pointer; */
}
.answer {
background-color: rgb(87, 255, 87);
box-shadow: 0 0 20px 5px rgb(87, 255, 87);
border: 1px solid rgb(50, 141, 50);
}
</style>

View File

@@ -3,18 +3,24 @@
label: string;
plus: (label: string) => void;
minus: (label: string) => void;
showPlus?: boolean;
showMinus?: boolean;
[key: string]: unknown;
}
let { label, plus, minus }: Props = $props();
let { label, plus, minus, showPlus = true, showMinus = true }: Props = $props();
</script>
<div class="specialBtn flex w-min gap-2 text-2xl">
<button class="innerBtn" onclick={() => minus(label)}>-</button>
{#if showMinus}
<button class="innerBtn" onclick={() => minus(label)}>-</button>
{/if}
<div class="whitespace-nowrap">
{label}
</div>
<button class="innerBtn" onclick={() => plus(label)}>+</button>
{#if showPlus}
<button class="innerBtn" onclick={() => plus(label)}>+</button>
{/if}
</div>
<style>

View File

@@ -4,10 +4,12 @@
interface Props {
players: Player[];
currentPlayer: string;
editable?: boolean;
onReload?: () => void;
[key: string]: unknown;
}
let { players, currentPlayer }: Props = $props();
let { players, currentPlayer, editable = false, onReload = () => {} }: Props = $props();
let _players = $derived(() => {
let p = [...players];
@@ -16,18 +18,33 @@
</script>
<div
class="h-full w-fit max-w-[400px] overflow-hidden border-r-1 border-solid border-gray-300 pr-4 pl-4"
class="h-full w-fit {editable === true
? 'max-w-[600px]'
: 'max-w-[400px]'} overflow-hidden border-r-1 border-solid border-gray-300 pr-4 pl-4"
>
<div class="flex justify-center">
<div class="flex items-center justify-around">
<h3 class="text-5xl">Scoreboard</h3>
{#if editable === true}
<button class="btn w-16" onclick={() => onReload()}>&#x21bb;</button>
{/if}
</div>
<div class="mt-4 text-3xl">
<table class="w-1/1">
<tbody>
{#each _players() as player}
{#each _players() as player (player.name)}
<tr class="{currentPlayer === player.name ? 'current' : ''} h-12">
<td class="pr-4 pl-2">{player.points}</td>
<td>{player.name}</td>
<td class="pr-4 pl-2">
{#if editable === true}
<input
class="inputField max-w-[200px]"
type="number"
bind:value={player.points}
/>
{:else}
{player.points}
{/if}
</td>
<td class="whitespace-nowrap">{player.name}</td>
</tr>
{/each}
</tbody>

View File

@@ -4,16 +4,19 @@
interface Props {
question: SimpleQuestion;
showAnswer: boolean;
showQuestion: boolean;
[key: string]: unknown;
}
let { question, showAnswer }: Props = $props();
let { question, showAnswer, showQuestion }: Props = $props();
</script>
<div class="mb-4 flex grow flex-col items-center text-6xl">
<div class="flex grow-1 items-center">
<div>{question.data.question}</div>
</div>
{#if showQuestion || showAnswer}
<div class="flex grow-1 items-center">
<div>{question.data.question}</div>
</div>
{/if}
{#if showAnswer}
<div class="flex grow-1 items-center">
{question.data.answer}

View File

@@ -10,10 +10,20 @@ const games: Games = [
questions: [
{
points: 100,
type: "SIMPLE",
type: "MULTIPLE_CHOICE",
data: {
question: "Question 1?",
answer: "Answer 1"
question: "Wie heißt unser Planet?",
choices: [
"Erde",
"Sonne",
"Mars",
"Venus",
"Saturn",
"Jupiter",
"Merkur",
"Uranus",
"Neptun"
]
}
},
{
@@ -946,11 +956,13 @@ export type SimpleQuestion = Question & {
};
};
/**
* First choice is correct answer. Choices need to be shuffled in component
*/
export type MultipleChoiceQuestion = Question & {
type: "MULTIPLE_CHOICE";
data: {
question: string;
answer: number;
choices: string[];
};
};