feat: add tokens column to dashboard and update rendering logic
All checks were successful
Build and Push Docker Image / docker (push) Successful in 8s

This commit is contained in:
2025-09-05 15:21:48 +02:00
parent e70cbbb712
commit de2c7b0a3a
3 changed files with 107 additions and 91 deletions

View File

@@ -113,6 +113,7 @@
<th class="py-2 pr-3">Verbindung</th> <th class="py-2 pr-3">Verbindung</th>
<th class="py-2 pr-3">Ready</th> <th class="py-2 pr-3">Ready</th>
<th class="py-2 pr-3">Score</th> <th class="py-2 pr-3">Score</th>
<th class="py-2 pr-3">Tokens</th>
</tr> </tr>
</thead> </thead>
<tbody id="dashboardList" class="divide-y divide-slate-200 dark:divide-slate-800"></tbody> <tbody id="dashboardList" class="divide-y divide-slate-200 dark:divide-slate-800"></tbody>
@@ -144,8 +145,11 @@
</div> </div>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- Player Card -->
<div id="nowPlaying" <div id="nowPlaying"
class="hidden rounded-lg border border-slate-200 dark:border-slate-800 p-4 bg-slate-50/60 dark:bg-slate-800/60"> class="hidden md:row-span-2 h-full rounded-lg border border-slate-200 dark:border-slate-800 p-4 bg-slate-50/60 dark:bg-slate-800/60">
<h3 class="text-lg font-semibold mb-2">Musik-Player</h3>
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-3"> <div class="flex flex-col md:flex-row md:items-center md:justify-between gap-3">
<div class="text-lg font-semibold"> <div class="text-lg font-semibold">
<strong id="npTitle">&nbsp;</strong><span id="npArtist"></span><span id="npYear" <strong id="npTitle">&nbsp;</strong><span id="npArtist"></span><span id="npYear"
@@ -201,45 +205,60 @@
<input id="volumeSlider" type="range" min="0" max="1" step="0.01" class="w-40 accent-indigo-600" /> <input id="volumeSlider" type="range" min="0" max="1" step="0.01" class="w-40 accent-indigo-600" />
</label> </label>
</div> </div>
</div>
</div>
</div>
<!-- Answer form: everyone can try to guess title & artist for a coin --> <!-- Guess Card -->
<form id="answerForm" class="mt-4 w-full flex flex-col md:flex-row gap-2 md:items-end"> <div id="guessBox"
<label class="flex-1 text-sm"> class="rounded-lg border border-slate-200 dark:border-slate-800 p-4 bg-white/70 dark:bg-slate-900/60">
<h3 class="text-lg font-semibold">Raten</h3>
<p class="text-sm text-slate-500 dark:text-slate-400 mb-2">Gib Titel und Künstler ein und drücke Abschicken.
</p>
<form id="answerForm" class="mt-2 w-full flex flex-col gap-2">
<label class="text-sm">
<span class="text-slate-700 dark:text-slate-300">Titel</span> <span class="text-slate-700 dark:text-slate-300">Titel</span>
<input id="guessTitle" name="title" placeholder="Songtitel" autocomplete="off" <input id="guessTitle" name="title" placeholder="Songtitel" autocomplete="off"
class="mt-1 w-full h-10 rounded-lg border border-slate-300 dark:border-slate-700 bg-white/80 dark:bg-slate-800 px-3" /> class="mt-1 w-full h-11 rounded-lg border border-slate-300 dark:border-slate-700 bg-white/80 dark:bg-slate-800 px-3" />
</label> </label>
<label class="flex-1 text-sm"> <label class="text-sm">
<span class="text-slate-700 dark:text-slate-300">Künstler</span> <span class="text-slate-700 dark:text-slate-300">Künstler</span>
<input id="guessArtist" name="artist" placeholder="Künstler" autocomplete="off" <input id="guessArtist" name="artist" placeholder="Künstler" autocomplete="off"
class="mt-1 w-full h-10 rounded-lg border border-slate-300 dark:border-slate-700 bg-white/80 dark:bg-slate-800 px-3" /> class="mt-1 w-full h-11 rounded-lg border border-slate-300 dark:border-slate-700 bg-white/80 dark:bg-slate-800 px-3" />
</label> </label>
<div class="flex items-center gap-2">
<button id="submitAnswer" type="submit" <button id="submitAnswer" type="submit"
class="h-10 px-4 rounded-lg bg-emerald-600 hover:bg-emerald-700 text-white font-medium"> class="h-11 px-4 rounded-lg bg-emerald-600 hover:bg-emerald-700 text-white font-medium">
Abschicken Abschicken
</button> </button>
<div id="answerResult" class="text-sm"></div>
</div>
</form> </form>
<div id="answerResult" class="mt-1 text-sm"></div>
</div> </div>
</div>
<div class="mt-3 flex flex-wrap items-center gap-3"> <!-- Position Card (under Guess, beside Player) -->
<div id="positionBox"
class="rounded-lg border border-slate-200 dark:border-slate-800 p-4 bg-white/70 dark:bg-slate-900/60 md:col-start-2">
<h3 class="text-lg font-semibold">Position</h3>
<p class="text-sm text-slate-500 dark:text-slate-400 mb-2">Wähle die Position und klicke Platzieren.</p>
<div class="flex flex-wrap items-center gap-3">
<div id="placeArea" class="hidden flex items-center gap-2"> <div id="placeArea" class="hidden flex items-center gap-2">
<label class="text-sm text-slate-600 dark:text-slate-300">Position:
<select id="slotSelect" <select id="slotSelect"
class="ml-2 h-10 rounded-lg border border-slate-300 dark:border-slate-700 bg-white/80 dark:bg-slate-800 px-3"></select> class="h-10 rounded-lg border border-slate-300 dark:border-slate-700 bg-white/80 dark:bg-slate-800 px-3"></select>
</label>
<button id="placeBtn" <button id="placeBtn"
class="h-10 px-4 rounded-lg bg-slate-900 hover:bg-slate-700 text-white font-medium dark:bg-slate-700 dark:hover:bg-slate-600"> class="h-10 px-4 rounded-lg bg-slate-900 hover:bg-slate-700 text-white font-medium dark:bg-slate-700 dark:hover:bg-slate-600">
Platzieren Platzieren
</button> </button>
</div> </div>
<div id="nextArea" class="hidden"> <div id="nextArea" class="hidden">
<button id="nextBtn" class="h-10 px-4 rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white font-medium"> <button id="nextBtn"
class="h-10 px-4 rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white font-medium">
Next Next
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div>
<div> <div>
<h3 class="text-lg font-semibold mt-2">Deine Zeitleiste</h3> <h3 class="text-lg font-semibold mt-2">Deine Zeitleiste</h3>
@@ -248,9 +267,7 @@
</div> </div>
</div> </div>
<div class="flex items-center gap-3 text-slate-700 dark:text-slate-300">
Tokens: <span id="tokens" class="font-semibold">0</span>
</div>
</div> </div>
</div> </div>

