Skip to content

Commit 947eb2d

Browse files
authored
Merge pull request #8 from Moldybot9411/develop
Merge dev into master
2 parents aa6391d + 19b1a8e commit 947eb2d

4 files changed

Lines changed: 130 additions & 64 deletions

File tree

src/lib/components/Evaluation.svelte

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import Card from './Card.svelte';
66
import { decode } from 'html-entities';
77
import ProgressBar from './ProgressBar.svelte';
8+
import Scoreboard from './Scoreboard.svelte';
9+
import { getSortedScoreboard, getTotalScore } from '$lib/util.svelte';
810
9-
let answerStats: { answer: string; numPicks: number }[] = $state([]);
11+
let answerStats: { answer: string; numPicks: number; correctAnswer: boolean }[] = $state([]);
1012
let totalAnswers: number = $derived.by(() => {
1113
let res = 0;
1214
answerStats.forEach((el) => (res += el.numPicks));
@@ -15,20 +17,31 @@
1517
1618
$effect(() => {
1719
if (gameData.lastAnswerStats) {
18-
let stats: { answer: string; numPicks: number }[] = [];
20+
let stats: { answer: string; numPicks: number; correctAnswer: boolean }[] = [];
1921
2022
for (const answer of Object.keys(gameData.lastAnswerStats)) {
21-
stats.push({ answer, numPicks: gameData.lastAnswerStats[answer] });
23+
stats.push({
24+
answer,
25+
numPicks: gameData.lastAnswerStats[answer],
26+
correctAnswer: answer === gameData.state.lastCorrectAnswer,
27+
});
2228
}
2329
24-
stats = stats.sort((a, b) => b.numPicks - a.numPicks);
30+
stats = stats.sort((a, b) => {
31+
if (a.correctAnswer) return -1;
32+
33+
return b.numPicks - a.numPicks;
34+
});
2535
2636
answerStats = stats;
2737
}
2838
});
2939
</script>
3040

31-
<h1 class="flex min-h-12 items-center pr-16 text-3xl font-bold text-balance">
41+
<h1 class="min-h-12 items-center pr-16 text-3xl font-bold text-balance">
42+
<span class="text-xl text-text-muted"
43+
>Round {gameData.state.currentRound + 1}/{gameData.state.numRounds}:
44+
</span><br />
3245
{decode(gameData.questionData?.question)}
3346
</h1>
3447

@@ -67,30 +80,40 @@
6780
</div>
6881
</Card>
6982

70-
<Card elevation="medium" class={['flex flex-1 items-center justify-center p-8 md:p-16']}>
83+
<Card
84+
elevation="medium"
85+
class={['flex flex-1 flex-col items-center justify-center gap-4 p-8 md:p-16']}>
7186
<div
7287
class={[
7388
'text-6xl font-bold',
7489
(gameData.roundResult?.score ?? 0) > 0 ? 'text-surface-success' : 'text-surface-error',
7590
]}>
7691
{(gameData.roundResult?.score ?? 0) >= 0 && '+'}{gameData.roundResult?.score ?? 0}
7792
</div>
93+
<div class="text-text-muted">
94+
Total: {getTotalScore()}
95+
</div>
7896
</Card>
7997
</div>
8098

81-
<Card elevation="low" class="mb-4">
99+
<Card elevation="low" class="mb-2">
82100
<span class="text-2xl font-bold"> Stats: </span>
83101
{#each answerStats as answer}
84102
<div class="mb-4 last:mb-0">
85103
<span class="mb-1 flex w-full justify-between gap-4 text-text-muted">
86-
<span>{decode(answer.answer)}</span>
104+
<span class={[answer.correctAnswer ? 'text-surface-success' : 'text-surface-error']}
105+
>{decode(answer.answer)}</span>
87106
<span>{totalAnswers ? ((answer.numPicks / totalAnswers) * 100).toFixed(2) : 0}%</span>
88107
</span>
89-
<ProgressBar color="info" value={totalAnswers ? (answer.numPicks / totalAnswers) * 100 : 0} />
108+
<ProgressBar
109+
color={answer.correctAnswer ? 'success' : 'error'}
110+
value={totalAnswers ? (answer.numPicks / totalAnswers) * 100 : 0} />
90111
</div>
91112
{/each}
92113
</Card>
93114

115+
<Scoreboard scoreData={getSortedScoreboard()} showGauges={false} class="mb-4" />
116+
94117
{#if gameData.isAdmin}
95118
<div class="flex w-full gap-2">
96119
<Button label="Back to Lobby" class="ml-auto" variant="secondary" onclick={backToLobby} />

src/lib/components/PostGame.svelte

Lines changed: 4 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,10 @@
33
import { House } from '@lucide/svelte';
44
import Button from './Button.svelte';
55
import Podest from './Podest.svelte';
6-
import ProgressBar from './ProgressBar.svelte';
6+
import Scoreboard from './Scoreboard.svelte';
7+
import { getSortedScoreboard } from '$lib/util.svelte';
78
8-
let scoreBoard = $derived(gameData.state.scoreBoard);
9-
10-
let scoreBoardArray = $derived.by(() => {
11-
let res: { name: string; totalScore: number; numCorrectAnswers: number }[] = [];
12-
13-
for (const id of Object.keys(scoreBoard)) {
14-
res.push({
15-
name: scoreBoard[id].name,
16-
totalScore: scoreBoard[id].totalScore,
17-
numCorrectAnswers: scoreBoard[id].numCorrectAnswers,
18-
});
19-
}
20-
21-
res = res.sort(
22-
(a, b) =>
23-
b.totalScore - a.totalScore ||
24-
b.numCorrectAnswers - a.numCorrectAnswers ||
25-
a.name.localeCompare(b.name)
26-
);
27-
28-
return res;
29-
});
9+
let scoreBoardArray = getSortedScoreboard();
3010
</script>
3111

3212
<div class="mt-20 flex h-100 flex-col items-center justify-center gap-2 md:flex-row md:items-end">
@@ -69,39 +49,8 @@
6949

7050
{#if scoreBoardArray.length >= 4}
7151
<hr class="my-4 border-border" />
72-
<div class="mb-2 text-2xl font-bold">The Rest</div>
7352

74-
<div class="highlight overflow-hidden rounded-md border border-border">
75-
<table class="w-full min-w-max table-auto rounded-md text-left">
76-
<thead>
77-
<tr class="border-b border-border bg-surface">
78-
<th class="p-2">Name</th>
79-
<th class="p-2">Score</th>
80-
<th class="p-2">Correct Answers</th>
81-
</tr>
82-
</thead>
83-
<tbody>
84-
{#each scoreBoardArray.slice(3) as player}
85-
{@const percentage = player.numCorrectAnswers
86-
? (player.numCorrectAnswers / gameData.state.numRounds) * 100
87-
: 0}
88-
<tr class="border-b border-border bg-surface-light text-text-muted last:border-b-0">
89-
<td class="p-2">
90-
{player.name}
91-
</td>
92-
<td class="p-2">
93-
{player.totalScore}
94-
</td>
95-
<td class="p-2">
96-
<ProgressBar
97-
color={percentage >= 50 ? 'success' : percentage > 20 ? 'warning' : 'error'}
98-
value={percentage} />
99-
</td>
100-
</tr>
101-
{/each}
102-
</tbody>
103-
</table>
104-
</div>
53+
<Scoreboard scoreData={scoreBoardArray.slice(3)} startPlacementAt={4} />
10554
{/if}
10655

10756
{#if !gameData.isAdmin}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<script lang="ts">
2+
import { gameData } from '$lib/gameStore.svelte';
3+
import type { ClassValue } from 'svelte/elements';
4+
import ProgressBar from './ProgressBar.svelte';
5+
6+
type Props = {
7+
scoreData: {
8+
id: string;
9+
name: string;
10+
totalScore: number;
11+
numCorrectAnswers: number;
12+
}[];
13+
startPlacementAt?: number;
14+
showGauges?: boolean;
15+
class?: ClassValue;
16+
style?: string;
17+
};
18+
19+
let {
20+
scoreData = [],
21+
startPlacementAt = 1,
22+
showGauges = true,
23+
class: classes,
24+
style,
25+
...others
26+
}: Props = $props();
27+
</script>
28+
29+
<div class={['overflow-hidden rounded-md border border-border', classes]} {style} {...others}>
30+
<table class="w-full min-w-max table-auto rounded-md text-left">
31+
<thead>
32+
<tr class="border-b border-border bg-surface">
33+
<th class="p-2"></th>
34+
<th class="p-2">Name</th>
35+
<th class="p-2">Score</th>
36+
{#if showGauges}
37+
<th class="p-2">Correct Answers</th>
38+
{/if}
39+
</tr>
40+
</thead>
41+
<tbody>
42+
{#each scoreData as player, index}
43+
{@const percentage = player.numCorrectAnswers
44+
? (player.numCorrectAnswers / gameData.state.numRounds) * 100
45+
: 0}
46+
<tr
47+
class={[
48+
'border-b border-border bg-surface-light text-text-muted last:border-b-0',
49+
player.id === gameData.socket?.id && 'bg-surface-dark! font-bold text-text!',
50+
]}>
51+
<td class="p-2">
52+
{index + startPlacementAt}.
53+
</td>
54+
<td class="p-2">
55+
{player.name}
56+
</td>
57+
<td class="p-2">
58+
{player.totalScore}
59+
</td>
60+
{#if showGauges}
61+
<td class="p-2">
62+
<ProgressBar
63+
color={percentage >= 50 ? 'success' : percentage > 20 ? 'warning' : 'error'}
64+
value={percentage} />
65+
</td>
66+
{/if}
67+
</tr>
68+
{/each}
69+
</tbody>
70+
</table>
71+
</div>

src/lib/util.svelte.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { gameData } from './gameStore.svelte';
2+
3+
export function getSortedScoreboard() {
4+
const res = Object.entries(gameData.state.scoreBoard).map(([id, player]) => ({
5+
id,
6+
name: player.name,
7+
totalScore: player.totalScore,
8+
numCorrectAnswers: player.numCorrectAnswers,
9+
}));
10+
11+
return res.sort(
12+
(a, b) =>
13+
b.totalScore - a.totalScore ||
14+
b.numCorrectAnswers - a.numCorrectAnswers ||
15+
a.name.localeCompare(b.name)
16+
);
17+
}
18+
19+
export function getTotalScore() {
20+
const playerData = gameData.state.scoreBoard[gameData.socket?.id ?? ''];
21+
22+
return playerData.totalScore ?? 0;
23+
}

0 commit comments

Comments
 (0)