View File

@@ -7,7 +7,6 @@ export const $nameDisplay = el('nameDisplay');
export const $status = el('status'); export const $status = el('status');
export const $guesser = el('guesser'); export const $guesser = el('guesser');
export const $timeline = el('timeline'); export const $timeline = el('timeline');
export const $tokens = el('tokens');
export const $audio = el('audio'); export const $audio = el('audio');
export const $np = el('nowPlaying'); export const $np = el('nowPlaying');
export const $npTitle = el('npTitle'); export const $npTitle = el('npTitle');

View File

@@ -18,7 +18,6 @@ import {
$startGame, $startGame,
$status, $status,
$timeline, $timeline,
$tokens,
} from './dom.js'; } from './dom.js';
export function renderRoom(room) { export function renderRoom(room) {
@@ -58,6 +57,7 @@ export function renderRoom(room) {
? '<span class="text-emerald-600">bereit</span>' ? '<span class="text-emerald-600">bereit</span>'
: '<span class="text-slate-400">-</span>'; : '<span class="text-slate-400">-</span>';
const score = room.state.timeline?.[p.id]?.length ?? 0; const score = room.state.timeline?.[p.id]?.length ?? 0;
const tokens = room.state.tokens?.[p.id] ?? 0;
const isMe = p.id === state.playerId; const isMe = p.id === state.playerId;
return ` return `
<tr class="align-top"> <tr class="align-top">
@@ -71,6 +71,7 @@ export function renderRoom(room) {
<td class="py-2 pr-3">${connected}</td> <td class="py-2 pr-3">${connected}</td>
<td class="py-2 pr-3">${ready}</td> <td class="py-2 pr-3">${ready}</td>
<td class="py-2 pr-3 font-semibold tabular-nums">${score}</td> <td class="py-2 pr-3 font-semibold tabular-nums">${score}</td>
<td class="py-2 pr-3 font-semibold tabular-nums">${tokens}</td>
</tr>`; </tr>`;
}) })
.join(''); .join('');
@@ -93,7 +94,6 @@ export function renderRoom(room) {
`; `;
}) })
.join(''); .join('');
$tokens.textContent = room.state.tokens?.[state.playerId] ?? 0;
if ($readyChk) { if ($readyChk) {
const serverReady = !!me?.ready; const serverReady = !!me?.ready;
if (state.pendingReady === null || state.pendingReady === undefined) { if (state.pendingReady === null || state.pendingReady === undefined) {